aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath.h9
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c28
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h31
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c71
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h7
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c3
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c65
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h17
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c158
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c158
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c9
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c32
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c35
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile6
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h178
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c334
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h208
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c318
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c531
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c54
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c322
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c780
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c50
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c45
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h35
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c122
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h80
-rw-r--r--drivers/net/wireless/ath/regd.c7
-rw-r--r--drivers/net/wireless/ath/regd_common.h2
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-rs.c1
-rw-r--r--drivers/net/wireless/mwifiex/11n.c32
-rw-r--r--drivers/net/wireless/mwifiex/11n.h53
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c5
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c12
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h6
-rw-r--r--drivers/net/wireless/mwifiex/README2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c115
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c9
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c194
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c7
-rw-r--r--drivers/net/wireless/mwifiex/decl.h24
-rw-r--r--drivers/net/wireless/mwifiex/fw.h27
-rw-r--r--drivers/net/wireless/mwifiex/init.c9
-rw-r--r--drivers/net/wireless/mwifiex/join.c90
-rw-r--r--drivers/net/wireless/mwifiex/main.c74
-rw-r--r--drivers/net/wireless/mwifiex/main.h140
-rw-r--r--drivers/net/wireless/mwifiex/scan.c133
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c33
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c127
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c47
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c25
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c1018
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c2
-rw-r--r--drivers/net/wireless/mwifiex/util.c51
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c19
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h8
-rw-r--r--drivers/net/wireless/mwl8k.c77
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c35
-rw-r--r--drivers/net/wireless/rtlwifi/base.c12
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.c14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c2
-rw-r--r--include/linux/nl80211.h34
-rw-r--r--include/net/cfg80211.h33
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/mac80211/cfg.c29
-rw-r--r--net/mac80211/debugfs_sta.c26
-rw-r--r--net/mac80211/driver-ops.h13
-rw-r--r--net/mac80211/driver-trace.h20
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/main.c9
-rw-r--r--net/mac80211/mesh.c14
-rw-r--r--net/mac80211/mesh.h3
-rw-r--r--net/mac80211/mesh_pathtbl.c49
-rw-r--r--net/mac80211/mesh_plink.c35
-rw-r--r--net/mac80211/mlme.c17
-rw-r--r--net/mac80211/rx.c23
-rw-r--r--net/mac80211/sta_info.c3
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/wireless/mesh.c23
-rw-r--r--net/wireless/nl80211.c67
-rw-r--r--net/wireless/nl80211.h4
110 files changed, 3829 insertions, 2962 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 6d7105b7e8f1..7cf4317a2a84 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -123,14 +123,7 @@ struct ath_ops {
123}; 123};
124 124
125struct ath_common; 125struct ath_common;
126 126struct ath_bus_ops;
127struct ath_bus_ops {
128 enum ath_bus_type ath_bus_type;
129 void (*read_cachesize)(struct ath_common *common, int *csz);
130 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
131 void (*bt_coex_prep)(struct ath_common *common);
132 void (*extn_synch_en)(struct ath_common *common);
133};
134 127
135struct ath_common { 128struct ath_common {
136 void *ah; 129 void *ah;
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
index 82324e98efef..ea9982781559 100644
--- a/drivers/net/wireless/ath/ath5k/ahb.c
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/nl80211.h> 19#include <linux/nl80211.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/etherdevice.h>
21#include <ar231x_platform.h> 22#include <ar231x_platform.h>
22#include "ath5k.h" 23#include "ath5k.h"
23#include "debug.h" 24#include "debug.h"
@@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah)
62 return 0; 63 return 0;
63} 64}
64 65
66static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
67{
68 struct ath5k_softc *sc = ah->ah_sc;
69 struct platform_device *pdev = to_platform_device(sc->dev);
70 struct ar231x_board_config *bcfg = pdev->dev.platform_data;
71 u8 *cfg_mac;
72
73 if (to_platform_device(sc->dev)->id == 0)
74 cfg_mac = bcfg->config->wlan0_mac;
75 else
76 cfg_mac = bcfg->config->wlan1_mac;
77
78 memcpy(mac, cfg_mac, ETH_ALEN);
79 return 0;
80}
81
65static const struct ath_bus_ops ath_ahb_bus_ops = { 82static const struct ath_bus_ops ath_ahb_bus_ops = {
66 .ath_bus_type = ATH_AHB, 83 .ath_bus_type = ATH_AHB,
67 .read_cachesize = ath5k_ahb_read_cachesize, 84 .read_cachesize = ath5k_ahb_read_cachesize,
68 .eeprom_read = ath5k_ahb_eeprom_read, 85 .eeprom_read = ath5k_ahb_eeprom_read,
86 .eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
69}; 87};
70 88
71/*Initialization*/ 89/*Initialization*/
@@ -142,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev)
142 else 160 else
143 reg |= AR5K_AR5312_ENABLE_WLAN1; 161 reg |= AR5K_AR5312_ENABLE_WLAN1;
144 __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); 162 __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
163
164 /*
165 * On a dual-band AR5312, the multiband radio is only
166 * used as pass-through. Disable 2 GHz support in the
167 * driver for it
168 */
169 if (to_platform_device(sc->dev)->id == 0 &&
170 (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) ==
171 (BD_WLAN1|BD_WLAN0))
172 __set_bit(ATH_STAT_2G_DISABLED, sc->status);
145 } 173 }
146 174
147 ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); 175 ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 8a06dbd39629..bb50700436fe 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -224,8 +224,7 @@
224 224
225/* SIFS */ 225/* SIFS */
226#define AR5K_INIT_SIFS_TURBO 6 226#define AR5K_INIT_SIFS_TURBO 6
227/* XXX: 8 from initvals 10 from standard */ 227#define AR5K_INIT_SIFS_DEFAULT_BG 10
228#define AR5K_INIT_SIFS_DEFAULT_BG 8
229#define AR5K_INIT_SIFS_DEFAULT_A 16 228#define AR5K_INIT_SIFS_DEFAULT_A 16
230#define AR5K_INIT_SIFS_HALF_RATE 32 229#define AR5K_INIT_SIFS_HALF_RATE 32
231#define AR5K_INIT_SIFS_QUARTER_RATE 64 230#define AR5K_INIT_SIFS_QUARTER_RATE 64
@@ -453,12 +452,10 @@ struct ath5k_tx_status {
453 u16 ts_seqnum; 452 u16 ts_seqnum;
454 u16 ts_tstamp; 453 u16 ts_tstamp;
455 u8 ts_status; 454 u8 ts_status;
456 u8 ts_rate[4];
457 u8 ts_retry[4];
458 u8 ts_final_idx; 455 u8 ts_final_idx;
456 u8 ts_final_retry;
459 s8 ts_rssi; 457 s8 ts_rssi;
460 u8 ts_shortretry; 458 u8 ts_shortretry;
461 u8 ts_longretry;
462 u8 ts_virtcol; 459 u8 ts_virtcol;
463 u8 ts_antenna; 460 u8 ts_antenna;
464}; 461};
@@ -875,6 +872,19 @@ enum ath5k_int {
875 AR5K_INT_QTRIG = 0x40000000, /* Non common */ 872 AR5K_INT_QTRIG = 0x40000000, /* Non common */
876 AR5K_INT_GLOBAL = 0x80000000, 873 AR5K_INT_GLOBAL = 0x80000000,
877 874
875 AR5K_INT_TX_ALL = AR5K_INT_TXOK
876 | AR5K_INT_TXDESC
877 | AR5K_INT_TXERR
878 | AR5K_INT_TXEOL
879 | AR5K_INT_TXURN,
880
881 AR5K_INT_RX_ALL = AR5K_INT_RXOK
882 | AR5K_INT_RXDESC
883 | AR5K_INT_RXERR
884 | AR5K_INT_RXNOFRM
885 | AR5K_INT_RXEOL
886 | AR5K_INT_RXORN,
887
878 AR5K_INT_COMMON = AR5K_INT_RXOK 888 AR5K_INT_COMMON = AR5K_INT_RXOK
879 | AR5K_INT_RXDESC 889 | AR5K_INT_RXDESC
880 | AR5K_INT_RXERR 890 | AR5K_INT_RXERR
@@ -1058,6 +1068,7 @@ struct ath5k_hw {
1058 u8 ah_coverage_class; 1068 u8 ah_coverage_class;
1059 bool ah_ack_bitrate_high; 1069 bool ah_ack_bitrate_high;
1060 u8 ah_bwmode; 1070 u8 ah_bwmode;
1071 bool ah_short_slot;
1061 1072
1062 /* Antenna Control */ 1073 /* Antenna Control */
1063 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 1074 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1144,6 +1155,13 @@ struct ath5k_hw {
1144 struct ath5k_rx_status *); 1155 struct ath5k_rx_status *);
1145}; 1156};
1146 1157
1158struct ath_bus_ops {
1159 enum ath_bus_type ath_bus_type;
1160 void (*read_cachesize)(struct ath_common *common, int *csz);
1161 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
1162 int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac);
1163};
1164
1147/* 1165/*
1148 * Prototypes 1166 * Prototypes
1149 */ 1167 */
@@ -1227,13 +1245,12 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah);
1227/* EEPROM access functions */ 1245/* EEPROM access functions */
1228int ath5k_eeprom_init(struct ath5k_hw *ah); 1246int ath5k_eeprom_init(struct ath5k_hw *ah);
1229void ath5k_eeprom_detach(struct ath5k_hw *ah); 1247void ath5k_eeprom_detach(struct ath5k_hw *ah);
1230int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1231 1248
1232 1249
1233/* Protocol Control Unit Functions */ 1250/* Protocol Control Unit Functions */
1234/* Helpers */ 1251/* Helpers */
1235int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, 1252int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
1236 int len, struct ieee80211_rate *rate); 1253 int len, struct ieee80211_rate *rate, bool shortpre);
1237unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); 1254unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
1238unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); 1255unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
1239extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); 1256extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index bc8240560488..1588401de3c4 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -313,12 +313,17 @@ int ath5k_hw_init(struct ath5k_softc *sc)
313 goto err; 313 goto err;
314 } 314 }
315 315
316 if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) {
317 __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode);
318 __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode);
319 }
320
316 /* Crypto settings */ 321 /* Crypto settings */
317 common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? 322 common->keymax = (sc->ah->ah_version == AR5K_AR5210 ?
318 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); 323 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);
319 324
320 if (srev >= AR5K_SREV_AR5212_V4 && 325 if (srev >= AR5K_SREV_AR5212_V4 &&
321 (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && 326 (ee->ee_version < AR5K_EEPROM_VERSION_5_0 ||
322 !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) 327 !AR5K_EEPROM_AES_DIS(ee->ee_misc5)))
323 common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; 328 common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
324 329
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4d7f21ee111c..7583841fc29a 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1444,6 +1444,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
1444} 1444}
1445 1445
1446static void 1446static void
1447ath5k_set_current_imask(struct ath5k_softc *sc)
1448{
1449 enum ath5k_int imask = sc->imask;
1450 unsigned long flags;
1451
1452 spin_lock_irqsave(&sc->irqlock, flags);
1453 if (sc->rx_pending)
1454 imask &= ~AR5K_INT_RX_ALL;
1455 if (sc->tx_pending)
1456 imask &= ~AR5K_INT_TX_ALL;
1457 ath5k_hw_set_imr(sc->ah, imask);
1458 spin_unlock_irqrestore(&sc->irqlock, flags);
1459}
1460
1461static void
1447ath5k_tasklet_rx(unsigned long data) 1462ath5k_tasklet_rx(unsigned long data)
1448{ 1463{
1449 struct ath5k_rx_status rs = {}; 1464 struct ath5k_rx_status rs = {};
@@ -1506,6 +1521,8 @@ next:
1506 } while (ath5k_rxbuf_setup(sc, bf) == 0); 1521 } while (ath5k_rxbuf_setup(sc, bf) == 0);
1507unlock: 1522unlock:
1508 spin_unlock(&sc->rxbuflock); 1523 spin_unlock(&sc->rxbuflock);
1524 sc->rx_pending = false;
1525 ath5k_set_current_imask(sc);
1509} 1526}
1510 1527
1511 1528
@@ -1573,28 +1590,28 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
1573 struct ath5k_txq *txq, struct ath5k_tx_status *ts) 1590 struct ath5k_txq *txq, struct ath5k_tx_status *ts)
1574{ 1591{
1575 struct ieee80211_tx_info *info; 1592 struct ieee80211_tx_info *info;
1593 u8 tries[3];
1576 int i; 1594 int i;
1577 1595
1578 sc->stats.tx_all_count++; 1596 sc->stats.tx_all_count++;
1579 sc->stats.tx_bytes_count += skb->len; 1597 sc->stats.tx_bytes_count += skb->len;
1580 info = IEEE80211_SKB_CB(skb); 1598 info = IEEE80211_SKB_CB(skb);
1581 1599
1600 tries[0] = info->status.rates[0].count;
1601 tries[1] = info->status.rates[1].count;
1602 tries[2] = info->status.rates[2].count;
1603
1582 ieee80211_tx_info_clear_status(info); 1604 ieee80211_tx_info_clear_status(info);
1583 for (i = 0; i < 4; i++) { 1605
1606 for (i = 0; i < ts->ts_final_idx; i++) {
1584 struct ieee80211_tx_rate *r = 1607 struct ieee80211_tx_rate *r =
1585 &info->status.rates[i]; 1608 &info->status.rates[i];
1586 1609
1587 if (ts->ts_rate[i]) { 1610 r->count = tries[i];
1588 r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]);
1589 r->count = ts->ts_retry[i];
1590 } else {
1591 r->idx = -1;
1592 r->count = 0;
1593 }
1594 } 1611 }
1595 1612
1596 /* count the successful attempt as well */ 1613 info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry;
1597 info->status.rates[ts->ts_final_idx].count++; 1614 info->status.rates[ts->ts_final_idx + 1].idx = -1;
1598 1615
1599 if (unlikely(ts->ts_status)) { 1616 if (unlikely(ts->ts_status)) {
1600 sc->stats.ack_fail++; 1617 sc->stats.ack_fail++;
@@ -1609,6 +1626,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
1609 } else { 1626 } else {
1610 info->flags |= IEEE80211_TX_STAT_ACK; 1627 info->flags |= IEEE80211_TX_STAT_ACK;
1611 info->status.ack_signal = ts->ts_rssi; 1628 info->status.ack_signal = ts->ts_rssi;
1629
1630 /* count the successful attempt as well */
1631 info->status.rates[ts->ts_final_idx].count++;
1612 } 1632 }
1613 1633
1614 /* 1634 /*
@@ -1690,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data)
1690 for (i=0; i < AR5K_NUM_TX_QUEUES; i++) 1710 for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
1691 if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) 1711 if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
1692 ath5k_tx_processq(sc, &sc->txqs[i]); 1712 ath5k_tx_processq(sc, &sc->txqs[i]);
1713
1714 sc->tx_pending = false;
1715 ath5k_set_current_imask(sc);
1693} 1716}
1694 1717
1695 1718
@@ -2119,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
2119 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ 2142 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
2120} 2143}
2121 2144
2145static void
2146ath5k_schedule_rx(struct ath5k_softc *sc)
2147{
2148 sc->rx_pending = true;
2149 tasklet_schedule(&sc->rxtq);
2150}
2151
2152static void
2153ath5k_schedule_tx(struct ath5k_softc *sc)
2154{
2155 sc->tx_pending = true;
2156 tasklet_schedule(&sc->txtq);
2157}
2158
2122irqreturn_t 2159irqreturn_t
2123ath5k_intr(int irq, void *dev_id) 2160ath5k_intr(int irq, void *dev_id)
2124{ 2161{
@@ -2161,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id)
2161 ieee80211_queue_work(sc->hw, &sc->reset_work); 2198 ieee80211_queue_work(sc->hw, &sc->reset_work);
2162 } 2199 }
2163 else 2200 else
2164 tasklet_schedule(&sc->rxtq); 2201 ath5k_schedule_rx(sc);
2165 } else { 2202 } else {
2166 if (status & AR5K_INT_SWBA) { 2203 if (status & AR5K_INT_SWBA) {
2167 tasklet_hi_schedule(&sc->beacontq); 2204 tasklet_hi_schedule(&sc->beacontq);
@@ -2179,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id)
2179 ath5k_hw_update_tx_triglevel(ah, true); 2216 ath5k_hw_update_tx_triglevel(ah, true);
2180 } 2217 }
2181 if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) 2218 if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
2182 tasklet_schedule(&sc->rxtq); 2219 ath5k_schedule_rx(sc);
2183 if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC 2220 if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
2184 | AR5K_INT_TXERR | AR5K_INT_TXEOL)) 2221 | AR5K_INT_TXERR | AR5K_INT_TXEOL))
2185 tasklet_schedule(&sc->txtq); 2222 ath5k_schedule_tx(sc);
2186 if (status & AR5K_INT_BMISS) { 2223 if (status & AR5K_INT_BMISS) {
2187 /* TODO */ 2224 /* TODO */
2188 } 2225 }
@@ -2201,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id)
2201 2238
2202 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); 2239 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
2203 2240
2241 if (sc->rx_pending || sc->tx_pending)
2242 ath5k_set_current_imask(sc);
2243
2204 if (unlikely(!counter)) 2244 if (unlikely(!counter))
2205 ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); 2245 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
2206 2246
@@ -2572,6 +2612,8 @@ done:
2572 2612
2573static void stop_tasklets(struct ath5k_softc *sc) 2613static void stop_tasklets(struct ath5k_softc *sc)
2574{ 2614{
2615 sc->rx_pending = false;
2616 sc->tx_pending = false;
2575 tasklet_kill(&sc->rxtq); 2617 tasklet_kill(&sc->rxtq);
2576 tasklet_kill(&sc->txtq); 2618 tasklet_kill(&sc->txtq);
2577 tasklet_kill(&sc->calib); 2619 tasklet_kill(&sc->calib);
@@ -2838,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw)
2838 INIT_WORK(&sc->reset_work, ath5k_reset_work); 2880 INIT_WORK(&sc->reset_work, ath5k_reset_work);
2839 INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); 2881 INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work);
2840 2882
2841 ret = ath5k_eeprom_read_mac(ah, mac); 2883 ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac);
2842 if (ret) { 2884 if (ret) {
2843 ATH5K_ERR(sc, "unable to read address from EEPROM\n"); 2885 ATH5K_ERR(sc, "unable to read address from EEPROM\n");
2844 goto err_queues; 2886 goto err_queues;
@@ -2898,7 +2940,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc)
2898 * XXX: ??? detach ath5k_hw ??? 2940 * XXX: ??? detach ath5k_hw ???
2899 * Other than that, it's straightforward... 2941 * Other than that, it's straightforward...
2900 */ 2942 */
2901 ath5k_debug_finish_device(sc);
2902 ieee80211_unregister_hw(hw); 2943 ieee80211_unregister_hw(hw);
2903 ath5k_desc_free(sc); 2944 ath5k_desc_free(sc);
2904 ath5k_txq_release(sc); 2945 ath5k_txq_release(sc);
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 978f1f4ac2f3..b294f3305011 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -193,12 +193,13 @@ struct ath5k_softc {
193 dma_addr_t desc_daddr; /* DMA (physical) address */ 193 dma_addr_t desc_daddr; /* DMA (physical) address */
194 size_t desc_len; /* size of TX/RX descriptors */ 194 size_t desc_len; /* size of TX/RX descriptors */
195 195
196 DECLARE_BITMAP(status, 5); 196 DECLARE_BITMAP(status, 6);
197#define ATH_STAT_INVALID 0 /* disable hardware accesses */ 197#define ATH_STAT_INVALID 0 /* disable hardware accesses */
198#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ 198#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
199#define ATH_STAT_PROMISC 2 199#define ATH_STAT_PROMISC 2
200#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ 200#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
201#define ATH_STAT_STARTED 4 /* opened & irqs enabled */ 201#define ATH_STAT_STARTED 4 /* opened & irqs enabled */
202#define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */
202 203
203 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ 204 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
204 struct ieee80211_channel *curchan; /* current h/w channel */ 205 struct ieee80211_channel *curchan; /* current h/w channel */
@@ -207,6 +208,10 @@ struct ath5k_softc {
207 208
208 enum ath5k_int imask; /* interrupt mask copy */ 209 enum ath5k_int imask; /* interrupt mask copy */
209 210
211 spinlock_t irqlock;
212 bool rx_pending; /* rx tasklet pending */
213 bool tx_pending; /* tx tasklet pending */
214
210 u8 lladdr[ETH_ALEN]; 215 u8 lladdr[ETH_ALEN];
211 u8 bssidmask[ETH_ALEN]; 216 u8 bssidmask[ETH_ALEN];
212 217
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index f77e8a703c5c..7dd88e1c3ff8 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
94 } 94 }
95 } 95 }
96 96
97 if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112)
98 __clear_bit(AR5K_MODE_11A, caps->cap_mode);
99
97 /* Set number of supported TX queues */ 100 /* Set number of supported TX queues */
98 if (ah->ah_version == AR5K_AR5210) 101 if (ah->ah_version == AR5K_AR5210)
99 caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; 102 caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU;
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 0230f30e9e9a..0bf7313b8a17 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -888,65 +888,38 @@ static const struct file_operations fops_queue = {
888void 888void
889ath5k_debug_init_device(struct ath5k_softc *sc) 889ath5k_debug_init_device(struct ath5k_softc *sc)
890{ 890{
891 sc->debug.level = ath5k_debug; 891 struct dentry *phydir;
892 892
893 sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", 893 sc->debug.level = ath5k_debug;
894 sc->hw->wiphy->debugfsdir);
895 894
896 sc->debug.debugfs_debug = debugfs_create_file("debug", 895 phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir);
897 S_IWUSR | S_IRUSR, 896 if (!phydir)
898 sc->debug.debugfs_phydir, sc, &fops_debug); 897 return;
899 898
900 sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR, 899 debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc,
901 sc->debug.debugfs_phydir, sc, &fops_registers); 900 &fops_debug);
902 901
903 sc->debug.debugfs_beacon = debugfs_create_file("beacon", 902 debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers);
904 S_IWUSR | S_IRUSR,
905 sc->debug.debugfs_phydir, sc, &fops_beacon);
906 903
907 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, 904 debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc,
908 sc->debug.debugfs_phydir, sc, &fops_reset); 905 &fops_beacon);
909 906
910 sc->debug.debugfs_antenna = debugfs_create_file("antenna", 907 debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset);
911 S_IWUSR | S_IRUSR,
912 sc->debug.debugfs_phydir, sc, &fops_antenna);
913 908
914 sc->debug.debugfs_misc = debugfs_create_file("misc", 909 debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc,
915 S_IRUSR, 910 &fops_antenna);
916 sc->debug.debugfs_phydir, sc, &fops_misc);
917 911
918 sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", 912 debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc);
919 S_IWUSR | S_IRUSR,
920 sc->debug.debugfs_phydir, sc,
921 &fops_frameerrors);
922 913
923 sc->debug.debugfs_ani = debugfs_create_file("ani", 914 debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc,
924 S_IWUSR | S_IRUSR, 915 &fops_frameerrors);
925 sc->debug.debugfs_phydir, sc,
926 &fops_ani);
927 916
928 sc->debug.debugfs_queue = debugfs_create_file("queue", 917 debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani);
929 S_IWUSR | S_IRUSR,
930 sc->debug.debugfs_phydir, sc,
931 &fops_queue);
932}
933 918
934void 919 debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc,
935ath5k_debug_finish_device(struct ath5k_softc *sc) 920 &fops_queue);
936{
937 debugfs_remove(sc->debug.debugfs_debug);
938 debugfs_remove(sc->debug.debugfs_registers);
939 debugfs_remove(sc->debug.debugfs_beacon);
940 debugfs_remove(sc->debug.debugfs_reset);
941 debugfs_remove(sc->debug.debugfs_antenna);
942 debugfs_remove(sc->debug.debugfs_misc);
943 debugfs_remove(sc->debug.debugfs_frameerrors);
944 debugfs_remove(sc->debug.debugfs_ani);
945 debugfs_remove(sc->debug.debugfs_queue);
946 debugfs_remove(sc->debug.debugfs_phydir);
947} 921}
948 922
949
950/* functions used in other places */ 923/* functions used in other places */
951 924
952void 925void
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index b0355aef68d3..193dd2d4ea3c 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -68,17 +68,6 @@ struct ath5k_buf;
68 68
69struct ath5k_dbg_info { 69struct ath5k_dbg_info {
70 unsigned int level; /* debug level */ 70 unsigned int level; /* debug level */
71 /* debugfs entries */
72 struct dentry *debugfs_phydir;
73 struct dentry *debugfs_debug;
74 struct dentry *debugfs_registers;
75 struct dentry *debugfs_beacon;
76 struct dentry *debugfs_reset;
77 struct dentry *debugfs_antenna;
78 struct dentry *debugfs_misc;
79 struct dentry *debugfs_frameerrors;
80 struct dentry *debugfs_ani;
81 struct dentry *debugfs_queue;
82}; 71};
83 72
84/** 73/**
@@ -141,9 +130,6 @@ void
141ath5k_debug_init_device(struct ath5k_softc *sc); 130ath5k_debug_init_device(struct ath5k_softc *sc);
142 131
143void 132void
144ath5k_debug_finish_device(struct ath5k_softc *sc);
145
146void
147ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); 133ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
148 134
149void 135void
@@ -167,9 +153,6 @@ static inline void
167ath5k_debug_init_device(struct ath5k_softc *sc) {} 153ath5k_debug_init_device(struct ath5k_softc *sc) {}
168 154
169static inline void 155static inline void
170ath5k_debug_finish_device(struct ath5k_softc *sc) {}
171
172static inline void
173ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} 156ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
174 157
175static inline void 158static inline void
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index 16b44ff7dd3e..dd7cd95c364a 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -185,6 +185,12 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
185 struct ath5k_hw_4w_tx_ctl *tx_ctl; 185 struct ath5k_hw_4w_tx_ctl *tx_ctl;
186 unsigned int frame_len; 186 unsigned int frame_len;
187 187
188 /*
189 * Use local variables for these to reduce load/store access on
190 * uncached memory
191 */
192 u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;
193
188 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 194 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
189 195
190 /* 196 /*
@@ -208,8 +214,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
208 if (tx_power > AR5K_TUNE_MAX_TXPOWER) 214 if (tx_power > AR5K_TUNE_MAX_TXPOWER)
209 tx_power = AR5K_TUNE_MAX_TXPOWER; 215 tx_power = AR5K_TUNE_MAX_TXPOWER;
210 216
211 /* Clear descriptor */ 217 /* Clear descriptor status area */
212 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); 218 memset(&desc->ud.ds_tx5212.tx_stat, 0,
219 sizeof(desc->ud.ds_tx5212.tx_stat));
213 220
214 /* Setup control descriptor */ 221 /* Setup control descriptor */
215 222
@@ -221,7 +228,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
221 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 228 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
222 return -EINVAL; 229 return -EINVAL;
223 230
224 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; 231 txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
225 232
226 /* Verify and set buffer length */ 233 /* Verify and set buffer length */
227 234
@@ -232,21 +239,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
232 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) 239 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
233 return -EINVAL; 240 return -EINVAL;
234 241
235 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; 242 txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
236 243
237 tx_ctl->tx_control_0 |= 244 txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
238 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | 245 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
239 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 246 txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
240 tx_ctl->tx_control_1 |= AR5K_REG_SM(type, 247 txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
241 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 248 txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
242 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0,
243 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
244 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
245 249
246#define _TX_FLAGS(_c, _flag) \ 250#define _TX_FLAGS(_c, _flag) \
247 if (flags & AR5K_TXDESC_##_flag) { \ 251 if (flags & AR5K_TXDESC_##_flag) { \
248 tx_ctl->tx_control_##_c |= \ 252 txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
249 AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
250 } 253 }
251 254
252 _TX_FLAGS(0, CLRDMASK); 255 _TX_FLAGS(0, CLRDMASK);
@@ -262,8 +265,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
262 * WEP crap 265 * WEP crap
263 */ 266 */
264 if (key_index != AR5K_TXKEYIX_INVALID) { 267 if (key_index != AR5K_TXKEYIX_INVALID) {
265 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 268 txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
266 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, 269 txctl1 |= AR5K_REG_SM(key_index,
267 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); 270 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
268 } 271 }
269 272
@@ -274,12 +277,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
274 if ((flags & AR5K_TXDESC_RTSENA) && 277 if ((flags & AR5K_TXDESC_RTSENA) &&
275 (flags & AR5K_TXDESC_CTSENA)) 278 (flags & AR5K_TXDESC_CTSENA))
276 return -EINVAL; 279 return -EINVAL;
277 tx_ctl->tx_control_2 |= rtscts_duration & 280 txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
278 AR5K_4W_TX_DESC_CTL2_RTS_DURATION; 281 txctl3 |= AR5K_REG_SM(rtscts_rate,
279 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
280 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); 282 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
281 } 283 }
282 284
285 tx_ctl->tx_control_0 = txctl0;
286 tx_ctl->tx_control_1 = txctl1;
287 tx_ctl->tx_control_2 = txctl2;
288 tx_ctl->tx_control_3 = txctl3;
289
283 return 0; 290 return 0;
284} 291}
285 292
@@ -364,7 +371,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
364 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 371 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
365 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 372 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
366 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 373 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
367 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 374 ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,
368 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 375 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
369 /*TODO: ts->ts_virtcol + test*/ 376 /*TODO: ts->ts_virtcol + test*/
370 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 377 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
@@ -373,9 +380,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
373 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 380 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
374 ts->ts_antenna = 1; 381 ts->ts_antenna = 1;
375 ts->ts_status = 0; 382 ts->ts_status = 0;
376 ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
377 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
378 ts->ts_retry[0] = ts->ts_longretry;
379 ts->ts_final_idx = 0; 383 ts->ts_final_idx = 0;
380 384
381 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 385 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
@@ -401,81 +405,48 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
401{ 405{
402 struct ath5k_hw_4w_tx_ctl *tx_ctl; 406 struct ath5k_hw_4w_tx_ctl *tx_ctl;
403 struct ath5k_hw_tx_status *tx_status; 407 struct ath5k_hw_tx_status *tx_status;
408 u32 txstat0, txstat1;
404 409
405 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 410 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
406 tx_status = &desc->ud.ds_tx5212.tx_stat; 411 tx_status = &desc->ud.ds_tx5212.tx_stat;
407 412
413 txstat1 = ACCESS_ONCE(tx_status->tx_status_1);
414
408 /* No frame has been send or error */ 415 /* No frame has been send or error */
409 if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) 416 if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))
410 return -EINPROGRESS; 417 return -EINPROGRESS;
411 418
419 txstat0 = ACCESS_ONCE(tx_status->tx_status_0);
420
412 /* 421 /*
413 * Get descriptor status 422 * Get descriptor status
414 */ 423 */
415 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, 424 ts->ts_tstamp = AR5K_REG_MS(txstat0,
416 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 425 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
417 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 426 ts->ts_shortretry = AR5K_REG_MS(txstat0,
418 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 427 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
419 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 428 ts->ts_final_retry = AR5K_REG_MS(txstat0,
420 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 429 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
421 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 430 ts->ts_seqnum = AR5K_REG_MS(txstat1,
422 AR5K_DESC_TX_STATUS1_SEQ_NUM); 431 AR5K_DESC_TX_STATUS1_SEQ_NUM);
423 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 432 ts->ts_rssi = AR5K_REG_MS(txstat1,
424 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 433 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
425 ts->ts_antenna = (tx_status->tx_status_1 & 434 ts->ts_antenna = (txstat1 &
426 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; 435 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;
427 ts->ts_status = 0; 436 ts->ts_status = 0;
428 437
429 ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, 438 ts->ts_final_idx = AR5K_REG_MS(txstat1,
430 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); 439 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);
431 440
432 /* The longretry counter has the number of un-acked retries
433 * for the final rate. To get the total number of retries
434 * we have to add the retry counters for the other rates
435 * as well
436 */
437 ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
438 switch (ts->ts_final_idx) {
439 case 3:
440 ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
441 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
442
443 ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
444 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
445 ts->ts_longretry += ts->ts_retry[2];
446 /* fall through */
447 case 2:
448 ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
449 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
450
451 ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
452 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
453 ts->ts_longretry += ts->ts_retry[1];
454 /* fall through */
455 case 1:
456 ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
457 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
458
459 ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
460 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
461 ts->ts_longretry += ts->ts_retry[0];
462 /* fall through */
463 case 0:
464 ts->ts_rate[0] = tx_ctl->tx_control_3 &
465 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
466 break;
467 }
468
469 /* TX error */ 441 /* TX error */
470 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 442 if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
471 if (tx_status->tx_status_0 & 443 if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
472 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
473 ts->ts_status |= AR5K_TXERR_XRETRY; 444 ts->ts_status |= AR5K_TXERR_XRETRY;
474 445
475 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 446 if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
476 ts->ts_status |= AR5K_TXERR_FIFO; 447 ts->ts_status |= AR5K_TXERR_FIFO;
477 448
478 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) 449 if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)
479 ts->ts_status |= AR5K_TXERR_FILT; 450 ts->ts_status |= AR5K_TXERR_FILT;
480 } 451 }
481 452
@@ -609,37 +580,37 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
609 struct ath5k_rx_status *rs) 580 struct ath5k_rx_status *rs)
610{ 581{
611 struct ath5k_hw_rx_status *rx_status; 582 struct ath5k_hw_rx_status *rx_status;
583 u32 rxstat0, rxstat1;
612 584
613 rx_status = &desc->ud.ds_rx.rx_stat; 585 rx_status = &desc->ud.ds_rx.rx_stat;
586 rxstat1 = ACCESS_ONCE(rx_status->rx_status_1);
614 587
615 /* No frame received / not ready */ 588 /* No frame received / not ready */
616 if (unlikely(!(rx_status->rx_status_1 & 589 if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))
617 AR5K_5212_RX_DESC_STATUS1_DONE)))
618 return -EINPROGRESS; 590 return -EINPROGRESS;
619 591
620 memset(rs, 0, sizeof(struct ath5k_rx_status)); 592 memset(rs, 0, sizeof(struct ath5k_rx_status));
593 rxstat0 = ACCESS_ONCE(rx_status->rx_status_0);
621 594
622 /* 595 /*
623 * Frame receive status 596 * Frame receive status
624 */ 597 */
625 rs->rs_datalen = rx_status->rx_status_0 & 598 rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
626 AR5K_5212_RX_DESC_STATUS0_DATA_LEN; 599 rs->rs_rssi = AR5K_REG_MS(rxstat0,
627 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
628 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); 600 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
629 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 601 rs->rs_rate = AR5K_REG_MS(rxstat0,
630 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); 602 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
631 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, 603 rs->rs_antenna = AR5K_REG_MS(rxstat0,
632 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); 604 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
633 rs->rs_more = !!(rx_status->rx_status_0 & 605 rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);
634 AR5K_5212_RX_DESC_STATUS0_MORE); 606 rs->rs_tstamp = AR5K_REG_MS(rxstat1,
635 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
636 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 607 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
637 608
638 /* 609 /*
639 * Key table status 610 * Key table status
640 */ 611 */
641 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) 612 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
642 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 613 rs->rs_keyix = AR5K_REG_MS(rxstat1,
643 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); 614 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
644 else 615 else
645 rs->rs_keyix = AR5K_RXKEYIX_INVALID; 616 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
@@ -647,27 +618,22 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
647 /* 618 /*
648 * Receive/descriptor errors 619 * Receive/descriptor errors
649 */ 620 */
650 if (!(rx_status->rx_status_1 & 621 if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
651 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 622 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
652 if (rx_status->rx_status_1 &
653 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
654 rs->rs_status |= AR5K_RXERR_CRC; 623 rs->rs_status |= AR5K_RXERR_CRC;
655 624
656 if (rx_status->rx_status_1 & 625 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
657 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
658 rs->rs_status |= AR5K_RXERR_PHY; 626 rs->rs_status |= AR5K_RXERR_PHY;
659 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, 627 rs->rs_phyerr = AR5K_REG_MS(rxstat1,
660 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); 628 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);
661 if (!ah->ah_capabilities.cap_has_phyerr_counters) 629 if (!ah->ah_capabilities.cap_has_phyerr_counters)
662 ath5k_ani_phy_error_report(ah, rs->rs_phyerr); 630 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
663 } 631 }
664 632
665 if (rx_status->rx_status_1 & 633 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
666 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
667 rs->rs_status |= AR5K_RXERR_DECRYPT; 634 rs->rs_status |= AR5K_RXERR_DECRYPT;
668 635
669 if (rx_status->rx_status_1 & 636 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
670 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
671 rs->rs_status |= AR5K_RXERR_MIC; 637 rs->rs_status |= AR5K_RXERR_MIC;
672 } 638 }
673 return 0; 639 return 0;
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index b6561f785c6e..e9263e4c7f3e 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
660 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; 660 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
661} 661}
662 662
663static int
664ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
665{
666 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
667 struct ath5k_chan_pcal_info *chinfo;
668 u8 pier, pdg;
669
670 switch (mode) {
671 case AR5K_EEPROM_MODE_11A:
672 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
673 return 0;
674 chinfo = ee->ee_pwr_cal_a;
675 break;
676 case AR5K_EEPROM_MODE_11B:
677 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
678 return 0;
679 chinfo = ee->ee_pwr_cal_b;
680 break;
681 case AR5K_EEPROM_MODE_11G:
682 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
683 return 0;
684 chinfo = ee->ee_pwr_cal_g;
685 break;
686 default:
687 return -EINVAL;
688 }
689
690 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
691 if (!chinfo[pier].pd_curves)
692 continue;
693
694 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
695 struct ath5k_pdgain_info *pd =
696 &chinfo[pier].pd_curves[pdg];
697
698 if (pd != NULL) {
699 kfree(pd->pd_step);
700 kfree(pd->pd_pwr);
701 }
702 }
703
704 kfree(chinfo[pier].pd_curves);
705 }
706
707 return 0;
708}
709
663/* Convert RF5111 specific data to generic raw data 710/* Convert RF5111 specific data to generic raw data
664 * used by interpolation code */ 711 * used by interpolation code */
665static int 712static int
@@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
684 GFP_KERNEL); 731 GFP_KERNEL);
685 732
686 if (!chinfo[pier].pd_curves) 733 if (!chinfo[pier].pd_curves)
687 return -ENOMEM; 734 goto err_out;
688 735
689 /* Only one curve for RF5111 736 /* Only one curve for RF5111
690 * find out which one and place 737 * find out which one and place
@@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
708 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 755 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
709 sizeof(u8), GFP_KERNEL); 756 sizeof(u8), GFP_KERNEL);
710 if (!pd->pd_step) 757 if (!pd->pd_step)
711 return -ENOMEM; 758 goto err_out;
712 759
713 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 760 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
714 sizeof(s16), GFP_KERNEL); 761 sizeof(s16), GFP_KERNEL);
715 if (!pd->pd_pwr) 762 if (!pd->pd_pwr)
716 return -ENOMEM; 763 goto err_out;
717 764
718 /* Fill raw dataset 765 /* Fill raw dataset
719 * (convert power to 0.25dB units 766 * (convert power to 0.25dB units
@@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
734 } 781 }
735 782
736 return 0; 783 return 0;
784
785err_out:
786 ath5k_eeprom_free_pcal_info(ah, mode);
787 return -ENOMEM;
737} 788}
738 789
739/* Parse EEPROM data */ 790/* Parse EEPROM data */
@@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
867 GFP_KERNEL); 918 GFP_KERNEL);
868 919
869 if (!chinfo[pier].pd_curves) 920 if (!chinfo[pier].pd_curves)
870 return -ENOMEM; 921 goto err_out;
871 922
872 /* Fill pd_curves */ 923 /* Fill pd_curves */
873 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 924 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
886 sizeof(u8), GFP_KERNEL); 937 sizeof(u8), GFP_KERNEL);
887 938
888 if (!pd->pd_step) 939 if (!pd->pd_step)
889 return -ENOMEM; 940 goto err_out;
890 941
891 pd->pd_pwr = kcalloc(pd->pd_points, 942 pd->pd_pwr = kcalloc(pd->pd_points,
892 sizeof(s16), GFP_KERNEL); 943 sizeof(s16), GFP_KERNEL);
893 944
894 if (!pd->pd_pwr) 945 if (!pd->pd_pwr)
895 return -ENOMEM; 946 goto err_out;
896
897 947
898 /* Fill raw dataset 948 /* Fill raw dataset
899 * (all power levels are in 0.25dB units) */ 949 * (all power levels are in 0.25dB units) */
@@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
925 sizeof(u8), GFP_KERNEL); 975 sizeof(u8), GFP_KERNEL);
926 976
927 if (!pd->pd_step) 977 if (!pd->pd_step)
928 return -ENOMEM; 978 goto err_out;
929 979
930 pd->pd_pwr = kcalloc(pd->pd_points, 980 pd->pd_pwr = kcalloc(pd->pd_points,
931 sizeof(s16), GFP_KERNEL); 981 sizeof(s16), GFP_KERNEL);
932 982
933 if (!pd->pd_pwr) 983 if (!pd->pd_pwr)
934 return -ENOMEM; 984 goto err_out;
935 985
936 /* Fill raw dataset 986 /* Fill raw dataset
937 * (all power levels are in 0.25dB units) */ 987 * (all power levels are in 0.25dB units) */
@@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
954 } 1004 }
955 1005
956 return 0; 1006 return 0;
1007
1008err_out:
1009 ath5k_eeprom_free_pcal_info(ah, mode);
1010 return -ENOMEM;
957} 1011}
958 1012
959/* Parse EEPROM data */ 1013/* Parse EEPROM data */
@@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1156 GFP_KERNEL); 1210 GFP_KERNEL);
1157 1211
1158 if (!chinfo[pier].pd_curves) 1212 if (!chinfo[pier].pd_curves)
1159 return -ENOMEM; 1213 goto err_out;
1160 1214
1161 /* Fill pd_curves */ 1215 /* Fill pd_curves */
1162 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 1216 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1177 sizeof(u8), GFP_KERNEL); 1231 sizeof(u8), GFP_KERNEL);
1178 1232
1179 if (!pd->pd_step) 1233 if (!pd->pd_step)
1180 return -ENOMEM; 1234 goto err_out;
1181 1235
1182 pd->pd_pwr = kcalloc(pd->pd_points, 1236 pd->pd_pwr = kcalloc(pd->pd_points,
1183 sizeof(s16), GFP_KERNEL); 1237 sizeof(s16), GFP_KERNEL);
1184 1238
1185 if (!pd->pd_pwr) 1239 if (!pd->pd_pwr)
1186 return -ENOMEM; 1240 goto err_out;
1187 1241
1188 /* Fill raw dataset 1242 /* Fill raw dataset
1189 * convert all pwr levels to 1243 * convert all pwr levels to
@@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1213 } 1267 }
1214 1268
1215 return 0; 1269 return 0;
1270
1271err_out:
1272 ath5k_eeprom_free_pcal_info(ah, mode);
1273 return -ENOMEM;
1216} 1274}
1217 1275
1218/* Parse EEPROM data */ 1276/* Parse EEPROM data */
@@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
1534 return 0; 1592 return 0;
1535} 1593}
1536 1594
1537static int
1538ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
1539{
1540 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1541 struct ath5k_chan_pcal_info *chinfo;
1542 u8 pier, pdg;
1543
1544 switch (mode) {
1545 case AR5K_EEPROM_MODE_11A:
1546 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1547 return 0;
1548 chinfo = ee->ee_pwr_cal_a;
1549 break;
1550 case AR5K_EEPROM_MODE_11B:
1551 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1552 return 0;
1553 chinfo = ee->ee_pwr_cal_b;
1554 break;
1555 case AR5K_EEPROM_MODE_11G:
1556 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1557 return 0;
1558 chinfo = ee->ee_pwr_cal_g;
1559 break;
1560 default:
1561 return -EINVAL;
1562 }
1563
1564 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1565 if (!chinfo[pier].pd_curves)
1566 continue;
1567
1568 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1569 struct ath5k_pdgain_info *pd =
1570 &chinfo[pier].pd_curves[pdg];
1571
1572 if (pd != NULL) {
1573 kfree(pd->pd_step);
1574 kfree(pd->pd_pwr);
1575 }
1576 }
1577
1578 kfree(chinfo[pier].pd_curves);
1579 }
1580
1581 return 0;
1582}
1583
1584/* Read conformance test limits used for regulatory control */ 1595/* Read conformance test limits used for regulatory control */
1585static int 1596static int
1586ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) 1597ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1721,35 +1732,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
1721 return ret; 1732 return ret;
1722} 1733}
1723 1734
1724/*
1725 * Read the MAC address from eeprom
1726 */
1727int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
1728{
1729 u8 mac_d[ETH_ALEN] = {};
1730 u32 total, offset;
1731 u16 data;
1732 int octet;
1733
1734 AR5K_EEPROM_READ(0x20, data);
1735
1736 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
1737 AR5K_EEPROM_READ(offset, data);
1738
1739 total += data;
1740 mac_d[octet + 1] = data & 0xff;
1741 mac_d[octet] = data >> 8;
1742 octet += 2;
1743 }
1744
1745 if (!total || total == 3 * 0xffff)
1746 return -EINVAL;
1747
1748 memcpy(mac, mac_d, ETH_ALEN);
1749
1750 return 0;
1751}
1752
1753 1735
1754/***********************\ 1736/***********************\
1755* Init/Detach functions * 1737* Init/Detach functions *
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 9be29b728b1c..807bd6440169 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
282 if (changes & BSS_CHANGED_BEACON_INT) 282 if (changes & BSS_CHANGED_BEACON_INT)
283 sc->bintval = bss_conf->beacon_int; 283 sc->bintval = bss_conf->beacon_int;
284 284
285 if (changes & BSS_CHANGED_ERP_SLOT) {
286 int slot_time;
287
288 ah->ah_short_slot = bss_conf->use_short_slot;
289 slot_time = ath5k_hw_get_default_slottime(ah) +
290 3 * ah->ah_coverage_class;
291 ath5k_hw_set_ifs_intervals(ah, slot_time);
292 }
293
285 if (changes & BSS_CHANGED_ASSOC) { 294 if (changes & BSS_CHANGED_ASSOC) {
286 avf->assoc = bss_conf->assoc; 295 avf->assoc = bss_conf->assoc;
287 if (bss_conf->assoc) 296 if (bss_conf->assoc)
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index 66598a0d1df0..5cc4a2fe47b6 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -17,6 +17,7 @@
17#include <linux/nl80211.h> 17#include <linux/nl80211.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/pci-aspm.h> 19#include <linux/pci-aspm.h>
20#include <linux/etherdevice.h>
20#include "../ath.h" 21#include "../ath.h"
21#include "ath5k.h" 22#include "ath5k.h"
22#include "debug.h" 23#include "debug.h"
@@ -108,11 +109,42 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah)
108 return 0; 109 return 0;
109} 110}
110 111
112/*
113 * Read the MAC address from eeprom or platform_data
114 */
115static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
116{
117 u8 mac_d[ETH_ALEN] = {};
118 u32 total, offset;
119 u16 data;
120 int octet;
121
122 AR5K_EEPROM_READ(0x20, data);
123
124 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
125 AR5K_EEPROM_READ(offset, data);
126
127 total += data;
128 mac_d[octet + 1] = data & 0xff;
129 mac_d[octet] = data >> 8;
130 octet += 2;
131 }
132
133 if (!total || total == 3 * 0xffff)
134 return -EINVAL;
135
136 memcpy(mac, mac_d, ETH_ALEN);
137
138 return 0;
139}
140
141
111/* Common ath_bus_opts structure */ 142/* Common ath_bus_opts structure */
112static const struct ath_bus_ops ath_pci_bus_ops = { 143static const struct ath_bus_ops ath_pci_bus_ops = {
113 .ath_bus_type = ATH_PCI, 144 .ath_bus_type = ATH_PCI,
114 .read_cachesize = ath5k_pci_read_cachesize, 145 .read_cachesize = ath5k_pci_read_cachesize,
115 .eeprom_read = ath5k_pci_eeprom_read, 146 .eeprom_read = ath5k_pci_eeprom_read,
147 .eeprom_read_mac = ath5k_pci_eeprom_read_mac,
116}; 148};
117 149
118/********************\ 150/********************\
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index a702817daf72..71b60b7c617e 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -75,7 +75,7 @@ static const unsigned int ack_rates_high[] =
75 * bwmodes. 75 * bwmodes.
76 */ 76 */
77int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, 77int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
78 int len, struct ieee80211_rate *rate) 78 int len, struct ieee80211_rate *rate, bool shortpre)
79{ 79{
80 struct ath5k_softc *sc = ah->ah_sc; 80 struct ath5k_softc *sc = ah->ah_sc;
81 int sifs, preamble, plcp_bits, sym_time; 81 int sifs, preamble, plcp_bits, sym_time;
@@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
84 84
85 /* Fallback */ 85 /* Fallback */
86 if (!ah->ah_bwmode) { 86 if (!ah->ah_bwmode) {
87 dur = ieee80211_generic_frame_duration(sc->hw, 87 __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw,
88 NULL, len, rate); 88 NULL, len, rate);
89 return le16_to_cpu(dur); 89
90 /* subtract difference between long and short preamble */
91 dur = le16_to_cpu(raw_dur);
92 if (shortpre)
93 dur -= 96;
94
95 return dur;
90 } 96 }
91 97
92 bitrate = rate->bitrate; 98 bitrate = rate->bitrate;
@@ -145,9 +151,9 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
145 slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; 151 slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
146 break; 152 break;
147 case AR5K_BWMODE_DEFAULT: 153 case AR5K_BWMODE_DEFAULT:
148 slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
149 default: 154 default:
150 if (channel->hw_value & CHANNEL_CCK) 155 slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
156 if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot)
151 slot_time = AR5K_INIT_SLOT_TIME_B; 157 slot_time = AR5K_INIT_SLOT_TIME_B;
152 break; 158 break;
153 } 159 }
@@ -263,27 +269,14 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
263 * actual rate for this rate. See mac80211 tx.c 269 * actual rate for this rate. See mac80211 tx.c
264 * ieee80211_duration() for a brief description of 270 * ieee80211_duration() for a brief description of
265 * what rate we should choose to TX ACKs. */ 271 * what rate we should choose to TX ACKs. */
266 tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); 272 tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
267 273
268 ath5k_hw_reg_write(ah, tx_time, reg); 274 ath5k_hw_reg_write(ah, tx_time, reg);
269 275
270 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) 276 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
271 continue; 277 continue;
272 278
273 /* 279 tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true);
274 * We're not distinguishing short preamble here,
275 * This is true, all we'll get is a longer value here
276 * which is not necessarilly bad. We could use
277 * export ieee80211_frame_duration() but that needs to be
278 * fixed first to be properly used by mac802111 drivers:
279 *
280 * - remove erp stuff and let the routine figure ofdm
281 * erp rates
282 * - remove passing argument ieee80211_local as
283 * drivers don't have access to it
284 * - move drivers using ieee80211_generic_frame_duration()
285 * to this
286 */
287 ath5k_hw_reg_write(ah, tx_time, 280 ath5k_hw_reg_write(ah, tx_time,
288 reg + (AR5K_SET_SHORT_PREAMBLE << 2)); 281 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
289 } 282 }
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 3343fb9e4940..b18c5021aac3 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
519 return -EINVAL; 519 return -EINVAL;
520 520
521 sifs = ath5k_hw_get_default_sifs(ah); 521 sifs = ath5k_hw_get_default_sifs(ah);
522 sifs_clock = ath5k_hw_htoclock(ah, sifs); 522 sifs_clock = ath5k_hw_htoclock(ah, sifs - 2);
523 523
524 /* EIFS 524 /* EIFS
525 * Txtime of ack at lowest rate + SIFS + DIFS 525 * Txtime of ack at lowest rate + SIFS + DIFS
@@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
550 else 550 else
551 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; 551 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
552 552
553 ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); 553 ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
554 554
555 /* ack_tx_time includes an SIFS already */ 555 /* ack_tx_time includes an SIFS already */
556 eifs = ack_tx_time + sifs + 2 * slot_time; 556 eifs = ack_tx_time + sifs + 2 * slot_time;
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index ad57a6d23110..d9ff8413ab9a 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -5,7 +5,7 @@ config ATH9K_COMMON
5 5
6config ATH9K 6config ATH9K
7 tristate "Atheros 802.11n wireless cards support" 7 tristate "Atheros 802.11n wireless cards support"
8 depends on PCI && MAC80211 8 depends on MAC80211
9 select ATH9K_HW 9 select ATH9K_HW
10 select MAC80211_LEDS 10 select MAC80211_LEDS
11 select LEDS_CLASS 11 select LEDS_CLASS
@@ -23,6 +23,25 @@ config ATH9K
23 23
24 If you choose to build a module, it'll be called ath9k. 24 If you choose to build a module, it'll be called ath9k.
25 25
26config ATH9K_PCI
27 bool "Atheros ath9k PCI/PCIe bus support"
28 depends on ATH9K && PCI
29 default PCI
30 ---help---
31 This option enables the PCI bus support in ath9k.
32
33 Say Y, if you have a compatible PCI/PCIe wireless card.
34
35config ATH9K_AHB
36 bool "Atheros ath9k AHB bus support"
37 depends on ATH9K
38 default n
39 ---help---
40 This option enables the AHB bus support in ath9k.
41
42 Say Y, if you have a SoC with a compatible built-in
43 wireless MAC. Say N if unsure.
44
26config ATH9K_DEBUGFS 45config ATH9K_DEBUGFS
27 bool "Atheros ath9k debugging" 46 bool "Atheros ath9k debugging"
28 depends on ATH9K && DEBUG_FS 47 depends on ATH9K && DEBUG_FS
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 4d66ca8042eb..05a6fade7b1c 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -6,8 +6,8 @@ ath9k-y += beacon.o \
6 xmit.o \ 6 xmit.o \
7 7
8ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o 8ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
9ath9k-$(CONFIG_PCI) += pci.o 9ath9k-$(CONFIG_ATH9K_PCI) += pci.o
10ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o 10ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
11ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o 11ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
12 12
13obj-$(CONFIG_ATH9K) += ath9k.o 13obj-$(CONFIG_ATH9K) += ath9k.o
@@ -48,4 +48,6 @@ ath9k_htc-y += htc_hst.o \
48 htc_drv_init.o \ 48 htc_drv_init.o \
49 htc_drv_gpio.o 49 htc_drv_gpio.o
50 50
51ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o
52
51obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o 53obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 9cb0efa9b4c0..5193ed58a17b 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -21,6 +21,14 @@
21#include <linux/ath9k_platform.h> 21#include <linux/ath9k_platform.h>
22#include "ath9k.h" 22#include "ath9k.h"
23 23
24const struct platform_device_id ath9k_platform_id_table[] = {
25 {
26 .name = "ath9k",
27 .driver_data = AR5416_AR9100_DEVID,
28 },
29 {},
30};
31
24/* return bus cachesize in 4B word units */ 32/* return bus cachesize in 4B word units */
25static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) 33static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
26{ 34{
@@ -57,6 +65,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
57 struct ath_softc *sc; 65 struct ath_softc *sc;
58 struct ieee80211_hw *hw; 66 struct ieee80211_hw *hw;
59 struct resource *res; 67 struct resource *res;
68 const struct platform_device_id *id = platform_get_device_id(pdev);
60 int irq; 69 int irq;
61 int ret = 0; 70 int ret = 0;
62 struct ath_hw *ah; 71 struct ath_hw *ah;
@@ -116,7 +125,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
116 goto err_free_hw; 125 goto err_free_hw;
117 } 126 }
118 127
119 ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); 128 ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops);
120 if (ret) { 129 if (ret) {
121 dev_err(&pdev->dev, "failed to initialize device\n"); 130 dev_err(&pdev->dev, "failed to initialize device\n");
122 goto err_irq; 131 goto err_irq;
@@ -165,8 +174,11 @@ static struct platform_driver ath_ahb_driver = {
165 .name = "ath9k", 174 .name = "ath9k",
166 .owner = THIS_MODULE, 175 .owner = THIS_MODULE,
167 }, 176 },
177 .id_table = ath9k_platform_id_table,
168}; 178};
169 179
180MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table);
181
170int ath_ahb_init(void) 182int ath_ahb_init(void)
171{ 183{
172 return platform_driver_register(&ath_ahb_driver); 184 return platform_driver_register(&ath_ahb_driver);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index 37663dbbcf57..47780ef1c892 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -483,7 +483,11 @@
483#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 483#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
484#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 484#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
485 485
486#define AR_PHY_TX_PWRCTRL8 0xa278
487
486#define AR_PHY_TX_PWRCTRL9 0xa27C 488#define AR_PHY_TX_PWRCTRL9 0xa27C
489
490#define AR_PHY_TX_PWRCTRL10 0xa394
487#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 491#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
488#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 492#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
489#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 493#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
@@ -495,6 +499,8 @@
495 499
496#define AR_PHY_CH0_TX_PWRCTRL11 0xa398 500#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
497#define AR_PHY_CH1_TX_PWRCTRL11 0xb398 501#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
502#define AR_PHY_CH0_TX_PWRCTRL12 0xa3dc
503#define AR_PHY_CH0_TX_PWRCTRL13 0xa3e0
498#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 504#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
499#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 505#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
500 506
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 9ecca93392e8..f915a3dbfcad 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -34,10 +34,10 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
34 34
35static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { 35static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
37 {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, 37 {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
38 {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, 38 {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
39 {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, 39 {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
40 {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 40 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
41 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 41 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
42 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 42 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
43 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, 43 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
@@ -119,14 +119,14 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
119 {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 119 {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
120 {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 120 {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
121 {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, 121 {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
122 {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, 122 {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
123 {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, 123 {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
124 {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, 124 {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
125 {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 125 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
126 {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, 126 {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
127 {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, 127 {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
128 {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, 128 {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
129 {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 129 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
130 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 130 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
131 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, 131 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
132 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 132 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
@@ -835,10 +835,10 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
835 835
836static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { 836static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
838 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 838 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
839 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 839 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
840 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 840 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
841 {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 841 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
842 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, 842 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
843 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 843 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
844 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, 844 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
@@ -920,14 +920,14 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
920 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 920 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
921 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 921 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
922 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 922 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
923 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 923 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
924 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 924 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
925 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 925 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
926 {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 926 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
927 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 927 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
928 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 928 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
929 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 929 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
930 {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 930 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
931 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, 931 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
932 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, 932 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
933 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, 933 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
@@ -941,10 +941,10 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
941 941
942static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { 942static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
943 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 943 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
944 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, 944 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
945 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, 945 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
946 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, 946 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
947 {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 947 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
948 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, 948 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
949 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 949 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
950 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, 950 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
@@ -1026,14 +1026,14 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
1026 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1026 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1027 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1027 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1028 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1028 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1029 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, 1029 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1030 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, 1030 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1031 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, 1031 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1032 {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1032 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1033 {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, 1033 {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1034 {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, 1034 {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1035 {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, 1035 {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1036 {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1036 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1037 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, 1037 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
1038 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, 1038 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
1039 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 1039 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
@@ -1307,10 +1307,10 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
1307 1307
1308static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { 1308static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
1309 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1309 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1310 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 1310 {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
1311 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 1311 {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
1312 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 1312 {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
1313 {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1313 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1314 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 1314 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1315 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1315 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1316 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, 1316 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
@@ -1329,21 +1329,21 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
1329 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, 1329 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1330 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, 1330 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1331 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, 1331 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1332 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, 1332 {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
1333 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, 1333 {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
1334 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, 1334 {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
1335 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, 1335 {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
1336 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, 1336 {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
1337 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, 1337 {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
1338 {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, 1338 {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
1339 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, 1339 {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
1340 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 1340 {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
1341 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 1341 {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
1342 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 1342 {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
1343 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 1343 {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
1344 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 1344 {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
1345 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 1345 {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
1346 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 1346 {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
1347 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, 1347 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
1348 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, 1348 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
1349 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, 1349 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
@@ -1361,45 +1361,45 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
1361 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, 1361 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
1362 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, 1362 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
1363 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, 1363 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
1364 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, 1364 {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
1365 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, 1365 {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
1366 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, 1366 {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
1367 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, 1367 {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
1368 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, 1368 {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
1369 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, 1369 {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
1370 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, 1370 {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
1371 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, 1371 {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
1372 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 1372 {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
1373 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 1373 {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
1374 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 1374 {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
1375 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 1375 {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
1376 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 1376 {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
1377 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 1377 {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
1378 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 1378 {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
1379 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1379 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1380 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1380 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1381 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1381 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1382 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1382 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1383 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1383 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1384 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, 1384 {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
1385 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, 1385 {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
1386 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, 1386 {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
1387 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, 1387 {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
1388 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, 1388 {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
1389 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, 1389 {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
1390 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, 1390 {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
1391 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1391 {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
1392 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1392 {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
1393 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1393 {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
1394 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1394 {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
1395 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 1395 {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
1396 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 1396 {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
1397 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 1397 {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
1398 {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1398 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1399 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 1399 {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
1400 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 1400 {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
1401 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 1401 {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
1402 {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1402 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1403 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 1403 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1404 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, 1404 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
1405 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 1405 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index eb250d6b8038..1bc33f51e466 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -75,9 +75,18 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
75 freq = centers.synth_center; 75 freq = centers.synth_center;
76 76
77 if (freq < 4800) { /* 2 GHz, fractional mode */ 77 if (freq < 4800) { /* 2 GHz, fractional mode */
78 if (AR_SREV_9485(ah)) 78 if (AR_SREV_9485(ah)) {
79 channelSel = CHANSEL_2G_9485(freq); 79 u32 chan_frac;
80 else 80
81 /*
82 * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0
83 * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
84 * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
85 */
86 channelSel = (freq * 4) / 120;
87 chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
88 channelSel = (channelSel << 17) | chan_frac;
89 } else
81 channelSel = CHANSEL_2G(freq); 90 channelSel = CHANSEL_2G(freq);
82 /* Set to 2G mode */ 91 /* Set to 2G mode */
83 bMode = 1; 92 bMode = 1;
@@ -401,7 +410,7 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
401 410
402 ar9003_hw_spur_ofdm_clear(ah); 411 ar9003_hw_spur_ofdm_clear(ah);
403 412
404 for (i = 0; spurChansPtr[i] && i < 5; i++) { 413 for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) {
405 freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; 414 freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
406 if (abs(freq_offset) < range) { 415 if (abs(freq_offset) < range) {
407 ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); 416 ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index f91f73e50d00..fbdde29f0ab8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -396,7 +396,7 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
396 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, 396 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
397 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, 397 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
398 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, 398 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
399 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, 399 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
400 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, 400 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
401 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, 401 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
402 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, 402 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -469,7 +469,7 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
469 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, 469 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
470 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, 470 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
471 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, 471 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
472 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, 472 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
473 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, 473 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
474 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, 474 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
475 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, 475 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -635,7 +635,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
635 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, 635 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
636 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, 636 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
637 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, 637 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
638 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, 638 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
639 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, 639 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
640 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, 640 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
641 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, 641 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -728,7 +728,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
728 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, 728 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
729 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, 729 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
730 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, 730 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
731 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, 731 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
732 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, 732 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
733 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, 733 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
734 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, 734 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -827,7 +827,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
827 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, 827 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
828 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, 828 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
829 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, 829 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
830 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, 830 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
831 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, 831 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
832 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, 832 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
833 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, 833 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 38835bc324b2..77ad407e9fa3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -665,7 +665,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
665bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); 665bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
666bool ath9k_uses_beacons(int type); 666bool ath9k_uses_beacons(int type);
667 667
668#ifdef CONFIG_PCI 668#ifdef CONFIG_ATH9K_PCI
669int ath_pci_init(void); 669int ath_pci_init(void);
670void ath_pci_exit(void); 670void ath_pci_exit(void);
671#else 671#else
@@ -673,7 +673,7 @@ static inline int ath_pci_init(void) { return 0; };
673static inline void ath_pci_exit(void) {}; 673static inline void ath_pci_exit(void) {};
674#endif 674#endif
675 675
676#ifdef CONFIG_ATHEROS_AR71XX 676#ifdef CONFIG_ATH9K_AHB
677int ath_ahb_init(void); 677int ath_ahb_init(void);
678void ath_ahb_exit(void); 678void ath_ahb_exit(void);
679#else 679#else
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index eccb0ec87adb..9193a385ceb2 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -320,6 +320,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
320 if (avp->av_bcbuf != NULL) { 320 if (avp->av_bcbuf != NULL) {
321 struct ath_buf *bf; 321 struct ath_buf *bf;
322 322
323 avp->is_bslot_active = false;
323 if (avp->av_bslot != -1) { 324 if (avp->av_bslot != -1) {
324 sc->beacon.bslot[avp->av_bslot] = NULL; 325 sc->beacon.bslot[avp->av_bslot] = NULL;
325 sc->nbcnvifs--; 326 sc->nbcnvifs--;
@@ -743,7 +744,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
743 cur_conf->dtim_period = 1; 744 cur_conf->dtim_period = 1;
744 745
745 ath_set_beacon(sc); 746 ath_set_beacon(sc);
746 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
747} 747}
748 748
749void ath_set_beacon(struct ath_softc *sc) 749void ath_set_beacon(struct ath_softc *sc)
@@ -761,6 +761,12 @@ void ath_set_beacon(struct ath_softc *sc)
761 break; 761 break;
762 case NL80211_IFTYPE_STATION: 762 case NL80211_IFTYPE_STATION:
763 ath_beacon_config_sta(sc, cur_conf); 763 ath_beacon_config_sta(sc, cur_conf);
764 /*
765 * Request a re-configuration of Beacon related timers
766 * on the receipt of the first Beacon frame (i.e.,
767 * after time sync with the AP).
768 */
769 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
764 break; 770 break;
765 default: 771 default:
766 ath_dbg(common, ATH_DBG_CONFIG, 772 ath_dbg(common, ATH_DBG_CONFIG,
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index a762cadb3ab7..34f191ec8e8c 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -845,7 +845,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
845 845
846 struct ath_softc *sc = file->private_data; 846 struct ath_softc *sc = file->private_data;
847 char *buf; 847 char *buf;
848 unsigned int len = 0, size = 1152; 848 unsigned int len = 0, size = 1400;
849 ssize_t retval = 0; 849 ssize_t retval = 0;
850 850
851 buf = kzalloc(size, GFP_KERNEL); 851 buf = kzalloc(size, GFP_KERNEL);
@@ -874,6 +874,34 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
874 "%18s : %10u\n", "DECRYPT BUSY ERR", 874 "%18s : %10u\n", "DECRYPT BUSY ERR",
875 sc->debug.stats.rxstats.decrypt_busy_err); 875 sc->debug.stats.rxstats.decrypt_busy_err);
876 876
877 len += snprintf(buf + len, size - len,
878 "%18s : %10d\n", "RSSI-CTL0",
879 sc->debug.stats.rxstats.rs_rssi_ctl0);
880
881 len += snprintf(buf + len, size - len,
882 "%18s : %10d\n", "RSSI-CTL1",
883 sc->debug.stats.rxstats.rs_rssi_ctl1);
884
885 len += snprintf(buf + len, size - len,
886 "%18s : %10d\n", "RSSI-CTL2",
887 sc->debug.stats.rxstats.rs_rssi_ctl2);
888
889 len += snprintf(buf + len, size - len,
890 "%18s : %10d\n", "RSSI-EXT0",
891 sc->debug.stats.rxstats.rs_rssi_ext0);
892
893 len += snprintf(buf + len, size - len,
894 "%18s : %10d\n", "RSSI-EXT1",
895 sc->debug.stats.rxstats.rs_rssi_ext1);
896
897 len += snprintf(buf + len, size - len,
898 "%18s : %10d\n", "RSSI-EXT2",
899 sc->debug.stats.rxstats.rs_rssi_ext2);
900
901 len += snprintf(buf + len, size - len,
902 "%18s : %10d\n", "Rx Antenna",
903 sc->debug.stats.rxstats.rs_antenna);
904
877 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); 905 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
878 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); 906 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
879 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); 907 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
@@ -948,6 +976,16 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
948 RX_PHY_ERR_INC(phyerr); 976 RX_PHY_ERR_INC(phyerr);
949 } 977 }
950 978
979 sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0;
980 sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1;
981 sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2;
982
983 sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0;
984 sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1;
985 sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2;
986
987 sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna;
988
951#undef RX_STAT_INC 989#undef RX_STAT_INC
952#undef RX_PHY_ERR_INC 990#undef RX_PHY_ERR_INC
953} 991}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 59338de0ce19..1f9f8eada465 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -157,6 +157,13 @@ struct ath_rx_stats {
157 u32 post_delim_crc_err; 157 u32 post_delim_crc_err;
158 u32 decrypt_busy_err; 158 u32 decrypt_busy_err;
159 u32 phy_err_stats[ATH9K_PHYERR_MAX]; 159 u32 phy_err_stats[ATH9K_PHYERR_MAX];
160 int8_t rs_rssi_ctl0;
161 int8_t rs_rssi_ctl1;
162 int8_t rs_rssi_ctl2;
163 int8_t rs_rssi_ext0;
164 int8_t rs_rssi_ext1;
165 int8_t rs_rssi_ext2;
166 u8 rs_antenna;
160}; 167};
161 168
162struct ath_stats { 169struct ath_stats {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index bd82447f5b78..3e316133f114 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -436,7 +436,11 @@ struct modal_eep_4k_header {
436 u8 db2_2:4, db2_3:4; 436 u8 db2_2:4, db2_3:4;
437 u8 db2_4:4, reserved:4; 437 u8 db2_4:4, reserved:4;
438#endif 438#endif
439 u8 futureModal[4]; 439 u8 tx_diversity;
440 u8 flc_pwr_thresh;
441 u8 bb_scale_smrt_antenna;
442#define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f
443 u8 futureModal[1];
440 struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; 444 struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
441} __packed; 445} __packed;
442 446
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index bc77a308c901..6f714dd72365 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -781,6 +781,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
781{ 781{
782 struct modal_eep_4k_header *pModal; 782 struct modal_eep_4k_header *pModal;
783 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; 783 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
784 struct base_eep_header_4k *pBase = &eep->baseEepHeader;
784 u8 txRxAttenLocal; 785 u8 txRxAttenLocal;
785 u8 ob[5], db1[5], db2[5]; 786 u8 ob[5], db1[5], db2[5];
786 u8 ant_div_control1, ant_div_control2; 787 u8 ant_div_control1, ant_div_control2;
@@ -1003,6 +1004,31 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1003 AR_PHY_SETTLING_SWITCH, 1004 AR_PHY_SETTLING_SWITCH,
1004 pModal->swSettleHt40); 1005 pModal->swSettleHt40);
1005 } 1006 }
1007 if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) {
1008 u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna &
1009 EEP_4K_BB_DESIRED_SCALE_MASK);
1010 if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
1011 u32 pwrctrl, mask, clr;
1012
1013 mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
1014 pwrctrl = mask * bb_desired_scale;
1015 clr = mask * 0x1f;
1016 REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
1017 REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
1018 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
1019
1020 mask = BIT(0)|BIT(5)|BIT(15);
1021 pwrctrl = mask * bb_desired_scale;
1022 clr = mask * 0x1f;
1023 REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr);
1024
1025 mask = BIT(0)|BIT(5);
1026 pwrctrl = mask * bb_desired_scale;
1027 clr = mask * 0x1f;
1028 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
1029 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
1030 }
1031 }
1006} 1032}
1007 1033
1008static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1034static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 2f0712ea49a6..13579752a300 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -858,35 +858,12 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
858{ 858{
859 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 859 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
860 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 860 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
861 u16 antWrites[AR9287_ANT_16S];
862 u32 regChainOffset, regval; 861 u32 regChainOffset, regval;
863 u8 txRxAttenLocal; 862 u8 txRxAttenLocal;
864 int i, j, offset_num; 863 int i;
865 864
866 pModal = &eep->modalHeader; 865 pModal = &eep->modalHeader;
867 866
868 antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF);
869 antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF);
870 antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF);
871 antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF);
872 antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF);
873 antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF);
874 antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF);
875 antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF);
876
877 offset_num = 8;
878
879 for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
880 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf);
881 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3);
882 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3);
883 antWrites[j++] = 0;
884 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3);
885 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3);
886 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3);
887 antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
888 }
889
890 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 867 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
891 868
892 for (i = 0; i < AR9287_MAX_CHAINS; i++) { 869 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index f1b8af64569c..48bcc1a21076 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -17,11 +17,9 @@
17#include "htc.h" 17#include "htc.h"
18 18
19/* identify firmware images */ 19/* identify firmware images */
20#define FIRMWARE_AR7010 "ar7010.fw" 20#define FIRMWARE_AR7010_1_1 "htc_7010.fw"
21#define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" 21#define FIRMWARE_AR9271 "htc_9271.fw"
22#define FIRMWARE_AR9271 "ar9271.fw"
23 22
24MODULE_FIRMWARE(FIRMWARE_AR7010);
25MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); 23MODULE_FIRMWARE(FIRMWARE_AR7010_1_1);
26MODULE_FIRMWARE(FIRMWARE_AR9271); 24MODULE_FIRMWARE(FIRMWARE_AR9271);
27 25
@@ -80,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb)
80 78
81 if (cmd) { 79 if (cmd) {
82 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, 80 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
83 cmd->skb, 1); 81 cmd->skb, true);
84 kfree(cmd); 82 kfree(cmd);
85 } 83 }
86 84
@@ -126,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
126 return ret; 124 return ret;
127} 125}
128 126
127static void hif_usb_mgmt_cb(struct urb *urb)
128{
129 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
130 struct hif_device_usb *hif_dev = cmd->hif_dev;
131 bool txok = true;
132
133 if (!cmd || !cmd->skb || !cmd->hif_dev)
134 return;
135
136 switch (urb->status) {
137 case 0:
138 break;
139 case -ENOENT:
140 case -ECONNRESET:
141 case -ENODEV:
142 case -ESHUTDOWN:
143 txok = false;
144
145 /*
146 * If the URBs are being flushed, no need to complete
147 * this packet.
148 */
149 spin_lock(&hif_dev->tx.tx_lock);
150 if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
151 spin_unlock(&hif_dev->tx.tx_lock);
152 dev_kfree_skb_any(cmd->skb);
153 kfree(cmd);
154 return;
155 }
156 spin_unlock(&hif_dev->tx.tx_lock);
157
158 break;
159 default:
160 txok = false;
161 break;
162 }
163
164 skb_pull(cmd->skb, 4);
165 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
166 cmd->skb, txok);
167 kfree(cmd);
168}
169
170static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev,
171 struct sk_buff *skb)
172{
173 struct urb *urb;
174 struct cmd_buf *cmd;
175 int ret = 0;
176 __le16 *hdr;
177
178 urb = usb_alloc_urb(0, GFP_ATOMIC);
179 if (urb == NULL)
180 return -ENOMEM;
181
182 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
183 if (cmd == NULL) {
184 usb_free_urb(urb);
185 return -ENOMEM;
186 }
187
188 cmd->skb = skb;
189 cmd->hif_dev = hif_dev;
190
191 hdr = (__le16 *) skb_push(skb, 4);
192 *hdr++ = cpu_to_le16(skb->len - 4);
193 *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG);
194
195 usb_fill_bulk_urb(urb, hif_dev->udev,
196 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
197 skb->data, skb->len,
198 hif_usb_mgmt_cb, cmd);
199
200 usb_anchor_urb(urb, &hif_dev->mgmt_submitted);
201 ret = usb_submit_urb(urb, GFP_ATOMIC);
202 if (ret) {
203 usb_unanchor_urb(urb);
204 kfree(cmd);
205 }
206 usb_free_urb(urb);
207
208 return ret;
209}
210
129static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, 211static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
130 struct sk_buff_head *list) 212 struct sk_buff_head *list)
131{ 213{
@@ -133,7 +215,22 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
133 215
134 while ((skb = __skb_dequeue(list)) != NULL) { 216 while ((skb = __skb_dequeue(list)) != NULL) {
135 dev_kfree_skb_any(skb); 217 dev_kfree_skb_any(skb);
136 TX_STAT_INC(skb_dropped); 218 }
219}
220
221static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,
222 struct sk_buff_head *queue,
223 bool txok)
224{
225 struct sk_buff *skb;
226
227 while ((skb = __skb_dequeue(queue)) != NULL) {
228 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
229 skb, txok);
230 if (txok)
231 TX_STAT_INC(skb_success);
232 else
233 TX_STAT_INC(skb_failed);
137 } 234 }
138} 235}
139 236
@@ -141,7 +238,7 @@ static void hif_usb_tx_cb(struct urb *urb)
141{ 238{
142 struct tx_buf *tx_buf = (struct tx_buf *) urb->context; 239 struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
143 struct hif_device_usb *hif_dev; 240 struct hif_device_usb *hif_dev;
144 struct sk_buff *skb; 241 bool txok = true;
145 242
146 if (!tx_buf || !tx_buf->hif_dev) 243 if (!tx_buf || !tx_buf->hif_dev)
147 return; 244 return;
@@ -155,10 +252,7 @@ static void hif_usb_tx_cb(struct urb *urb)
155 case -ECONNRESET: 252 case -ECONNRESET:
156 case -ENODEV: 253 case -ENODEV:
157 case -ESHUTDOWN: 254 case -ESHUTDOWN:
158 /* 255 txok = false;
159 * The URB has been killed, free the SKBs.
160 */
161 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
162 256
163 /* 257 /*
164 * If the URBs are being flushed, no need to add this 258 * If the URBs are being flushed, no need to add this
@@ -167,41 +261,19 @@ static void hif_usb_tx_cb(struct urb *urb)
167 spin_lock(&hif_dev->tx.tx_lock); 261 spin_lock(&hif_dev->tx.tx_lock);
168 if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { 262 if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
169 spin_unlock(&hif_dev->tx.tx_lock); 263 spin_unlock(&hif_dev->tx.tx_lock);
264 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
170 return; 265 return;
171 } 266 }
172 spin_unlock(&hif_dev->tx.tx_lock); 267 spin_unlock(&hif_dev->tx.tx_lock);
173 268
174 /* 269 break;
175 * In the stop() case, this URB has to be added to
176 * the free list.
177 */
178 goto add_free;
179 default: 270 default:
271 txok = false;
180 break; 272 break;
181 } 273 }
182 274
183 /* 275 ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok);
184 * Check if TX has been stopped, this is needed because
185 * this CB could have been invoked just after the TX lock
186 * was released in hif_stop() and kill_urb() hasn't been
187 * called yet.
188 */
189 spin_lock(&hif_dev->tx.tx_lock);
190 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
191 spin_unlock(&hif_dev->tx.tx_lock);
192 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
193 goto add_free;
194 }
195 spin_unlock(&hif_dev->tx.tx_lock);
196
197 /* Complete the queued SKBs. */
198 while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
199 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
200 skb, 1);
201 TX_STAT_INC(skb_completed);
202 }
203 276
204add_free:
205 /* Re-initialize the SKB queue */ 277 /* Re-initialize the SKB queue */
206 tx_buf->len = tx_buf->offset = 0; 278 tx_buf->len = tx_buf->offset = 0;
207 __skb_queue_head_init(&tx_buf->skb_queue); 279 __skb_queue_head_init(&tx_buf->skb_queue);
@@ -274,7 +346,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
274 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); 346 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
275 if (ret) { 347 if (ret) {
276 tx_buf->len = tx_buf->offset = 0; 348 tx_buf->len = tx_buf->offset = 0;
277 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); 349 ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false);
278 __skb_queue_head_init(&tx_buf->skb_queue); 350 __skb_queue_head_init(&tx_buf->skb_queue);
279 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); 351 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
280 hif_dev->tx.tx_buf_cnt++; 352 hif_dev->tx.tx_buf_cnt++;
@@ -286,10 +358,11 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
286 return ret; 358 return ret;
287} 359}
288 360
289static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, 361static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb)
290 struct ath9k_htc_tx_ctl *tx_ctl)
291{ 362{
363 struct ath9k_htc_tx_ctl *tx_ctl;
292 unsigned long flags; 364 unsigned long flags;
365 int ret = 0;
293 366
294 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); 367 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
295 368
@@ -304,26 +377,36 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
304 return -ENOMEM; 377 return -ENOMEM;
305 } 378 }
306 379
307 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); 380 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
308 hif_dev->tx.tx_skb_cnt++;
309 381
310 /* Send normal frames immediately */ 382 tx_ctl = HTC_SKB_CB(skb);
311 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) 383
312 __hif_usb_tx(hif_dev); 384 /* Mgmt/Beacon frames don't use the TX buffer pool */
385 if ((tx_ctl->type == ATH9K_HTC_MGMT) ||
386 (tx_ctl->type == ATH9K_HTC_BEACON)) {
387 ret = hif_usb_send_mgmt(hif_dev, skb);
388 }
389
390 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
391
392 if ((tx_ctl->type == ATH9K_HTC_NORMAL) ||
393 (tx_ctl->type == ATH9K_HTC_AMPDU)) {
394 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
395 hif_dev->tx.tx_skb_cnt++;
396 }
313 397
314 /* Check if AMPDUs have to be sent immediately */ 398 /* Check if AMPDUs have to be sent immediately */
315 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && 399 if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
316 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
317 (hif_dev->tx.tx_skb_cnt < 2)) { 400 (hif_dev->tx.tx_skb_cnt < 2)) {
318 __hif_usb_tx(hif_dev); 401 __hif_usb_tx(hif_dev);
319 } 402 }
320 403
321 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); 404 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
322 405
323 return 0; 406 return ret;
324} 407}
325 408
326static void hif_usb_start(void *hif_handle, u8 pipe_id) 409static void hif_usb_start(void *hif_handle)
327{ 410{
328 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; 411 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
329 unsigned long flags; 412 unsigned long flags;
@@ -335,14 +418,14 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id)
335 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); 418 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
336} 419}
337 420
338static void hif_usb_stop(void *hif_handle, u8 pipe_id) 421static void hif_usb_stop(void *hif_handle)
339{ 422{
340 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; 423 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
341 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; 424 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
342 unsigned long flags; 425 unsigned long flags;
343 426
344 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); 427 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
345 ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); 428 ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false);
346 hif_dev->tx.tx_skb_cnt = 0; 429 hif_dev->tx.tx_skb_cnt = 0;
347 hif_dev->tx.flags |= HIF_USB_TX_STOP; 430 hif_dev->tx.flags |= HIF_USB_TX_STOP;
348 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); 431 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
@@ -352,17 +435,18 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id)
352 &hif_dev->tx.tx_pending, list) { 435 &hif_dev->tx.tx_pending, list) {
353 usb_kill_urb(tx_buf->urb); 436 usb_kill_urb(tx_buf->urb);
354 } 437 }
438
439 usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
355} 440}
356 441
357static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, 442static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb)
358 struct ath9k_htc_tx_ctl *tx_ctl)
359{ 443{
360 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; 444 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
361 int ret = 0; 445 int ret = 0;
362 446
363 switch (pipe_id) { 447 switch (pipe_id) {
364 case USB_WLAN_TX_PIPE: 448 case USB_WLAN_TX_PIPE:
365 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); 449 ret = hif_usb_send_tx(hif_dev, skb);
366 break; 450 break;
367 case USB_REG_OUT_PIPE: 451 case USB_REG_OUT_PIPE:
368 ret = hif_usb_send_regout(hif_dev, skb); 452 ret = hif_usb_send_regout(hif_dev, skb);
@@ -377,6 +461,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
377 return ret; 461 return ret;
378} 462}
379 463
464static inline bool check_index(struct sk_buff *skb, u8 idx)
465{
466 struct ath9k_htc_tx_ctl *tx_ctl;
467
468 tx_ctl = HTC_SKB_CB(skb);
469
470 if ((tx_ctl->type == ATH9K_HTC_AMPDU) &&
471 (tx_ctl->sta_idx == idx))
472 return true;
473
474 return false;
475}
476
477static void hif_usb_sta_drain(void *hif_handle, u8 idx)
478{
479 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
480 struct sk_buff *skb, *tmp;
481 unsigned long flags;
482
483 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
484
485 skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) {
486 if (check_index(skb, idx)) {
487 __skb_unlink(skb, &hif_dev->tx.tx_skb_queue);
488 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
489 skb, false);
490 hif_dev->tx.tx_skb_cnt--;
491 TX_STAT_INC(skb_failed);
492 }
493 }
494
495 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
496}
497
380static struct ath9k_htc_hif hif_usb = { 498static struct ath9k_htc_hif hif_usb = {
381 .transport = ATH9K_HIF_USB, 499 .transport = ATH9K_HIF_USB,
382 .name = "ath9k_hif_usb", 500 .name = "ath9k_hif_usb",
@@ -386,6 +504,7 @@ static struct ath9k_htc_hif hif_usb = {
386 504
387 .start = hif_usb_start, 505 .start = hif_usb_start,
388 .stop = hif_usb_stop, 506 .stop = hif_usb_stop,
507 .sta_drain = hif_usb_sta_drain,
389 .send = hif_usb_send, 508 .send = hif_usb_send,
390}; 509};
391 510
@@ -567,6 +686,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
567 case -ESHUTDOWN: 686 case -ESHUTDOWN:
568 goto free; 687 goto free;
569 default: 688 default:
689 skb_reset_tail_pointer(skb);
690 skb_trim(skb, 0);
691
570 goto resubmit; 692 goto resubmit;
571 } 693 }
572 694
@@ -591,23 +713,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
591 USB_REG_IN_PIPE), 713 USB_REG_IN_PIPE),
592 nskb->data, MAX_REG_IN_BUF_SIZE, 714 nskb->data, MAX_REG_IN_BUF_SIZE,
593 ath9k_hif_usb_reg_in_cb, nskb); 715 ath9k_hif_usb_reg_in_cb, nskb);
594
595 ret = usb_submit_urb(urb, GFP_ATOMIC);
596 if (ret) {
597 kfree_skb(nskb);
598 urb->context = NULL;
599 }
600
601 return;
602 } 716 }
603 717
604resubmit: 718resubmit:
605 skb_reset_tail_pointer(skb); 719 usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
606 skb_trim(skb, 0);
607
608 ret = usb_submit_urb(urb, GFP_ATOMIC); 720 ret = usb_submit_urb(urb, GFP_ATOMIC);
609 if (ret) 721 if (ret) {
722 usb_unanchor_urb(urb);
610 goto free; 723 goto free;
724 }
611 725
612 return; 726 return;
613free: 727free:
@@ -641,6 +755,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
641 kfree(tx_buf->buf); 755 kfree(tx_buf->buf);
642 kfree(tx_buf); 756 kfree(tx_buf);
643 } 757 }
758
759 usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
644} 760}
645 761
646static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) 762static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
@@ -652,6 +768,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
652 INIT_LIST_HEAD(&hif_dev->tx.tx_pending); 768 INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
653 spin_lock_init(&hif_dev->tx.tx_lock); 769 spin_lock_init(&hif_dev->tx.tx_lock);
654 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); 770 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
771 init_usb_anchor(&hif_dev->mgmt_submitted);
655 772
656 for (i = 0; i < MAX_TX_URB_NUM; i++) { 773 for (i = 0; i < MAX_TX_URB_NUM; i++) {
657 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); 774 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
@@ -748,43 +865,67 @@ err_urb:
748 return ret; 865 return ret;
749} 866}
750 867
751static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) 868static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
752{ 869{
753 if (hif_dev->reg_in_urb) { 870 usb_kill_anchored_urbs(&hif_dev->reg_in_submitted);
754 usb_kill_urb(hif_dev->reg_in_urb);
755 if (hif_dev->reg_in_urb->context)
756 kfree_skb((void *)hif_dev->reg_in_urb->context);
757 usb_free_urb(hif_dev->reg_in_urb);
758 hif_dev->reg_in_urb = NULL;
759 }
760} 871}
761 872
762static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) 873static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
763{ 874{
764 struct sk_buff *skb; 875 struct urb *urb = NULL;
876 struct sk_buff *skb = NULL;
877 int i, ret;
765 878
766 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); 879 init_usb_anchor(&hif_dev->reg_in_submitted);
767 if (hif_dev->reg_in_urb == NULL)
768 return -ENOMEM;
769 880
770 skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); 881 for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
771 if (!skb)
772 goto err;
773 882
774 usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, 883 /* Allocate URB */
775 usb_rcvbulkpipe(hif_dev->udev, 884 urb = usb_alloc_urb(0, GFP_KERNEL);
776 USB_REG_IN_PIPE), 885 if (urb == NULL) {
777 skb->data, MAX_REG_IN_BUF_SIZE, 886 ret = -ENOMEM;
778 ath9k_hif_usb_reg_in_cb, skb); 887 goto err_urb;
888 }
779 889
780 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) 890 /* Allocate buffer */
781 goto err; 891 skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
892 if (!skb) {
893 ret = -ENOMEM;
894 goto err_skb;
895 }
896
897 usb_fill_bulk_urb(urb, hif_dev->udev,
898 usb_rcvbulkpipe(hif_dev->udev,
899 USB_REG_IN_PIPE),
900 skb->data, MAX_REG_IN_BUF_SIZE,
901 ath9k_hif_usb_reg_in_cb, skb);
902
903 /* Anchor URB */
904 usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
905
906 /* Submit URB */
907 ret = usb_submit_urb(urb, GFP_KERNEL);
908 if (ret) {
909 usb_unanchor_urb(urb);
910 goto err_submit;
911 }
912
913 /*
914 * Drop reference count.
915 * This ensures that the URB is freed when killing them.
916 */
917 usb_free_urb(urb);
918 }
782 919
783 return 0; 920 return 0;
784 921
785err: 922err_submit:
786 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); 923 kfree_skb(skb);
787 return -ENOMEM; 924err_skb:
925 usb_free_urb(urb);
926err_urb:
927 ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
928 return ret;
788} 929}
789 930
790static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) 931static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
@@ -801,7 +942,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
801 goto err_rx; 942 goto err_rx;
802 943
803 /* Register Read */ 944 /* Register Read */
804 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) 945 if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0)
805 goto err_reg; 946 goto err_reg;
806 947
807 return 0; 948 return 0;
@@ -816,7 +957,7 @@ err:
816static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) 957static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
817{ 958{
818 usb_kill_anchored_urbs(&hif_dev->regout_submitted); 959 usb_kill_anchored_urbs(&hif_dev->regout_submitted);
819 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); 960 ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
820 ath9k_hif_usb_dealloc_tx_urbs(hif_dev); 961 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
821 ath9k_hif_usb_dealloc_rx_urbs(hif_dev); 962 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
822} 963}
@@ -1026,10 +1167,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
1026 /* Find out which firmware to load */ 1167 /* Find out which firmware to load */
1027 1168
1028 if (IS_AR7010_DEVICE(id->driver_info)) 1169 if (IS_AR7010_DEVICE(id->driver_info))
1029 if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) 1170 hif_dev->fw_name = FIRMWARE_AR7010_1_1;
1030 hif_dev->fw_name = FIRMWARE_AR7010_1_1;
1031 else
1032 hif_dev->fw_name = FIRMWARE_AR7010;
1033 else 1171 else
1034 hif_dev->fw_name = FIRMWARE_AR9271; 1172 hif_dev->fw_name = FIRMWARE_AR9271;
1035 1173
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 7b9d863d4035..f59df48a86e2 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -31,7 +31,7 @@
31 31
32/* FIXME: Verify these numbers (with Windows) */ 32/* FIXME: Verify these numbers (with Windows) */
33#define MAX_TX_URB_NUM 8 33#define MAX_TX_URB_NUM 8
34#define MAX_TX_BUF_NUM 1024 34#define MAX_TX_BUF_NUM 256
35#define MAX_TX_BUF_SIZE 32768 35#define MAX_TX_BUF_SIZE 32768
36#define MAX_TX_AGGR_NUM 20 36#define MAX_TX_AGGR_NUM 20
37 37
@@ -40,7 +40,7 @@
40#define MAX_PKT_NUM_IN_TRANSFER 10 40#define MAX_PKT_NUM_IN_TRANSFER 10
41 41
42#define MAX_REG_OUT_URB_NUM 1 42#define MAX_REG_OUT_URB_NUM 1
43#define MAX_REG_OUT_BUF_NUM 8 43#define MAX_REG_IN_URB_NUM 64
44 44
45#define MAX_REG_IN_BUF_SIZE 64 45#define MAX_REG_IN_BUF_SIZE 64
46 46
@@ -90,9 +90,10 @@ struct hif_device_usb {
90 const struct firmware *firmware; 90 const struct firmware *firmware;
91 struct htc_target *htc_handle; 91 struct htc_target *htc_handle;
92 struct hif_usb_tx tx; 92 struct hif_usb_tx tx;
93 struct urb *reg_in_urb;
94 struct usb_anchor regout_submitted; 93 struct usb_anchor regout_submitted;
95 struct usb_anchor rx_submitted; 94 struct usb_anchor rx_submitted;
95 struct usb_anchor reg_in_submitted;
96 struct usb_anchor mgmt_submitted;
96 struct sk_buff *remain_skb; 97 struct sk_buff *remain_skb;
97 const char *fw_name; 98 const char *fw_name;
98 int rx_remain_len; 99 int rx_remain_len;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index ec47be94b74f..cc5d0a4b9da2 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -67,8 +67,11 @@ enum htc_opmode {
67}; 67};
68 68
69#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) 69#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
70#define ATH9K_HTC_AMPDU 1 70
71#define ATH9K_HTC_AMPDU 1
71#define ATH9K_HTC_NORMAL 2 72#define ATH9K_HTC_NORMAL 2
73#define ATH9K_HTC_BEACON 3
74#define ATH9K_HTC_MGMT 4
72 75
73#define ATH9K_HTC_TX_CTSONLY 0x1 76#define ATH9K_HTC_TX_CTSONLY 0x1
74#define ATH9K_HTC_TX_RTSCTS 0x2 77#define ATH9K_HTC_TX_RTSCTS 0x2
@@ -82,7 +85,8 @@ struct tx_frame_hdr {
82 __be32 flags; /* ATH9K_HTC_TX_* */ 85 __be32 flags; /* ATH9K_HTC_TX_* */
83 u8 key_type; 86 u8 key_type;
84 u8 keyix; 87 u8 keyix;
85 u8 reserved[26]; 88 u8 cookie;
89 u8 pad;
86} __packed; 90} __packed;
87 91
88struct tx_mgmt_hdr { 92struct tx_mgmt_hdr {
@@ -92,26 +96,16 @@ struct tx_mgmt_hdr {
92 u8 flags; 96 u8 flags;
93 u8 key_type; 97 u8 key_type;
94 u8 keyix; 98 u8 keyix;
95 u16 reserved; 99 u8 cookie;
100 u8 pad;
96} __packed; 101} __packed;
97 102
98struct tx_beacon_header { 103struct tx_beacon_header {
99 u8 len_changed;
100 u8 vif_index; 104 u8 vif_index;
105 u8 len_changed;
101 u16 rev; 106 u16 rev;
102} __packed; 107} __packed;
103 108
104struct ath9k_htc_target_hw {
105 u32 flags;
106 u32 flags_ext;
107 u32 ampdu_limit;
108 u8 ampdu_subframes;
109 u8 tx_chainmask;
110 u8 tx_chainmask_legacy;
111 u8 rtscts_ratecode;
112 u8 protmode;
113} __packed;
114
115struct ath9k_htc_cap_target { 109struct ath9k_htc_cap_target {
116 u32 flags; 110 u32 flags;
117 u32 flags_ext; 111 u32 flags_ext;
@@ -121,21 +115,16 @@ struct ath9k_htc_cap_target {
121 u8 tx_chainmask_legacy; 115 u8 tx_chainmask_legacy;
122 u8 rtscts_ratecode; 116 u8 rtscts_ratecode;
123 u8 protmode; 117 u8 protmode;
118 u8 pad;
124} __packed; 119} __packed;
125 120
126struct ath9k_htc_target_vif { 121struct ath9k_htc_target_vif {
127 u8 index; 122 u8 index;
128 u8 des_bssid[ETH_ALEN]; 123 u8 opmode;
129 __be32 opmode;
130 u8 myaddr[ETH_ALEN]; 124 u8 myaddr[ETH_ALEN];
131 u8 bssid[ETH_ALEN];
132 u32 flags;
133 u32 flags_ext;
134 u16 ps_sta;
135 __be16 rtsthreshold;
136 u8 ath_cap; 125 u8 ath_cap;
137 u8 node; 126 __be16 rtsthreshold;
138 s8 mcast_rate; 127 u8 pad;
139} __packed; 128} __packed;
140 129
141#define ATH_HTC_STA_AUTH 0x0001 130#define ATH_HTC_STA_AUTH 0x0001
@@ -143,27 +132,16 @@ struct ath9k_htc_target_vif {
143#define ATH_HTC_STA_ERP 0x0004 132#define ATH_HTC_STA_ERP 0x0004
144#define ATH_HTC_STA_HT 0x0008 133#define ATH_HTC_STA_HT 0x0008
145 134
146/* FIXME: UAPSD variables */
147struct ath9k_htc_target_sta { 135struct ath9k_htc_target_sta {
148 u16 associd;
149 u16 txpower;
150 u32 ucastkey;
151 u8 macaddr[ETH_ALEN]; 136 u8 macaddr[ETH_ALEN];
152 u8 bssid[ETH_ALEN]; 137 u8 bssid[ETH_ALEN];
153 u8 sta_index; 138 u8 sta_index;
154 u8 vif_index; 139 u8 vif_index;
155 u8 vif_sta;
156 __be16 flags; /* ATH_HTC_STA_* */
157 u16 htcap;
158 u8 valid;
159 u16 capinfo;
160 struct ath9k_htc_target_hw *hw;
161 struct ath9k_htc_target_vif *vif;
162 u16 txseqmgmt;
163 u8 is_vif_sta; 140 u8 is_vif_sta;
164 u16 maxampdu; 141 __be16 flags; /* ATH_HTC_STA_* */
165 u16 iv16; 142 __be16 htcap;
166 u32 iv32; 143 __be16 maxampdu;
144 u8 pad;
167} __packed; 145} __packed;
168 146
169struct ath9k_htc_target_aggr { 147struct ath9k_htc_target_aggr {
@@ -197,12 +175,31 @@ struct ath9k_htc_target_rate {
197 struct ath9k_htc_rate rates; 175 struct ath9k_htc_rate rates;
198}; 176};
199 177
200struct ath9k_htc_target_stats { 178struct ath9k_htc_target_int_stats {
201 __be32 tx_shortretry; 179 __be32 rx;
202 __be32 tx_longretry; 180 __be32 rxorn;
203 __be32 tx_xretries; 181 __be32 rxeol;
204 __be32 ht_txunaggr_xretry; 182 __be32 txurn;
205 __be32 ht_tx_xretries; 183 __be32 txto;
184 __be32 cst;
185} __packed;
186
187struct ath9k_htc_target_tx_stats {
188 __be32 xretries;
189 __be32 fifoerr;
190 __be32 filtered;
191 __be32 timer_exp;
192 __be32 shortretries;
193 __be32 longretries;
194 __be32 qnull;
195 __be32 encap_fail;
196 __be32 nobuf;
197} __packed;
198
199struct ath9k_htc_target_rx_stats {
200 __be32 nobuf;
201 __be32 host_send;
202 __be32 host_done;
206} __packed; 203} __packed;
207 204
208#define ATH9K_HTC_MAX_VIF 2 205#define ATH9K_HTC_MAX_VIF 2
@@ -244,6 +241,8 @@ struct ath9k_htc_vif {
244 u8 index; 241 u8 index;
245 u16 seq_no; 242 u16 seq_no;
246 bool beacon_configured; 243 bool beacon_configured;
244 int bslot;
245 __le64 tsfadjust;
247}; 246};
248 247
249struct ath9k_vif_iter_data { 248struct ath9k_vif_iter_data {
@@ -282,23 +281,65 @@ struct ath9k_htc_rx {
282 spinlock_t rxbuflock; 281 spinlock_t rxbuflock;
283}; 282};
284 283
284#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */
285#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */
286#define ATH9K_HTC_TX_RESERVE 10
287#define ATH9K_HTC_TX_TIMEOUT_COUNT 20
288#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE)
289
290#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0)
291#define ATH9K_HTC_OP_TX_DRAIN BIT(1)
292
293struct ath9k_htc_tx {
294 u8 flags;
295 int queued_cnt;
296 struct sk_buff_head mgmt_ep_queue;
297 struct sk_buff_head cab_ep_queue;
298 struct sk_buff_head data_be_queue;
299 struct sk_buff_head data_bk_queue;
300 struct sk_buff_head data_vi_queue;
301 struct sk_buff_head data_vo_queue;
302 struct sk_buff_head tx_failed;
303 DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
304 struct timer_list cleanup_timer;
305 spinlock_t tx_lock;
306};
307
285struct ath9k_htc_tx_ctl { 308struct ath9k_htc_tx_ctl {
286 u8 type; /* ATH9K_HTC_* */ 309 u8 type; /* ATH9K_HTC_* */
310 u8 epid;
311 u8 txok;
312 u8 sta_idx;
313 unsigned long timestamp;
287}; 314};
288 315
316static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
317{
318 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
319
320 BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) >
321 IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
322 return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data;
323}
324
289#ifdef CONFIG_ATH9K_HTC_DEBUGFS 325#ifdef CONFIG_ATH9K_HTC_DEBUGFS
290 326
291#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) 327#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
292#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) 328#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
329#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
293 330
294#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) 331#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
295 332
333void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
334 struct ath_htc_rx_status *rxs);
335
296struct ath_tx_stats { 336struct ath_tx_stats {
297 u32 buf_queued; 337 u32 buf_queued;
298 u32 buf_completed; 338 u32 buf_completed;
299 u32 skb_queued; 339 u32 skb_queued;
300 u32 skb_completed; 340 u32 skb_success;
301 u32 skb_dropped; 341 u32 skb_failed;
342 u32 cab_queued;
302 u32 queue_stats[WME_NUM_AC]; 343 u32 queue_stats[WME_NUM_AC];
303}; 344};
304 345
@@ -306,25 +347,42 @@ struct ath_rx_stats {
306 u32 skb_allocated; 347 u32 skb_allocated;
307 u32 skb_completed; 348 u32 skb_completed;
308 u32 skb_dropped; 349 u32 skb_dropped;
350 u32 err_crc;
351 u32 err_decrypt_crc;
352 u32 err_mic;
353 u32 err_pre_delim;
354 u32 err_post_delim;
355 u32 err_decrypt_busy;
356 u32 err_phy;
357 u32 err_phy_stats[ATH9K_PHYERR_MAX];
309}; 358};
310 359
311struct ath9k_debug { 360struct ath9k_debug {
312 struct dentry *debugfs_phy; 361 struct dentry *debugfs_phy;
313 struct dentry *debugfs_tgt_stats; 362 struct dentry *debugfs_tgt_int_stats;
363 struct dentry *debugfs_tgt_tx_stats;
364 struct dentry *debugfs_tgt_rx_stats;
314 struct dentry *debugfs_xmit; 365 struct dentry *debugfs_xmit;
315 struct dentry *debugfs_recv; 366 struct dentry *debugfs_recv;
367 struct dentry *debugfs_slot;
368 struct dentry *debugfs_queue;
316 struct ath_tx_stats tx_stats; 369 struct ath_tx_stats tx_stats;
317 struct ath_rx_stats rx_stats; 370 struct ath_rx_stats rx_stats;
318 u32 txrate;
319}; 371};
320 372
321#else 373#else
322 374
323#define TX_STAT_INC(c) do { } while (0) 375#define TX_STAT_INC(c) do { } while (0)
324#define RX_STAT_INC(c) do { } while (0) 376#define RX_STAT_INC(c) do { } while (0)
377#define CAB_STAT_INC do { } while (0)
325 378
326#define TX_QSTAT_INC(c) do { } while (0) 379#define TX_QSTAT_INC(c) do { } while (0)
327 380
381static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
382 struct ath_htc_rx_status *rxs)
383{
384}
385
328#endif /* CONFIG_ATH9K_HTC_DEBUGFS */ 386#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
329 387
330#define ATH_LED_PIN_DEF 1 388#define ATH_LED_PIN_DEF 1
@@ -351,10 +409,21 @@ struct ath_led {
351 int brightness; 409 int brightness;
352}; 410};
353 411
412#define BSTUCK_THRESHOLD 10
413
414/*
415 * Adjust these when the max. no of beaconing interfaces is
416 * increased.
417 */
418#define DEFAULT_SWBA_RESPONSE 40 /* in TUs */
419#define MIN_SWBA_RESPONSE 10 /* in TUs */
420
354struct htc_beacon_config { 421struct htc_beacon_config {
422 struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF];
355 u16 beacon_interval; 423 u16 beacon_interval;
356 u16 dtim_period; 424 u16 dtim_period;
357 u16 bmiss_timeout; 425 u16 bmiss_timeout;
426 u32 bmiss_cnt;
358}; 427};
359 428
360struct ath_btcoex { 429struct ath_btcoex {
@@ -388,6 +457,9 @@ struct ath9k_htc_priv {
388 struct htc_target *htc; 457 struct htc_target *htc;
389 struct wmi *wmi; 458 struct wmi *wmi;
390 459
460 u16 fw_version_major;
461 u16 fw_version_minor;
462
391 enum htc_endpoint_id wmi_cmd_ep; 463 enum htc_endpoint_id wmi_cmd_ep;
392 enum htc_endpoint_id beacon_ep; 464 enum htc_endpoint_id beacon_ep;
393 enum htc_endpoint_id cab_ep; 465 enum htc_endpoint_id cab_ep;
@@ -411,27 +483,23 @@ struct ath9k_htc_priv {
411 u16 txpowlimit; 483 u16 txpowlimit;
412 u16 nvifs; 484 u16 nvifs;
413 u16 nstations; 485 u16 nstations;
414 u32 bmiss_cnt;
415 bool rearm_ani; 486 bool rearm_ani;
416 bool reconfig_beacon; 487 bool reconfig_beacon;
488 unsigned int rxfilter;
417 489
418 struct ath9k_hw_cal_data caldata; 490 struct ath9k_hw_cal_data caldata;
491 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
419 492
420 spinlock_t beacon_lock; 493 spinlock_t beacon_lock;
494 struct htc_beacon_config cur_beacon_conf;
421 495
422 bool tx_queues_stop; 496 struct ath9k_htc_rx rx;
423 spinlock_t tx_lock; 497 struct ath9k_htc_tx tx;
424 498
425 struct ieee80211_vif *vif;
426 struct htc_beacon_config cur_beacon_conf;
427 unsigned int rxfilter;
428 struct tasklet_struct swba_tasklet; 499 struct tasklet_struct swba_tasklet;
429 struct tasklet_struct rx_tasklet; 500 struct tasklet_struct rx_tasklet;
430 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
431 struct ath9k_htc_rx rx;
432 struct tasklet_struct tx_tasklet;
433 struct sk_buff_head tx_queue;
434 struct delayed_work ani_work; 501 struct delayed_work ani_work;
502 struct tasklet_struct tx_failed_tasklet;
435 struct work_struct ps_work; 503 struct work_struct ps_work;
436 struct work_struct fatal_work; 504 struct work_struct fatal_work;
437 505
@@ -470,11 +538,18 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
470 538
471void ath9k_htc_reset(struct ath9k_htc_priv *priv); 539void ath9k_htc_reset(struct ath9k_htc_priv *priv);
472 540
541void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv,
542 struct ieee80211_vif *vif);
543void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv,
544 struct ieee80211_vif *vif);
545void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv,
546 struct ieee80211_vif *vif);
473void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); 547void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
474void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, 548void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
475 struct ieee80211_vif *vif); 549 struct ieee80211_vif *vif);
476void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); 550void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv);
477void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); 551void ath9k_htc_swba(struct ath9k_htc_priv *priv,
552 struct wmi_event_swba *swba);
478 553
479void ath9k_htc_rxep(void *priv, struct sk_buff *skb, 554void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
480 enum htc_endpoint_id ep_id); 555 enum htc_endpoint_id ep_id);
@@ -491,14 +566,23 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
491void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); 566void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
492 567
493int ath9k_tx_init(struct ath9k_htc_priv *priv); 568int ath9k_tx_init(struct ath9k_htc_priv *priv);
494void ath9k_tx_tasklet(unsigned long data); 569int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
495int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); 570 struct sk_buff *skb, u8 slot, bool is_cab);
496void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); 571void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
497bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); 572bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype);
498int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); 573int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv);
499int get_hw_qnum(u16 queue, int *hwq_map); 574int get_hw_qnum(u16 queue, int *hwq_map);
500int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, 575int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
501 struct ath9k_tx_queue_info *qinfo); 576 struct ath9k_tx_queue_info *qinfo);
577void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv);
578void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv);
579int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv);
580void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot);
581void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
582void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
583void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv);
584void ath9k_tx_failed_tasklet(unsigned long data);
585void ath9k_htc_tx_cleanup_timer(unsigned long data);
502 586
503int ath9k_rx_init(struct ath9k_htc_priv *priv); 587int ath9k_rx_init(struct ath9k_htc_priv *priv);
504void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); 588void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 8f56158e5887..bf7ef1b7eb3f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -18,6 +18,50 @@
18 18
19#define FUDGE 2 19#define FUDGE 2
20 20
21void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
22{
23 struct ath_hw *ah = priv->ah;
24 struct ath9k_tx_queue_info qi, qi_be;
25
26 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
27 memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
28
29 ath9k_hw_get_txq_props(ah, priv->beaconq, &qi);
30
31 if (priv->ah->opmode == NL80211_IFTYPE_AP) {
32 qi.tqi_aifs = 1;
33 qi.tqi_cwmin = 0;
34 qi.tqi_cwmax = 0;
35 } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
36 int qnum = priv->hwq_map[WME_AC_BE];
37
38 ath9k_hw_get_txq_props(ah, qnum, &qi_be);
39
40 qi.tqi_aifs = qi_be.tqi_aifs;
41
42 /*
43 * For WIFI Beacon Distribution
44 * Long slot time : 2x cwmin
45 * Short slot time : 4x cwmin
46 */
47 if (ah->slottime == ATH9K_SLOT_TIME_20)
48 qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
49 else
50 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
51
52 qi.tqi_cwmax = qi_be.tqi_cwmax;
53
54 }
55
56 if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
57 ath_err(ath9k_hw_common(ah),
58 "Unable to update beacon queue %u!\n", priv->beaconq);
59 } else {
60 ath9k_hw_resettxqueue(ah, priv->beaconq);
61 }
62}
63
64
21static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, 65static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
22 struct htc_beacon_config *bss_conf) 66 struct htc_beacon_config *bss_conf)
23{ 67{
@@ -154,6 +198,15 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
154 intval /= ATH9K_HTC_MAX_BCN_VIF; 198 intval /= ATH9K_HTC_MAX_BCN_VIF;
155 nexttbtt = intval; 199 nexttbtt = intval;
156 200
201 /*
202 * To reduce beacon misses under heavy TX load,
203 * set the beacon response time to a larger value.
204 */
205 if (intval > DEFAULT_SWBA_RESPONSE)
206 priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE;
207 else
208 priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
209
157 if (priv->op_flags & OP_TSF_RESET) { 210 if (priv->op_flags & OP_TSF_RESET) {
158 ath9k_hw_reset_tsf(priv->ah); 211 ath9k_hw_reset_tsf(priv->ah);
159 priv->op_flags &= ~OP_TSF_RESET; 212 priv->op_flags &= ~OP_TSF_RESET;
@@ -172,12 +225,16 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
172 imask |= ATH9K_INT_SWBA; 225 imask |= ATH9K_INT_SWBA;
173 226
174 ath_dbg(common, ATH_DBG_CONFIG, 227 ath_dbg(common, ATH_DBG_CONFIG,
175 "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n", 228 "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d "
176 bss_conf->beacon_interval, nexttbtt, imask); 229 "imask: 0x%x\n",
230 bss_conf->beacon_interval, nexttbtt,
231 priv->ah->config.sw_beacon_response_time, imask);
232
233 ath9k_htc_beaconq_config(priv);
177 234
178 WMI_CMD(WMI_DISABLE_INTR_CMDID); 235 WMI_CMD(WMI_DISABLE_INTR_CMDID);
179 ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); 236 ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
180 priv->bmiss_cnt = 0; 237 priv->cur_beacon_conf.bmiss_cnt = 0;
181 htc_imask = cpu_to_be32(imask); 238 htc_imask = cpu_to_be32(imask);
182 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); 239 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
183} 240}
@@ -205,16 +262,26 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
205 nexttbtt += intval; 262 nexttbtt += intval;
206 } while (nexttbtt < tsftu); 263 } while (nexttbtt < tsftu);
207 264
265 /*
266 * Only one IBSS interfce is allowed.
267 */
268 if (intval > DEFAULT_SWBA_RESPONSE)
269 priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE;
270 else
271 priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
272
208 if (priv->op_flags & OP_ENABLE_BEACON) 273 if (priv->op_flags & OP_ENABLE_BEACON)
209 imask |= ATH9K_INT_SWBA; 274 imask |= ATH9K_INT_SWBA;
210 275
211 ath_dbg(common, ATH_DBG_CONFIG, 276 ath_dbg(common, ATH_DBG_CONFIG,
212 "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n", 277 "IBSS Beacon config, intval: %d, nexttbtt: %u, "
213 bss_conf->beacon_interval, nexttbtt, imask); 278 "resp_time: %d, imask: 0x%x\n",
279 bss_conf->beacon_interval, nexttbtt,
280 priv->ah->config.sw_beacon_response_time, imask);
214 281
215 WMI_CMD(WMI_DISABLE_INTR_CMDID); 282 WMI_CMD(WMI_DISABLE_INTR_CMDID);
216 ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); 283 ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
217 priv->bmiss_cnt = 0; 284 priv->cur_beacon_conf.bmiss_cnt = 0;
218 htc_imask = cpu_to_be32(imask); 285 htc_imask = cpu_to_be32(imask);
219 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); 286 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
220} 287}
@@ -225,38 +292,101 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
225 dev_kfree_skb_any(skb); 292 dev_kfree_skb_any(skb);
226} 293}
227 294
228void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) 295static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,
296 int slot)
297{
298 struct ath_common *common = ath9k_hw_common(priv->ah);
299 struct ieee80211_vif *vif;
300 struct sk_buff *skb;
301 struct ieee80211_hdr *hdr;
302 int padpos, padsize, ret, tx_slot;
303
304 spin_lock_bh(&priv->beacon_lock);
305
306 vif = priv->cur_beacon_conf.bslot[slot];
307
308 skb = ieee80211_get_buffered_bc(priv->hw, vif);
309
310 while(skb) {
311 hdr = (struct ieee80211_hdr *) skb->data;
312
313 padpos = ath9k_cmn_padpos(hdr->frame_control);
314 padsize = padpos & 3;
315 if (padsize && skb->len > padpos) {
316 if (skb_headroom(skb) < padsize) {
317 dev_kfree_skb_any(skb);
318 goto next;
319 }
320 skb_push(skb, padsize);
321 memmove(skb->data, skb->data + padsize, padpos);
322 }
323
324 tx_slot = ath9k_htc_tx_get_slot(priv);
325 if (tx_slot != 0) {
326 ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n");
327 dev_kfree_skb_any(skb);
328 goto next;
329 }
330
331 ret = ath9k_htc_tx_start(priv, skb, tx_slot, true);
332 if (ret != 0) {
333 ath9k_htc_tx_clear_slot(priv, tx_slot);
334 dev_kfree_skb_any(skb);
335
336 ath_dbg(common, ATH_DBG_XMIT,
337 "Failed to send CAB frame\n");
338 } else {
339 spin_lock_bh(&priv->tx.tx_lock);
340 priv->tx.queued_cnt++;
341 spin_unlock_bh(&priv->tx.tx_lock);
342 }
343 next:
344 skb = ieee80211_get_buffered_bc(priv->hw, vif);
345 }
346
347 spin_unlock_bh(&priv->beacon_lock);
348}
349
350static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
351 int slot)
229{ 352{
230 struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv; 353 struct ath_common *common = ath9k_hw_common(priv->ah);
354 struct ieee80211_vif *vif;
355 struct ath9k_htc_vif *avp;
231 struct tx_beacon_header beacon_hdr; 356 struct tx_beacon_header beacon_hdr;
232 struct ath9k_htc_tx_ctl tx_ctl; 357 struct ath9k_htc_tx_ctl *tx_ctl;
233 struct ieee80211_tx_info *info; 358 struct ieee80211_tx_info *info;
359 struct ieee80211_mgmt *mgmt;
234 struct sk_buff *beacon; 360 struct sk_buff *beacon;
235 u8 *tx_fhdr; 361 u8 *tx_fhdr;
362 int ret;
236 363
237 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); 364 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
238 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
239
240 /* FIXME: Handle BMISS */
241 if (beacon_pending != 0) {
242 priv->bmiss_cnt++;
243 return;
244 }
245 365
246 spin_lock_bh(&priv->beacon_lock); 366 spin_lock_bh(&priv->beacon_lock);
247 367
368 vif = priv->cur_beacon_conf.bslot[slot];
369 avp = (struct ath9k_htc_vif *)vif->drv_priv;
370
248 if (unlikely(priv->op_flags & OP_SCANNING)) { 371 if (unlikely(priv->op_flags & OP_SCANNING)) {
249 spin_unlock_bh(&priv->beacon_lock); 372 spin_unlock_bh(&priv->beacon_lock);
250 return; 373 return;
251 } 374 }
252 375
253 /* Get a new beacon */ 376 /* Get a new beacon */
254 beacon = ieee80211_beacon_get(priv->hw, priv->vif); 377 beacon = ieee80211_beacon_get(priv->hw, vif);
255 if (!beacon) { 378 if (!beacon) {
256 spin_unlock_bh(&priv->beacon_lock); 379 spin_unlock_bh(&priv->beacon_lock);
257 return; 380 return;
258 } 381 }
259 382
383 /*
384 * Update the TSF adjust value here, the HW will
385 * add this value for every beacon.
386 */
387 mgmt = (struct ieee80211_mgmt *)beacon->data;
388 mgmt->u.beacon.timestamp = avp->tsfadjust;
389
260 info = IEEE80211_SKB_CB(beacon); 390 info = IEEE80211_SKB_CB(beacon);
261 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 391 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
262 struct ieee80211_hdr *hdr = 392 struct ieee80211_hdr *hdr =
@@ -266,45 +396,149 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
266 hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); 396 hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
267 } 397 }
268 398
269 tx_ctl.type = ATH9K_HTC_NORMAL; 399 tx_ctl = HTC_SKB_CB(beacon);
400 memset(tx_ctl, 0, sizeof(*tx_ctl));
401
402 tx_ctl->type = ATH9K_HTC_BEACON;
403 tx_ctl->epid = priv->beacon_ep;
404
270 beacon_hdr.vif_index = avp->index; 405 beacon_hdr.vif_index = avp->index;
271 tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); 406 tx_fhdr = skb_push(beacon, sizeof(beacon_hdr));
272 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); 407 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
273 408
274 htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); 409 ret = htc_send(priv->htc, beacon);
410 if (ret != 0) {
411 if (ret == -ENOMEM) {
412 ath_dbg(common, ATH_DBG_BSTUCK,
413 "Failed to send beacon, no free TX buffer\n");
414 }
415 dev_kfree_skb_any(beacon);
416 }
417
418 spin_unlock_bh(&priv->beacon_lock);
419}
420
421static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
422 struct wmi_event_swba *swba)
423{
424 struct ath_common *common = ath9k_hw_common(priv->ah);
425 u64 tsf;
426 u32 tsftu;
427 u16 intval;
428 int slot;
429
430 intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD;
275 431
432 tsf = be64_to_cpu(swba->tsf);
433 tsftu = TSF_TO_TU(tsf >> 32, tsf);
434 slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval;
435 slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1;
436
437 ath_dbg(common, ATH_DBG_BEACON,
438 "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n",
439 slot, tsf, tsftu, intval);
440
441 return slot;
442}
443
444void ath9k_htc_swba(struct ath9k_htc_priv *priv,
445 struct wmi_event_swba *swba)
446{
447 struct ath_common *common = ath9k_hw_common(priv->ah);
448 int slot;
449
450 if (swba->beacon_pending != 0) {
451 priv->cur_beacon_conf.bmiss_cnt++;
452 if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) {
453 ath_dbg(common, ATH_DBG_BSTUCK,
454 "Beacon stuck, HW reset\n");
455 ieee80211_queue_work(priv->hw,
456 &priv->fatal_work);
457 }
458 return;
459 }
460
461 if (priv->cur_beacon_conf.bmiss_cnt) {
462 ath_dbg(common, ATH_DBG_BSTUCK,
463 "Resuming beacon xmit after %u misses\n",
464 priv->cur_beacon_conf.bmiss_cnt);
465 priv->cur_beacon_conf.bmiss_cnt = 0;
466 }
467
468 slot = ath9k_htc_choose_bslot(priv, swba);
469 spin_lock_bh(&priv->beacon_lock);
470 if (priv->cur_beacon_conf.bslot[slot] == NULL) {
471 spin_unlock_bh(&priv->beacon_lock);
472 return;
473 }
276 spin_unlock_bh(&priv->beacon_lock); 474 spin_unlock_bh(&priv->beacon_lock);
475
476 ath9k_htc_send_buffered(priv, slot);
477 ath9k_htc_send_beacon(priv, slot);
277} 478}
278 479
279/* Currently, only for IBSS */ 480void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv,
280void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) 481 struct ieee80211_vif *vif)
281{ 482{
282 struct ath_hw *ah = priv->ah; 483 struct ath_common *common = ath9k_hw_common(priv->ah);
283 struct ath9k_tx_queue_info qi, qi_be; 484 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
284 int qnum = priv->hwq_map[WME_AC_BE]; 485 int i = 0;
285 486
286 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); 487 spin_lock_bh(&priv->beacon_lock);
287 memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); 488 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) {
489 if (priv->cur_beacon_conf.bslot[i] == NULL) {
490 avp->bslot = i;
491 break;
492 }
493 }
494
495 priv->cur_beacon_conf.bslot[avp->bslot] = vif;
496 spin_unlock_bh(&priv->beacon_lock);
497
498 ath_dbg(common, ATH_DBG_CONFIG,
499 "Added interface at beacon slot: %d\n", avp->bslot);
500}
501
502void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv,
503 struct ieee80211_vif *vif)
504{
505 struct ath_common *common = ath9k_hw_common(priv->ah);
506 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
507
508 spin_lock_bh(&priv->beacon_lock);
509 priv->cur_beacon_conf.bslot[avp->bslot] = NULL;
510 spin_unlock_bh(&priv->beacon_lock);
511
512 ath_dbg(common, ATH_DBG_CONFIG,
513 "Removed interface at beacon slot: %d\n", avp->bslot);
514}
288 515
289 ath9k_hw_get_txq_props(ah, qnum, &qi_be); 516/*
517 * Calculate the TSF adjustment value for all slots
518 * other than zero.
519 */
520void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv,
521 struct ieee80211_vif *vif)
522{
523 struct ath_common *common = ath9k_hw_common(priv->ah);
524 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
525 struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
526 u64 tsfadjust;
527
528 if (avp->bslot == 0)
529 return;
290 530
291 qi.tqi_aifs = qi_be.tqi_aifs; 531 /*
292 /* For WIFI Beacon Distribution 532 * The beacon interval cannot be different for multi-AP mode,
293 * Long slot time : 2x cwmin 533 * and we reach here only for VIF slots greater than zero,
294 * Short slot time : 4x cwmin 534 * so beacon_interval is guaranteed to be set in cur_conf.
295 */ 535 */
296 if (ah->slottime == ATH9K_SLOT_TIME_20) 536 tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF;
297 qi.tqi_cwmin = 2*qi_be.tqi_cwmin; 537 avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
298 else
299 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
300 qi.tqi_cwmax = qi_be.tqi_cwmax;
301 538
302 if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { 539 ath_dbg(common, ATH_DBG_CONFIG,
303 ath_err(ath9k_hw_common(ah), 540 "tsfadjust is: %llu for bslot: %d\n",
304 "Unable to update beacon queue %u!\n", qnum); 541 (unsigned long long)tsfadjust, avp->bslot);
305 } else {
306 ath9k_hw_resettxqueue(ah, priv->beaconq);
307 }
308} 542}
309 543
310static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) 544static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
new file mode 100644
index 000000000000..8d0de60e0c27
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -0,0 +1,531 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19static struct dentry *ath9k_debugfs_root;
20
21static int ath9k_debugfs_open(struct inode *inode, struct file *file)
22{
23 file->private_data = inode->i_private;
24 return 0;
25}
26
27static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
28 size_t count, loff_t *ppos)
29{
30 struct ath9k_htc_priv *priv = file->private_data;
31 struct ath9k_htc_target_int_stats cmd_rsp;
32 char buf[512];
33 unsigned int len = 0;
34 int ret = 0;
35
36 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
37
38 WMI_CMD(WMI_INT_STATS_CMDID);
39 if (ret)
40 return -EINVAL;
41
42 len += snprintf(buf + len, sizeof(buf) - len,
43 "%20s : %10u\n", "RX",
44 be32_to_cpu(cmd_rsp.rx));
45
46 len += snprintf(buf + len, sizeof(buf) - len,
47 "%20s : %10u\n", "RXORN",
48 be32_to_cpu(cmd_rsp.rxorn));
49
50 len += snprintf(buf + len, sizeof(buf) - len,
51 "%20s : %10u\n", "RXEOL",
52 be32_to_cpu(cmd_rsp.rxeol));
53
54 len += snprintf(buf + len, sizeof(buf) - len,
55 "%20s : %10u\n", "TXURN",
56 be32_to_cpu(cmd_rsp.txurn));
57
58 len += snprintf(buf + len, sizeof(buf) - len,
59 "%20s : %10u\n", "TXTO",
60 be32_to_cpu(cmd_rsp.txto));
61
62 len += snprintf(buf + len, sizeof(buf) - len,
63 "%20s : %10u\n", "CST",
64 be32_to_cpu(cmd_rsp.cst));
65
66 if (len > sizeof(buf))
67 len = sizeof(buf);
68
69 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
70}
71
72static const struct file_operations fops_tgt_int_stats = {
73 .read = read_file_tgt_int_stats,
74 .open = ath9k_debugfs_open,
75 .owner = THIS_MODULE,
76 .llseek = default_llseek,
77};
78
79static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
80 size_t count, loff_t *ppos)
81{
82 struct ath9k_htc_priv *priv = file->private_data;
83 struct ath9k_htc_target_tx_stats cmd_rsp;
84 char buf[512];
85 unsigned int len = 0;
86 int ret = 0;
87
88 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
89
90 WMI_CMD(WMI_TX_STATS_CMDID);
91 if (ret)
92 return -EINVAL;
93
94 len += snprintf(buf + len, sizeof(buf) - len,
95 "%20s : %10u\n", "Xretries",
96 be32_to_cpu(cmd_rsp.xretries));
97
98 len += snprintf(buf + len, sizeof(buf) - len,
99 "%20s : %10u\n", "FifoErr",
100 be32_to_cpu(cmd_rsp.fifoerr));
101
102 len += snprintf(buf + len, sizeof(buf) - len,
103 "%20s : %10u\n", "Filtered",
104 be32_to_cpu(cmd_rsp.filtered));
105
106 len += snprintf(buf + len, sizeof(buf) - len,
107 "%20s : %10u\n", "TimerExp",
108 be32_to_cpu(cmd_rsp.timer_exp));
109
110 len += snprintf(buf + len, sizeof(buf) - len,
111 "%20s : %10u\n", "ShortRetries",
112 be32_to_cpu(cmd_rsp.shortretries));
113
114 len += snprintf(buf + len, sizeof(buf) - len,
115 "%20s : %10u\n", "LongRetries",
116 be32_to_cpu(cmd_rsp.longretries));
117
118 len += snprintf(buf + len, sizeof(buf) - len,
119 "%20s : %10u\n", "QueueNull",
120 be32_to_cpu(cmd_rsp.qnull));
121
122 len += snprintf(buf + len, sizeof(buf) - len,
123 "%20s : %10u\n", "EncapFail",
124 be32_to_cpu(cmd_rsp.encap_fail));
125
126 len += snprintf(buf + len, sizeof(buf) - len,
127 "%20s : %10u\n", "NoBuf",
128 be32_to_cpu(cmd_rsp.nobuf));
129
130 if (len > sizeof(buf))
131 len = sizeof(buf);
132
133 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
134}
135
136static const struct file_operations fops_tgt_tx_stats = {
137 .read = read_file_tgt_tx_stats,
138 .open = ath9k_debugfs_open,
139 .owner = THIS_MODULE,
140 .llseek = default_llseek,
141};
142
143static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
144 size_t count, loff_t *ppos)
145{
146 struct ath9k_htc_priv *priv = file->private_data;
147 struct ath9k_htc_target_rx_stats cmd_rsp;
148 char buf[512];
149 unsigned int len = 0;
150 int ret = 0;
151
152 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
153
154 WMI_CMD(WMI_RX_STATS_CMDID);
155 if (ret)
156 return -EINVAL;
157
158 len += snprintf(buf + len, sizeof(buf) - len,
159 "%20s : %10u\n", "NoBuf",
160 be32_to_cpu(cmd_rsp.nobuf));
161
162 len += snprintf(buf + len, sizeof(buf) - len,
163 "%20s : %10u\n", "HostSend",
164 be32_to_cpu(cmd_rsp.host_send));
165
166 len += snprintf(buf + len, sizeof(buf) - len,
167 "%20s : %10u\n", "HostDone",
168 be32_to_cpu(cmd_rsp.host_done));
169
170 if (len > sizeof(buf))
171 len = sizeof(buf);
172
173 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
174}
175
176static const struct file_operations fops_tgt_rx_stats = {
177 .read = read_file_tgt_rx_stats,
178 .open = ath9k_debugfs_open,
179 .owner = THIS_MODULE,
180 .llseek = default_llseek,
181};
182
183static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
184 size_t count, loff_t *ppos)
185{
186 struct ath9k_htc_priv *priv = file->private_data;
187 char buf[512];
188 unsigned int len = 0;
189
190 len += snprintf(buf + len, sizeof(buf) - len,
191 "%20s : %10u\n", "Buffers queued",
192 priv->debug.tx_stats.buf_queued);
193 len += snprintf(buf + len, sizeof(buf) - len,
194 "%20s : %10u\n", "Buffers completed",
195 priv->debug.tx_stats.buf_completed);
196 len += snprintf(buf + len, sizeof(buf) - len,
197 "%20s : %10u\n", "SKBs queued",
198 priv->debug.tx_stats.skb_queued);
199 len += snprintf(buf + len, sizeof(buf) - len,
200 "%20s : %10u\n", "SKBs success",
201 priv->debug.tx_stats.skb_success);
202 len += snprintf(buf + len, sizeof(buf) - len,
203 "%20s : %10u\n", "SKBs failed",
204 priv->debug.tx_stats.skb_failed);
205 len += snprintf(buf + len, sizeof(buf) - len,
206 "%20s : %10u\n", "CAB queued",
207 priv->debug.tx_stats.cab_queued);
208
209 len += snprintf(buf + len, sizeof(buf) - len,
210 "%20s : %10u\n", "BE queued",
211 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
212 len += snprintf(buf + len, sizeof(buf) - len,
213 "%20s : %10u\n", "BK queued",
214 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
215 len += snprintf(buf + len, sizeof(buf) - len,
216 "%20s : %10u\n", "VI queued",
217 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
218 len += snprintf(buf + len, sizeof(buf) - len,
219 "%20s : %10u\n", "VO queued",
220 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
221
222 if (len > sizeof(buf))
223 len = sizeof(buf);
224
225 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
226}
227
228static const struct file_operations fops_xmit = {
229 .read = read_file_xmit,
230 .open = ath9k_debugfs_open,
231 .owner = THIS_MODULE,
232 .llseek = default_llseek,
233};
234
235void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
236 struct ath_htc_rx_status *rxs)
237{
238#define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++
239
240 if (rxs->rs_status & ATH9K_RXERR_CRC)
241 priv->debug.rx_stats.err_crc++;
242 if (rxs->rs_status & ATH9K_RXERR_DECRYPT)
243 priv->debug.rx_stats.err_decrypt_crc++;
244 if (rxs->rs_status & ATH9K_RXERR_MIC)
245 priv->debug.rx_stats.err_mic++;
246 if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
247 priv->debug.rx_stats.err_pre_delim++;
248 if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST)
249 priv->debug.rx_stats.err_post_delim++;
250 if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY)
251 priv->debug.rx_stats.err_decrypt_busy++;
252
253 if (rxs->rs_status & ATH9K_RXERR_PHY) {
254 priv->debug.rx_stats.err_phy++;
255 if (rxs->rs_phyerr < ATH9K_PHYERR_MAX)
256 RX_PHY_ERR_INC(rxs->rs_phyerr);
257 }
258
259#undef RX_PHY_ERR_INC
260}
261
262static ssize_t read_file_recv(struct file *file, char __user *user_buf,
263 size_t count, loff_t *ppos)
264{
265#define PHY_ERR(s, p) \
266 len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \
267 priv->debug.rx_stats.err_phy_stats[p]);
268
269 struct ath9k_htc_priv *priv = file->private_data;
270 char *buf;
271 unsigned int len = 0, size = 1500;
272 ssize_t retval = 0;
273
274 buf = kzalloc(size, GFP_KERNEL);
275 if (buf == NULL)
276 return -ENOMEM;
277
278 len += snprintf(buf + len, size - len,
279 "%20s : %10u\n", "SKBs allocated",
280 priv->debug.rx_stats.skb_allocated);
281 len += snprintf(buf + len, size - len,
282 "%20s : %10u\n", "SKBs completed",
283 priv->debug.rx_stats.skb_completed);
284 len += snprintf(buf + len, size - len,
285 "%20s : %10u\n", "SKBs Dropped",
286 priv->debug.rx_stats.skb_dropped);
287
288 len += snprintf(buf + len, size - len,
289 "%20s : %10u\n", "CRC ERR",
290 priv->debug.rx_stats.err_crc);
291 len += snprintf(buf + len, size - len,
292 "%20s : %10u\n", "DECRYPT CRC ERR",
293 priv->debug.rx_stats.err_decrypt_crc);
294 len += snprintf(buf + len, size - len,
295 "%20s : %10u\n", "MIC ERR",
296 priv->debug.rx_stats.err_mic);
297 len += snprintf(buf + len, size - len,
298 "%20s : %10u\n", "PRE-DELIM CRC ERR",
299 priv->debug.rx_stats.err_pre_delim);
300 len += snprintf(buf + len, size - len,
301 "%20s : %10u\n", "POST-DELIM CRC ERR",
302 priv->debug.rx_stats.err_post_delim);
303 len += snprintf(buf + len, size - len,
304 "%20s : %10u\n", "DECRYPT BUSY ERR",
305 priv->debug.rx_stats.err_decrypt_busy);
306 len += snprintf(buf + len, size - len,
307 "%20s : %10u\n", "TOTAL PHY ERR",
308 priv->debug.rx_stats.err_phy);
309
310
311 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
312 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
313 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
314 PHY_ERR("RATE", ATH9K_PHYERR_RATE);
315 PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
316 PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
317 PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
318 PHY_ERR("TOR", ATH9K_PHYERR_TOR);
319 PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
320 PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
321 PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
322 PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
323 PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
324 PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
325 PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
326 PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
327 PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
328 PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
329 PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
330 PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
331 PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
332 PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
333 PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
334 PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
335 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
336 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
337
338 if (len > size)
339 len = size;
340
341 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
342 kfree(buf);
343
344 return retval;
345
346#undef PHY_ERR
347}
348
349static const struct file_operations fops_recv = {
350 .read = read_file_recv,
351 .open = ath9k_debugfs_open,
352 .owner = THIS_MODULE,
353 .llseek = default_llseek,
354};
355
356static ssize_t read_file_slot(struct file *file, char __user *user_buf,
357 size_t count, loff_t *ppos)
358{
359 struct ath9k_htc_priv *priv = file->private_data;
360 char buf[512];
361 unsigned int len = 0;
362
363 spin_lock_bh(&priv->tx.tx_lock);
364
365 len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : ");
366
367 len += bitmap_scnprintf(buf + len, sizeof(buf) - len,
368 priv->tx.tx_slot, MAX_TX_BUF_NUM);
369
370 len += snprintf(buf + len, sizeof(buf) - len, "\n");
371
372 len += snprintf(buf + len, sizeof(buf) - len,
373 "Used slots : %d\n",
374 bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
375
376 spin_unlock_bh(&priv->tx.tx_lock);
377
378 if (len > sizeof(buf))
379 len = sizeof(buf);
380
381 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
382}
383
384static const struct file_operations fops_slot = {
385 .read = read_file_slot,
386 .open = ath9k_debugfs_open,
387 .owner = THIS_MODULE,
388 .llseek = default_llseek,
389};
390
391static ssize_t read_file_queue(struct file *file, char __user *user_buf,
392 size_t count, loff_t *ppos)
393{
394 struct ath9k_htc_priv *priv = file->private_data;
395 char buf[512];
396 unsigned int len = 0;
397
398 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
399 "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue));
400
401 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
402 "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue));
403
404 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
405 "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue));
406
407 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
408 "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue));
409
410 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
411 "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue));
412
413 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
414 "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue));
415
416 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
417 "Failed queue", skb_queue_len(&priv->tx.tx_failed));
418
419 spin_lock_bh(&priv->tx.tx_lock);
420 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
421 "Queued count", priv->tx.queued_cnt);
422 spin_unlock_bh(&priv->tx.tx_lock);
423
424 if (len > sizeof(buf))
425 len = sizeof(buf);
426
427 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
428
429}
430
431static const struct file_operations fops_queue = {
432 .read = read_file_queue,
433 .open = ath9k_debugfs_open,
434 .owner = THIS_MODULE,
435 .llseek = default_llseek,
436};
437
438int ath9k_htc_init_debug(struct ath_hw *ah)
439{
440 struct ath_common *common = ath9k_hw_common(ah);
441 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
442
443 if (!ath9k_debugfs_root)
444 return -ENOENT;
445
446 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
447 ath9k_debugfs_root);
448 if (!priv->debug.debugfs_phy)
449 goto err;
450
451 priv->debug.debugfs_tgt_int_stats = debugfs_create_file("tgt_int_stats",
452 S_IRUSR,
453 priv->debug.debugfs_phy,
454 priv, &fops_tgt_int_stats);
455 if (!priv->debug.debugfs_tgt_int_stats)
456 goto err;
457
458 priv->debug.debugfs_tgt_tx_stats = debugfs_create_file("tgt_tx_stats",
459 S_IRUSR,
460 priv->debug.debugfs_phy,
461 priv, &fops_tgt_tx_stats);
462 if (!priv->debug.debugfs_tgt_tx_stats)
463 goto err;
464
465 priv->debug.debugfs_tgt_rx_stats = debugfs_create_file("tgt_rx_stats",
466 S_IRUSR,
467 priv->debug.debugfs_phy,
468 priv, &fops_tgt_rx_stats);
469 if (!priv->debug.debugfs_tgt_rx_stats)
470 goto err;
471
472 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
473 priv->debug.debugfs_phy,
474 priv, &fops_xmit);
475 if (!priv->debug.debugfs_xmit)
476 goto err;
477
478 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
479 priv->debug.debugfs_phy,
480 priv, &fops_recv);
481 if (!priv->debug.debugfs_recv)
482 goto err;
483
484 priv->debug.debugfs_slot = debugfs_create_file("slot", S_IRUSR,
485 priv->debug.debugfs_phy,
486 priv, &fops_slot);
487 if (!priv->debug.debugfs_slot)
488 goto err;
489
490 priv->debug.debugfs_queue = debugfs_create_file("queue", S_IRUSR,
491 priv->debug.debugfs_phy,
492 priv, &fops_queue);
493 if (!priv->debug.debugfs_queue)
494 goto err;
495
496 return 0;
497
498err:
499 ath9k_htc_exit_debug(ah);
500 return -ENOMEM;
501}
502
503void ath9k_htc_exit_debug(struct ath_hw *ah)
504{
505 struct ath_common *common = ath9k_hw_common(ah);
506 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
507
508 debugfs_remove(priv->debug.debugfs_queue);
509 debugfs_remove(priv->debug.debugfs_slot);
510 debugfs_remove(priv->debug.debugfs_recv);
511 debugfs_remove(priv->debug.debugfs_xmit);
512 debugfs_remove(priv->debug.debugfs_tgt_int_stats);
513 debugfs_remove(priv->debug.debugfs_tgt_tx_stats);
514 debugfs_remove(priv->debug.debugfs_tgt_rx_stats);
515 debugfs_remove(priv->debug.debugfs_phy);
516}
517
518int ath9k_htc_debug_create_root(void)
519{
520 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
521 if (!ath9k_debugfs_root)
522 return -ENOENT;
523
524 return 0;
525}
526
527void ath9k_htc_debug_remove_root(void)
528{
529 debugfs_remove(ath9k_debugfs_root);
530 ath9k_debugfs_root = NULL;
531}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 7e630a81b453..dc0b33d01210 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -398,9 +398,9 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
398 398
399 /* Start TX */ 399 /* Start TX */
400 htc_start(priv->htc); 400 htc_start(priv->htc);
401 spin_lock_bh(&priv->tx_lock); 401 spin_lock_bh(&priv->tx.tx_lock);
402 priv->tx_queues_stop = false; 402 priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
403 spin_unlock_bh(&priv->tx_lock); 403 spin_unlock_bh(&priv->tx.tx_lock);
404 ieee80211_wake_queues(hw); 404 ieee80211_wake_queues(hw);
405 405
406 WMI_CMD(WMI_ENABLE_INTR_CMDID); 406 WMI_CMD(WMI_ENABLE_INTR_CMDID);
@@ -429,13 +429,15 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
429 429
430 /* Stop TX */ 430 /* Stop TX */
431 ieee80211_stop_queues(hw); 431 ieee80211_stop_queues(hw);
432 htc_stop(priv->htc); 432 ath9k_htc_tx_drain(priv);
433 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 433 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
434 skb_queue_purge(&priv->tx_queue);
435 434
436 /* Stop RX */ 435 /* Stop RX */
437 WMI_CMD(WMI_STOP_RECV_CMDID); 436 WMI_CMD(WMI_STOP_RECV_CMDID);
438 437
438 /* Clear the WMI event queue */
439 ath9k_wmi_event_drain(priv);
440
439 /* 441 /*
440 * The MIB counters have to be disabled here, 442 * The MIB counters have to be disabled here,
441 * since the target doesn't do it. 443 * since the target doesn't do it.
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 8303b34bdc90..22736eb901cf 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -643,7 +643,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
643{ 643{
644 struct ath_hw *ah = NULL; 644 struct ath_hw *ah = NULL;
645 struct ath_common *common; 645 struct ath_common *common;
646 int ret = 0, csz = 0; 646 int i, ret = 0, csz = 0;
647 647
648 priv->op_flags |= OP_INVALID; 648 priv->op_flags |= OP_INVALID;
649 649
@@ -671,20 +671,19 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
671 common->priv = priv; 671 common->priv = priv;
672 common->debug_mask = ath9k_debug; 672 common->debug_mask = ath9k_debug;
673 673
674 spin_lock_init(&priv->wmi->wmi_lock);
675 spin_lock_init(&priv->beacon_lock); 674 spin_lock_init(&priv->beacon_lock);
676 spin_lock_init(&priv->tx_lock); 675 spin_lock_init(&priv->tx.tx_lock);
677 mutex_init(&priv->mutex); 676 mutex_init(&priv->mutex);
678 mutex_init(&priv->htc_pm_lock); 677 mutex_init(&priv->htc_pm_lock);
679 tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet,
680 (unsigned long)priv);
681 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, 678 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
682 (unsigned long)priv); 679 (unsigned long)priv);
683 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, 680 tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet,
684 (unsigned long)priv); 681 (unsigned long)priv);
685 INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); 682 INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work);
686 INIT_WORK(&priv->ps_work, ath9k_ps_work); 683 INIT_WORK(&priv->ps_work, ath9k_ps_work);
687 INIT_WORK(&priv->fatal_work, ath9k_fatal_work); 684 INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
685 setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer,
686 (unsigned long)priv);
688 687
689 /* 688 /*
690 * Cache line size is used to size and align various 689 * Cache line size is used to size and align various
@@ -711,6 +710,9 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
711 if (ret) 710 if (ret)
712 goto err_queues; 711 goto err_queues;
713 712
713 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
714 priv->cur_beacon_conf.bslot[i] = NULL;
715
714 ath9k_init_crypto(priv); 716 ath9k_init_crypto(priv);
715 ath9k_init_channels_rates(priv); 717 ath9k_init_channels_rates(priv);
716 ath9k_init_misc(priv); 718 ath9k_init_misc(priv);
@@ -745,11 +747,15 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
745 IEEE80211_HW_HAS_RATE_CONTROL | 747 IEEE80211_HW_HAS_RATE_CONTROL |
746 IEEE80211_HW_RX_INCLUDES_FCS | 748 IEEE80211_HW_RX_INCLUDES_FCS |
747 IEEE80211_HW_SUPPORTS_PS | 749 IEEE80211_HW_SUPPORTS_PS |
748 IEEE80211_HW_PS_NULLFUNC_STACK; 750 IEEE80211_HW_PS_NULLFUNC_STACK |
751 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
749 752
750 hw->wiphy->interface_modes = 753 hw->wiphy->interface_modes =
751 BIT(NL80211_IFTYPE_STATION) | 754 BIT(NL80211_IFTYPE_STATION) |
752 BIT(NL80211_IFTYPE_ADHOC); 755 BIT(NL80211_IFTYPE_ADHOC) |
756 BIT(NL80211_IFTYPE_AP) |
757 BIT(NL80211_IFTYPE_P2P_GO) |
758 BIT(NL80211_IFTYPE_P2P_CLIENT);
753 759
754 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 760 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
755 761
@@ -782,6 +788,32 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
782 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 788 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
783} 789}
784 790
791static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
792{
793 struct ieee80211_hw *hw = priv->hw;
794 struct wmi_fw_version cmd_rsp;
795 int ret;
796
797 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
798
799 WMI_CMD(WMI_GET_FW_VERSION);
800 if (ret)
801 return -EINVAL;
802
803 priv->fw_version_major = be16_to_cpu(cmd_rsp.major);
804 priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor);
805
806 snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d",
807 priv->fw_version_major,
808 priv->fw_version_minor);
809
810 dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n",
811 priv->fw_version_major,
812 priv->fw_version_minor);
813
814 return 0;
815}
816
785static int ath9k_init_device(struct ath9k_htc_priv *priv, 817static int ath9k_init_device(struct ath9k_htc_priv *priv,
786 u16 devid, char *product, u32 drv_info) 818 u16 devid, char *product, u32 drv_info)
787{ 819{
@@ -801,6 +833,10 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
801 common = ath9k_hw_common(ah); 833 common = ath9k_hw_common(ah);
802 ath9k_set_hw_capab(priv, hw); 834 ath9k_set_hw_capab(priv, hw);
803 835
836 error = ath9k_init_firmware_version(priv);
837 if (error != 0)
838 goto err_fw;
839
804 /* Initialize regulatory */ 840 /* Initialize regulatory */
805 error = ath_regd_init(&common->regulatory, priv->hw->wiphy, 841 error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
806 ath9k_reg_notifier); 842 ath9k_reg_notifier);
@@ -861,6 +897,8 @@ err_rx:
861err_tx: 897err_tx:
862 /* Nothing */ 898 /* Nothing */
863err_regd: 899err_regd:
900 /* Nothing */
901err_fw:
864 ath9k_deinit_priv(priv); 902 ath9k_deinit_priv(priv);
865err_init: 903err_init:
866 return error; 904 return error;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index db8c0c044e9e..4de38643cb53 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -16,10 +16,6 @@
16 16
17#include "htc.h" 17#include "htc.h"
18 18
19#ifdef CONFIG_ATH9K_HTC_DEBUGFS
20static struct dentry *ath9k_debugfs_root;
21#endif
22
23/*************/ 19/*************/
24/* Utilities */ 20/* Utilities */
25/*************/ 21/*************/
@@ -197,11 +193,16 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
197 193
198 ath9k_htc_stop_ani(priv); 194 ath9k_htc_stop_ani(priv);
199 ieee80211_stop_queues(priv->hw); 195 ieee80211_stop_queues(priv->hw);
200 htc_stop(priv->htc); 196
197 del_timer_sync(&priv->tx.cleanup_timer);
198 ath9k_htc_tx_drain(priv);
199
201 WMI_CMD(WMI_DISABLE_INTR_CMDID); 200 WMI_CMD(WMI_DISABLE_INTR_CMDID);
202 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 201 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
203 WMI_CMD(WMI_STOP_RECV_CMDID); 202 WMI_CMD(WMI_STOP_RECV_CMDID);
204 203
204 ath9k_wmi_event_drain(priv);
205
205 caldata = &priv->caldata; 206 caldata = &priv->caldata;
206 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); 207 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
207 if (ret) { 208 if (ret) {
@@ -225,6 +226,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
225 ath9k_htc_vif_reconfig(priv); 226 ath9k_htc_vif_reconfig(priv);
226 ieee80211_wake_queues(priv->hw); 227 ieee80211_wake_queues(priv->hw);
227 228
229 mod_timer(&priv->tx.cleanup_timer,
230 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
231
228 ath9k_htc_ps_restore(priv); 232 ath9k_htc_ps_restore(priv);
229 mutex_unlock(&priv->mutex); 233 mutex_unlock(&priv->mutex);
230} 234}
@@ -250,11 +254,16 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
250 fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); 254 fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
251 255
252 ath9k_htc_ps_wakeup(priv); 256 ath9k_htc_ps_wakeup(priv);
253 htc_stop(priv->htc); 257
258 del_timer_sync(&priv->tx.cleanup_timer);
259 ath9k_htc_tx_drain(priv);
260
254 WMI_CMD(WMI_DISABLE_INTR_CMDID); 261 WMI_CMD(WMI_DISABLE_INTR_CMDID);
255 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 262 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
256 WMI_CMD(WMI_STOP_RECV_CMDID); 263 WMI_CMD(WMI_STOP_RECV_CMDID);
257 264
265 ath9k_wmi_event_drain(priv);
266
258 ath_dbg(common, ATH_DBG_CONFIG, 267 ath_dbg(common, ATH_DBG_CONFIG,
259 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", 268 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
260 priv->ah->curchan->channel, 269 priv->ah->curchan->channel,
@@ -263,6 +272,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
263 272
264 if (!fastcc) 273 if (!fastcc)
265 caldata = &priv->caldata; 274 caldata = &priv->caldata;
275
266 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); 276 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
267 if (ret) { 277 if (ret) {
268 ath_err(common, 278 ath_err(common,
@@ -296,6 +306,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
296 !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) 306 !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
297 ath9k_htc_vif_reconfig(priv); 307 ath9k_htc_vif_reconfig(priv);
298 308
309 mod_timer(&priv->tx.cleanup_timer,
310 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
311
299err: 312err:
300 ath9k_htc_ps_restore(priv); 313 ath9k_htc_ps_restore(priv);
301 return ret; 314 return ret;
@@ -349,7 +362,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
349 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); 362 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
350 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); 363 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
351 364
352 hvif.opmode = cpu_to_be32(HTC_M_MONITOR); 365 hvif.opmode = HTC_M_MONITOR;
353 hvif.index = ffz(priv->vif_slot); 366 hvif.index = ffz(priv->vif_slot);
354 367
355 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); 368 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
@@ -382,7 +395,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
382 tsta.is_vif_sta = 1; 395 tsta.is_vif_sta = 1;
383 tsta.sta_index = sta_idx; 396 tsta.sta_index = sta_idx;
384 tsta.vif_index = hvif.index; 397 tsta.vif_index = hvif.index;
385 tsta.maxampdu = 0xffff; 398 tsta.maxampdu = cpu_to_be16(0xffff);
386 399
387 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); 400 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
388 if (ret) { 401 if (ret) {
@@ -463,9 +476,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
463 ista = (struct ath9k_htc_sta *) sta->drv_priv; 476 ista = (struct ath9k_htc_sta *) sta->drv_priv;
464 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); 477 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
465 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); 478 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
466 tsta.associd = common->curaid;
467 tsta.is_vif_sta = 0; 479 tsta.is_vif_sta = 0;
468 tsta.valid = true;
469 ista->index = sta_idx; 480 ista->index = sta_idx;
470 } else { 481 } else {
471 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); 482 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
@@ -474,7 +485,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
474 485
475 tsta.sta_index = sta_idx; 486 tsta.sta_index = sta_idx;
476 tsta.vif_index = avp->index; 487 tsta.vif_index = avp->index;
477 tsta.maxampdu = 0xffff; 488 tsta.maxampdu = cpu_to_be16(0xffff);
478 if (sta && sta->ht_cap.ht_supported) 489 if (sta && sta->ht_cap.ht_supported)
479 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); 490 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
480 491
@@ -709,218 +720,13 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
709 (aggr.aggr_enable) ? "Starting" : "Stopping", 720 (aggr.aggr_enable) ? "Starting" : "Stopping",
710 sta->addr, tid); 721 sta->addr, tid);
711 722
712 spin_lock_bh(&priv->tx_lock); 723 spin_lock_bh(&priv->tx.tx_lock);
713 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; 724 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
714 spin_unlock_bh(&priv->tx_lock); 725 spin_unlock_bh(&priv->tx.tx_lock);
715 726
716 return ret; 727 return ret;
717} 728}
718 729
719/*********/
720/* DEBUG */
721/*********/
722
723#ifdef CONFIG_ATH9K_HTC_DEBUGFS
724
725static int ath9k_debugfs_open(struct inode *inode, struct file *file)
726{
727 file->private_data = inode->i_private;
728 return 0;
729}
730
731static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
732 size_t count, loff_t *ppos)
733{
734 struct ath9k_htc_priv *priv = file->private_data;
735 struct ath9k_htc_target_stats cmd_rsp;
736 char buf[512];
737 unsigned int len = 0;
738 int ret = 0;
739
740 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
741
742 WMI_CMD(WMI_TGT_STATS_CMDID);
743 if (ret)
744 return -EINVAL;
745
746
747 len += snprintf(buf + len, sizeof(buf) - len,
748 "%19s : %10u\n", "TX Short Retries",
749 be32_to_cpu(cmd_rsp.tx_shortretry));
750 len += snprintf(buf + len, sizeof(buf) - len,
751 "%19s : %10u\n", "TX Long Retries",
752 be32_to_cpu(cmd_rsp.tx_longretry));
753 len += snprintf(buf + len, sizeof(buf) - len,
754 "%19s : %10u\n", "TX Xretries",
755 be32_to_cpu(cmd_rsp.tx_xretries));
756 len += snprintf(buf + len, sizeof(buf) - len,
757 "%19s : %10u\n", "TX Unaggr. Xretries",
758 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
759 len += snprintf(buf + len, sizeof(buf) - len,
760 "%19s : %10u\n", "TX Xretries (HT)",
761 be32_to_cpu(cmd_rsp.ht_tx_xretries));
762 len += snprintf(buf + len, sizeof(buf) - len,
763 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
764
765 if (len > sizeof(buf))
766 len = sizeof(buf);
767
768 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
769}
770
771static const struct file_operations fops_tgt_stats = {
772 .read = read_file_tgt_stats,
773 .open = ath9k_debugfs_open,
774 .owner = THIS_MODULE,
775 .llseek = default_llseek,
776};
777
778static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
779 size_t count, loff_t *ppos)
780{
781 struct ath9k_htc_priv *priv = file->private_data;
782 char buf[512];
783 unsigned int len = 0;
784
785 len += snprintf(buf + len, sizeof(buf) - len,
786 "%20s : %10u\n", "Buffers queued",
787 priv->debug.tx_stats.buf_queued);
788 len += snprintf(buf + len, sizeof(buf) - len,
789 "%20s : %10u\n", "Buffers completed",
790 priv->debug.tx_stats.buf_completed);
791 len += snprintf(buf + len, sizeof(buf) - len,
792 "%20s : %10u\n", "SKBs queued",
793 priv->debug.tx_stats.skb_queued);
794 len += snprintf(buf + len, sizeof(buf) - len,
795 "%20s : %10u\n", "SKBs completed",
796 priv->debug.tx_stats.skb_completed);
797 len += snprintf(buf + len, sizeof(buf) - len,
798 "%20s : %10u\n", "SKBs dropped",
799 priv->debug.tx_stats.skb_dropped);
800
801 len += snprintf(buf + len, sizeof(buf) - len,
802 "%20s : %10u\n", "BE queued",
803 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
804 len += snprintf(buf + len, sizeof(buf) - len,
805 "%20s : %10u\n", "BK queued",
806 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
807 len += snprintf(buf + len, sizeof(buf) - len,
808 "%20s : %10u\n", "VI queued",
809 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
810 len += snprintf(buf + len, sizeof(buf) - len,
811 "%20s : %10u\n", "VO queued",
812 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
813
814 if (len > sizeof(buf))
815 len = sizeof(buf);
816
817 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
818}
819
820static const struct file_operations fops_xmit = {
821 .read = read_file_xmit,
822 .open = ath9k_debugfs_open,
823 .owner = THIS_MODULE,
824 .llseek = default_llseek,
825};
826
827static ssize_t read_file_recv(struct file *file, char __user *user_buf,
828 size_t count, loff_t *ppos)
829{
830 struct ath9k_htc_priv *priv = file->private_data;
831 char buf[512];
832 unsigned int len = 0;
833
834 len += snprintf(buf + len, sizeof(buf) - len,
835 "%20s : %10u\n", "SKBs allocated",
836 priv->debug.rx_stats.skb_allocated);
837 len += snprintf(buf + len, sizeof(buf) - len,
838 "%20s : %10u\n", "SKBs completed",
839 priv->debug.rx_stats.skb_completed);
840 len += snprintf(buf + len, sizeof(buf) - len,
841 "%20s : %10u\n", "SKBs Dropped",
842 priv->debug.rx_stats.skb_dropped);
843
844 if (len > sizeof(buf))
845 len = sizeof(buf);
846
847 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
848}
849
850static const struct file_operations fops_recv = {
851 .read = read_file_recv,
852 .open = ath9k_debugfs_open,
853 .owner = THIS_MODULE,
854 .llseek = default_llseek,
855};
856
857int ath9k_htc_init_debug(struct ath_hw *ah)
858{
859 struct ath_common *common = ath9k_hw_common(ah);
860 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
861
862 if (!ath9k_debugfs_root)
863 return -ENOENT;
864
865 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
866 ath9k_debugfs_root);
867 if (!priv->debug.debugfs_phy)
868 goto err;
869
870 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
871 priv->debug.debugfs_phy,
872 priv, &fops_tgt_stats);
873 if (!priv->debug.debugfs_tgt_stats)
874 goto err;
875
876
877 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
878 priv->debug.debugfs_phy,
879 priv, &fops_xmit);
880 if (!priv->debug.debugfs_xmit)
881 goto err;
882
883 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
884 priv->debug.debugfs_phy,
885 priv, &fops_recv);
886 if (!priv->debug.debugfs_recv)
887 goto err;
888
889 return 0;
890
891err:
892 ath9k_htc_exit_debug(ah);
893 return -ENOMEM;
894}
895
896void ath9k_htc_exit_debug(struct ath_hw *ah)
897{
898 struct ath_common *common = ath9k_hw_common(ah);
899 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
900
901 debugfs_remove(priv->debug.debugfs_recv);
902 debugfs_remove(priv->debug.debugfs_xmit);
903 debugfs_remove(priv->debug.debugfs_tgt_stats);
904 debugfs_remove(priv->debug.debugfs_phy);
905}
906
907int ath9k_htc_debug_create_root(void)
908{
909 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
910 if (!ath9k_debugfs_root)
911 return -ENOENT;
912
913 return 0;
914}
915
916void ath9k_htc_debug_remove_root(void)
917{
918 debugfs_remove(ath9k_debugfs_root);
919 ath9k_debugfs_root = NULL;
920}
921
922#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
923
924/*******/ 730/*******/
925/* ANI */ 731/* ANI */
926/*******/ 732/*******/
@@ -1040,7 +846,8 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1040{ 846{
1041 struct ieee80211_hdr *hdr; 847 struct ieee80211_hdr *hdr;
1042 struct ath9k_htc_priv *priv = hw->priv; 848 struct ath9k_htc_priv *priv = hw->priv;
1043 int padpos, padsize, ret; 849 struct ath_common *common = ath9k_hw_common(priv->ah);
850 int padpos, padsize, ret, slot;
1044 851
1045 hdr = (struct ieee80211_hdr *) skb->data; 852 hdr = (struct ieee80211_hdr *) skb->data;
1046 853
@@ -1048,30 +855,32 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1048 padpos = ath9k_cmn_padpos(hdr->frame_control); 855 padpos = ath9k_cmn_padpos(hdr->frame_control);
1049 padsize = padpos & 3; 856 padsize = padpos & 3;
1050 if (padsize && skb->len > padpos) { 857 if (padsize && skb->len > padpos) {
1051 if (skb_headroom(skb) < padsize) 858 if (skb_headroom(skb) < padsize) {
859 ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n");
1052 goto fail_tx; 860 goto fail_tx;
861 }
1053 skb_push(skb, padsize); 862 skb_push(skb, padsize);
1054 memmove(skb->data, skb->data + padsize, padpos); 863 memmove(skb->data, skb->data + padsize, padpos);
1055 } 864 }
1056 865
1057 ret = ath9k_htc_tx_start(priv, skb); 866 slot = ath9k_htc_tx_get_slot(priv);
1058 if (ret != 0) { 867 if (slot < 0) {
1059 if (ret == -ENOMEM) { 868 ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n");
1060 ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1061 "Stopping TX queues\n");
1062 ieee80211_stop_queues(hw);
1063 spin_lock_bh(&priv->tx_lock);
1064 priv->tx_queues_stop = true;
1065 spin_unlock_bh(&priv->tx_lock);
1066 } else {
1067 ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1068 "Tx failed\n");
1069 }
1070 goto fail_tx; 869 goto fail_tx;
1071 } 870 }
1072 871
872 ret = ath9k_htc_tx_start(priv, skb, slot, false);
873 if (ret != 0) {
874 ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n");
875 goto clear_slot;
876 }
877
878 ath9k_htc_check_stop_queues(priv);
879
1073 return; 880 return;
1074 881
882clear_slot:
883 ath9k_htc_tx_clear_slot(priv, slot);
1075fail_tx: 884fail_tx:
1076 dev_kfree_skb_any(skb); 885 dev_kfree_skb_any(skb);
1077} 886}
@@ -1130,12 +939,15 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1130 priv->op_flags &= ~OP_INVALID; 939 priv->op_flags &= ~OP_INVALID;
1131 htc_start(priv->htc); 940 htc_start(priv->htc);
1132 941
1133 spin_lock_bh(&priv->tx_lock); 942 spin_lock_bh(&priv->tx.tx_lock);
1134 priv->tx_queues_stop = false; 943 priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
1135 spin_unlock_bh(&priv->tx_lock); 944 spin_unlock_bh(&priv->tx.tx_lock);
1136 945
1137 ieee80211_wake_queues(hw); 946 ieee80211_wake_queues(hw);
1138 947
948 mod_timer(&priv->tx.cleanup_timer,
949 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
950
1139 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { 951 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
1140 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 952 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1141 AR_STOMP_LOW_WLAN_WGHT); 953 AR_STOMP_LOW_WLAN_WGHT);
@@ -1164,16 +976,16 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1164 } 976 }
1165 977
1166 ath9k_htc_ps_wakeup(priv); 978 ath9k_htc_ps_wakeup(priv);
1167 htc_stop(priv->htc); 979
1168 WMI_CMD(WMI_DISABLE_INTR_CMDID); 980 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1169 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 981 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1170 WMI_CMD(WMI_STOP_RECV_CMDID); 982 WMI_CMD(WMI_STOP_RECV_CMDID);
1171 983
1172 tasklet_kill(&priv->swba_tasklet);
1173 tasklet_kill(&priv->rx_tasklet); 984 tasklet_kill(&priv->rx_tasklet);
1174 tasklet_kill(&priv->tx_tasklet);
1175 985
1176 skb_queue_purge(&priv->tx_queue); 986 del_timer_sync(&priv->tx.cleanup_timer);
987 ath9k_htc_tx_drain(priv);
988 ath9k_wmi_event_drain(priv);
1177 989
1178 mutex_unlock(&priv->mutex); 990 mutex_unlock(&priv->mutex);
1179 991
@@ -1245,13 +1057,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1245 1057
1246 switch (vif->type) { 1058 switch (vif->type) {
1247 case NL80211_IFTYPE_STATION: 1059 case NL80211_IFTYPE_STATION:
1248 hvif.opmode = cpu_to_be32(HTC_M_STA); 1060 hvif.opmode = HTC_M_STA;
1249 break; 1061 break;
1250 case NL80211_IFTYPE_ADHOC: 1062 case NL80211_IFTYPE_ADHOC:
1251 hvif.opmode = cpu_to_be32(HTC_M_IBSS); 1063 hvif.opmode = HTC_M_IBSS;
1252 break; 1064 break;
1253 case NL80211_IFTYPE_AP: 1065 case NL80211_IFTYPE_AP:
1254 hvif.opmode = cpu_to_be32(HTC_M_HOSTAP); 1066 hvif.opmode = HTC_M_HOSTAP;
1255 break; 1067 break;
1256 default: 1068 default:
1257 ath_err(common, 1069 ath_err(common,
@@ -1281,14 +1093,20 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1281 1093
1282 priv->vif_slot |= (1 << avp->index); 1094 priv->vif_slot |= (1 << avp->index);
1283 priv->nvifs++; 1095 priv->nvifs++;
1284 priv->vif = vif;
1285 1096
1286 INC_VIF(priv, vif->type); 1097 INC_VIF(priv, vif->type);
1098
1099 if ((vif->type == NL80211_IFTYPE_AP) ||
1100 (vif->type == NL80211_IFTYPE_ADHOC))
1101 ath9k_htc_assign_bslot(priv, vif);
1102
1287 ath9k_htc_set_opmode(priv); 1103 ath9k_htc_set_opmode(priv);
1288 1104
1289 if ((priv->ah->opmode == NL80211_IFTYPE_AP) && 1105 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1290 !(priv->op_flags & OP_ANI_RUNNING)) 1106 !(priv->op_flags & OP_ANI_RUNNING)) {
1107 ath9k_hw_set_tsfadjust(priv->ah, 1);
1291 ath9k_htc_start_ani(priv); 1108 ath9k_htc_start_ani(priv);
1109 }
1292 1110
1293 ath_dbg(common, ATH_DBG_CONFIG, 1111 ath_dbg(common, ATH_DBG_CONFIG,
1294 "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); 1112 "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index);
@@ -1321,9 +1139,13 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1321 priv->vif_slot &= ~(1 << avp->index); 1139 priv->vif_slot &= ~(1 << avp->index);
1322 1140
1323 ath9k_htc_remove_station(priv, vif, NULL); 1141 ath9k_htc_remove_station(priv, vif, NULL);
1324 priv->vif = NULL;
1325 1142
1326 DEC_VIF(priv, vif->type); 1143 DEC_VIF(priv, vif->type);
1144
1145 if ((vif->type == NL80211_IFTYPE_AP) ||
1146 (vif->type == NL80211_IFTYPE_ADHOC))
1147 ath9k_htc_remove_bslot(priv, vif);
1148
1327 ath9k_htc_set_opmode(priv); 1149 ath9k_htc_set_opmode(priv);
1328 1150
1329 /* 1151 /*
@@ -1493,10 +1315,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1493 struct ieee80211_sta *sta) 1315 struct ieee80211_sta *sta)
1494{ 1316{
1495 struct ath9k_htc_priv *priv = hw->priv; 1317 struct ath9k_htc_priv *priv = hw->priv;
1318 struct ath9k_htc_sta *ista;
1496 int ret; 1319 int ret;
1497 1320
1498 mutex_lock(&priv->mutex); 1321 mutex_lock(&priv->mutex);
1499 ath9k_htc_ps_wakeup(priv); 1322 ath9k_htc_ps_wakeup(priv);
1323 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1324 htc_sta_drain(priv->htc, ista->index);
1500 ret = ath9k_htc_remove_station(priv, vif, sta); 1325 ret = ath9k_htc_remove_station(priv, vif, sta);
1501 ath9k_htc_ps_restore(priv); 1326 ath9k_htc_ps_restore(priv);
1502 mutex_unlock(&priv->mutex); 1327 mutex_unlock(&priv->mutex);
@@ -1644,6 +1469,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1644 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { 1469 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
1645 ath_dbg(common, ATH_DBG_CONFIG, 1470 ath_dbg(common, ATH_DBG_CONFIG,
1646 "Beacon enabled for BSS: %pM\n", bss_conf->bssid); 1471 "Beacon enabled for BSS: %pM\n", bss_conf->bssid);
1472 ath9k_htc_set_tsfadjust(priv, vif);
1647 priv->op_flags |= OP_ENABLE_BEACON; 1473 priv->op_flags |= OP_ENABLE_BEACON;
1648 ath9k_htc_beacon_config(priv, vif); 1474 ath9k_htc_beacon_config(priv, vif);
1649 } 1475 }
@@ -1758,9 +1584,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1758 break; 1584 break;
1759 case IEEE80211_AMPDU_TX_OPERATIONAL: 1585 case IEEE80211_AMPDU_TX_OPERATIONAL:
1760 ista = (struct ath9k_htc_sta *) sta->drv_priv; 1586 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1761 spin_lock_bh(&priv->tx_lock); 1587 spin_lock_bh(&priv->tx.tx_lock);
1762 ista->tid_state[tid] = AGGR_OPERATIONAL; 1588 ista->tid_state[tid] = AGGR_OPERATIONAL;
1763 spin_unlock_bh(&priv->tx_lock); 1589 spin_unlock_bh(&priv->tx.tx_lock);
1764 break; 1590 break;
1765 default: 1591 default:
1766 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); 1592 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 4a4f27ba96af..723a3a9c5cd9 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -53,6 +53,138 @@ int get_hw_qnum(u16 queue, int *hwq_map)
53 } 53 }
54} 54}
55 55
56void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv)
57{
58 spin_lock_bh(&priv->tx.tx_lock);
59 priv->tx.queued_cnt++;
60 if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) &&
61 !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
62 priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP;
63 ieee80211_stop_queues(priv->hw);
64 }
65 spin_unlock_bh(&priv->tx.tx_lock);
66}
67
68void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv)
69{
70 spin_lock_bh(&priv->tx.tx_lock);
71 if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) &&
72 (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
73 priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
74 ieee80211_wake_queues(priv->hw);
75 }
76 spin_unlock_bh(&priv->tx.tx_lock);
77}
78
79int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv)
80{
81 int slot;
82
83 spin_lock_bh(&priv->tx.tx_lock);
84 slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM);
85 if (slot >= MAX_TX_BUF_NUM) {
86 spin_unlock_bh(&priv->tx.tx_lock);
87 return -ENOBUFS;
88 }
89 __set_bit(slot, priv->tx.tx_slot);
90 spin_unlock_bh(&priv->tx.tx_lock);
91
92 return slot;
93}
94
95void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot)
96{
97 spin_lock_bh(&priv->tx.tx_lock);
98 __clear_bit(slot, priv->tx.tx_slot);
99 spin_unlock_bh(&priv->tx.tx_lock);
100}
101
102static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
103 u16 qnum)
104{
105 enum htc_endpoint_id epid;
106
107 switch (qnum) {
108 case 0:
109 TX_QSTAT_INC(WME_AC_VO);
110 epid = priv->data_vo_ep;
111 break;
112 case 1:
113 TX_QSTAT_INC(WME_AC_VI);
114 epid = priv->data_vi_ep;
115 break;
116 case 2:
117 TX_QSTAT_INC(WME_AC_BE);
118 epid = priv->data_be_ep;
119 break;
120 case 3:
121 default:
122 TX_QSTAT_INC(WME_AC_BK);
123 epid = priv->data_bk_ep;
124 break;
125 }
126
127 return epid;
128}
129
130static inline struct sk_buff_head*
131get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid)
132{
133 struct ath_common *common = ath9k_hw_common(priv->ah);
134 struct sk_buff_head *epid_queue = NULL;
135
136 if (epid == priv->mgmt_ep)
137 epid_queue = &priv->tx.mgmt_ep_queue;
138 else if (epid == priv->cab_ep)
139 epid_queue = &priv->tx.cab_ep_queue;
140 else if (epid == priv->data_be_ep)
141 epid_queue = &priv->tx.data_be_queue;
142 else if (epid == priv->data_bk_ep)
143 epid_queue = &priv->tx.data_bk_queue;
144 else if (epid == priv->data_vi_ep)
145 epid_queue = &priv->tx.data_vi_queue;
146 else if (epid == priv->data_vo_ep)
147 epid_queue = &priv->tx.data_vo_queue;
148 else
149 ath_err(common, "Invalid EPID: %d\n", epid);
150
151 return epid_queue;
152}
153
154/*
155 * Removes the driver header and returns the TX slot number
156 */
157static inline int strip_drv_header(struct ath9k_htc_priv *priv,
158 struct sk_buff *skb)
159{
160 struct ath_common *common = ath9k_hw_common(priv->ah);
161 struct ath9k_htc_tx_ctl *tx_ctl;
162 int slot;
163
164 tx_ctl = HTC_SKB_CB(skb);
165
166 if (tx_ctl->epid == priv->mgmt_ep) {
167 struct tx_mgmt_hdr *tx_mhdr =
168 (struct tx_mgmt_hdr *)skb->data;
169 slot = tx_mhdr->cookie;
170 skb_pull(skb, sizeof(struct tx_mgmt_hdr));
171 } else if ((tx_ctl->epid == priv->data_bk_ep) ||
172 (tx_ctl->epid == priv->data_be_ep) ||
173 (tx_ctl->epid == priv->data_vi_ep) ||
174 (tx_ctl->epid == priv->data_vo_ep) ||
175 (tx_ctl->epid == priv->cab_ep)) {
176 struct tx_frame_hdr *tx_fhdr =
177 (struct tx_frame_hdr *)skb->data;
178 slot = tx_fhdr->cookie;
179 skb_pull(skb, sizeof(struct tx_frame_hdr));
180 } else {
181 ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid);
182 slot = -EINVAL;
183 }
184
185 return slot;
186}
187
56int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, 188int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
57 struct ath9k_tx_queue_info *qinfo) 189 struct ath9k_tx_queue_info *qinfo)
58{ 190{
@@ -79,23 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
79 return error; 211 return error;
80} 212}
81 213
82int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) 214static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,
215 struct ath9k_htc_vif *avp,
216 struct sk_buff *skb,
217 u8 sta_idx, u8 vif_idx, u8 slot)
218{
219 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
220 struct ieee80211_mgmt *mgmt;
221 struct ieee80211_hdr *hdr;
222 struct tx_mgmt_hdr mgmt_hdr;
223 struct ath9k_htc_tx_ctl *tx_ctl;
224 u8 *tx_fhdr;
225
226 tx_ctl = HTC_SKB_CB(skb);
227 hdr = (struct ieee80211_hdr *) skb->data;
228
229 memset(tx_ctl, 0, sizeof(*tx_ctl));
230 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
231
232 /*
233 * Set the TSF adjust value for probe response
234 * frame also.
235 */
236 if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
237 mgmt = (struct ieee80211_mgmt *)skb->data;
238 mgmt->u.probe_resp.timestamp = avp->tsfadjust;
239 }
240
241 tx_ctl->type = ATH9K_HTC_MGMT;
242
243 mgmt_hdr.node_idx = sta_idx;
244 mgmt_hdr.vif_idx = vif_idx;
245 mgmt_hdr.tidno = 0;
246 mgmt_hdr.flags = 0;
247 mgmt_hdr.cookie = slot;
248
249 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
250 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
251 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
252 else
253 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
254
255 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
256 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
257 tx_ctl->epid = priv->mgmt_ep;
258}
259
260static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
261 struct ieee80211_vif *vif,
262 struct sk_buff *skb,
263 u8 sta_idx, u8 vif_idx, u8 slot,
264 bool is_cab)
265{
266 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
267 struct ieee80211_hdr *hdr;
268 struct ath9k_htc_tx_ctl *tx_ctl;
269 struct tx_frame_hdr tx_hdr;
270 u32 flags = 0;
271 u8 *qc, *tx_fhdr;
272 u16 qnum;
273
274 tx_ctl = HTC_SKB_CB(skb);
275 hdr = (struct ieee80211_hdr *) skb->data;
276
277 memset(tx_ctl, 0, sizeof(*tx_ctl));
278 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
279
280 tx_hdr.node_idx = sta_idx;
281 tx_hdr.vif_idx = vif_idx;
282 tx_hdr.cookie = slot;
283
284 /*
285 * This is a bit redundant but it helps to get
286 * the per-packet index quickly when draining the
287 * TX queue in the HIF layer. Otherwise we would
288 * have to parse the packet contents ...
289 */
290 tx_ctl->sta_idx = sta_idx;
291
292 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
293 tx_ctl->type = ATH9K_HTC_AMPDU;
294 tx_hdr.data_type = ATH9K_HTC_AMPDU;
295 } else {
296 tx_ctl->type = ATH9K_HTC_NORMAL;
297 tx_hdr.data_type = ATH9K_HTC_NORMAL;
298 }
299
300 if (ieee80211_is_data_qos(hdr->frame_control)) {
301 qc = ieee80211_get_qos_ctl(hdr);
302 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
303 }
304
305 /* Check for RTS protection */
306 if (priv->hw->wiphy->rts_threshold != (u32) -1)
307 if (skb->len > priv->hw->wiphy->rts_threshold)
308 flags |= ATH9K_HTC_TX_RTSCTS;
309
310 /* CTS-to-self */
311 if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
312 (vif && vif->bss_conf.use_cts_prot))
313 flags |= ATH9K_HTC_TX_CTSONLY;
314
315 tx_hdr.flags = cpu_to_be32(flags);
316 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
317 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
318 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
319 else
320 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
321
322 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
323 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
324
325 if (is_cab) {
326 CAB_STAT_INC;
327 tx_ctl->epid = priv->cab_ep;
328 return;
329 }
330
331 qnum = skb_get_queue_mapping(skb);
332 tx_ctl->epid = get_htc_epid(priv, qnum);
333}
334
335int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
336 struct sk_buff *skb,
337 u8 slot, bool is_cab)
83{ 338{
84 struct ieee80211_hdr *hdr; 339 struct ieee80211_hdr *hdr;
85 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 340 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
86 struct ieee80211_sta *sta = tx_info->control.sta; 341 struct ieee80211_sta *sta = tx_info->control.sta;
87 struct ieee80211_vif *vif = tx_info->control.vif; 342 struct ieee80211_vif *vif = tx_info->control.vif;
88 struct ath9k_htc_sta *ista; 343 struct ath9k_htc_sta *ista;
89 struct ath9k_htc_vif *avp; 344 struct ath9k_htc_vif *avp = NULL;
90 struct ath9k_htc_tx_ctl tx_ctl;
91 enum htc_endpoint_id epid;
92 u16 qnum;
93 __le16 fc;
94 u8 *tx_fhdr;
95 u8 sta_idx, vif_idx; 345 u8 sta_idx, vif_idx;
96 346
97 hdr = (struct ieee80211_hdr *) skb->data; 347 hdr = (struct ieee80211_hdr *) skb->data;
98 fc = hdr->frame_control;
99 348
100 /* 349 /*
101 * Find out on which interface this packet has to be 350 * Find out on which interface this packet has to be
@@ -124,218 +373,432 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
124 sta_idx = priv->vif_sta_pos[vif_idx]; 373 sta_idx = priv->vif_sta_pos[vif_idx];
125 } 374 }
126 375
127 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); 376 if (ieee80211_is_data(hdr->frame_control))
377 ath9k_htc_tx_data(priv, vif, skb,
378 sta_idx, vif_idx, slot, is_cab);
379 else
380 ath9k_htc_tx_mgmt(priv, avp, skb,
381 sta_idx, vif_idx, slot);
128 382
129 if (ieee80211_is_data(fc)) {
130 struct tx_frame_hdr tx_hdr;
131 u32 flags = 0;
132 u8 *qc;
133 383
134 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); 384 return htc_send(priv->htc, skb);
385}
135 386
136 tx_hdr.node_idx = sta_idx; 387static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
137 tx_hdr.vif_idx = vif_idx; 388 struct ath9k_htc_sta *ista, u8 tid)
389{
390 bool ret = false;
138 391
139 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 392 spin_lock_bh(&priv->tx.tx_lock);
140 tx_ctl.type = ATH9K_HTC_AMPDU; 393 if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
141 tx_hdr.data_type = ATH9K_HTC_AMPDU; 394 ret = true;
142 } else { 395 spin_unlock_bh(&priv->tx.tx_lock);
143 tx_ctl.type = ATH9K_HTC_NORMAL; 396
144 tx_hdr.data_type = ATH9K_HTC_NORMAL; 397 return ret;
145 } 398}
399
400static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
401 struct ieee80211_vif *vif,
402 struct sk_buff *skb)
403{
404 struct ieee80211_sta *sta;
405 struct ieee80211_hdr *hdr;
406 __le16 fc;
407
408 hdr = (struct ieee80211_hdr *) skb->data;
409 fc = hdr->frame_control;
410
411 rcu_read_lock();
412
413 sta = ieee80211_find_sta(vif, hdr->addr1);
414 if (!sta) {
415 rcu_read_unlock();
416 return;
417 }
146 418
419 if (sta && conf_is_ht(&priv->hw->conf) &&
420 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
147 if (ieee80211_is_data_qos(fc)) { 421 if (ieee80211_is_data_qos(fc)) {
422 u8 *qc, tid;
423 struct ath9k_htc_sta *ista;
424
148 qc = ieee80211_get_qos_ctl(hdr); 425 qc = ieee80211_get_qos_ctl(hdr);
149 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 426 tid = qc[0] & 0xf;
427 ista = (struct ath9k_htc_sta *)sta->drv_priv;
428 if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) {
429 ieee80211_start_tx_ba_session(sta, tid, 0);
430 spin_lock_bh(&priv->tx.tx_lock);
431 ista->tid_state[tid] = AGGR_PROGRESS;
432 spin_unlock_bh(&priv->tx.tx_lock);
433 }
150 } 434 }
435 }
151 436
152 /* Check for RTS protection */ 437 rcu_read_unlock();
153 if (priv->hw->wiphy->rts_threshold != (u32) -1) 438}
154 if (skb->len > priv->hw->wiphy->rts_threshold)
155 flags |= ATH9K_HTC_TX_RTSCTS;
156 439
157 /* CTS-to-self */ 440static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
158 if (!(flags & ATH9K_HTC_TX_RTSCTS) && 441 struct sk_buff *skb,
159 (vif && vif->bss_conf.use_cts_prot)) 442 struct __wmi_event_txstatus *txs)
160 flags |= ATH9K_HTC_TX_CTSONLY; 443{
444 struct ieee80211_vif *vif;
445 struct ath9k_htc_tx_ctl *tx_ctl;
446 struct ieee80211_tx_info *tx_info;
447 struct ieee80211_tx_rate *rate;
448 struct ieee80211_conf *cur_conf = &priv->hw->conf;
449 struct ieee80211_supported_band *sband;
450 bool txok;
451 int slot;
161 452
162 tx_hdr.flags = cpu_to_be32(flags); 453 slot = strip_drv_header(priv, skb);
163 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); 454 if (slot < 0) {
164 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) 455 dev_kfree_skb_any(skb);
165 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; 456 return;
166 else 457 }
167 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
168 458
169 tx_fhdr = skb_push(skb, sizeof(tx_hdr)); 459 tx_ctl = HTC_SKB_CB(skb);
170 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); 460 txok = tx_ctl->txok;
461 tx_info = IEEE80211_SKB_CB(skb);
462 vif = tx_info->control.vif;
463 rate = &tx_info->status.rates[0];
464 sband = priv->hw->wiphy->bands[cur_conf->channel->band];
171 465
172 qnum = skb_get_queue_mapping(skb); 466 memset(&tx_info->status, 0, sizeof(tx_info->status));
173 467
174 switch (qnum) { 468 /*
175 case 0: 469 * URB submission failed for this frame, it never reached
176 TX_QSTAT_INC(WME_AC_VO); 470 * the target.
177 epid = priv->data_vo_ep; 471 */
178 break; 472 if (!txok || !vif || !txs)
179 case 1: 473 goto send_mac80211;
180 TX_QSTAT_INC(WME_AC_VI);
181 epid = priv->data_vi_ep;
182 break;
183 case 2:
184 TX_QSTAT_INC(WME_AC_BE);
185 epid = priv->data_be_ep;
186 break;
187 case 3:
188 default:
189 TX_QSTAT_INC(WME_AC_BK);
190 epid = priv->data_bk_ep;
191 break;
192 }
193 } else {
194 struct tx_mgmt_hdr mgmt_hdr;
195 474
196 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); 475 if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK)
476 tx_info->flags |= IEEE80211_TX_STAT_ACK;
477
478 if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT)
479 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
197 480
198 tx_ctl.type = ATH9K_HTC_NORMAL; 481 if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS)
482 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
199 483
200 mgmt_hdr.node_idx = sta_idx; 484 rate->count = 1;
201 mgmt_hdr.vif_idx = vif_idx; 485 rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE);
202 mgmt_hdr.tidno = 0;
203 mgmt_hdr.flags = 0;
204 486
205 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); 487 if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) {
206 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) 488 rate->flags |= IEEE80211_TX_RC_MCS;
207 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
208 else
209 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
210 489
211 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); 490 if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40)
212 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); 491 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
213 epid = priv->mgmt_ep; 492 if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI)
493 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
494 } else {
495 if (cur_conf->channel->band == IEEE80211_BAND_5GHZ)
496 rate->idx += 4; /* No CCK rates */
214 } 497 }
215 498
216 return htc_send(priv->htc, skb, epid, &tx_ctl); 499 ath9k_htc_check_tx_aggr(priv, vif, skb);
500
501send_mac80211:
502 spin_lock_bh(&priv->tx.tx_lock);
503 if (WARN_ON(--priv->tx.queued_cnt < 0))
504 priv->tx.queued_cnt = 0;
505 spin_unlock_bh(&priv->tx.tx_lock);
506
507 ath9k_htc_tx_clear_slot(priv, slot);
508
509 /* Send status to mac80211 */
510 ieee80211_tx_status(priv->hw, skb);
217} 511}
218 512
219static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, 513static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv,
220 struct ath9k_htc_sta *ista, u8 tid) 514 struct sk_buff_head *queue)
221{ 515{
222 bool ret = false; 516 struct sk_buff *skb;
223 517
224 spin_lock_bh(&priv->tx_lock); 518 while ((skb = skb_dequeue(queue)) != NULL) {
225 if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) 519 ath9k_htc_tx_process(priv, skb, NULL);
226 ret = true; 520 }
227 spin_unlock_bh(&priv->tx_lock); 521}
228 522
229 return ret; 523void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv)
524{
525 struct ath9k_htc_tx_event *event, *tmp;
526
527 spin_lock_bh(&priv->tx.tx_lock);
528 priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN;
529 spin_unlock_bh(&priv->tx.tx_lock);
530
531 /*
532 * Ensure that all pending TX frames are flushed,
533 * and that the TX completion/failed tasklets is killed.
534 */
535 htc_stop(priv->htc);
536 tasklet_kill(&priv->wmi->wmi_event_tasklet);
537 tasklet_kill(&priv->tx_failed_tasklet);
538
539 ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue);
540 ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue);
541 ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue);
542 ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue);
543 ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue);
544 ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue);
545 ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
546
547 /*
548 * The TX cleanup timer has already been killed.
549 */
550 spin_lock_bh(&priv->wmi->event_lock);
551 list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
552 list_del(&event->list);
553 kfree(event);
554 }
555 spin_unlock_bh(&priv->wmi->event_lock);
556
557 spin_lock_bh(&priv->tx.tx_lock);
558 priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN;
559 spin_unlock_bh(&priv->tx.tx_lock);
230} 560}
231 561
232void ath9k_tx_tasklet(unsigned long data) 562void ath9k_tx_failed_tasklet(unsigned long data)
233{ 563{
234 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; 564 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
235 struct ieee80211_vif *vif;
236 struct ieee80211_sta *sta;
237 struct ieee80211_hdr *hdr;
238 struct ieee80211_tx_info *tx_info;
239 struct sk_buff *skb = NULL;
240 __le16 fc;
241 565
242 while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) { 566 spin_lock_bh(&priv->tx.tx_lock);
567 if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
568 spin_unlock_bh(&priv->tx.tx_lock);
569 return;
570 }
571 spin_unlock_bh(&priv->tx.tx_lock);
243 572
244 hdr = (struct ieee80211_hdr *) skb->data; 573 ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
245 fc = hdr->frame_control; 574}
246 tx_info = IEEE80211_SKB_CB(skb);
247 vif = tx_info->control.vif;
248 575
249 memset(&tx_info->status, 0, sizeof(tx_info->status)); 576static inline bool check_cookie(struct ath9k_htc_priv *priv,
577 struct sk_buff *skb,
578 u8 cookie, u8 epid)
579{
580 u8 fcookie = 0;
581
582 if (epid == priv->mgmt_ep) {
583 struct tx_mgmt_hdr *hdr;
584 hdr = (struct tx_mgmt_hdr *) skb->data;
585 fcookie = hdr->cookie;
586 } else if ((epid == priv->data_bk_ep) ||
587 (epid == priv->data_be_ep) ||
588 (epid == priv->data_vi_ep) ||
589 (epid == priv->data_vo_ep) ||
590 (epid == priv->cab_ep)) {
591 struct tx_frame_hdr *hdr;
592 hdr = (struct tx_frame_hdr *) skb->data;
593 fcookie = hdr->cookie;
594 }
250 595
251 if (!vif) 596 if (fcookie == cookie)
252 goto send_mac80211; 597 return true;
253 598
254 rcu_read_lock(); 599 return false;
600}
255 601
256 sta = ieee80211_find_sta(vif, hdr->addr1); 602static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv,
257 if (!sta) { 603 struct __wmi_event_txstatus *txs)
258 rcu_read_unlock(); 604{
259 ieee80211_tx_status(priv->hw, skb); 605 struct ath_common *common = ath9k_hw_common(priv->ah);
260 continue; 606 struct sk_buff_head *epid_queue;
607 struct sk_buff *skb, *tmp;
608 unsigned long flags;
609 u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID);
610
611 epid_queue = get_htc_epid_queue(priv, epid);
612 if (!epid_queue)
613 return NULL;
614
615 spin_lock_irqsave(&epid_queue->lock, flags);
616 skb_queue_walk_safe(epid_queue, skb, tmp) {
617 if (check_cookie(priv, skb, txs->cookie, epid)) {
618 __skb_unlink(skb, epid_queue);
619 spin_unlock_irqrestore(&epid_queue->lock, flags);
620 return skb;
261 } 621 }
622 }
623 spin_unlock_irqrestore(&epid_queue->lock, flags);
262 624
263 /* Check if we need to start aggregation */ 625 ath_dbg(common, ATH_DBG_XMIT,
626 "No matching packet for cookie: %d, epid: %d\n",
627 txs->cookie, epid);
264 628
265 if (sta && conf_is_ht(&priv->hw->conf) && 629 return NULL;
266 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { 630}
267 if (ieee80211_is_data_qos(fc)) {
268 u8 *qc, tid;
269 struct ath9k_htc_sta *ista;
270 631
271 qc = ieee80211_get_qos_ctl(hdr); 632void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event)
272 tid = qc[0] & 0xf; 633{
273 ista = (struct ath9k_htc_sta *)sta->drv_priv; 634 struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event;
635 struct __wmi_event_txstatus *__txs;
636 struct sk_buff *skb;
637 struct ath9k_htc_tx_event *tx_pend;
638 int i;
274 639
275 if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { 640 for (i = 0; i < txs->cnt; i++) {
276 ieee80211_start_tx_ba_session(sta, tid, 0); 641 WARN_ON(txs->cnt > HTC_MAX_TX_STATUS);
277 spin_lock_bh(&priv->tx_lock);
278 ista->tid_state[tid] = AGGR_PROGRESS;
279 spin_unlock_bh(&priv->tx_lock);
280 }
281 }
282 }
283 642
284 rcu_read_unlock(); 643 __txs = &txs->txstatus[i];
644
645 skb = ath9k_htc_tx_get_packet(priv, __txs);
646 if (!skb) {
647 /*
648 * Store this event, so that the TX cleanup
649 * routine can check later for the needed packet.
650 */
651 tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event),
652 GFP_ATOMIC);
653 if (!tx_pend)
654 continue;
655
656 memcpy(&tx_pend->txs, __txs,
657 sizeof(struct __wmi_event_txstatus));
658
659 spin_lock(&priv->wmi->event_lock);
660 list_add_tail(&tx_pend->list,
661 &priv->wmi->pending_tx_events);
662 spin_unlock(&priv->wmi->event_lock);
285 663
286 send_mac80211: 664 continue;
287 /* Send status to mac80211 */ 665 }
288 ieee80211_tx_status(priv->hw, skb); 666
667 ath9k_htc_tx_process(priv, skb, __txs);
289 } 668 }
290 669
291 /* Wake TX queues if needed */ 670 /* Wake TX queues if needed */
292 spin_lock_bh(&priv->tx_lock); 671 ath9k_htc_check_wake_queues(priv);
293 if (priv->tx_queues_stop) {
294 priv->tx_queues_stop = false;
295 spin_unlock_bh(&priv->tx_lock);
296 ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
297 "Waking up TX queues\n");
298 ieee80211_wake_queues(priv->hw);
299 return;
300 }
301 spin_unlock_bh(&priv->tx_lock);
302} 672}
303 673
304void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, 674void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
305 enum htc_endpoint_id ep_id, bool txok) 675 enum htc_endpoint_id ep_id, bool txok)
306{ 676{
307 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; 677 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
308 struct ath_common *common = ath9k_hw_common(priv->ah); 678 struct ath9k_htc_tx_ctl *tx_ctl;
309 struct ieee80211_tx_info *tx_info; 679 struct sk_buff_head *epid_queue;
310 680
311 if (!skb) 681 tx_ctl = HTC_SKB_CB(skb);
682 tx_ctl->txok = txok;
683 tx_ctl->timestamp = jiffies;
684
685 if (!txok) {
686 skb_queue_tail(&priv->tx.tx_failed, skb);
687 tasklet_schedule(&priv->tx_failed_tasklet);
312 return; 688 return;
689 }
313 690
314 if (ep_id == priv->mgmt_ep) { 691 epid_queue = get_htc_epid_queue(priv, ep_id);
315 skb_pull(skb, sizeof(struct tx_mgmt_hdr)); 692 if (!epid_queue) {
316 } else if ((ep_id == priv->data_bk_ep) ||
317 (ep_id == priv->data_be_ep) ||
318 (ep_id == priv->data_vi_ep) ||
319 (ep_id == priv->data_vo_ep)) {
320 skb_pull(skb, sizeof(struct tx_frame_hdr));
321 } else {
322 ath_err(common, "Unsupported TX EPID: %d\n", ep_id);
323 dev_kfree_skb_any(skb); 693 dev_kfree_skb_any(skb);
324 return; 694 return;
325 } 695 }
326 696
327 tx_info = IEEE80211_SKB_CB(skb); 697 skb_queue_tail(epid_queue, skb);
698}
328 699
329 if (txok) 700static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb)
330 tx_info->flags |= IEEE80211_TX_STAT_ACK; 701{
702 struct ath_common *common = ath9k_hw_common(priv->ah);
703 struct ath9k_htc_tx_ctl *tx_ctl;
331 704
332 skb_queue_tail(&priv->tx_queue, skb); 705 tx_ctl = HTC_SKB_CB(skb);
333 tasklet_schedule(&priv->tx_tasklet); 706
707 if (time_after(jiffies,
708 tx_ctl->timestamp +
709 msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) {
710 ath_dbg(common, ATH_DBG_XMIT,
711 "Dropping a packet due to TX timeout\n");
712 return true;
713 }
714
715 return false;
716}
717
718static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv,
719 struct sk_buff_head *epid_queue)
720{
721 bool process = false;
722 unsigned long flags;
723 struct sk_buff *skb, *tmp;
724 struct sk_buff_head queue;
725
726 skb_queue_head_init(&queue);
727
728 spin_lock_irqsave(&epid_queue->lock, flags);
729 skb_queue_walk_safe(epid_queue, skb, tmp) {
730 if (check_packet(priv, skb)) {
731 __skb_unlink(skb, epid_queue);
732 __skb_queue_tail(&queue, skb);
733 process = true;
734 }
735 }
736 spin_unlock_irqrestore(&epid_queue->lock, flags);
737
738 if (process) {
739 skb_queue_walk_safe(&queue, skb, tmp) {
740 __skb_unlink(skb, &queue);
741 ath9k_htc_tx_process(priv, skb, NULL);
742 }
743 }
744}
745
746void ath9k_htc_tx_cleanup_timer(unsigned long data)
747{
748 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data;
749 struct ath_common *common = ath9k_hw_common(priv->ah);
750 struct ath9k_htc_tx_event *event, *tmp;
751 struct sk_buff *skb;
752
753 spin_lock(&priv->wmi->event_lock);
754 list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
755
756 skb = ath9k_htc_tx_get_packet(priv, &event->txs);
757 if (skb) {
758 ath_dbg(common, ATH_DBG_XMIT,
759 "Found packet for cookie: %d, epid: %d\n",
760 event->txs.cookie,
761 MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID));
762
763 ath9k_htc_tx_process(priv, skb, &event->txs);
764 list_del(&event->list);
765 kfree(event);
766 continue;
767 }
768
769 if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) {
770 list_del(&event->list);
771 kfree(event);
772 }
773 }
774 spin_unlock(&priv->wmi->event_lock);
775
776 /*
777 * Check if status-pending packets have to be cleaned up.
778 */
779 ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue);
780 ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue);
781 ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue);
782 ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue);
783 ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue);
784 ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue);
785
786 /* Wake TX queues if needed */
787 ath9k_htc_check_wake_queues(priv);
788
789 mod_timer(&priv->tx.cleanup_timer,
790 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
334} 791}
335 792
336int ath9k_tx_init(struct ath9k_htc_priv *priv) 793int ath9k_tx_init(struct ath9k_htc_priv *priv)
337{ 794{
338 skb_queue_head_init(&priv->tx_queue); 795 skb_queue_head_init(&priv->tx.mgmt_ep_queue);
796 skb_queue_head_init(&priv->tx.cab_ep_queue);
797 skb_queue_head_init(&priv->tx.data_be_queue);
798 skb_queue_head_init(&priv->tx.data_bk_queue);
799 skb_queue_head_init(&priv->tx.data_vi_queue);
800 skb_queue_head_init(&priv->tx.data_vo_queue);
801 skb_queue_head_init(&priv->tx.tx_failed);
339 return 0; 802 return 0;
340} 803}
341 804
@@ -507,8 +970,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
507 int last_rssi = ATH_RSSI_DUMMY_MARKER; 970 int last_rssi = ATH_RSSI_DUMMY_MARKER;
508 __le16 fc; 971 __le16 fc;
509 972
510 if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { 973 if (skb->len < HTC_RX_FRAME_HEADER_SIZE) {
511 ath_err(common, "Corrupted RX frame, dropping\n"); 974 ath_err(common, "Corrupted RX frame, dropping (len: %d)\n",
975 skb->len);
512 goto rx_next; 976 goto rx_next;
513 } 977 }
514 978
@@ -522,6 +986,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
522 goto rx_next; 986 goto rx_next;
523 } 987 }
524 988
989 ath9k_htc_err_stat_rx(priv, rxstatus);
990
525 /* Get the RX status information */ 991 /* Get the RX status information */
526 memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); 992 memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
527 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); 993 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index c41ab8c30161..5c76352b1319 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -17,8 +17,8 @@
17#include "htc.h" 17#include "htc.h"
18 18
19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, 19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
20 u16 len, u8 flags, u8 epid, 20 u16 len, u8 flags, u8 epid)
21 struct ath9k_htc_tx_ctl *tx_ctl) 21
22{ 22{
23 struct htc_frame_hdr *hdr; 23 struct htc_frame_hdr *hdr;
24 struct htc_endpoint *endpoint = &target->endpoint[epid]; 24 struct htc_endpoint *endpoint = &target->endpoint[epid];
@@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
30 hdr->flags = flags; 30 hdr->flags = flags;
31 hdr->payload_len = cpu_to_be16(len); 31 hdr->payload_len = cpu_to_be16(len);
32 32
33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, 33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb);
34 tx_ctl); 34
35 return status; 35 return status;
36} 36}
37 37
@@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target)
162 162
163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; 163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
164 164
165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); 165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
166 if (ret) 166 if (ret)
167 goto err; 167 goto err;
168 168
@@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target)
197 197
198 target->htc_flags |= HTC_OP_START_WAIT; 198 target->htc_flags |= HTC_OP_START_WAIT;
199 199
200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); 200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
201 if (ret) 201 if (ret)
202 goto err; 202 goto err;
203 203
@@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target,
268 conn_msg->dl_pipeid = endpoint->dl_pipeid; 268 conn_msg->dl_pipeid = endpoint->dl_pipeid;
269 conn_msg->ul_pipeid = endpoint->ul_pipeid; 269 conn_msg->ul_pipeid = endpoint->ul_pipeid;
270 270
271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); 271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
272 if (ret) 272 if (ret)
273 goto err; 273 goto err;
274 274
@@ -286,35 +286,33 @@ err:
286 return ret; 286 return ret;
287} 287}
288 288
289int htc_send(struct htc_target *target, struct sk_buff *skb, 289int htc_send(struct htc_target *target, struct sk_buff *skb)
290 enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
291{ 290{
292 return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); 291 struct ath9k_htc_tx_ctl *tx_ctl;
292
293 tx_ctl = HTC_SKB_CB(skb);
294 return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid);
293} 295}
294 296
295void htc_stop(struct htc_target *target) 297int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
298 enum htc_endpoint_id epid)
296{ 299{
297 enum htc_endpoint_id epid; 300 return htc_issue_send(target, skb, skb->len, 0, epid);
298 struct htc_endpoint *endpoint; 301}
299 302
300 for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { 303void htc_stop(struct htc_target *target)
301 endpoint = &target->endpoint[epid]; 304{
302 if (endpoint->service_id != 0) 305 target->hif->stop(target->hif_dev);
303 target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
304 }
305} 306}
306 307
307void htc_start(struct htc_target *target) 308void htc_start(struct htc_target *target)
308{ 309{
309 enum htc_endpoint_id epid; 310 target->hif->start(target->hif_dev);
310 struct htc_endpoint *endpoint; 311}
311 312
312 for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { 313void htc_sta_drain(struct htc_target *target, u8 idx)
313 endpoint = &target->endpoint[epid]; 314{
314 if (endpoint->service_id != 0) 315 target->hif->sta_drain(target->hif_dev, idx);
315 target->hif->start(target->hif_dev,
316 endpoint->ul_pipeid);
317 }
318} 316}
319 317
320void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, 318void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index ecd018798c47..cb9174ade53e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -33,10 +33,10 @@ struct ath9k_htc_hif {
33 u8 control_dl_pipe; 33 u8 control_dl_pipe;
34 u8 control_ul_pipe; 34 u8 control_ul_pipe;
35 35
36 void (*start) (void *hif_handle, u8 pipe); 36 void (*start) (void *hif_handle);
37 void (*stop) (void *hif_handle, u8 pipe); 37 void (*stop) (void *hif_handle);
38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, 38 void (*sta_drain) (void *hif_handle, u8 idx);
39 struct ath9k_htc_tx_ctl *tx_ctl); 39 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf);
40}; 40};
41 41
42enum htc_endpoint_id { 42enum htc_endpoint_id {
@@ -205,10 +205,12 @@ int htc_init(struct htc_target *target);
205int htc_connect_service(struct htc_target *target, 205int htc_connect_service(struct htc_target *target,
206 struct htc_service_connreq *service_connreq, 206 struct htc_service_connreq *service_connreq,
207 enum htc_endpoint_id *conn_rsp_eid); 207 enum htc_endpoint_id *conn_rsp_eid);
208int htc_send(struct htc_target *target, struct sk_buff *skb, 208int htc_send(struct htc_target *target, struct sk_buff *skb);
209 enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); 209int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
210 enum htc_endpoint_id epid);
210void htc_stop(struct htc_target *target); 211void htc_stop(struct htc_target *target);
211void htc_start(struct htc_target *target); 212void htc_start(struct htc_target *target);
213void htc_sta_drain(struct htc_target *target, u8 idx);
212 214
213void ath9k_htc_rx_msg(struct htc_target *htc_handle, 215void ath9k_htc_rx_msg(struct htc_target *htc_handle,
214 struct sk_buff *skb, u32 len, u8 pipe_id); 216 struct sk_buff *skb, u32 len, u8 pipe_id);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1b5bd13b0a6c..3a8c41c782e9 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -676,42 +676,55 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
676} 676}
677EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); 677EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
678 678
679#define DPLL2_KD_VAL 0x3D 679#define DPLL3_PHASE_SHIFT_VAL 0x1
680#define DPLL2_KI_VAL 0x06
681#define DPLL3_PHASE_SHIFT_VAL 0x1
682
683static void ath9k_hw_init_pll(struct ath_hw *ah, 680static void ath9k_hw_init_pll(struct ath_hw *ah,
684 struct ath9k_channel *chan) 681 struct ath9k_channel *chan)
685{ 682{
686 u32 pll; 683 u32 pll;
687 684
688 if (AR_SREV_9485(ah)) { 685 if (AR_SREV_9485(ah)) {
689 REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
690 REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01);
691
692 REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3,
693 AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
694 686
695 REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); 687 /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
696 udelay(1000); 688 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
689 AR_CH0_BB_DPLL2_PLL_PWD, 0x1);
690 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
691 AR_CH0_DPLL2_KD, 0x40);
692 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
693 AR_CH0_DPLL2_KI, 0x4);
697 694
698 REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); 695 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
696 AR_CH0_BB_DPLL1_REFDIV, 0x5);
697 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
698 AR_CH0_BB_DPLL1_NINI, 0x58);
699 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
700 AR_CH0_BB_DPLL1_NFRAC, 0x0);
699 701
700 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 702 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
701 AR_CH0_DPLL2_KD, DPLL2_KD_VAL); 703 AR_CH0_BB_DPLL2_OUTDIV, 0x1);
704 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
705 AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1);
702 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 706 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
703 AR_CH0_DPLL2_KI, DPLL2_KI_VAL); 707 AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1);
704 708
709 /* program BB PLL phase_shift to 0x6 */
705 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, 710 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
706 AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); 711 AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6);
707 REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); 712
713 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
714 AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
708 udelay(1000); 715 udelay(1000);
716
717 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
718 AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
709 } 719 }
710 720
711 pll = ath9k_hw_compute_pll_control(ah, chan); 721 pll = ath9k_hw_compute_pll_control(ah, chan);
712 722
713 REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 723 REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
714 724
725 if (AR_SREV_9485(ah))
726 udelay(1000);
727
715 /* Switch the core clock for ar9271 to 117Mhz */ 728 /* Switch the core clock for ar9271 to 117Mhz */
716 if (AR_SREV_9271(ah)) { 729 if (AR_SREV_9271(ah)) {
717 udelay(500); 730 udelay(500);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index a778b66f4438..073bc9e1c792 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -846,6 +846,14 @@ struct ath_hw {
846 u32 ent_mode; 846 u32 ent_mode;
847}; 847};
848 848
849struct ath_bus_ops {
850 enum ath_bus_type ath_bus_type;
851 void (*read_cachesize)(struct ath_common *common, int *csz);
852 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
853 void (*bt_coex_prep)(struct ath_common *common);
854 void (*extn_synch_en)(struct ath_common *common);
855};
856
849static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) 857static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
850{ 858{
851 return &ah->common; 859 return &ah->common;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index ba1c9a684eff..a55a8929810b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1375,6 +1375,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
1375 if ((iter_data.naps + iter_data.nadhocs) > 0) { 1375 if ((iter_data.naps + iter_data.nadhocs) > 0) {
1376 sc->sc_flags |= SC_OP_ANI_RUN; 1376 sc->sc_flags |= SC_OP_ANI_RUN;
1377 ath_start_ani(common); 1377 ath_start_ani(common);
1378 } else {
1379 sc->sc_flags &= ~SC_OP_ANI_RUN;
1380 del_timer_sync(&common->ani.timer);
1378 } 1381 }
1379} 1382}
1380 1383
@@ -2201,6 +2204,21 @@ out:
2201 ath9k_ps_restore(sc); 2204 ath9k_ps_restore(sc);
2202} 2205}
2203 2206
2207static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
2208{
2209 struct ath_softc *sc = hw->priv;
2210 int i;
2211
2212 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2213 if (!ATH_TXQ_SETUP(sc, i))
2214 continue;
2215
2216 if (ath9k_has_pending_frames(sc, &sc->tx.txq[i]))
2217 return true;
2218 }
2219 return false;
2220}
2221
2204struct ieee80211_ops ath9k_ops = { 2222struct ieee80211_ops ath9k_ops = {
2205 .tx = ath9k_tx, 2223 .tx = ath9k_tx,
2206 .start = ath9k_start, 2224 .start = ath9k_start,
@@ -2223,4 +2241,5 @@ struct ieee80211_ops ath9k_ops = {
2223 .rfkill_poll = ath9k_rfkill_poll_state, 2241 .rfkill_poll = ath9k_rfkill_poll_state,
2224 .set_coverage_class = ath9k_set_coverage_class, 2242 .set_coverage_class = ath9k_set_coverage_class,
2225 .flush = ath9k_flush, 2243 .flush = ath9k_flush,
2244 .tx_frames_pending = ath9k_tx_frames_pending,
2226}; 2245};
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index f50e2c29f71e..8e5fe9d7f174 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -19,7 +19,6 @@
19 19
20#define CHANSEL_DIV 15 20#define CHANSEL_DIV 15
21#define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) 21#define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV)
22#define CHANSEL_2G_9485(_freq) ((((_freq) * 0x10000) - 215) / CHANSEL_DIV)
23#define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) 22#define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV)
24 23
25#define AR_PHY_BASE 0x9800 24#define AR_PHY_BASE 0x9800
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index a3241cd089b1..2a40532126f3 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1092,8 +1092,7 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
1092 if (!(rate->flags & IEEE80211_TX_RC_MCS)) 1092 if (!(rate->flags & IEEE80211_TX_RC_MCS))
1093 return rate->idx; 1093 return rate->idx;
1094 1094
1095 while (rate->idx > mcs_rix_off[i] && 1095 while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
1096 i < ARRAY_SIZE(mcs_rix_off)) {
1097 rix++; i++; 1096 rix++; i++;
1098 } 1097 }
1099 1098
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 3842b7518661..b81bfc4d66ef 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -75,7 +75,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
75 *sc->rx.rxlink = bf->bf_daddr; 75 *sc->rx.rxlink = bf->bf_daddr;
76 76
77 sc->rx.rxlink = &ds->ds_link; 77 sc->rx.rxlink = &ds->ds_link;
78 ath9k_hw_rxena(ah);
79} 78}
80 79
81static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) 80static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
@@ -426,9 +425,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
426 else 425 else
427 rfilt |= ATH9K_RX_FILTER_BEACON; 426 rfilt |= ATH9K_RX_FILTER_BEACON;
428 427
429 if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || 428 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
430 AR_SREV_9285_12_OR_LATER(sc->sc_ah)) &&
431 (sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
432 (sc->rx.rxfilter & FIF_PSPOLL)) 429 (sc->rx.rxfilter & FIF_PSPOLL))
433 rfilt |= ATH9K_RX_FILTER_PSPOLL; 430 rfilt |= ATH9K_RX_FILTER_PSPOLL;
434 431
@@ -1767,6 +1764,7 @@ requeue:
1767 } else { 1764 } else {
1768 list_move_tail(&bf->list, &sc->rx.rxbuf); 1765 list_move_tail(&bf->list, &sc->rx.rxbuf);
1769 ath_rx_buf_link(sc, bf); 1766 ath_rx_buf_link(sc, bf);
1767 ath9k_hw_rxena(ah);
1770 } 1768 }
1771 } while (1); 1769 } while (1);
1772 1770
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 693d543937b5..6acbf0e2240b 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -858,9 +858,7 @@
858#define AR_SREV_9300(_ah) \ 858#define AR_SREV_9300(_ah) \
859 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) 859 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
860#define AR_SREV_9300_20_OR_LATER(_ah) \ 860#define AR_SREV_9300_20_OR_LATER(_ah) \
861 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ 861 ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
862 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
863 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
864 862
865#define AR_SREV_9485(_ah) \ 863#define AR_SREV_9485(_ah) \
866 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) 864 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
@@ -1088,14 +1086,35 @@ enum {
1088#define AR_ENT_OTP 0x40d8 1086#define AR_ENT_OTP 0x40d8
1089#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 1087#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
1090#define AR_ENT_OTP_MPSD 0x00800000 1088#define AR_ENT_OTP_MPSD 0x00800000
1091#define AR_CH0_BB_DPLL2 0x16184 1089
1090#define AR_CH0_BB_DPLL1 0x16180
1091#define AR_CH0_BB_DPLL1_REFDIV 0xF8000000
1092#define AR_CH0_BB_DPLL1_REFDIV_S 27
1093#define AR_CH0_BB_DPLL1_NINI 0x07FC0000
1094#define AR_CH0_BB_DPLL1_NINI_S 18
1095#define AR_CH0_BB_DPLL1_NFRAC 0x0003FFFF
1096#define AR_CH0_BB_DPLL1_NFRAC_S 0
1097
1098#define AR_CH0_BB_DPLL2 0x16184
1099#define AR_CH0_BB_DPLL2_LOCAL_PLL 0x40000000
1100#define AR_CH0_BB_DPLL2_LOCAL_PLL_S 30
1101#define AR_CH0_DPLL2_KI 0x3C000000
1102#define AR_CH0_DPLL2_KI_S 26
1103#define AR_CH0_DPLL2_KD 0x03F80000
1104#define AR_CH0_DPLL2_KD_S 19
1105#define AR_CH0_BB_DPLL2_EN_NEGTRIG 0x00040000
1106#define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18
1107#define AR_CH0_BB_DPLL2_PLL_PWD 0x00010000
1108#define AR_CH0_BB_DPLL2_PLL_PWD_S 16
1109#define AR_CH0_BB_DPLL2_OUTDIV 0x0000E000
1110#define AR_CH0_BB_DPLL2_OUTDIV_S 13
1111
1092#define AR_CH0_BB_DPLL3 0x16188 1112#define AR_CH0_BB_DPLL3 0x16188
1113#define AR_CH0_BB_DPLL3_PHASE_SHIFT 0x3F800000
1114#define AR_CH0_BB_DPLL3_PHASE_SHIFT_S 23
1115
1093#define AR_CH0_DDR_DPLL2 0x16244 1116#define AR_CH0_DDR_DPLL2 0x16244
1094#define AR_CH0_DDR_DPLL3 0x16248 1117#define AR_CH0_DDR_DPLL3 0x16248
1095#define AR_CH0_DPLL2_KD 0x03F80000
1096#define AR_CH0_DPLL2_KD_S 19
1097#define AR_CH0_DPLL2_KI 0x3C000000
1098#define AR_CH0_DPLL2_KI_S 26
1099#define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 1118#define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000
1100#define AR_CH0_DPLL3_PHASE_SHIFT_S 23 1119#define AR_CH0_DPLL3_PHASE_SHIFT_S 23
1101#define AR_PHY_CCA_NOM_VAL_2GHZ -118 1120#define AR_PHY_CCA_NOM_VAL_2GHZ -118
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index d3d24904f62f..8f095ad0a3db 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -23,20 +23,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
23 return "WMI_ECHO_CMDID"; 23 return "WMI_ECHO_CMDID";
24 case WMI_ACCESS_MEMORY_CMDID: 24 case WMI_ACCESS_MEMORY_CMDID:
25 return "WMI_ACCESS_MEMORY_CMDID"; 25 return "WMI_ACCESS_MEMORY_CMDID";
26 case WMI_GET_FW_VERSION:
27 return "WMI_GET_FW_VERSION";
26 case WMI_DISABLE_INTR_CMDID: 28 case WMI_DISABLE_INTR_CMDID:
27 return "WMI_DISABLE_INTR_CMDID"; 29 return "WMI_DISABLE_INTR_CMDID";
28 case WMI_ENABLE_INTR_CMDID: 30 case WMI_ENABLE_INTR_CMDID:
29 return "WMI_ENABLE_INTR_CMDID"; 31 return "WMI_ENABLE_INTR_CMDID";
30 case WMI_RX_LINK_CMDID:
31 return "WMI_RX_LINK_CMDID";
32 case WMI_ATH_INIT_CMDID: 32 case WMI_ATH_INIT_CMDID:
33 return "WMI_ATH_INIT_CMDID"; 33 return "WMI_ATH_INIT_CMDID";
34 case WMI_ABORT_TXQ_CMDID: 34 case WMI_ABORT_TXQ_CMDID:
35 return "WMI_ABORT_TXQ_CMDID"; 35 return "WMI_ABORT_TXQ_CMDID";
36 case WMI_STOP_TX_DMA_CMDID: 36 case WMI_STOP_TX_DMA_CMDID:
37 return "WMI_STOP_TX_DMA_CMDID"; 37 return "WMI_STOP_TX_DMA_CMDID";
38 case WMI_STOP_DMA_RECV_CMDID:
39 return "WMI_STOP_DMA_RECV_CMDID";
40 case WMI_ABORT_TX_DMA_CMDID: 38 case WMI_ABORT_TX_DMA_CMDID:
41 return "WMI_ABORT_TX_DMA_CMDID"; 39 return "WMI_ABORT_TX_DMA_CMDID";
42 case WMI_DRAIN_TXQ_CMDID: 40 case WMI_DRAIN_TXQ_CMDID:
@@ -51,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
51 return "WMI_FLUSH_RECV_CMDID"; 49 return "WMI_FLUSH_RECV_CMDID";
52 case WMI_SET_MODE_CMDID: 50 case WMI_SET_MODE_CMDID:
53 return "WMI_SET_MODE_CMDID"; 51 return "WMI_SET_MODE_CMDID";
54 case WMI_RESET_CMDID:
55 return "WMI_RESET_CMDID";
56 case WMI_NODE_CREATE_CMDID: 52 case WMI_NODE_CREATE_CMDID:
57 return "WMI_NODE_CREATE_CMDID"; 53 return "WMI_NODE_CREATE_CMDID";
58 case WMI_NODE_REMOVE_CMDID: 54 case WMI_NODE_REMOVE_CMDID:
@@ -61,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
61 return "WMI_VAP_REMOVE_CMDID"; 57 return "WMI_VAP_REMOVE_CMDID";
62 case WMI_VAP_CREATE_CMDID: 58 case WMI_VAP_CREATE_CMDID:
63 return "WMI_VAP_CREATE_CMDID"; 59 return "WMI_VAP_CREATE_CMDID";
64 case WMI_BEACON_UPDATE_CMDID:
65 return "WMI_BEACON_UPDATE_CMDID";
66 case WMI_REG_READ_CMDID: 60 case WMI_REG_READ_CMDID:
67 return "WMI_REG_READ_CMDID"; 61 return "WMI_REG_READ_CMDID";
68 case WMI_REG_WRITE_CMDID: 62 case WMI_REG_WRITE_CMDID:
@@ -71,20 +65,20 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
71 return "WMI_RC_STATE_CHANGE_CMDID"; 65 return "WMI_RC_STATE_CHANGE_CMDID";
72 case WMI_RC_RATE_UPDATE_CMDID: 66 case WMI_RC_RATE_UPDATE_CMDID:
73 return "WMI_RC_RATE_UPDATE_CMDID"; 67 return "WMI_RC_RATE_UPDATE_CMDID";
74 case WMI_DEBUG_INFO_CMDID:
75 return "WMI_DEBUG_INFO_CMDID";
76 case WMI_HOST_ATTACH:
77 return "WMI_HOST_ATTACH";
78 case WMI_TARGET_IC_UPDATE_CMDID: 68 case WMI_TARGET_IC_UPDATE_CMDID:
79 return "WMI_TARGET_IC_UPDATE_CMDID"; 69 return "WMI_TARGET_IC_UPDATE_CMDID";
80 case WMI_TGT_STATS_CMDID:
81 return "WMI_TGT_STATS_CMDID";
82 case WMI_TX_AGGR_ENABLE_CMDID: 70 case WMI_TX_AGGR_ENABLE_CMDID:
83 return "WMI_TX_AGGR_ENABLE_CMDID"; 71 return "WMI_TX_AGGR_ENABLE_CMDID";
84 case WMI_TGT_DETACH_CMDID: 72 case WMI_TGT_DETACH_CMDID:
85 return "WMI_TGT_DETACH_CMDID"; 73 return "WMI_TGT_DETACH_CMDID";
86 case WMI_TGT_TXQ_ENABLE_CMDID: 74 case WMI_NODE_UPDATE_CMDID:
87 return "WMI_TGT_TXQ_ENABLE_CMDID"; 75 return "WMI_NODE_UPDATE_CMDID";
76 case WMI_INT_STATS_CMDID:
77 return "WMI_INT_STATS_CMDID";
78 case WMI_TX_STATS_CMDID:
79 return "WMI_TX_STATS_CMDID";
80 case WMI_RX_STATS_CMDID:
81 return "WMI_RX_STATS_CMDID";
88 case WMI_AGGR_LIMIT_CMD: 82 case WMI_AGGR_LIMIT_CMD:
89 return "WMI_AGGR_LIMIT_CMD"; 83 return "WMI_AGGR_LIMIT_CMD";
90 } 84 }
@@ -102,9 +96,15 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
102 96
103 wmi->drv_priv = priv; 97 wmi->drv_priv = priv;
104 wmi->stopped = false; 98 wmi->stopped = false;
99 skb_queue_head_init(&wmi->wmi_event_queue);
100 spin_lock_init(&wmi->wmi_lock);
101 spin_lock_init(&wmi->event_lock);
105 mutex_init(&wmi->op_mutex); 102 mutex_init(&wmi->op_mutex);
106 mutex_init(&wmi->multi_write_mutex); 103 mutex_init(&wmi->multi_write_mutex);
107 init_completion(&wmi->cmd_wait); 104 init_completion(&wmi->cmd_wait);
105 INIT_LIST_HEAD(&wmi->pending_tx_events);
106 tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
107 (unsigned long)wmi);
108 108
109 return wmi; 109 return wmi;
110} 110}
@@ -120,11 +120,65 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
120 kfree(priv->wmi); 120 kfree(priv->wmi);
121} 121}
122 122
123void ath9k_swba_tasklet(unsigned long data) 123void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv)
124{ 124{
125 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; 125 unsigned long flags;
126 126
127 ath9k_htc_swba(priv, priv->wmi->beacon_pending); 127 tasklet_kill(&priv->wmi->wmi_event_tasklet);
128 spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
129 __skb_queue_purge(&priv->wmi->wmi_event_queue);
130 spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
131}
132
133void ath9k_wmi_event_tasklet(unsigned long data)
134{
135 struct wmi *wmi = (struct wmi *)data;
136 struct ath9k_htc_priv *priv = wmi->drv_priv;
137 struct wmi_cmd_hdr *hdr;
138 void *wmi_event;
139 struct wmi_event_swba *swba;
140 struct sk_buff *skb = NULL;
141 unsigned long flags;
142 u16 cmd_id;
143
144 do {
145 spin_lock_irqsave(&wmi->wmi_lock, flags);
146 skb = __skb_dequeue(&wmi->wmi_event_queue);
147 if (!skb) {
148 spin_unlock_irqrestore(&wmi->wmi_lock, flags);
149 return;
150 }
151 spin_unlock_irqrestore(&wmi->wmi_lock, flags);
152
153 hdr = (struct wmi_cmd_hdr *) skb->data;
154 cmd_id = be16_to_cpu(hdr->command_id);
155 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
156
157 switch (cmd_id) {
158 case WMI_SWBA_EVENTID:
159 swba = (struct wmi_event_swba *) wmi_event;
160 ath9k_htc_swba(priv, swba);
161 break;
162 case WMI_FATAL_EVENTID:
163 ieee80211_queue_work(wmi->drv_priv->hw,
164 &wmi->drv_priv->fatal_work);
165 break;
166 case WMI_TXSTATUS_EVENTID:
167 spin_lock_bh(&priv->tx.tx_lock);
168 if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
169 spin_unlock_bh(&priv->tx.tx_lock);
170 break;
171 }
172 spin_unlock_bh(&priv->tx.tx_lock);
173
174 ath9k_htc_txstatus(priv, wmi_event);
175 break;
176 default:
177 break;
178 }
179
180 kfree_skb(skb);
181 } while (1);
128} 182}
129 183
130void ath9k_fatal_work(struct work_struct *work) 184void ath9k_fatal_work(struct work_struct *work)
@@ -153,10 +207,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
153 struct wmi *wmi = (struct wmi *) priv; 207 struct wmi *wmi = (struct wmi *) priv;
154 struct wmi_cmd_hdr *hdr; 208 struct wmi_cmd_hdr *hdr;
155 u16 cmd_id; 209 u16 cmd_id;
156 void *wmi_event;
157#ifdef CONFIG_ATH9K_HTC_DEBUGFS
158 __be32 txrate;
159#endif
160 210
161 if (unlikely(wmi->stopped)) 211 if (unlikely(wmi->stopped))
162 goto free_skb; 212 goto free_skb;
@@ -165,26 +215,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
165 cmd_id = be16_to_cpu(hdr->command_id); 215 cmd_id = be16_to_cpu(hdr->command_id);
166 216
167 if (cmd_id & 0x1000) { 217 if (cmd_id & 0x1000) {
168 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); 218 spin_lock(&wmi->wmi_lock);
169 switch (cmd_id) { 219 __skb_queue_tail(&wmi->wmi_event_queue, skb);
170 case WMI_SWBA_EVENTID: 220 spin_unlock(&wmi->wmi_lock);
171 wmi->beacon_pending = *(u8 *)wmi_event; 221 tasklet_schedule(&wmi->wmi_event_tasklet);
172 tasklet_schedule(&wmi->drv_priv->swba_tasklet);
173 break;
174 case WMI_FATAL_EVENTID:
175 ieee80211_queue_work(wmi->drv_priv->hw,
176 &wmi->drv_priv->fatal_work);
177 break;
178 case WMI_TXRATE_EVENTID:
179#ifdef CONFIG_ATH9K_HTC_DEBUGFS
180 txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
181 wmi->drv_priv->debug.txrate = be32_to_cpu(txrate);
182#endif
183 break;
184 default:
185 break;
186 }
187 kfree_skb(skb);
188 return; 222 return;
189 } 223 }
190 224
@@ -243,7 +277,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
243 hdr->command_id = cpu_to_be16(cmd); 277 hdr->command_id = cpu_to_be16(cmd);
244 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); 278 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
245 279
246 return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); 280 return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid);
247} 281}
248 282
249int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, 283int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 42084277522d..02ecb9f06db0 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -17,7 +17,6 @@
17#ifndef WMI_H 17#ifndef WMI_H
18#define WMI_H 18#define WMI_H
19 19
20
21struct wmi_event_txrate { 20struct wmi_event_txrate {
22 __be32 txrate; 21 __be32 txrate;
23 struct { 22 struct {
@@ -31,18 +30,65 @@ struct wmi_cmd_hdr {
31 __be16 seq_no; 30 __be16 seq_no;
32} __packed; 31} __packed;
33 32
33struct wmi_fw_version {
34 __be16 major;
35 __be16 minor;
36
37} __packed;
38
39struct wmi_event_swba {
40 __be64 tsf;
41 u8 beacon_pending;
42};
43
44/*
45 * 64 - HTC header - WMI header - 1 / txstatus
46 * And some other hdr. space is also accounted for.
47 * 12 seems to be the magic number.
48 */
49#define HTC_MAX_TX_STATUS 12
50
51#define ATH9K_HTC_TXSTAT_ACK BIT(0)
52#define ATH9K_HTC_TXSTAT_FILT BIT(1)
53#define ATH9K_HTC_TXSTAT_RTC_CTS BIT(2)
54#define ATH9K_HTC_TXSTAT_MCS BIT(3)
55#define ATH9K_HTC_TXSTAT_CW40 BIT(4)
56#define ATH9K_HTC_TXSTAT_SGI BIT(5)
57
58/*
59 * Legacy rates are indicated as indices.
60 * HT rates are indicated as dot11 numbers.
61 * This allows us to resrict the rate field
62 * to 4 bits.
63 */
64#define ATH9K_HTC_TXSTAT_RATE 0x0f
65#define ATH9K_HTC_TXSTAT_RATE_S 0
66
67#define ATH9K_HTC_TXSTAT_EPID 0xf0
68#define ATH9K_HTC_TXSTAT_EPID_S 4
69
70struct __wmi_event_txstatus {
71 u8 cookie;
72 u8 ts_rate; /* Also holds EP ID */
73 u8 ts_flags;
74};
75
76struct wmi_event_txstatus {
77 u8 cnt;
78 struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS];
79} __packed;
80
34enum wmi_cmd_id { 81enum wmi_cmd_id {
35 WMI_ECHO_CMDID = 0x0001, 82 WMI_ECHO_CMDID = 0x0001,
36 WMI_ACCESS_MEMORY_CMDID, 83 WMI_ACCESS_MEMORY_CMDID,
37 84
38 /* Commands to Target */ 85 /* Commands to Target */
86 WMI_GET_FW_VERSION,
39 WMI_DISABLE_INTR_CMDID, 87 WMI_DISABLE_INTR_CMDID,
40 WMI_ENABLE_INTR_CMDID, 88 WMI_ENABLE_INTR_CMDID,
41 WMI_RX_LINK_CMDID,
42 WMI_ATH_INIT_CMDID, 89 WMI_ATH_INIT_CMDID,
43 WMI_ABORT_TXQ_CMDID, 90 WMI_ABORT_TXQ_CMDID,
44 WMI_STOP_TX_DMA_CMDID, 91 WMI_STOP_TX_DMA_CMDID,
45 WMI_STOP_DMA_RECV_CMDID,
46 WMI_ABORT_TX_DMA_CMDID, 92 WMI_ABORT_TX_DMA_CMDID,
47 WMI_DRAIN_TXQ_CMDID, 93 WMI_DRAIN_TXQ_CMDID,
48 WMI_DRAIN_TXQ_ALL_CMDID, 94 WMI_DRAIN_TXQ_ALL_CMDID,
@@ -50,23 +96,21 @@ enum wmi_cmd_id {
50 WMI_STOP_RECV_CMDID, 96 WMI_STOP_RECV_CMDID,
51 WMI_FLUSH_RECV_CMDID, 97 WMI_FLUSH_RECV_CMDID,
52 WMI_SET_MODE_CMDID, 98 WMI_SET_MODE_CMDID,
53 WMI_RESET_CMDID,
54 WMI_NODE_CREATE_CMDID, 99 WMI_NODE_CREATE_CMDID,
55 WMI_NODE_REMOVE_CMDID, 100 WMI_NODE_REMOVE_CMDID,
56 WMI_VAP_REMOVE_CMDID, 101 WMI_VAP_REMOVE_CMDID,
57 WMI_VAP_CREATE_CMDID, 102 WMI_VAP_CREATE_CMDID,
58 WMI_BEACON_UPDATE_CMDID,
59 WMI_REG_READ_CMDID, 103 WMI_REG_READ_CMDID,
60 WMI_REG_WRITE_CMDID, 104 WMI_REG_WRITE_CMDID,
61 WMI_RC_STATE_CHANGE_CMDID, 105 WMI_RC_STATE_CHANGE_CMDID,
62 WMI_RC_RATE_UPDATE_CMDID, 106 WMI_RC_RATE_UPDATE_CMDID,
63 WMI_DEBUG_INFO_CMDID,
64 WMI_HOST_ATTACH,
65 WMI_TARGET_IC_UPDATE_CMDID, 107 WMI_TARGET_IC_UPDATE_CMDID,
66 WMI_TGT_STATS_CMDID,
67 WMI_TX_AGGR_ENABLE_CMDID, 108 WMI_TX_AGGR_ENABLE_CMDID,
68 WMI_TGT_DETACH_CMDID, 109 WMI_TGT_DETACH_CMDID,
69 WMI_TGT_TXQ_ENABLE_CMDID, 110 WMI_NODE_UPDATE_CMDID,
111 WMI_INT_STATS_CMDID,
112 WMI_TX_STATS_CMDID,
113 WMI_RX_STATS_CMDID,
70 WMI_AGGR_LIMIT_CMD = 0x0026, 114 WMI_AGGR_LIMIT_CMD = 0x0026,
71}; 115};
72 116
@@ -76,9 +120,8 @@ enum wmi_event_id {
76 WMI_FATAL_EVENTID, 120 WMI_FATAL_EVENTID,
77 WMI_TXTO_EVENTID, 121 WMI_TXTO_EVENTID,
78 WMI_BMISS_EVENTID, 122 WMI_BMISS_EVENTID,
79 WMI_WLAN_TXCOMP_EVENTID,
80 WMI_DELBA_EVENTID, 123 WMI_DELBA_EVENTID,
81 WMI_TXRATE_EVENTID, 124 WMI_TXSTATUS_EVENTID,
82}; 125};
83 126
84#define MAX_CMD_NUMBER 62 127#define MAX_CMD_NUMBER 62
@@ -88,6 +131,12 @@ struct register_write {
88 __be32 val; 131 __be32 val;
89}; 132};
90 133
134struct ath9k_htc_tx_event {
135 int count;
136 struct __wmi_event_txstatus txs;
137 struct list_head list;
138};
139
91struct wmi { 140struct wmi {
92 struct ath9k_htc_priv *drv_priv; 141 struct ath9k_htc_priv *drv_priv;
93 struct htc_target *htc; 142 struct htc_target *htc;
@@ -95,12 +144,16 @@ struct wmi {
95 struct mutex op_mutex; 144 struct mutex op_mutex;
96 struct completion cmd_wait; 145 struct completion cmd_wait;
97 enum wmi_cmd_id last_cmd_id; 146 enum wmi_cmd_id last_cmd_id;
147 struct sk_buff_head wmi_event_queue;
148 struct tasklet_struct wmi_event_tasklet;
98 u16 tx_seq_id; 149 u16 tx_seq_id;
99 u8 *cmd_rsp_buf; 150 u8 *cmd_rsp_buf;
100 u32 cmd_rsp_len; 151 u32 cmd_rsp_len;
101 bool stopped; 152 bool stopped;
102 153
103 u8 beacon_pending; 154 struct list_head pending_tx_events;
155 spinlock_t event_lock;
156
104 spinlock_t wmi_lock; 157 spinlock_t wmi_lock;
105 158
106 atomic_t mwrite_cnt; 159 atomic_t mwrite_cnt;
@@ -117,8 +170,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
117 u8 *cmd_buf, u32 cmd_len, 170 u8 *cmd_buf, u32 cmd_len,
118 u8 *rsp_buf, u32 rsp_len, 171 u8 *rsp_buf, u32 rsp_len,
119 u32 timeout); 172 u32 timeout);
120void ath9k_swba_tasklet(unsigned long data); 173void ath9k_wmi_event_tasklet(unsigned long data);
121void ath9k_fatal_work(struct work_struct *work); 174void ath9k_fatal_work(struct work_struct *work);
175void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
122 176
123#define WMI_CMD(_wmi_cmd) \ 177#define WMI_CMD(_wmi_cmd) \
124 do { \ 178 do { \
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index f828f294ba89..7e3b29015dda 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -97,8 +97,8 @@ static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
97 } 97 }
98}; 98};
99 99
100/* Can be used by 0x67, 0x6A and 0x68 */ 100/* Can be used by 0x67, 0x68, 0x6A and 0x6C */
101static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { 101static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
102 .n_reg_rules = 4, 102 .n_reg_rules = 4,
103 .alpha2 = "99", 103 .alpha2 = "99",
104 .reg_rules = { 104 .reg_rules = {
@@ -151,7 +151,8 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
151 case 0x67: 151 case 0x67:
152 case 0x68: 152 case 0x68:
153 case 0x6A: 153 case 0x6A:
154 return &ath_world_regdom_67_68_6A; 154 case 0x6C:
155 return &ath_world_regdom_67_68_6A_6C;
155 default: 156 default:
156 WARN_ON(1); 157 WARN_ON(1);
157 return ath_default_world_regdomain(); 158 return ath_default_world_regdomain();
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index 5c2cfe694152..24b53839fc3a 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -86,6 +86,7 @@ enum EnumRd {
86 WOR9_WORLD = 0x69, 86 WOR9_WORLD = 0x69,
87 WORA_WORLD = 0x6A, 87 WORA_WORLD = 0x6A,
88 WORB_WORLD = 0x6B, 88 WORB_WORLD = 0x6B,
89 WORC_WORLD = 0x6C,
89 90
90 MKK3_MKKB = 0x80, 91 MKK3_MKKB = 0x80,
91 MKK3_MKKA2 = 0x81, 92 MKK3_MKKA2 = 0x81,
@@ -282,6 +283,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
282 {WOR9_WORLD, NO_CTL, NO_CTL}, 283 {WOR9_WORLD, NO_CTL, NO_CTL},
283 {WORA_WORLD, NO_CTL, NO_CTL}, 284 {WORA_WORLD, NO_CTL, NO_CTL},
284 {WORB_WORLD, NO_CTL, NO_CTL}, 285 {WORB_WORLD, NO_CTL, NO_CTL},
286 {WORC_WORLD, NO_CTL, NO_CTL},
285}; 287};
286 288
287static struct country_code_to_enum_rd allCountries[] = { 289static struct country_code_to_enum_rd allCountries[] = {
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
index 31ac672b64e1..89509392ef5d 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
@@ -2860,7 +2860,6 @@ static struct rate_control_ops rs_4965_ops = {
2860 2860
2861int iwl4965_rate_control_register(void) 2861int iwl4965_rate_control_register(void)
2862{ 2862{
2863 pr_err("Registering 4965 rate control operations\n");
2864 return ieee80211_rate_control_register(&rs_4965_ops); 2863 return ieee80211_rate_control_register(&rs_4965_ops);
2865} 2864}
2866 2865
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 73a6e62f5680..d64065ff235c 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -242,9 +242,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
242 * 242 *
243 * Handling includes changing the header fields into CPU format. 243 * Handling includes changing the header fields into CPU format.
244 */ 244 */
245int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, 245int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf)
246 struct host_cmd_ds_command *resp,
247 void *data_buf)
248{ 246{
249 struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; 247 struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL;
250 struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; 248 struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg;
@@ -298,8 +296,7 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
298 * - Setting AMSDU control parameters (for SET only) 296 * - Setting AMSDU control parameters (for SET only)
299 * - Ensuring correct endian-ness 297 * - Ensuring correct endian-ness
300 */ 298 */
301int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, 299int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
302 struct host_cmd_ds_command *cmd,
303 int cmd_action, void *data_buf) 300 int cmd_action, void *data_buf)
304{ 301{
305 struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = 302 struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
@@ -331,8 +328,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv,
331 * 328 *
332 * Handling includes changing the header fields into CPU format. 329 * Handling includes changing the header fields into CPU format.
333 */ 330 */
334int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, 331int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
335 struct host_cmd_ds_command *resp,
336 void *data_buf) 332 void *data_buf)
337{ 333{
338 struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; 334 struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL;
@@ -357,8 +353,7 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv,
357 * - Setting HT Tx capability and HT Tx information fields 353 * - Setting HT Tx capability and HT Tx information fields
358 * - Ensuring correct endian-ness 354 * - Ensuring correct endian-ness
359 */ 355 */
360int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, 356int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
361 struct host_cmd_ds_command *cmd,
362 u16 cmd_action, void *data_buf) 357 u16 cmd_action, void *data_buf)
363{ 358{
364 struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; 359 struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
@@ -541,11 +536,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
541 else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) 536 else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K)
542 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; 537 curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K;
543 if (curr_tx_buf_size != tx_buf) 538 if (curr_tx_buf_size != tx_buf)
544 mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, 539 mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
545 HostCmd_ACT_GEN_SET, 0, 540 HostCmd_ACT_GEN_SET, 0, &tx_buf);
546 NULL, &tx_buf);
547
548 return;
549} 541}
550 542
551/* 543/*
@@ -583,8 +575,6 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
583 list_del(&tx_ba_tsr_tbl->list); 575 list_del(&tx_ba_tsr_tbl->list);
584 576
585 kfree(tx_ba_tsr_tbl); 577 kfree(tx_ba_tsr_tbl);
586
587 return;
588} 578}
589 579
590/* 580/*
@@ -663,8 +653,6 @@ void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
663 list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); 653 list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr);
664 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); 654 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
665 } 655 }
666
667 return;
668} 656}
669 657
670/* 658/*
@@ -694,8 +682,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
694 memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); 682 memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
695 683
696 /* We don't wait for the response of this command */ 684 /* We don't wait for the response of this command */
697 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, 685 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ,
698 0, 0, NULL, &add_ba_req); 686 0, 0, &add_ba_req);
699 687
700 return ret; 688 return ret;
701} 689}
@@ -722,8 +710,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
722 memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); 710 memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
723 711
724 /* We don't wait for the response of this command */ 712 /* We don't wait for the response of this command */
725 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 713 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA,
726 HostCmd_ACT_GEN_SET, 0, NULL, &delba); 714 HostCmd_ACT_GEN_SET, 0, &delba);
727 715
728 return ret; 716 return ret;
729} 717}
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 71a853e61b61..02602ff30cbf 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -28,15 +28,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
28 struct host_cmd_ds_command *resp); 28 struct host_cmd_ds_command *resp);
29int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, 29int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
30 struct host_cmd_ds_command *resp); 30 struct host_cmd_ds_command *resp);
31int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, 31int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp,
32 struct host_cmd_ds_command *resp,
33 void *data_buf); 32 void *data_buf);
34int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, 33int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
35 struct host_cmd_ds_command *cmd,
36 u16 cmd_action, void *data_buf);
37
38int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv,
39 struct host_cmd_ds_command *cmd,
40 u16 cmd_action, void *data_buf); 34 u16 cmd_action, void *data_buf);
41 35
42int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, 36int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
@@ -67,24 +61,19 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
67 struct mwifiex_ds_rx_reorder_tbl *buf); 61 struct mwifiex_ds_rx_reorder_tbl *buf);
68int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, 62int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
69 struct mwifiex_ds_tx_ba_stream_tbl *buf); 63 struct mwifiex_ds_tx_ba_stream_tbl *buf);
70int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, 64int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
71 struct host_cmd_ds_command
72 *resp,
73 void *data_buf); 65 void *data_buf);
74int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, 66int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
75 struct host_cmd_ds_command *cmd, 67 struct host_cmd_ds_command *cmd,
76 int cmd_action, void *data_buf); 68 int cmd_action, void *data_buf);
77int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, 69int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
78 struct host_cmd_ds_command *cmd, 70 int cmd_action, void *data_buf);
79 int cmd_action,
80 void *data_buf);
81 71
82/* 72/*
83 * This function checks whether AMPDU is allowed or not for a particular TID. 73 * This function checks whether AMPDU is allowed or not for a particular TID.
84 */ 74 */
85static inline u8 75static inline u8
86mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, 76mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid)
87 struct mwifiex_ra_list_tbl *ptr, int tid)
88{ 77{
89 return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) 78 return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED)
90 ? true : false); 79 ? true : false);
@@ -94,8 +83,7 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv,
94 * This function checks whether AMSDU is allowed or not for a particular TID. 83 * This function checks whether AMSDU is allowed or not for a particular TID.
95 */ 84 */
96static inline u8 85static inline u8
97mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, 86mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid)
98 struct mwifiex_ra_list_tbl *ptr, int tid)
99{ 87{
100 return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) 88 return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED)
101 && ((priv->is_data_rate_auto) 89 && ((priv->is_data_rate_auto)
@@ -104,23 +92,21 @@ mwifiex_is_amsdu_allowed(struct mwifiex_private *priv,
104} 92}
105 93
106/* 94/*
107 * This function checks whether a BA stream is available or not. 95 * This function checks whether a space is available for new BA stream or not.
108 */ 96 */
109static inline u8 97static inline u8 mwifiex_space_avail_for_new_ba_stream(
110mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) 98 struct mwifiex_adapter *adapter)
111{ 99{
112 struct mwifiex_private *pmpriv = NULL; 100 struct mwifiex_private *priv;
113 u8 i = 0; 101 u8 i;
114 u32 ba_stream_num = 0; 102 u32 ba_stream_num = 0;
115 103
116 for (i = 0; i < priv->adapter->priv_num; i++) { 104 for (i = 0; i < adapter->priv_num; i++) {
117 pmpriv = priv->adapter->priv[i]; 105 priv = adapter->priv[i];
118 if (pmpriv) 106 if (priv)
119 ba_stream_num += 107 ba_stream_num += mwifiex_wmm_list_len(
120 mwifiex_wmm_list_len(priv->adapter, 108 (struct list_head *)
121 (struct list_head 109 &priv->tx_ba_stream_tbl_ptr);
122 *) &pmpriv->
123 tx_ba_stream_tbl_ptr);
124 } 110 }
125 111
126 return ((ba_stream_num < 112 return ((ba_stream_num <
@@ -133,8 +119,7 @@ mwifiex_is_ba_stream_avail(struct mwifiex_private *priv)
133 * Upon successfully locating, both the TID and the RA are returned. 119 * Upon successfully locating, both the TID and the RA are returned.
134 */ 120 */
135static inline u8 121static inline u8
136mwifiex_find_stream_to_delete(struct mwifiex_private *priv, 122mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
137 struct mwifiex_ra_list_tbl *ptr, int ptr_tid,
138 int *ptid, u8 *ra) 123 int *ptid, u8 *ra)
139{ 124{
140 int tid; 125 int tid;
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index c2abced66957..c9fb0627de43 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -44,8 +44,7 @@
44 * MSDU => |DA|SA|Length|SNAP|...... ..| 44 * MSDU => |DA|SA|Length|SNAP|...... ..|
45 */ 45 */
46static int 46static int
47mwifiex_11n_form_amsdu_pkt(struct mwifiex_adapter *adapter, 47mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
48 struct sk_buff *skb_aggr,
49 struct sk_buff *skb_src, int *pad) 48 struct sk_buff *skb_src, int *pad)
50 49
51{ 50{
@@ -324,7 +323,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
324 323
325 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 324 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
326 ra_list_flags); 325 ra_list_flags);
327 mwifiex_11n_form_amsdu_pkt(adapter, skb_aggr, skb_src, &pad); 326 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
328 327
329 mwifiex_write_data_complete(adapter, skb_src, 0); 328 mwifiex_write_data_complete(adapter, skb_src, 0);
330 329
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 8e94e620e6f4..755e5d533c03 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -309,8 +309,6 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
309 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); 309 spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
310 list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); 310 list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr);
311 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); 311 spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
312
313 return;
314} 312}
315 313
316/* 314/*
@@ -321,8 +319,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
321 * - Setting add BA request buffer 319 * - Setting add BA request buffer
322 * - Ensuring correct endian-ness 320 * - Ensuring correct endian-ness
323 */ 321 */
324int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, 322int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf)
325 struct host_cmd_ds_command *cmd, void *data_buf)
326{ 323{
327 struct host_cmd_ds_11n_addba_req *add_ba_req = 324 struct host_cmd_ds_11n_addba_req *add_ba_req =
328 (struct host_cmd_ds_11n_addba_req *) 325 (struct host_cmd_ds_11n_addba_req *)
@@ -393,8 +390,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
393 * - Setting del BA request buffer 390 * - Setting del BA request buffer
394 * - Ensuring correct endian-ness 391 * - Ensuring correct endian-ness
395 */ 392 */
396int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, 393int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf)
397 struct host_cmd_ds_command *cmd, void *data_buf)
398{ 394{
399 struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) 395 struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *)
400 &cmd->params.del_ba; 396 &cmd->params.del_ba;
@@ -609,9 +605,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
609 delba.del_ba_param_set |= cpu_to_le16( 605 delba.del_ba_param_set |= cpu_to_le16(
610 (u16) event->origninator << DELBA_INITIATOR_POS); 606 (u16) event->origninator << DELBA_INITIATOR_POS);
611 delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); 607 delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
612 mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba); 608 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba);
613
614 return;
615} 609}
616 610
617/* 611/*
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 42f569035745..f3ca8c8c18f9 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -49,14 +49,12 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
49int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, 49int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
50 struct host_cmd_ds_command 50 struct host_cmd_ds_command
51 *resp); 51 *resp);
52int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, 52int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd,
53 struct host_cmd_ds_command *cmd,
54 void *data_buf); 53 void *data_buf);
55int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, 54int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
56 struct host_cmd_ds_command 55 struct host_cmd_ds_command
57 *cmd, void *data_buf); 56 *cmd, void *data_buf);
58int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, 57int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd,
59 struct host_cmd_ds_command *cmd,
60 void *data_buf); 58 void *data_buf);
61void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); 59void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv);
62struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct 60struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index 338377f7093b..b55badef4660 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -157,7 +157,7 @@ info
157 mp_wr_bitmap = <SDIO multi-port write bitmap> 157 mp_wr_bitmap = <SDIO multi-port write bitmap>
158 cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> 158 cmd_resp_received = <0/1, no cmd response to process/response received and yet to process>
159 event_received = <0/1, no event to process/event received and yet to process> 159 event_received = <0/1, no event to process/event received and yet to process>
160 ioctl_pending = <number of ioctl pending> 160 cmd_pending = <number of cmd pending>
161 tx_pending = <number of Tx packet pending> 161 tx_pending = <number of Tx packet pending>
162 rx_pending = <number of Rx packet pending> 162 rx_pending = <number of Rx packet pending>
163 163
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ec0895f4e8d3..74b6cf20da04 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -139,8 +139,16 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
139{ 139{
140 int ret = 0; 140 int ret = 0;
141 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 141 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
142 struct mwifiex_power_cfg power_cfg;
142 143
143 ret = mwifiex_set_tx_power(priv, type, dbm); 144 if (type == NL80211_TX_POWER_FIXED) {
145 power_cfg.is_power_auto = 0;
146 power_cfg.power_level = dbm;
147 } else {
148 power_cfg.is_power_auto = 1;
149 }
150
151 ret = mwifiex_set_tx_power(priv, &power_cfg);
144 152
145 return ret; 153 return ret;
146} 154}
@@ -157,13 +165,15 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
157{ 165{
158 int ret = 0; 166 int ret = 0;
159 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 167 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
168 u32 ps_mode;
160 169
161 if (timeout) 170 if (timeout)
162 wiphy_dbg(wiphy, 171 wiphy_dbg(wiphy,
163 "info: ignoring the timeout value" 172 "info: ignoring the timeout value"
164 " for IEEE power save\n"); 173 " for IEEE power save\n");
165 174
166 ret = mwifiex_drv_set_power(priv, enabled); 175 ps_mode = enabled;
176 ret = mwifiex_drv_set_power(priv, &ps_mode);
167 177
168 return ret; 178 return ret;
169} 179}
@@ -291,8 +301,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
291 301
292 domain_info->no_of_triplet = no_of_triplet; 302 domain_info->no_of_triplet = no_of_triplet;
293 /* Send cmd to FW to set domain info */ 303 /* Send cmd to FW to set domain info */
294 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 304 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
295 HostCmd_ACT_GEN_SET, 0, NULL, NULL); 305 HostCmd_ACT_GEN_SET, 0, NULL);
296 if (ret) 306 if (ret)
297 wiphy_err(wiphy, "11D: setting domain info in FW\n"); 307 wiphy_err(wiphy, "11D: setting domain info in FW\n");
298 308
@@ -347,7 +357,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
347{ 357{
348 struct mwifiex_chan_freq_power cfp; 358 struct mwifiex_chan_freq_power cfp;
349 int ret = 0; 359 int ret = 0;
350 int status = 0;
351 struct mwifiex_ds_band_cfg band_cfg; 360 struct mwifiex_ds_band_cfg band_cfg;
352 u32 config_bands = 0; 361 u32 config_bands = 0;
353 struct wiphy *wiphy = priv->wdev->wiphy; 362 struct wiphy *wiphy = priv->wdev->wiphy;
@@ -370,10 +379,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
370 band_cfg.sec_chan_offset = 379 band_cfg.sec_chan_offset =
371 mwifiex_cfg80211_channel_type_to_mwifiex_channels 380 mwifiex_cfg80211_channel_type_to_mwifiex_channels
372 (channel_type); 381 (channel_type);
373 status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET, 382 ret = mwifiex_set_radio_band_cfg(priv, &band_cfg);
374 &band_cfg);
375 383
376 if (status) 384 if (ret)
377 return -EFAULT; 385 return -EFAULT;
378 mwifiex_send_domain_info_cmd_fw(wiphy); 386 mwifiex_send_domain_info_cmd_fw(wiphy);
379 } 387 }
@@ -389,8 +397,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
389 /* Convert frequency to channel */ 397 /* Convert frequency to channel */
390 cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); 398 cfp.channel = ieee80211_frequency_to_channel(chan->center_freq);
391 399
392 status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp); 400 ret = mwifiex_bss_set_channel(priv, &cfp);
393 if (status) 401 if (ret)
394 return -EFAULT; 402 return -EFAULT;
395 403
396 ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); 404 ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
@@ -422,66 +430,45 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
422/* 430/*
423 * This function sets the fragmentation threshold. 431 * This function sets the fragmentation threshold.
424 * 432 *
425 * This function creates an IOCTL request, populates it accordingly 433 * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE
426 * and issues an IOCTL.
427 *
428 * The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE
429 * and MWIFIEX_FRAG_MAX_VALUE. 434 * and MWIFIEX_FRAG_MAX_VALUE.
430 */ 435 */
431static int 436static int
432mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) 437mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
433{ 438{
434 int ret = 0; 439 int ret = 0;
435 int status = 0;
436 struct mwifiex_wait_queue *wait = NULL;
437 u8 wait_option = MWIFIEX_IOCTL_WAIT;
438 440
439 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE 441 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
440 || frag_thr > MWIFIEX_FRAG_MAX_VALUE) 442 || frag_thr > MWIFIEX_FRAG_MAX_VALUE)
441 return -EINVAL; 443 return -EINVAL;
442 444
443 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); 445 /* Send request to firmware */
444 if (!wait) 446 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
445 return -ENOMEM; 447 HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
446 448 &frag_thr);
447 status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I,
448 HostCmd_ACT_GEN_SET, &frag_thr);
449
450 if (mwifiex_request_ioctl(priv, wait, status, wait_option))
451 ret = -EFAULT;
452 449
453 kfree(wait);
454 return ret; 450 return ret;
455} 451}
456 452
457/* 453/*
458 * This function sets the RTS threshold. 454 * This function sets the RTS threshold.
459 * 455
460 * This function creates an IOCTL request, populates it accordingly 456 * The rts value must lie between MWIFIEX_RTS_MIN_VALUE
461 * and issues an IOCTL. 457 * and MWIFIEX_RTS_MAX_VALUE.
462 */ 458 */
463static int 459static int
464mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) 460mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
465{ 461{
466 int ret = 0; 462 int ret = 0;
467 struct mwifiex_wait_queue *wait = NULL;
468 int status = 0;
469 u8 wait_option = MWIFIEX_IOCTL_WAIT;
470 463
471 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) 464 if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
472 rts_thr = MWIFIEX_RTS_MAX_VALUE; 465 rts_thr = MWIFIEX_RTS_MAX_VALUE;
473 466
474 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); 467 /* Send request to firmware */
475 if (!wait) 468 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
476 return -ENOMEM; 469 HostCmd_ACT_GEN_SET, RTS_THRESH_I,
470 &rts_thr);
477 471
478 status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I,
479 HostCmd_ACT_GEN_SET, &rts_thr);
480
481 if (mwifiex_request_ioctl(priv, wait, status, wait_option))
482 ret = -EFAULT;
483
484 kfree(wait);
485 return ret; 472 return ret;
486} 473}
487 474
@@ -518,7 +505,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
518{ 505{
519 int ret = 0; 506 int ret = 0;
520 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 507 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
521 struct mwifiex_wait_queue *wait = NULL;
522 508
523 if (priv->bss_mode == type) { 509 if (priv->bss_mode == type) {
524 wiphy_warn(wiphy, "already set to required type\n"); 510 wiphy_warn(wiphy, "already set to required type\n");
@@ -545,24 +531,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
545 return -EINVAL; 531 return -EINVAL;
546 } 532 }
547 533
548 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); 534 mwifiex_deauthenticate(priv, NULL);
549 if (!wait)
550 return -ENOMEM;
551
552 mwifiex_deauthenticate(priv, wait, NULL);
553 535
554 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; 536 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
555 537
556 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, 538 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
557 HostCmd_ACT_GEN_SET, 0, wait, NULL); 539 HostCmd_ACT_GEN_SET, 0, NULL);
558 if (!ret)
559 ret = -EINPROGRESS;
560 540
561 ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT);
562 if (ret)
563 ret = -EFAULT;
564
565 kfree(wait);
566 return ret; 541 return ret;
567} 542}
568 543
@@ -592,7 +567,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
592 567
593 /* Get signal information from the firmware */ 568 /* Get signal information from the firmware */
594 memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); 569 memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal));
595 if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) { 570 if (mwifiex_get_signal_info(priv, &signal)) {
596 dev_err(priv->adapter->dev, "getting signal information\n"); 571 dev_err(priv->adapter->dev, "getting signal information\n");
597 ret = -EFAULT; 572 ret = -EFAULT;
598 } 573 }
@@ -750,7 +725,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
750 return -EBUSY; 725 return -EBUSY;
751 726
752 priv->disconnect = 1; 727 priv->disconnect = 1;
753 if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) 728 if (mwifiex_deauthenticate(priv, NULL))
754 return -EFAULT; 729 return -EFAULT;
755 730
756 wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" 731 wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
@@ -838,8 +813,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
838 u8 element_id, element_len; 813 u8 element_id, element_len;
839 814
840 memset(&scan_resp, 0, sizeof(scan_resp)); 815 memset(&scan_resp, 0, sizeof(scan_resp));
841 if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp)) 816 scan_resp.scan_table = (u8 *) priv->adapter->scan_table;
842 return -EFAULT; 817 scan_resp.num_in_scan_table = priv->adapter->num_in_scan_table;
843 818
844#define MAX_IE_BUF 2048 819#define MAX_IE_BUF 2048
845 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); 820 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
@@ -986,7 +961,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
986 } 961 }
987 962
988 /* disconnect before try to associate */ 963 /* disconnect before try to associate */
989 mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL); 964 mwifiex_deauthenticate(priv, NULL);
990 965
991 if (channel) 966 if (channel)
992 ret = mwifiex_set_rf_channel(priv, channel, 967 ret = mwifiex_set_rf_channel(priv, channel,
@@ -1046,7 +1021,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
1046 } 1021 }
1047done: 1022done:
1048 /* Do specific SSID scanning */ 1023 /* Do specific SSID scanning */
1049 if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) { 1024 if (mwifiex_request_scan(priv, &req_ssid)) {
1050 dev_err(priv->adapter->dev, "scan error\n"); 1025 dev_err(priv->adapter->dev, "scan error\n");
1051 return -EFAULT; 1026 return -EFAULT;
1052 } 1027 }
@@ -1055,8 +1030,7 @@ done:
1055 memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); 1030 memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid));
1056 1031
1057 if (mode != NL80211_IFTYPE_ADHOC) { 1032 if (mode != NL80211_IFTYPE_ADHOC) {
1058 if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, 1033 if (mwifiex_find_best_bss(priv, &ssid_bssid))
1059 &ssid_bssid))
1060 return -EFAULT; 1034 return -EFAULT;
1061 /* Inform the BSS information to kernel, otherwise 1035 /* Inform the BSS information to kernel, otherwise
1062 * kernel will give a panic after successful assoc */ 1036 * kernel will give a panic after successful assoc */
@@ -1072,7 +1046,10 @@ done:
1072 /* Connect to BSS by ESSID */ 1046 /* Connect to BSS by ESSID */
1073 memset(&ssid_bssid.bssid, 0, ETH_ALEN); 1047 memset(&ssid_bssid.bssid, 0, ETH_ALEN);
1074 1048
1075 if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) 1049 if (!netif_queue_stopped(priv->netdev))
1050 netif_stop_queue(priv->netdev);
1051
1052 if (mwifiex_bss_start(priv, &ssid_bssid))
1076 return -EFAULT; 1053 return -EFAULT;
1077 1054
1078 if (mode == NL80211_IFTYPE_ADHOC) { 1055 if (mode == NL80211_IFTYPE_ADHOC) {
@@ -1176,7 +1153,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1176 1153
1177 wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", 1154 wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
1178 priv->cfg_bssid); 1155 priv->cfg_bssid);
1179 if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) 1156 if (mwifiex_deauthenticate(priv, NULL))
1180 return -EFAULT; 1157 return -EFAULT;
1181 1158
1182 queue_work(priv->workqueue, &priv->cfg_workqueue); 1159 queue_work(priv->workqueue, &priv->cfg_workqueue);
@@ -1451,6 +1428,4 @@ done:
1451 memset(priv->cfg_bssid, 0, ETH_ALEN); 1428 memset(priv->cfg_bssid, 0, ETH_ALEN);
1452 priv->disconnect = 0; 1429 priv->disconnect = 0;
1453 } 1430 }
1454
1455 return;
1456} 1431}
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 07187a405fee..bb73cfe14aeb 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -75,8 +75,7 @@ u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
75 * This function maps an index in supported rates table into 75 * This function maps an index in supported rates table into
76 * the corresponding data rate. 76 * the corresponding data rate.
77 */ 77 */
78u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, 78u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info)
79 u8 ht_info)
80{ 79{
81 u16 mcs_rate[4][8] = { 80 u16 mcs_rate[4][8] = {
82 {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} 81 {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e}
@@ -126,7 +125,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index,
126 * This function maps a data rate value into corresponding index in supported 125 * This function maps a data rate value into corresponding index in supported
127 * rates table. 126 * rates table.
128 */ 127 */
129u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate) 128u8 mwifiex_data_rate_to_index(u32 rate)
130{ 129{
131 u16 *ptr; 130 u16 *ptr;
132 131
@@ -265,9 +264,7 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv)
265/* 264/*
266 * This function converts rate bitmap into rate index. 265 * This function converts rate bitmap into rate index.
267 */ 266 */
268int 267int mwifiex_get_rate_index(u16 *rate_bitmap, int size)
269mwifiex_get_rate_index(struct mwifiex_adapter *adapter, u16 *rate_bitmap,
270 int size)
271{ 268{
272 int i; 269 int i;
273 270
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index a9aeb31af455..776146a104ec 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -36,11 +36,12 @@
36static void 36static void
37mwifiex_init_cmd_node(struct mwifiex_private *priv, 37mwifiex_init_cmd_node(struct mwifiex_private *priv,
38 struct cmd_ctrl_node *cmd_node, 38 struct cmd_ctrl_node *cmd_node,
39 u32 cmd_oid, void *wait_queue, void *data_buf) 39 u32 cmd_oid, void *data_buf)
40{ 40{
41 cmd_node->priv = priv; 41 cmd_node->priv = priv;
42 cmd_node->cmd_oid = cmd_oid; 42 cmd_node->cmd_oid = cmd_oid;
43 cmd_node->wq_buf = wait_queue; 43 cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required;
44 priv->adapter->cmd_wait_q_required = false;
44 cmd_node->data_buf = data_buf; 45 cmd_node->data_buf = data_buf;
45 cmd_node->cmd_skb = cmd_node->skb; 46 cmd_node->cmd_skb = cmd_node->skb;
46} 47}
@@ -86,39 +87,13 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
86{ 87{
87 cmd_node->cmd_oid = 0; 88 cmd_node->cmd_oid = 0;
88 cmd_node->cmd_flag = 0; 89 cmd_node->cmd_flag = 0;
89 cmd_node->wq_buf = NULL;
90 cmd_node->data_buf = NULL; 90 cmd_node->data_buf = NULL;
91 cmd_node->wait_q_enabled = false;
91 92
92 if (cmd_node->resp_skb) { 93 if (cmd_node->resp_skb) {
93 mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); 94 mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0);
94 cmd_node->resp_skb = NULL; 95 cmd_node->resp_skb = NULL;
95 } 96 }
96
97 return;
98}
99
100/*
101 * This function returns a command node from the pending queue which
102 * matches the given IOCTL request.
103 */
104static struct cmd_ctrl_node *
105mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter,
106 struct mwifiex_wait_queue *wait_queue)
107{
108 unsigned long flags;
109 struct cmd_ctrl_node *cmd_node;
110
111 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
112 list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
113 if (cmd_node->wq_buf == wait_queue) {
114 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
115 flags);
116 return cmd_node;
117 }
118 }
119 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
120
121 return NULL;
122} 97}
123 98
124/* 99/*
@@ -155,7 +130,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
155 struct mwifiex_adapter *adapter = priv->adapter; 130 struct mwifiex_adapter *adapter = priv->adapter;
156 int ret = 0; 131 int ret = 0;
157 struct host_cmd_ds_command *host_cmd; 132 struct host_cmd_ds_command *host_cmd;
158 struct mwifiex_wait_queue *wait_queue = NULL;
159 uint16_t cmd_code; 133 uint16_t cmd_code;
160 uint16_t cmd_size; 134 uint16_t cmd_size;
161 struct timeval tstamp; 135 struct timeval tstamp;
@@ -165,15 +139,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
165 return -1; 139 return -1;
166 140
167 host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); 141 host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
168 if (cmd_node->wq_buf)
169 wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
170 142
171 /* Sanity test */ 143 /* Sanity test */
172 if (host_cmd == NULL || host_cmd->size == 0) { 144 if (host_cmd == NULL || host_cmd->size == 0) {
173 dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" 145 dev_err(adapter->dev, "DNLD_CMD: host_cmd is null"
174 " or cmd size is 0, not sending\n"); 146 " or cmd size is 0, not sending\n");
175 if (wait_queue) 147 if (cmd_node->wait_q_enabled)
176 wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; 148 adapter->cmd_wait_q.status = -1;
177 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 149 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
178 return -1; 150 return -1;
179 } 151 }
@@ -206,10 +178,12 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
206 cmd_node->cmd_skb->data, 178 cmd_node->cmd_skb->data,
207 cmd_node->cmd_skb->len, NULL); 179 cmd_node->cmd_skb->len, NULL);
208 180
181 skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
182
209 if (ret == -1) { 183 if (ret == -1) {
210 dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); 184 dev_err(adapter->dev, "DNLD_CMD: host to card failed\n");
211 if (wait_queue) 185 if (cmd_node->wait_q_enabled)
212 wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; 186 adapter->cmd_wait_q.status = -1;
213 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 187 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
214 188
215 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 189 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
@@ -435,7 +409,31 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
435} 409}
436 410
437/* 411/*
438 * This function prepares a command before sending it to the firmware. 412 * This function is used to send synchronous command to the firmware.
413 *
414 * it allocates a wait queue for the command and wait for the command
415 * response.
416 */
417int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
418 u16 cmd_action, u32 cmd_oid, void *data_buf)
419{
420 int ret = 0;
421 struct mwifiex_adapter *adapter = priv->adapter;
422
423 adapter->cmd_wait_q_required = true;
424 adapter->cmd_wait_q.condition = false;
425
426 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
427 data_buf);
428 if (!ret)
429 ret = mwifiex_wait_queue_complete(adapter);
430
431 return ret;
432}
433
434
435/*
436 * This function prepares a command and asynchronously send it to the firmware.
439 * 437 *
440 * Preparation includes - 438 * Preparation includes -
441 * - Sanity tests to make sure the card is still present or the FW 439 * - Sanity tests to make sure the card is still present or the FW
@@ -445,9 +443,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
445 * - Fill up the non-default parameters and buffer pointers 443 * - Fill up the non-default parameters and buffer pointers
446 * - Add the command to pending queue 444 * - Add the command to pending queue
447 */ 445 */
448int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, 446int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
449 u16 cmd_action, u32 cmd_oid, 447 u16 cmd_action, u32 cmd_oid, void *data_buf)
450 void *wait_queue, void *data_buf)
451{ 448{
452 int ret = 0; 449 int ret = 0;
453 struct mwifiex_adapter *adapter = priv->adapter; 450 struct mwifiex_adapter *adapter = priv->adapter;
@@ -485,7 +482,7 @@ int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
485 } 482 }
486 483
487 /* Initialize the command node */ 484 /* Initialize the command node */
488 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf); 485 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf);
489 486
490 if (!cmd_node->cmd_skb) { 487 if (!cmd_node->cmd_skb) {
491 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); 488 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
@@ -535,18 +532,13 @@ void
535mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, 532mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
536 struct cmd_ctrl_node *cmd_node) 533 struct cmd_ctrl_node *cmd_node)
537{ 534{
538 struct mwifiex_wait_queue *wait_queue = NULL;
539 unsigned long flags; 535 unsigned long flags;
540 536
541 if (cmd_node == NULL) 537 if (!cmd_node)
542 return; 538 return;
543 if (cmd_node->wq_buf) { 539
544 wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; 540 if (cmd_node->wait_q_enabled)
545 if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR) 541 mwifiex_complete_cmd(adapter);
546 mwifiex_ioctl_complete(adapter, wait_queue, -1);
547 else
548 mwifiex_ioctl_complete(adapter, wait_queue, 0);
549 }
550 /* Clean the node */ 542 /* Clean the node */
551 mwifiex_clean_cmd_node(adapter, cmd_node); 543 mwifiex_clean_cmd_node(adapter, cmd_node);
552 544
@@ -554,8 +546,6 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
554 spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); 546 spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
555 list_add_tail(&cmd_node->list, &adapter->cmd_free_q); 547 list_add_tail(&cmd_node->list, &adapter->cmd_free_q);
556 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); 548 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
557
558 return;
559} 549}
560 550
561/* 551/*
@@ -600,8 +590,6 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
600 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); 590 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
601 591
602 dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); 592 dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command);
603
604 return;
605} 593}
606 594
607/* 595/*
@@ -692,7 +680,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
692 uint16_t orig_cmdresp_no; 680 uint16_t orig_cmdresp_no;
693 uint16_t cmdresp_no; 681 uint16_t cmdresp_no;
694 uint16_t cmdresp_result; 682 uint16_t cmdresp_result;
695 struct mwifiex_wait_queue *wait_queue = NULL;
696 struct timeval tstamp; 683 struct timeval tstamp;
697 unsigned long flags; 684 unsigned long flags;
698 685
@@ -706,10 +693,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
706 return -1; 693 return -1;
707 } 694 }
708 695
709 if (adapter->curr_cmd->wq_buf)
710 wait_queue = (struct mwifiex_wait_queue *)
711 adapter->curr_cmd->wq_buf;
712
713 adapter->num_cmd_timeout = 0; 696 adapter->num_cmd_timeout = 0;
714 697
715 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; 698 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
@@ -764,8 +747,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
764 747
765 if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { 748 if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
766 dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); 749 dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
767 if (wait_queue) 750 if (adapter->curr_cmd->wait_q_enabled)
768 wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP; 751 adapter->cmd_wait_q.status = -1;
769 752
770 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 753 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
771 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 754 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
@@ -781,8 +764,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
781 ret = mwifiex_ret_802_11_hs_cfg(priv, resp); 764 ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
782 } else { 765 } else {
783 /* handle response */ 766 /* handle response */
784 ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp, 767 ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp);
785 wait_queue);
786 } 768 }
787 769
788 /* Check init command response */ 770 /* Check init command response */
@@ -797,10 +779,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
797 } 779 }
798 780
799 if (adapter->curr_cmd) { 781 if (adapter->curr_cmd) {
800 if (wait_queue && (!ret)) 782 if (adapter->curr_cmd->wait_q_enabled && (!ret))
801 wait_queue->status = MWIFIEX_ERROR_NO_ERROR; 783 adapter->cmd_wait_q.status = 0;
802 else if (wait_queue && (ret == -1)) 784 else if (adapter->curr_cmd->wait_q_enabled && (ret == -1))
803 wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL; 785 adapter->cmd_wait_q.status = -1;
804 786
805 /* Clean up and put current command back to cmd_free_q */ 787 /* Clean up and put current command back to cmd_free_q */
806 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); 788 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
@@ -824,7 +806,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
824 struct mwifiex_adapter *adapter = 806 struct mwifiex_adapter *adapter =
825 (struct mwifiex_adapter *) function_context; 807 (struct mwifiex_adapter *) function_context;
826 struct cmd_ctrl_node *cmd_node = NULL; 808 struct cmd_ctrl_node *cmd_node = NULL;
827 struct mwifiex_wait_queue *wait_queue = NULL;
828 struct timeval tstamp; 809 struct timeval tstamp;
829 810
830 adapter->num_cmd_timeout++; 811 adapter->num_cmd_timeout++;
@@ -834,10 +815,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
834 return; 815 return;
835 } 816 }
836 cmd_node = adapter->curr_cmd; 817 cmd_node = adapter->curr_cmd;
837 if (cmd_node->wq_buf) { 818 if (cmd_node->wait_q_enabled)
838 wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; 819 adapter->cmd_wait_q.status = -ETIMEDOUT;
839 wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT;
840 }
841 820
842 if (cmd_node) { 821 if (cmd_node) {
843 adapter->dbg.timeout_cmd_id = 822 adapter->dbg.timeout_cmd_id =
@@ -886,8 +865,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
886 } 865 }
887 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 866 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
888 mwifiex_init_fw_complete(adapter); 867 mwifiex_init_fw_complete(adapter);
889
890 return;
891} 868}
892 869
893/* 870/*
@@ -901,18 +878,15 @@ void
901mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) 878mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
902{ 879{
903 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 880 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
904 struct mwifiex_wait_queue *wait_queue = NULL;
905 unsigned long flags; 881 unsigned long flags;
906 882
907 /* Cancel current cmd */ 883 /* Cancel current cmd */
908 if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) { 884 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
909 wait_queue =
910 (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf;
911 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 885 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
912 adapter->curr_cmd->wq_buf = NULL; 886 adapter->curr_cmd->wait_q_enabled = false;
913 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 887 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
914 wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; 888 adapter->cmd_wait_q.status = -1;
915 mwifiex_ioctl_complete(adapter, wait_queue, -1); 889 mwifiex_complete_cmd(adapter);
916 } 890 }
917 /* Cancel all pending command */ 891 /* Cancel all pending command */
918 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); 892 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
@@ -921,12 +895,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
921 list_del(&cmd_node->list); 895 list_del(&cmd_node->list);
922 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); 896 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
923 897
924 if (cmd_node->wq_buf) { 898 if (cmd_node->wait_q_enabled) {
925 wait_queue = 899 adapter->cmd_wait_q.status = -1;
926 (struct mwifiex_wait_queue *) cmd_node->wq_buf; 900 mwifiex_complete_cmd(adapter);
927 wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; 901 cmd_node->wait_q_enabled = false;
928 mwifiex_ioctl_complete(adapter, wait_queue, -1);
929 cmd_node->wq_buf = NULL;
930 } 902 }
931 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 903 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
932 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); 904 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
@@ -940,7 +912,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
940 list_del(&cmd_node->list); 912 list_del(&cmd_node->list);
941 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 913 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
942 914
943 cmd_node->wq_buf = NULL; 915 cmd_node->wait_q_enabled = false;
944 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 916 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
945 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 917 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
946 } 918 }
@@ -962,8 +934,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
962 * are cancelled. 934 * are cancelled.
963 */ 935 */
964void 936void
965mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, 937mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
966 struct mwifiex_wait_queue *wait_queue)
967{ 938{
968 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 939 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
969 unsigned long cmd_flags; 940 unsigned long cmd_flags;
@@ -972,45 +943,33 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
972 uint16_t cancel_scan_cmd = false; 943 uint16_t cancel_scan_cmd = false;
973 944
974 if ((adapter->curr_cmd) && 945 if ((adapter->curr_cmd) &&
975 (adapter->curr_cmd->wq_buf == wait_queue)) { 946 (adapter->curr_cmd->wait_q_enabled)) {
976 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); 947 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
977 cmd_node = adapter->curr_cmd; 948 cmd_node = adapter->curr_cmd;
978 cmd_node->wq_buf = NULL; 949 cmd_node->wait_q_enabled = false;
979 cmd_node->cmd_flag |= CMD_F_CANCELED; 950 cmd_node->cmd_flag |= CMD_F_CANCELED;
980 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
981 }
982
983 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
984 while (1) {
985 cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue);
986 if (!cmd_node)
987 break;
988
989 spin_lock_irqsave(&adapter->cmd_pending_q_lock, 951 spin_lock_irqsave(&adapter->cmd_pending_q_lock,
990 cmd_pending_q_flags); 952 cmd_pending_q_flags);
991 list_del(&cmd_node->list); 953 list_del(&cmd_node->list);
992 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, 954 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
993 cmd_pending_q_flags); 955 cmd_pending_q_flags);
994
995 cmd_node->wq_buf = NULL;
996 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 956 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
957 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
997 } 958 }
998 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 959
999 /* Cancel all pending scan command */ 960 /* Cancel all pending scan command */
1000 spin_lock_irqsave(&adapter->scan_pending_q_lock, 961 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1001 scan_pending_q_flags); 962 scan_pending_q_flags);
1002 list_for_each_entry_safe(cmd_node, tmp_node, 963 list_for_each_entry_safe(cmd_node, tmp_node,
1003 &adapter->scan_pending_q, list) { 964 &adapter->scan_pending_q, list) {
1004 if (cmd_node->wq_buf == wait_queue) { 965 list_del(&cmd_node->list);
1005 list_del(&cmd_node->list); 966 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1006 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 967 scan_pending_q_flags);
1007 scan_pending_q_flags); 968 cmd_node->wait_q_enabled = false;
1008 cmd_node->wq_buf = NULL; 969 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1009 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 970 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1010 spin_lock_irqsave(&adapter->scan_pending_q_lock, 971 scan_pending_q_flags);
1011 scan_pending_q_flags); 972 cancel_scan_cmd = true;
1012 cancel_scan_cmd = true;
1013 }
1014 } 973 }
1015 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 974 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1016 scan_pending_q_flags); 975 scan_pending_q_flags);
@@ -1020,10 +979,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
1020 adapter->scan_processing = false; 979 adapter->scan_processing = false;
1021 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 980 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1022 } 981 }
1023 wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; 982 adapter->cmd_wait_q.status = -1;
1024 mwifiex_ioctl_complete(adapter, wait_queue, -1); 983 mwifiex_complete_cmd(adapter);
1025
1026 return;
1027} 984}
1028 985
1029/* 986/*
@@ -1127,7 +1084,6 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
1127 adapter->is_hs_configured = false; 1084 adapter->is_hs_configured = false;
1128 mwifiex_hs_activated_event(mwifiex_get_priv(adapter, 1085 mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
1129 MWIFIEX_BSS_ROLE_ANY), false); 1086 MWIFIEX_BSS_ROLE_ANY), false);
1130 return;
1131} 1087}
1132 1088
1133/* 1089/*
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 63b09692f27d..7ddcb062f103 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -129,8 +129,8 @@ static struct mwifiex_debug_data items[] = {
129 item_addr(event_received), 1}, 129 item_addr(event_received), 1},
130 130
131 /* variables defined in struct mwifiex_adapter */ 131 /* variables defined in struct mwifiex_adapter */
132 {"ioctl_pending", adapter_item_size(ioctl_pending), 132 {"cmd_pending", adapter_item_size(cmd_pending),
133 adapter_item_addr(ioctl_pending), 1}, 133 adapter_item_addr(cmd_pending), 1},
134 {"tx_pending", adapter_item_size(tx_pending), 134 {"tx_pending", adapter_item_size(tx_pending),
135 adapter_item_addr(tx_pending), 1}, 135 adapter_item_addr(tx_pending), 1},
136 {"rx_pending", adapter_item_size(rx_pending), 136 {"rx_pending", adapter_item_size(rx_pending),
@@ -735,8 +735,6 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
735 MWIFIEX_DFS_ADD_FILE(getlog); 735 MWIFIEX_DFS_ADD_FILE(getlog);
736 MWIFIEX_DFS_ADD_FILE(regrdwr); 736 MWIFIEX_DFS_ADD_FILE(regrdwr);
737 MWIFIEX_DFS_ADD_FILE(rdeeprom); 737 MWIFIEX_DFS_ADD_FILE(rdeeprom);
738
739 return;
740} 738}
741 739
742/* 740/*
@@ -749,7 +747,6 @@ mwifiex_dev_debugfs_remove(struct mwifiex_private *priv)
749 return; 747 return;
750 748
751 debugfs_remove_recursive(priv->dfs_dev_dir); 749 debugfs_remove_recursive(priv->dfs_dev_dir);
752 return;
753} 750}
754 751
755/* 752/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index c3c15f9e757e..8364b62c3298 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -61,23 +61,6 @@
61 61
62#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) 62#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0)
63 63
64enum mwifiex_error_code {
65 MWIFIEX_ERROR_NO_ERROR = 0,
66 MWIFIEX_ERROR_FW_NOT_READY = 0x00000001,
67 MWIFIEX_ERROR_FW_BUSY,
68 MWIFIEX_ERROR_FW_CMDRESP,
69 MWIFIEX_ERROR_PKT_SIZE_INVALID = 0x80000001,
70 MWIFIEX_ERROR_PKT_TIMEOUT,
71 MWIFIEX_ERROR_CMD_INVALID,
72 MWIFIEX_ERROR_CMD_TIMEOUT,
73 MWIFIEX_ERROR_CMD_DNLD_FAIL,
74 MWIFIEX_ERROR_CMD_CANCEL,
75 MWIFIEX_ERROR_CMD_RESP_FAIL,
76 MWIFIEX_ERROR_ASSOC_FAIL,
77 MWIFIEX_ERROR_EVENT_UNKNOWN,
78 MWIFIEX_ERROR_INVALID_PARAMETER,
79};
80
81enum mwifiex_bss_type { 64enum mwifiex_bss_type {
82 MWIFIEX_BSS_TYPE_STA = 0, 65 MWIFIEX_BSS_TYPE_STA = 0,
83 MWIFIEX_BSS_TYPE_UAP = 1, 66 MWIFIEX_BSS_TYPE_UAP = 1,
@@ -112,12 +95,9 @@ struct mwifiex_802_11_ssid {
112}; 95};
113 96
114struct mwifiex_wait_queue { 97struct mwifiex_wait_queue {
115 u32 bss_index; 98 wait_queue_head_t wait;
116 wait_queue_head_t *wait; 99 u16 condition;
117 u16 *condition;
118 u32 start_time;
119 int status; 100 int status;
120 u32 enabled;
121}; 101};
122 102
123struct mwifiex_rxinfo { 103struct mwifiex_rxinfo {
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 2b938115b26a..f8c008f8f476 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -72,33 +72,12 @@ enum KEY_TYPE_ID {
72 KEY_TYPE_ID_AES, 72 KEY_TYPE_ID_AES,
73 KEY_TYPE_ID_WAPI, 73 KEY_TYPE_ID_WAPI,
74}; 74};
75 75#define KEY_MCAST BIT(0)
76enum KEY_INFO_WEP { 76#define KEY_UNICAST BIT(1)
77 KEY_INFO_WEP_MCAST = 0x01, 77#define KEY_ENABLED BIT(2)
78 KEY_INFO_WEP_UNICAST = 0x02,
79 KEY_INFO_WEP_ENABLED = 0x04
80};
81
82enum KEY_INFO_TKIP {
83 KEY_INFO_TKIP_MCAST = 0x01,
84 KEY_INFO_TKIP_UNICAST = 0x02,
85 KEY_INFO_TKIP_ENABLED = 0x04
86};
87
88enum KEY_INFO_AES {
89 KEY_INFO_AES_MCAST = 0x01,
90 KEY_INFO_AES_UNICAST = 0x02,
91 KEY_INFO_AES_ENABLED = 0x04
92};
93 78
94#define WAPI_KEY_LEN 50 79#define WAPI_KEY_LEN 50
95 80
96enum KEY_INFO_WAPI {
97 KEY_INFO_WAPI_MCAST = 0x01,
98 KEY_INFO_WAPI_UNICAST = 0x02,
99 KEY_INFO_WAPI_ENABLED = 0x04
100};
101
102#define MAX_POLL_TRIES 100 81#define MAX_POLL_TRIES 100
103 82
104#define MAX_MULTI_INTERFACE_POLL_TRIES 1000 83#define MAX_MULTI_INTERFACE_POLL_TRIES 1000
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 8189862da1f9..1b79a5ac9214 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -35,7 +35,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
35{ 35{
36 struct mwifiex_adapter *adapter = priv->adapter; 36 struct mwifiex_adapter *adapter = priv->adapter;
37 struct mwifiex_bss_prio_node *bss_prio; 37 struct mwifiex_bss_prio_node *bss_prio;
38 int status = 0;
39 unsigned long flags; 38 unsigned long flags;
40 39
41 bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); 40 bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
@@ -59,7 +58,7 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
59 spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] 58 spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
60 .bss_prio_lock, flags); 59 .bss_prio_lock, flags);
61 60
62 return status; 61 return 0;
63} 62}
64 63
65/* 64/*
@@ -300,8 +299,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
300 adapter->adhoc_awake_period = 0; 299 adapter->adhoc_awake_period = 0;
301 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 300 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
302 adapter->arp_filter_size = 0; 301 adapter->arp_filter_size = 0;
303
304 return;
305} 302}
306 303
307/* 304/*
@@ -340,8 +337,6 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
340 adapter->if_ops.cleanup_if(adapter); 337 adapter->if_ops.cleanup_if(adapter);
341 338
342 dev_kfree_skb_any(adapter->sleep_cfm); 339 dev_kfree_skb_any(adapter->sleep_cfm);
343
344 return;
345} 340}
346 341
347/* 342/*
@@ -429,8 +424,6 @@ void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
429 list_del(&priv->rx_reorder_tbl_ptr); 424 list_del(&priv->rx_reorder_tbl_ptr);
430 } 425 }
431 } 426 }
432
433 return;
434} 427}
435 428
436/* 429/*
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 7a9e0b5962ed..60d25c690c07 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -590,11 +590,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
590 * an association success (0) or failure (non-zero). 590 * an association success (0) or failure (non-zero).
591 */ 591 */
592int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, 592int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
593 struct host_cmd_ds_command *resp, void *wq_buf) 593 struct host_cmd_ds_command *resp)
594{ 594{
595 struct mwifiex_adapter *adapter = priv->adapter;
595 int ret = 0; 596 int ret = 0;
596 struct mwifiex_wait_queue *wait_queue =
597 (struct mwifiex_wait_queue *) wq_buf;
598 struct ieee_types_assoc_rsp *assoc_rsp; 597 struct ieee_types_assoc_rsp *assoc_rsp;
599 struct mwifiex_bssdescriptor *bss_desc; 598 struct mwifiex_bssdescriptor *bss_desc;
600 u8 enable_data = true; 599 u8 enable_data = true;
@@ -718,16 +717,11 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
718 717
719done: 718done:
720 /* Need to indicate IOCTL complete */ 719 /* Need to indicate IOCTL complete */
721 if (wait_queue) { 720 if (adapter->curr_cmd->wait_q_enabled) {
722 if (ret) { 721 if (ret)
723 if (assoc_rsp->status_code) 722 adapter->cmd_wait_q.status = -1;
724 wait_queue->status = 723 else
725 le16_to_cpu(assoc_rsp->status_code); 724 adapter->cmd_wait_q.status = 0;
726 else
727 wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL;
728 } else {
729 wait_queue->status = MWIFIEX_ERROR_NO_ERROR;
730 }
731 } 725 }
732 726
733 return ret; 727 return ret;
@@ -885,9 +879,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
885 mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); 879 mwifiex_get_active_data_rates(priv, adhoc_start->DataRate);
886 if ((adapter->adhoc_start_band & BAND_G) && 880 if ((adapter->adhoc_start_band & BAND_G) &&
887 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { 881 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
888 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, 882 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
889 HostCmd_ACT_GEN_SET, 883 HostCmd_ACT_GEN_SET, 0,
890 0, NULL, &priv->curr_pkt_filter); 884 &priv->curr_pkt_filter);
891 885
892 if (ret) { 886 if (ret) {
893 dev_err(adapter->dev, 887 dev_err(adapter->dev,
@@ -1066,9 +1060,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1066 priv-> 1060 priv->
1067 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; 1061 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1068 1062
1069 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, 1063 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
1070 HostCmd_ACT_GEN_SET, 0, NULL, 1064 HostCmd_ACT_GEN_SET, 0,
1071 &curr_pkt_filter); 1065 &curr_pkt_filter);
1072 if (ret) { 1066 if (ret) {
1073 dev_err(priv->adapter->dev, 1067 dev_err(priv->adapter->dev,
1074 "ADHOC_J_CMD: G Protection config failed\n"); 1068 "ADHOC_J_CMD: G Protection config failed\n");
@@ -1192,11 +1186,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1192 * saves the beacon buffer. 1186 * saves the beacon buffer.
1193 */ 1187 */
1194int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, 1188int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1195 struct host_cmd_ds_command *resp, void *wq_buf) 1189 struct host_cmd_ds_command *resp)
1196{ 1190{
1197 int ret = 0; 1191 int ret = 0;
1198 struct mwifiex_wait_queue *wait_queue = 1192 struct mwifiex_adapter *adapter = priv->adapter;
1199 (struct mwifiex_wait_queue *) wq_buf;
1200 struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; 1193 struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
1201 struct mwifiex_bssdescriptor *bss_desc; 1194 struct mwifiex_bssdescriptor *bss_desc;
1202 u16 command = le16_to_cpu(resp->command); 1195 u16 command = le16_to_cpu(resp->command);
@@ -1264,11 +1257,11 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1264 1257
1265done: 1258done:
1266 /* Need to indicate IOCTL complete */ 1259 /* Need to indicate IOCTL complete */
1267 if (wait_queue) { 1260 if (adapter->curr_cmd->wait_q_enabled) {
1268 if (ret) 1261 if (ret)
1269 wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; 1262 adapter->cmd_wait_q.status = -1;
1270 else 1263 else
1271 wait_queue->status = MWIFIEX_ERROR_NO_ERROR; 1264 adapter->cmd_wait_q.status = 0;
1272 1265
1273 } 1266 }
1274 1267
@@ -1283,7 +1276,7 @@ done:
1283 * command to firmware. 1276 * command to firmware.
1284 */ 1277 */
1285int mwifiex_associate(struct mwifiex_private *priv, 1278int mwifiex_associate(struct mwifiex_private *priv,
1286 void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) 1279 struct mwifiex_bssdescriptor *bss_desc)
1287{ 1280{
1288 int ret = 0; 1281 int ret = 0;
1289 u8 current_bssid[ETH_ALEN]; 1282 u8 current_bssid[ETH_ALEN];
@@ -1301,9 +1294,8 @@ int mwifiex_associate(struct mwifiex_private *priv,
1301 retrieval */ 1294 retrieval */
1302 priv->assoc_rsp_size = 0; 1295 priv->assoc_rsp_size = 0;
1303 1296
1304 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE, 1297 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE,
1305 HostCmd_ACT_GEN_SET, 0, wait_queue, 1298 HostCmd_ACT_GEN_SET, 0, bss_desc);
1306 bss_desc);
1307 1299
1308 return ret; 1300 return ret;
1309} 1301}
@@ -1315,7 +1307,7 @@ int mwifiex_associate(struct mwifiex_private *priv,
1315 */ 1307 */
1316int 1308int
1317mwifiex_adhoc_start(struct mwifiex_private *priv, 1309mwifiex_adhoc_start(struct mwifiex_private *priv,
1318 void *wait_queue, struct mwifiex_802_11_ssid *adhoc_ssid) 1310 struct mwifiex_802_11_ssid *adhoc_ssid)
1319{ 1311{
1320 int ret = 0; 1312 int ret = 0;
1321 1313
@@ -1326,9 +1318,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv,
1326 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", 1318 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
1327 priv->curr_bss_params.band); 1319 priv->curr_bss_params.band);
1328 1320
1329 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START, 1321 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START,
1330 HostCmd_ACT_GEN_SET, 0, wait_queue, 1322 HostCmd_ACT_GEN_SET, 0, adhoc_ssid);
1331 adhoc_ssid);
1332 1323
1333 return ret; 1324 return ret;
1334} 1325}
@@ -1340,7 +1331,7 @@ mwifiex_adhoc_start(struct mwifiex_private *priv,
1340 * if already not connected to the requested SSID. 1331 * if already not connected to the requested SSID.
1341 */ 1332 */
1342int mwifiex_adhoc_join(struct mwifiex_private *priv, 1333int mwifiex_adhoc_join(struct mwifiex_private *priv,
1343 void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) 1334 struct mwifiex_bssdescriptor *bss_desc)
1344{ 1335{
1345 int ret = 0; 1336 int ret = 0;
1346 1337
@@ -1369,9 +1360,8 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
1369 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", 1360 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
1370 priv->curr_bss_params.band); 1361 priv->curr_bss_params.band);
1371 1362
1372 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, 1363 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1373 HostCmd_ACT_GEN_SET, 0, wait_queue, 1364 HostCmd_ACT_GEN_SET, 0, bss_desc);
1374 bss_desc);
1375 1365
1376 return ret; 1366 return ret;
1377} 1367}
@@ -1380,9 +1370,7 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
1380 * This function deauthenticates/disconnects from infra network by sending 1370 * This function deauthenticates/disconnects from infra network by sending
1381 * deauthentication request. 1371 * deauthentication request.
1382 */ 1372 */
1383static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, 1373static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1384 struct mwifiex_wait_queue *wait,
1385 u8 *mac)
1386{ 1374{
1387 u8 mac_address[ETH_ALEN]; 1375 u8 mac_address[ETH_ALEN];
1388 int ret = 0; 1376 int ret = 0;
@@ -1400,11 +1388,8 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv,
1400 bss_descriptor.mac_address, ETH_ALEN); 1388 bss_descriptor.mac_address, ETH_ALEN);
1401 } 1389 }
1402 1390
1403 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, 1391 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1404 HostCmd_ACT_GEN_SET, 0, wait, &mac_address); 1392 HostCmd_ACT_GEN_SET, 0, &mac_address);
1405
1406 if (!ret && wait)
1407 ret = -EINPROGRESS;
1408 1393
1409 return ret; 1394 return ret;
1410} 1395}
@@ -1415,26 +1400,23 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv,
1415 * In case of infra made, it sends deauthentication request, and 1400 * In case of infra made, it sends deauthentication request, and
1416 * in case of ad-hoc mode, a stop network request is sent to the firmware. 1401 * in case of ad-hoc mode, a stop network request is sent to the firmware.
1417 */ 1402 */
1418int mwifiex_deauthenticate(struct mwifiex_private *priv, 1403int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1419 struct mwifiex_wait_queue *wait, u8 *mac)
1420{ 1404{
1421 int ret = 0; 1405 int ret = 0;
1422 1406
1423 if (priv->media_connected) { 1407 if (priv->media_connected) {
1424 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 1408 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
1425 ret = mwifiex_deauthenticate_infra(priv, wait, mac); 1409 ret = mwifiex_deauthenticate_infra(priv, mac);
1426 } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 1410 } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
1427 ret = mwifiex_prepare_cmd(priv, 1411 ret = mwifiex_send_cmd_sync(priv,
1428 HostCmd_CMD_802_11_AD_HOC_STOP, 1412 HostCmd_CMD_802_11_AD_HOC_STOP,
1429 HostCmd_ACT_GEN_SET, 0, wait, NULL); 1413 HostCmd_ACT_GEN_SET, 0, NULL);
1430
1431 if (!ret && wait)
1432 ret = -EINPROGRESS;
1433 } 1414 }
1434 } 1415 }
1435 1416
1436 return ret; 1417 return ret;
1437} 1418}
1419EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
1438 1420
1439/* 1421/*
1440 * This function converts band to radio type used in channel TLV. 1422 * This function converts band to radio type used in channel TLV.
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index ed89ca41a902..77abfc3d6c32 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -505,7 +505,6 @@ mwifiex_fill_buffer(struct sk_buff *skb)
505 */ 505 */
506 do_gettimeofday(&tv); 506 do_gettimeofday(&tv);
507 skb->tstamp = timeval_to_ktime(tv); 507 skb->tstamp = timeval_to_ktime(tv);
508 return;
509} 508}
510 509
511/* 510/*
@@ -597,16 +596,23 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
597{ 596{
598 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 597 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
599 struct sockaddr *hw_addr = (struct sockaddr *) addr; 598 struct sockaddr *hw_addr = (struct sockaddr *) addr;
599 int ret = 0;
600 600
601 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); 601 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
602 602
603 if (mwifiex_request_set_mac_address(priv)) { 603 /* Send request to firmware */
604 dev_err(priv->adapter->dev, "set MAC address failed\n"); 604 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
605 return -EFAULT; 605 HostCmd_ACT_GEN_SET, 0, NULL);
606 } 606
607 if (!ret)
608 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
609 else
610 dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
611 "\n", ret);
612
607 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); 613 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
608 614
609 return 0; 615 return ret;
610} 616}
611 617
612/* 618/*
@@ -615,7 +621,20 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
615static void mwifiex_set_multicast_list(struct net_device *dev) 621static void mwifiex_set_multicast_list(struct net_device *dev)
616{ 622{
617 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 623 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
618 mwifiex_request_set_multicast_list(priv, dev); 624 struct mwifiex_multicast_list mcast_list;
625
626 if (dev->flags & IFF_PROMISC) {
627 mcast_list.mode = MWIFIEX_PROMISC_MODE;
628 } else if (dev->flags & IFF_ALLMULTI ||
629 netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
630 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
631 } else {
632 mcast_list.mode = MWIFIEX_MULTICAST_MODE;
633 if (netdev_mc_count(dev))
634 mcast_list.num_multicast_addr =
635 mwifiex_copy_mcast_addr(&mcast_list, dev);
636 }
637 mwifiex_request_set_multicast_list(priv, &mcast_list);
619} 638}
620 639
621/* 640/*
@@ -677,9 +696,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
677{ 696{
678 dev->netdev_ops = &mwifiex_netdev_ops; 697 dev->netdev_ops = &mwifiex_netdev_ops;
679 /* Initialize private structure */ 698 /* Initialize private structure */
680 init_waitqueue_head(&priv->ioctl_wait_q);
681 init_waitqueue_head(&priv->cmd_wait_q);
682 init_waitqueue_head(&priv->w_stats_wait_q);
683 priv->current_key_index = 0; 699 priv->current_key_index = 0;
684 priv->media_connected = false; 700 priv->media_connected = false;
685 memset(&priv->nick_name, 0, sizeof(priv->nick_name)); 701 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
@@ -803,35 +819,7 @@ mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
803 wiphy_unregister(priv->wdev->wiphy); 819 wiphy_unregister(priv->wdev->wiphy);
804 wiphy_free(priv->wdev->wiphy); 820 wiphy_free(priv->wdev->wiphy);
805 kfree(priv->wdev); 821 kfree(priv->wdev);
806
807 return;
808}
809
810/*
811 * Sends IOCTL request to shutdown firmware.
812 *
813 * This function allocates the IOCTL request buffer, fills it
814 * with requisite parameters and calls the IOCTL handler.
815 */
816int mwifiex_shutdown_fw(struct mwifiex_private *priv, u8 wait_option)
817{
818 struct mwifiex_wait_queue *wait = NULL;
819 int status = 0;
820
821 /* Allocate an IOCTL request buffer */
822 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
823 if (!wait)
824 return -ENOMEM;
825
826 status = mwifiex_misc_ioctl_init_shutdown(priv->adapter, wait,
827 MWIFIEX_FUNC_SHUTDOWN);
828
829 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
830
831 kfree(wait);
832 return status;
833} 822}
834EXPORT_SYMBOL_GPL(mwifiex_shutdown_fw);
835 823
836/* 824/*
837 * This function check if command is pending. 825 * This function check if command is pending.
@@ -927,6 +915,10 @@ mwifiex_add_card(void *card, struct semaphore *sem,
927 adapter->is_suspended = false; 915 adapter->is_suspended = false;
928 adapter->hs_activated = false; 916 adapter->hs_activated = false;
929 init_waitqueue_head(&adapter->hs_activate_wait_q); 917 init_waitqueue_head(&adapter->hs_activate_wait_q);
918 adapter->cmd_wait_q_required = false;
919 init_waitqueue_head(&adapter->cmd_wait_q.wait);
920 adapter->cmd_wait_q.condition = false;
921 adapter->cmd_wait_q.status = 0;
930 922
931 /* Create workqueue */ 923 /* Create workqueue */
932 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); 924 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
@@ -1038,12 +1030,12 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
1038 dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); 1030 dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
1039 if (atomic_read(&adapter->rx_pending) || 1031 if (atomic_read(&adapter->rx_pending) ||
1040 atomic_read(&adapter->tx_pending) || 1032 atomic_read(&adapter->tx_pending) ||
1041 atomic_read(&adapter->ioctl_pending)) { 1033 atomic_read(&adapter->cmd_pending)) {
1042 dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " 1034 dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
1043 "ioctl_pending=%d\n", 1035 "cmd_pending=%d\n",
1044 atomic_read(&adapter->rx_pending), 1036 atomic_read(&adapter->rx_pending),
1045 atomic_read(&adapter->tx_pending), 1037 atomic_read(&adapter->tx_pending),
1046 atomic_read(&adapter->ioctl_pending)); 1038 atomic_read(&adapter->cmd_pending));
1047 } 1039 }
1048 1040
1049 /* Remove interface */ 1041 /* Remove interface */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 43ff149de9db..2d296dcc210e 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -42,11 +42,8 @@ extern const char driver_version[];
42extern struct mwifiex_adapter *g_adapter; 42extern struct mwifiex_adapter *g_adapter;
43 43
44enum { 44enum {
45 MWIFIEX_NO_WAIT, 45 MWIFIEX_ASYNC_CMD,
46 MWIFIEX_IOCTL_WAIT, 46 MWIFIEX_SYNC_CMD
47 MWIFIEX_CMD_WAIT,
48 MWIFIEX_PROC_WAIT,
49 MWIFIEX_WSTATS_WAIT
50}; 47};
51 48
52#define DRV_MODE_STA 0x1 49#define DRV_MODE_STA 0x1
@@ -468,10 +465,6 @@ struct mwifiex_private {
468 u32 curr_bcn_size; 465 u32 curr_bcn_size;
469 /* spin lock for beacon buffer */ 466 /* spin lock for beacon buffer */
470 spinlock_t curr_bcn_buf_lock; 467 spinlock_t curr_bcn_buf_lock;
471 u16 ioctl_wait_q_woken;
472 wait_queue_head_t ioctl_wait_q;
473 u16 cmd_wait_q_woken;
474 wait_queue_head_t cmd_wait_q;
475 struct wireless_dev *wdev; 468 struct wireless_dev *wdev;
476 struct mwifiex_chan_freq_power cfp; 469 struct mwifiex_chan_freq_power cfp;
477 char version_str[128]; 470 char version_str[128];
@@ -480,8 +473,6 @@ struct mwifiex_private {
480#endif 473#endif
481 u8 nick_name[16]; 474 u8 nick_name[16];
482 struct iw_statistics w_stats; 475 struct iw_statistics w_stats;
483 u16 w_stats_wait_q_woken;
484 wait_queue_head_t w_stats_wait_q;
485 u16 current_key_index; 476 u16 current_key_index;
486 struct semaphore async_sem; 477 struct semaphore async_sem;
487 u8 scan_pending_on_block; 478 u8 scan_pending_on_block;
@@ -552,7 +543,7 @@ struct cmd_ctrl_node {
552 struct sk_buff *cmd_skb; 543 struct sk_buff *cmd_skb;
553 struct sk_buff *resp_skb; 544 struct sk_buff *resp_skb;
554 void *data_buf; 545 void *data_buf;
555 void *wq_buf; 546 u32 wait_q_enabled;
556 struct sk_buff *skb; 547 struct sk_buff *skb;
557}; 548};
558 549
@@ -590,7 +581,7 @@ struct mwifiex_adapter {
590 struct mwifiex_if_ops if_ops; 581 struct mwifiex_if_ops if_ops;
591 atomic_t rx_pending; 582 atomic_t rx_pending;
592 atomic_t tx_pending; 583 atomic_t tx_pending;
593 atomic_t ioctl_pending; 584 atomic_t cmd_pending;
594 struct workqueue_struct *workqueue; 585 struct workqueue_struct *workqueue;
595 struct work_struct main_work; 586 struct work_struct main_work;
596 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; 587 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
@@ -684,6 +675,8 @@ struct mwifiex_adapter {
684 struct mwifiex_dbg dbg; 675 struct mwifiex_dbg dbg;
685 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; 676 u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
686 u32 arp_filter_size; 677 u32 arp_filter_size;
678 u16 cmd_wait_q_required;
679 struct mwifiex_wait_queue cmd_wait_q;
687}; 680};
688 681
689int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 682int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -707,29 +700,23 @@ int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
707 700
708int mwifiex_process_event(struct mwifiex_adapter *adapter); 701int mwifiex_process_event(struct mwifiex_adapter *adapter);
709 702
710int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, 703int mwifiex_complete_cmd(struct mwifiex_adapter *adapter);
711 struct mwifiex_wait_queue *ioctl_wq,
712 int status);
713 704
714int mwifiex_prepare_cmd(struct mwifiex_private *priv, 705int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
715 uint16_t cmd_no, 706 u16 cmd_action, u32 cmd_oid, void *data_buf);
716 u16 cmd_action, 707
717 u32 cmd_oid, 708int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
718 void *wait_queue, void *data_buf); 709 u16 cmd_action, u32 cmd_oid, void *data_buf);
719 710
720void mwifiex_cmd_timeout_func(unsigned long function_context); 711void mwifiex_cmd_timeout_func(unsigned long function_context);
721 712
722int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter,
723 struct mwifiex_wait_queue *wait_queue,
724 u32 func_init_shutdown);
725int mwifiex_get_debug_info(struct mwifiex_private *, 713int mwifiex_get_debug_info(struct mwifiex_private *,
726 struct mwifiex_debug_info *); 714 struct mwifiex_debug_info *);
727 715
728int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); 716int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter);
729int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); 717int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter);
730void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); 718void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter);
731void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, 719void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter);
732 struct mwifiex_wait_queue *ioctl_wq);
733 720
734void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, 721void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
735 struct cmd_ctrl_node *cmd_node); 722 struct cmd_ctrl_node *cmd_node);
@@ -772,24 +759,20 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no,
772 u16 cmd_action, u32 cmd_oid, 759 u16 cmd_action, u32 cmd_oid,
773 void *data_buf, void *cmd_buf); 760 void *data_buf, void *cmd_buf);
774int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, 761int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
775 void *cmd_buf, void *ioctl); 762 void *cmd_buf);
776int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, 763int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
777 struct sk_buff *skb); 764 struct sk_buff *skb);
778int mwifiex_process_sta_event(struct mwifiex_private *); 765int mwifiex_process_sta_event(struct mwifiex_private *);
779void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); 766void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
780int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); 767int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
781int mwifiex_scan_networks(struct mwifiex_private *priv, void *wait_queue, 768int mwifiex_scan_networks(struct mwifiex_private *priv,
782 u16 action, 769 const struct mwifiex_user_scan_cfg *user_scan_in);
783 const struct mwifiex_user_scan_cfg 770int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
784 *user_scan_in, struct mwifiex_scan_resp *);
785int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv,
786 struct host_cmd_ds_command *cmd,
787 void *data_buf); 771 void *data_buf);
788void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, 772void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
789 struct cmd_ctrl_node *cmd_node); 773 struct cmd_ctrl_node *cmd_node);
790int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, 774int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
791 struct host_cmd_ds_command *resp, 775 struct host_cmd_ds_command *resp);
792 void *wait_queue);
793s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, 776s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
794 struct mwifiex_802_11_ssid *ssid, u8 *bssid, 777 struct mwifiex_802_11_ssid *ssid, u8 *bssid,
795 u32 mode); 778 u32 mode);
@@ -799,23 +782,20 @@ int mwifiex_find_best_network(struct mwifiex_private *priv,
799 struct mwifiex_ssid_bssid *req_ssid_bssid); 782 struct mwifiex_ssid_bssid *req_ssid_bssid);
800s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, 783s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
801 struct mwifiex_802_11_ssid *ssid2); 784 struct mwifiex_802_11_ssid *ssid2);
802int mwifiex_associate(struct mwifiex_private *priv, void *wait_queue, 785int mwifiex_associate(struct mwifiex_private *priv,
803 struct mwifiex_bssdescriptor *bss_desc); 786 struct mwifiex_bssdescriptor *bss_desc);
804int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, 787int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
805 struct host_cmd_ds_command 788 struct host_cmd_ds_command
806 *cmd, void *data_buf); 789 *cmd, void *data_buf);
807int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, 790int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
808 struct host_cmd_ds_command *resp, 791 struct host_cmd_ds_command *resp);
809 void *wait_queue);
810void mwifiex_reset_connect_state(struct mwifiex_private *priv); 792void mwifiex_reset_connect_state(struct mwifiex_private *priv);
811void mwifiex_2040_coex_event(struct mwifiex_private *priv); 793void mwifiex_2040_coex_event(struct mwifiex_private *priv);
812u8 mwifiex_band_to_radio_type(u8 band); 794u8 mwifiex_band_to_radio_type(u8 band);
813int mwifiex_deauthenticate(struct mwifiex_private *priv, 795int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
814 struct mwifiex_wait_queue *wait_queue, 796int mwifiex_adhoc_start(struct mwifiex_private *priv,
815 u8 *mac);
816int mwifiex_adhoc_start(struct mwifiex_private *priv, void *wait_queue,
817 struct mwifiex_802_11_ssid *adhoc_ssid); 797 struct mwifiex_802_11_ssid *adhoc_ssid);
818int mwifiex_adhoc_join(struct mwifiex_private *priv, void *wait_queue, 798int mwifiex_adhoc_join(struct mwifiex_private *priv,
819 struct mwifiex_bssdescriptor *bss_desc); 799 struct mwifiex_bssdescriptor *bss_desc);
820int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, 800int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
821 struct host_cmd_ds_command *cmd, 801 struct host_cmd_ds_command *cmd,
@@ -824,11 +804,8 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
824 struct host_cmd_ds_command *cmd, 804 struct host_cmd_ds_command *cmd,
825 void *data_buf); 805 void *data_buf);
826int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, 806int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
827 struct host_cmd_ds_command *resp, 807 struct host_cmd_ds_command *resp);
828 void *wait_queue); 808int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd);
829int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv,
830 struct host_cmd_ds_command *cmd,
831 void *data_buf);
832struct mwifiex_chan_freq_power * 809struct mwifiex_chan_freq_power *
833 mwifiex_get_cfp_by_band_and_channel_from_cfg80211( 810 mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
834 struct mwifiex_private *priv, 811 struct mwifiex_private *priv,
@@ -836,20 +813,16 @@ struct mwifiex_chan_freq_power *
836struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( 813struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
837 struct mwifiex_private *priv, 814 struct mwifiex_private *priv,
838 u8 band, u32 freq); 815 u8 band, u32 freq);
839u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, 816u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info);
840 u8 ht_info);
841u32 mwifiex_find_freq_from_band_chan(u8, u8); 817u32 mwifiex_find_freq_from_band_chan(u8, u8);
842int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, 818int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
843 u8 **buffer); 819 u8 **buffer);
844u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index,
845 u8 ht_info);
846u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, 820u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv,
847 u8 *rates); 821 u8 *rates);
848u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); 822u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates);
849u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate); 823u8 mwifiex_data_rate_to_index(u32 rate);
850u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); 824u8 mwifiex_is_rate_auto(struct mwifiex_private *priv);
851int mwifiex_get_rate_index(struct mwifiex_adapter *adapter, 825int mwifiex_get_rate_index(u16 *rateBitmap, int size);
852 u16 *rateBitmap, int size);
853extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; 826extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE];
854void mwifiex_save_curr_bcn(struct mwifiex_private *priv); 827void mwifiex_save_curr_bcn(struct mwifiex_private *priv);
855void mwifiex_free_curr_bcn(struct mwifiex_private *priv); 828void mwifiex_free_curr_bcn(struct mwifiex_private *priv);
@@ -943,52 +916,34 @@ mwifiex_netdev_get_priv(struct net_device *dev)
943 return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); 916 return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev));
944} 917}
945 918
946struct mwifiex_wait_queue *mwifiex_alloc_fill_wait_queue(
947 struct mwifiex_private *,
948 u8 wait_option);
949struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter 919struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
950 *adapter, u8 bss_index); 920 *adapter, u8 bss_index);
951int mwifiex_shutdown_fw(struct mwifiex_private *, u8); 921int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
952 922 u32 func_init_shutdown);
953int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); 923int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *);
954int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); 924int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
955 925
956void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, 926void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
957 int maxlen); 927 int maxlen);
958int mwifiex_request_set_mac_address(struct mwifiex_private *priv); 928int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
959void mwifiex_request_set_multicast_list(struct mwifiex_private *priv, 929 struct mwifiex_multicast_list *mcast_list);
960 struct net_device *dev); 930int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
961int mwifiex_request_ioctl(struct mwifiex_private *priv, 931 struct net_device *dev);
962 struct mwifiex_wait_queue *req, 932int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
963 int, u8 wait_option);
964int mwifiex_disconnect(struct mwifiex_private *, u8, u8 *);
965int mwifiex_bss_start(struct mwifiex_private *priv, 933int mwifiex_bss_start(struct mwifiex_private *priv,
966 u8 wait_option,
967 struct mwifiex_ssid_bssid *ssid_bssid); 934 struct mwifiex_ssid_bssid *ssid_bssid);
968int mwifiex_set_hs_params(struct mwifiex_private *priv, 935int mwifiex_set_hs_params(struct mwifiex_private *priv,
969 u16 action, u8 wait_option, 936 u16 action, int cmd_type,
970 struct mwifiex_ds_hs_cfg *hscfg); 937 struct mwifiex_ds_hs_cfg *hscfg);
971int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option); 938int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
972int mwifiex_enable_hs(struct mwifiex_adapter *adapter); 939int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
973void mwifiex_process_ioctl_resp(struct mwifiex_private *priv,
974 struct mwifiex_wait_queue *req);
975u32 mwifiex_get_mode(struct mwifiex_private *priv, u8 wait_option);
976int mwifiex_get_signal_info(struct mwifiex_private *priv, 940int mwifiex_get_signal_info(struct mwifiex_private *priv,
977 u8 wait_option,
978 struct mwifiex_ds_get_signal *signal); 941 struct mwifiex_ds_get_signal *signal);
979int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, 942int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
980 struct mwifiex_rate_cfg *rate); 943 struct mwifiex_rate_cfg *rate);
981int mwifiex_get_channel_list(struct mwifiex_private *priv, 944int mwifiex_find_best_bss(struct mwifiex_private *priv,
982 u8 wait_option,
983 struct mwifiex_chan_list *chanlist);
984int mwifiex_get_scan_table(struct mwifiex_private *priv,
985 u8 wait_option,
986 struct mwifiex_scan_resp *scanresp);
987int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option);
988int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option,
989 struct mwifiex_ssid_bssid *ssid_bssid); 945 struct mwifiex_ssid_bssid *ssid_bssid);
990int mwifiex_request_scan(struct mwifiex_private *priv, 946int mwifiex_request_scan(struct mwifiex_private *priv,
991 u8 wait_option,
992 struct mwifiex_802_11_ssid *req_ssid); 947 struct mwifiex_802_11_ssid *req_ssid);
993int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, 948int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
994 struct mwifiex_user_scan_cfg *scan_req); 949 struct mwifiex_user_scan_cfg *scan_req);
@@ -1024,27 +979,22 @@ int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index);
1024 979
1025int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); 980int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index);
1026 981
1027int mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on); 982int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode);
1028 983
1029int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, 984int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter,
1030 char *version, int max_len); 985 char *version, int max_len);
1031 986
1032int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm); 987int mwifiex_set_tx_power(struct mwifiex_private *priv,
988 struct mwifiex_power_cfg *power_cfg);
1033 989
1034int mwifiex_main_process(struct mwifiex_adapter *); 990int mwifiex_main_process(struct mwifiex_adapter *);
1035 991
1036int mwifiex_bss_ioctl_channel(struct mwifiex_private *, 992int mwifiex_bss_set_channel(struct mwifiex_private *,
1037 u16 action, 993 struct mwifiex_chan_freq_power *cfp);
1038 struct mwifiex_chan_freq_power *cfp);
1039int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, 994int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *,
1040 struct mwifiex_wait_queue *,
1041 struct mwifiex_ssid_bssid *); 995 struct mwifiex_ssid_bssid *);
1042int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *, 996int mwifiex_set_radio_band_cfg(struct mwifiex_private *,
1043 u16 action, 997 struct mwifiex_ds_band_cfg *);
1044 struct mwifiex_ds_band_cfg *);
1045int mwifiex_snmp_mib_ioctl(struct mwifiex_private *,
1046 struct mwifiex_wait_queue *,
1047 u32 cmd_oid, u16 action, u32 *value);
1048int mwifiex_get_bss_info(struct mwifiex_private *, 998int mwifiex_get_bss_info(struct mwifiex_private *,
1049 struct mwifiex_bss_info *); 999 struct mwifiex_bss_info *);
1050 1000
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 6bb52d0e6cfa..84742715893f 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -178,9 +178,8 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
178 * with requisite parameters and calls the IOCTL handler. 178 * with requisite parameters and calls the IOCTL handler.
179 */ 179 */
180int mwifiex_find_best_bss(struct mwifiex_private *priv, 180int mwifiex_find_best_bss(struct mwifiex_private *priv,
181 u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid) 181 struct mwifiex_ssid_bssid *ssid_bssid)
182{ 182{
183 struct mwifiex_wait_queue *wait = NULL;
184 struct mwifiex_ssid_bssid tmp_ssid_bssid; 183 struct mwifiex_ssid_bssid tmp_ssid_bssid;
185 int ret = 0; 184 int ret = 0;
186 u8 *mac = NULL; 185 u8 *mac = NULL;
@@ -188,14 +187,9 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv,
188 if (!ssid_bssid) 187 if (!ssid_bssid)
189 return -1; 188 return -1;
190 189
191 /* Allocate wait request buffer */
192 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
193 if (!wait)
194 return -ENOMEM;
195
196 memcpy(&tmp_ssid_bssid, ssid_bssid, 190 memcpy(&tmp_ssid_bssid, ssid_bssid,
197 sizeof(struct mwifiex_ssid_bssid)); 191 sizeof(struct mwifiex_ssid_bssid));
198 ret = mwifiex_bss_ioctl_find_bss(priv, wait, &tmp_ssid_bssid); 192 ret = mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid);
199 193
200 if (!ret) { 194 if (!ret) {
201 memcpy(ssid_bssid, &tmp_ssid_bssid, 195 memcpy(ssid_bssid, &tmp_ssid_bssid,
@@ -205,7 +199,6 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv,
205 " %pM\n", ssid_bssid->ssid.ssid, mac); 199 " %pM\n", ssid_bssid->ssid.ssid, mac);
206 } 200 }
207 201
208 kfree(wait);
209 return ret; 202 return ret;
210} 203}
211 204
@@ -221,22 +214,14 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv,
221int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, 214int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
222 struct mwifiex_user_scan_cfg *scan_req) 215 struct mwifiex_user_scan_cfg *scan_req)
223{ 216{
224 struct mwifiex_wait_queue *wait = NULL;
225 int status = 0; 217 int status = 0;
226 u8 wait_option = MWIFIEX_IOCTL_WAIT;
227
228 /* Allocate an IOCTL request buffer */
229 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
230 if (!wait)
231 return -ENOMEM;
232 218
233 status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, 219 priv->adapter->cmd_wait_q.condition = false;
234 scan_req, NULL);
235 220
236 status = mwifiex_request_ioctl(priv, wait, status, wait_option); 221 status = mwifiex_scan_networks(priv, scan_req);
222 if (!status)
223 status = mwifiex_wait_queue_complete(priv->adapter);
237 224
238 if (wait && (status != -EINPROGRESS))
239 kfree(wait);
240 return status; 225 return status;
241} 226}
242 227
@@ -674,7 +659,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
674 * along with the other TLVs, to the firmware. 659 * along with the other TLVs, to the firmware.
675 */ 660 */
676static int 661static int
677mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, 662mwifiex_scan_channel_list(struct mwifiex_private *priv,
678 u32 max_chan_per_scan, u8 filtered_scan, 663 u32 max_chan_per_scan, u8 filtered_scan,
679 struct mwifiex_scan_cmd_config *scan_cfg_out, 664 struct mwifiex_scan_cmd_config *scan_cfg_out,
680 struct mwifiex_ie_types_chan_list_param_set 665 struct mwifiex_ie_types_chan_list_param_set
@@ -808,9 +793,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf,
808 793
809 /* Send the scan command to the firmware with the specified 794 /* Send the scan command to the firmware with the specified
810 cfg */ 795 cfg */
811 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN, 796 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN,
812 HostCmd_ACT_GEN_SET, 797 HostCmd_ACT_GEN_SET, 0,
813 0, wait_buf, scan_cfg_out); 798 scan_cfg_out);
814 if (ret) 799 if (ret)
815 break; 800 break;
816 } 801 }
@@ -2271,9 +2256,7 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv,
2271 * update the internal driver scan table. 2256 * update the internal driver scan table.
2272 */ 2257 */
2273int mwifiex_scan_networks(struct mwifiex_private *priv, 2258int mwifiex_scan_networks(struct mwifiex_private *priv,
2274 void *wait_buf, u16 action, 2259 const struct mwifiex_user_scan_cfg *user_scan_in)
2275 const struct mwifiex_user_scan_cfg *user_scan_in,
2276 struct mwifiex_scan_resp *scan_resp)
2277{ 2260{
2278 int ret = 0; 2261 int ret = 0;
2279 struct mwifiex_adapter *adapter = priv->adapter; 2262 struct mwifiex_adapter *adapter = priv->adapter;
@@ -2288,18 +2271,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2288 u8 max_chan_per_scan; 2271 u8 max_chan_per_scan;
2289 unsigned long flags; 2272 unsigned long flags;
2290 2273
2291 if (action == HostCmd_ACT_GEN_GET) { 2274 if (adapter->scan_processing) {
2292 if (scan_resp) {
2293 scan_resp->scan_table = (u8 *) adapter->scan_table;
2294 scan_resp->num_in_scan_table =
2295 adapter->num_in_scan_table;
2296 } else {
2297 ret = -1;
2298 }
2299 return ret;
2300 }
2301
2302 if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) {
2303 dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); 2275 dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
2304 return ret; 2276 return ret;
2305 } 2277 }
@@ -2308,7 +2280,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2308 adapter->scan_processing = true; 2280 adapter->scan_processing = true;
2309 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 2281 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
2310 2282
2311 if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { 2283 if (priv->scan_block) {
2312 dev_dbg(adapter->dev, 2284 dev_dbg(adapter->dev,
2313 "cmd: Scan is blocked during association...\n"); 2285 "cmd: Scan is blocked during association...\n");
2314 return ret; 2286 return ret;
@@ -2348,9 +2320,9 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2348 adapter->bcn_buf_end = adapter->bcn_buf; 2320 adapter->bcn_buf_end = adapter->bcn_buf;
2349 } 2321 }
2350 2322
2351 ret = mwifiex_scan_channel_list(priv, wait_buf, max_chan_per_scan, 2323 ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
2352 filtered_scan, &scan_cfg_out->config, 2324 &scan_cfg_out->config, chan_list_out,
2353 chan_list_out, scan_chan_list); 2325 scan_chan_list);
2354 2326
2355 /* Get scan command from scan_pending_q and put to cmd_pending_q */ 2327 /* Get scan command from scan_pending_q and put to cmd_pending_q */
2356 if (!ret) { 2328 if (!ret) {
@@ -2367,7 +2339,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2367 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 2339 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
2368 flags); 2340 flags);
2369 } 2341 }
2370 ret = -EINPROGRESS;
2371 } else { 2342 } else {
2372 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 2343 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
2373 adapter->scan_processing = true; 2344 adapter->scan_processing = true;
@@ -2393,8 +2364,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2393 * - Setting command ID, and proper size 2364 * - Setting command ID, and proper size
2394 * - Ensuring correct endian-ness 2365 * - Ensuring correct endian-ness
2395 */ 2366 */
2396int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, 2367int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf)
2397 struct host_cmd_ds_command *cmd, void *data_buf)
2398{ 2368{
2399 struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; 2369 struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
2400 struct mwifiex_scan_cmd_config *scan_cfg; 2370 struct mwifiex_scan_cmd_config *scan_cfg;
@@ -2437,11 +2407,10 @@ int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv,
2437 * .-------------------------------------------------------------. 2407 * .-------------------------------------------------------------.
2438 */ 2408 */
2439int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, 2409int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2440 struct host_cmd_ds_command *resp, void *wq_buf) 2410 struct host_cmd_ds_command *resp)
2441{ 2411{
2442 int ret = 0; 2412 int ret = 0;
2443 struct mwifiex_adapter *adapter = priv->adapter; 2413 struct mwifiex_adapter *adapter = priv->adapter;
2444 struct mwifiex_wait_queue *wait_queue = NULL;
2445 struct cmd_ctrl_node *cmd_node = NULL; 2414 struct cmd_ctrl_node *cmd_node = NULL;
2446 struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; 2415 struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL;
2447 struct mwifiex_bssdescriptor *bss_new_entry = NULL; 2416 struct mwifiex_bssdescriptor *bss_new_entry = NULL;
@@ -2653,13 +2622,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2653 mwifiex_process_scan_results(priv); 2622 mwifiex_process_scan_results(priv);
2654 2623
2655 /* Need to indicate IOCTL complete */ 2624 /* Need to indicate IOCTL complete */
2656 wait_queue = (struct mwifiex_wait_queue *) wq_buf; 2625 if (adapter->curr_cmd->wait_q_enabled) {
2657 if (wait_queue) { 2626 adapter->cmd_wait_q.status = 0;
2658 wait_queue->status = MWIFIEX_ERROR_NO_ERROR; 2627 mwifiex_complete_cmd(adapter);
2659
2660 /* Indicate ioctl complete */
2661 mwifiex_ioctl_complete(adapter,
2662 (struct mwifiex_wait_queue *) wait_queue, 0);
2663 } 2628 }
2664 if (priv->report_scan_result) 2629 if (priv->report_scan_result)
2665 priv->report_scan_result = false; 2630 priv->report_scan_result = false;
@@ -2692,9 +2657,7 @@ done:
2692 * - Setting background scan flush parameter 2657 * - Setting background scan flush parameter
2693 * - Ensuring correct endian-ness 2658 * - Ensuring correct endian-ness
2694 */ 2659 */
2695int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, 2660int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
2696 struct host_cmd_ds_command *cmd,
2697 void *data_buf)
2698{ 2661{
2699 struct host_cmd_ds_802_11_bg_scan_query *bg_query = 2662 struct host_cmd_ds_802_11_bg_scan_query *bg_query =
2700 &cmd->params.bg_scan_query; 2663 &cmd->params.bg_scan_query;
@@ -2853,6 +2816,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
2853 struct mwifiex_adapter *adapter = priv->adapter; 2816 struct mwifiex_adapter *adapter = priv->adapter;
2854 unsigned long flags; 2817 unsigned long flags;
2855 2818
2819 cmd_node->wait_q_enabled = true;
2856 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 2820 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
2857 list_add_tail(&cmd_node->list, &adapter->scan_pending_q); 2821 list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
2858 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 2822 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
@@ -2899,9 +2863,7 @@ int mwifiex_find_best_network(struct mwifiex_private *priv,
2899 * firmware, filtered on a specific SSID. 2863 * firmware, filtered on a specific SSID.
2900 */ 2864 */
2901static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, 2865static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2902 void *wait_buf, u16 action, 2866 struct mwifiex_802_11_ssid *req_ssid)
2903 struct mwifiex_802_11_ssid *req_ssid,
2904 struct mwifiex_scan_resp *scan_resp)
2905{ 2867{
2906 struct mwifiex_adapter *adapter = priv->adapter; 2868 struct mwifiex_adapter *adapter = priv->adapter;
2907 int ret = 0; 2869 int ret = 0;
@@ -2910,24 +2872,12 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2910 if (!req_ssid) 2872 if (!req_ssid)
2911 return -1; 2873 return -1;
2912 2874
2913 if (action == HostCmd_ACT_GEN_GET) { 2875 if (adapter->scan_processing) {
2914 if (scan_resp) {
2915 scan_resp->scan_table =
2916 (u8 *) &priv->curr_bss_params.bss_descriptor;
2917 scan_resp->num_in_scan_table =
2918 adapter->num_in_scan_table;
2919 } else {
2920 ret = -1;
2921 }
2922 return ret;
2923 }
2924
2925 if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) {
2926 dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); 2876 dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
2927 return ret; 2877 return ret;
2928 } 2878 }
2929 2879
2930 if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { 2880 if (priv->scan_block) {
2931 dev_dbg(adapter->dev, 2881 dev_dbg(adapter->dev,
2932 "cmd: Scan is blocked during association...\n"); 2882 "cmd: Scan is blocked during association...\n");
2933 return ret; 2883 return ret;
@@ -2945,7 +2895,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2945 req_ssid->ssid_len); 2895 req_ssid->ssid_len);
2946 scan_cfg->keep_previous_scan = true; 2896 scan_cfg->keep_previous_scan = true;
2947 2897
2948 ret = mwifiex_scan_networks(priv, wait_buf, action, scan_cfg, NULL); 2898 ret = mwifiex_scan_networks(priv, scan_cfg);
2949 2899
2950 kfree(scan_cfg); 2900 kfree(scan_cfg);
2951 return ret; 2901 return ret;
@@ -2960,12 +2910,10 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2960 * Scan command can be issued for both normal scan and specific SSID 2910 * Scan command can be issued for both normal scan and specific SSID
2961 * scan, depending upon whether an SSID is provided or not. 2911 * scan, depending upon whether an SSID is provided or not.
2962 */ 2912 */
2963int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, 2913int mwifiex_request_scan(struct mwifiex_private *priv,
2964 struct mwifiex_802_11_ssid *req_ssid) 2914 struct mwifiex_802_11_ssid *req_ssid)
2965{ 2915{
2966 int ret = 0; 2916 int ret = 0;
2967 struct mwifiex_wait_queue *wait = NULL;
2968 int status = 0;
2969 2917
2970 if (down_interruptible(&priv->async_sem)) { 2918 if (down_interruptible(&priv->async_sem)) {
2971 dev_err(priv->adapter->dev, "%s: acquire semaphore\n", 2919 dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
@@ -2974,32 +2922,23 @@ int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option,
2974 } 2922 }
2975 priv->scan_pending_on_block = true; 2923 priv->scan_pending_on_block = true;
2976 2924
2977 /* Allocate wait request buffer */ 2925 priv->adapter->cmd_wait_q.condition = false;
2978 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
2979 if (!wait) {
2980 ret = -1;
2981 goto done;
2982 }
2983 2926
2984 if (req_ssid && req_ssid->ssid_len != 0) 2927 if (req_ssid && req_ssid->ssid_len != 0)
2985 /* Specific SSID scan */ 2928 /* Specific SSID scan */
2986 status = mwifiex_scan_specific_ssid(priv, wait, 2929 ret = mwifiex_scan_specific_ssid(priv, req_ssid);
2987 HostCmd_ACT_GEN_SET,
2988 req_ssid, NULL);
2989 else 2930 else
2990 /* Normal scan */ 2931 /* Normal scan */
2991 status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, 2932 ret = mwifiex_scan_networks(priv, NULL);
2992 NULL, NULL); 2933
2993 status = mwifiex_request_ioctl(priv, wait, status, wait_option); 2934 if (!ret)
2994 if (status == -1) 2935 ret = mwifiex_wait_queue_complete(priv->adapter);
2995 ret = -1; 2936
2996done:
2997 if ((wait) && (status != -EINPROGRESS))
2998 kfree(wait);
2999 if (ret == -1) { 2937 if (ret == -1) {
3000 priv->scan_pending_on_block = false; 2938 priv->scan_pending_on_block = false;
3001 up(&priv->async_sem); 2939 up(&priv->async_sem);
3002 } 2940 }
2941
3003 return ret; 2942 return ret;
3004} 2943}
3005 2944
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index f21e5cd19839..41c087d3f0f5 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -208,7 +208,7 @@ static int mwifiex_sdio_resume(struct device *dev)
208 208
209 /* Disable Host Sleep */ 209 /* Disable Host Sleep */
210 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), 210 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
211 MWIFIEX_NO_WAIT); 211 MWIFIEX_ASYNC_CMD);
212 212
213 return 0; 213 return 0;
214} 214}
@@ -282,7 +282,7 @@ mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data)
282 */ 282 */
283static int 283static int
284mwifiex_write_data_sync(struct mwifiex_adapter *adapter, 284mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
285 u8 *buffer, u32 pkt_len, u32 port, u32 timeout) 285 u8 *buffer, u32 pkt_len, u32 port)
286{ 286{
287 struct sdio_mmc_card *card = adapter->card; 287 struct sdio_mmc_card *card = adapter->card;
288 int ret = -1; 288 int ret = -1;
@@ -314,9 +314,8 @@ mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
314/* 314/*
315 * This function reads multiple data from SDIO card memory. 315 * This function reads multiple data from SDIO card memory.
316 */ 316 */
317static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, 317static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
318 u8 *buffer, u32 len, 318 u32 len, u32 port, u8 claim)
319 u32 port, u32 timeout, u8 claim)
320{ 319{
321 struct sdio_mmc_card *card = adapter->card; 320 struct sdio_mmc_card *card = adapter->card;
322 int ret = -1; 321 int ret = -1;
@@ -430,8 +429,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
430 int ret = 0; 429 int ret = 0;
431 430
432 do { 431 do {
433 ret = mwifiex_write_data_sync(adapter, payload, pkt_len, 432 ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port);
434 port, 0);
435 if (ret) { 433 if (ret) {
436 i++; 434 i++;
437 dev_err(adapter->dev, "host_to_card, write iomem" 435 dev_err(adapter->dev, "host_to_card, write iomem"
@@ -630,7 +628,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
630 return -1; 628 return -1;
631 } 629 }
632 630
633 ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 0, 1); 631 ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1);
634 632
635 if (ret) { 633 if (ret) {
636 dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, 634 dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__,
@@ -769,7 +767,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
769 767
770 ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * 768 ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks *
771 MWIFIEX_SDIO_BLOCK_SIZE, 769 MWIFIEX_SDIO_BLOCK_SIZE,
772 adapter->ioport, 0); 770 adapter->ioport);
773 if (ret) { 771 if (ret) {
774 dev_err(adapter->dev, "FW download, write iomem (%d)" 772 dev_err(adapter->dev, "FW download, write iomem (%d)"
775 " failed @ %d\n", i, offset); 773 " failed @ %d\n", i, offset);
@@ -842,7 +840,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
842 unsigned long flags; 840 unsigned long flags;
843 841
844 if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, 842 if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS,
845 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0, 843 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK,
846 0)) { 844 0)) {
847 dev_err(adapter->dev, "read mp_regs failed\n"); 845 dev_err(adapter->dev, "read mp_regs failed\n");
848 return; 846 return;
@@ -859,8 +857,6 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
859 adapter->int_status |= sdio_ireg; 857 adapter->int_status |= sdio_ireg;
860 spin_unlock_irqrestore(&adapter->int_lock, flags); 858 spin_unlock_irqrestore(&adapter->int_lock, flags);
861 } 859 }
862
863 return;
864} 860}
865 861
866/* 862/*
@@ -891,8 +887,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func)
891 887
892 mwifiex_interrupt_status(adapter); 888 mwifiex_interrupt_status(adapter);
893 queue_work(adapter->workqueue, &adapter->main_work); 889 queue_work(adapter->workqueue, &adapter->main_work);
894
895 return;
896} 890}
897 891
898/* 892/*
@@ -1054,7 +1048,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1054 card->mpa_rx.buf_len, 1048 card->mpa_rx.buf_len,
1055 (adapter->ioport | 0x1000 | 1049 (adapter->ioport | 0x1000 |
1056 (card->mpa_rx.ports << 4)) + 1050 (card->mpa_rx.ports << 4)) +
1057 card->mpa_rx.start_port, 0, 1)) 1051 card->mpa_rx.start_port, 1))
1058 return -1; 1052 return -1;
1059 1053
1060 curr_ptr = card->mpa_rx.buf; 1054 curr_ptr = card->mpa_rx.buf;
@@ -1745,13 +1739,12 @@ mwifiex_sdio_cleanup_module(void)
1745 for (i = 0; i < adapter->priv_num; i++) 1739 for (i = 0; i < adapter->priv_num; i++)
1746 if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && 1740 if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) &&
1747 adapter->priv[i]->media_connected) 1741 adapter->priv[i]->media_connected)
1748 mwifiex_disconnect(adapter->priv[i], MWIFIEX_CMD_WAIT, 1742 mwifiex_deauthenticate(adapter->priv[i], NULL);
1749 NULL);
1750 1743
1751 if (!adapter->surprise_removed) 1744 if (!adapter->surprise_removed)
1752 mwifiex_shutdown_fw(mwifiex_get_priv 1745 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
1753 (adapter, MWIFIEX_BSS_ROLE_ANY), 1746 MWIFIEX_BSS_ROLE_ANY),
1754 MWIFIEX_CMD_WAIT); 1747 MWIFIEX_FUNC_SHUTDOWN);
1755 1748
1756exit: 1749exit:
1757 up(&add_remove_card_sem); 1750 up(&add_remove_card_sem);
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 6fff26153e26..33c8ba1f5e33 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -190,8 +190,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
190 * - Ensuring correct endian-ness 190 * - Ensuring correct endian-ness
191 */ 191 */
192static int 192static int
193mwifiex_cmd_802_11_get_log(struct mwifiex_private *priv, 193mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd)
194 struct host_cmd_ds_command *cmd)
195{ 194{
196 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); 195 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
197 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + 196 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) +
@@ -272,8 +271,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
272 * (as required) 271 * (as required)
273 * - Ensuring correct endian-ness 272 * - Ensuring correct endian-ness
274 */ 273 */
275static int mwifiex_cmd_tx_power_cfg(struct mwifiex_private *priv, 274static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd,
276 struct host_cmd_ds_command *cmd,
277 u16 cmd_action, void *data_buf) 275 u16 cmd_action, void *data_buf)
278{ 276{
279 struct mwifiex_types_power_group *pg_tlv = NULL; 277 struct mwifiex_types_power_group *pg_tlv = NULL;
@@ -407,8 +405,7 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv,
407 * - Setting MAC multicast address 405 * - Setting MAC multicast address
408 * - Ensuring correct endian-ness 406 * - Ensuring correct endian-ness
409 */ 407 */
410static int mwifiex_cmd_mac_multicast_adr(struct mwifiex_private *priv, 408static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd,
411 struct host_cmd_ds_command *cmd,
412 u16 cmd_action, void *data_buf) 409 u16 cmd_action, void *data_buf)
413{ 410{
414 struct mwifiex_multicast_list *mcast_list = 411 struct mwifiex_multicast_list *mcast_list =
@@ -463,8 +460,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv,
463 * - Setting command ID and proper size 460 * - Setting command ID and proper size
464 * - Ensuring correct endian-ness 461 * - Ensuring correct endian-ness
465 */ 462 */
466static int mwifiex_cmd_802_11_ad_hoc_stop(struct mwifiex_private *priv, 463static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd)
467 struct host_cmd_ds_command *cmd)
468{ 464{
469 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); 465 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
470 cmd->size = cpu_to_le16(S_DS_GEN); 466 cmd->size = cpu_to_le16(S_DS_GEN);
@@ -500,9 +496,8 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
500 key_param_set->key_type_id = 496 key_param_set->key_type_id =
501 cpu_to_le16(KEY_TYPE_ID_WEP); 497 cpu_to_le16(KEY_TYPE_ID_WEP);
502 key_param_set->key_info = 498 key_param_set->key_info =
503 cpu_to_le16(KEY_INFO_WEP_ENABLED | 499 cpu_to_le16(KEY_ENABLED | KEY_UNICAST |
504 KEY_INFO_WEP_UNICAST | 500 KEY_MCAST);
505 KEY_INFO_WEP_MCAST);
506 key_param_set->key_len = 501 key_param_set->key_len =
507 cpu_to_le16(priv->wep_key[i].key_length); 502 cpu_to_le16(priv->wep_key[i].key_length);
508 /* Set WEP key index */ 503 /* Set WEP key index */
@@ -589,10 +584,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
589 cpu_to_le16(KEY_TYPE_ID_WAPI); 584 cpu_to_le16(KEY_TYPE_ID_WAPI);
590 if (cmd_oid == KEY_INFO_ENABLED) 585 if (cmd_oid == KEY_INFO_ENABLED)
591 key_material->key_param_set.key_info = 586 key_material->key_param_set.key_info =
592 cpu_to_le16(KEY_INFO_WAPI_ENABLED); 587 cpu_to_le16(KEY_ENABLED);
593 else 588 else
594 key_material->key_param_set.key_info = 589 key_material->key_param_set.key_info =
595 cpu_to_le16(!KEY_INFO_WAPI_ENABLED); 590 cpu_to_le16(!KEY_ENABLED);
596 591
597 key_material->key_param_set.key[0] = enc_key->key_index; 592 key_material->key_param_set.key[0] = enc_key->key_index;
598 if (!priv->sec_info.wapi_key_on) 593 if (!priv->sec_info.wapi_key_on)
@@ -604,10 +599,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
604 if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { 599 if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) {
605 /* WAPI pairwise key: unicast */ 600 /* WAPI pairwise key: unicast */
606 key_material->key_param_set.key_info |= 601 key_material->key_param_set.key_info |=
607 cpu_to_le16(KEY_INFO_WAPI_UNICAST); 602 cpu_to_le16(KEY_UNICAST);
608 } else { /* WAPI group key: multicast */ 603 } else { /* WAPI group key: multicast */
609 key_material->key_param_set.key_info |= 604 key_material->key_param_set.key_info |=
610 cpu_to_le16(KEY_INFO_WAPI_MCAST); 605 cpu_to_le16(KEY_MCAST);
611 priv->sec_info.wapi_key_on = true; 606 priv->sec_info.wapi_key_on = true;
612 } 607 }
613 608
@@ -634,32 +629,32 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
634 cpu_to_le16(KEY_TYPE_ID_AES); 629 cpu_to_le16(KEY_TYPE_ID_AES);
635 if (cmd_oid == KEY_INFO_ENABLED) 630 if (cmd_oid == KEY_INFO_ENABLED)
636 key_material->key_param_set.key_info = 631 key_material->key_param_set.key_info =
637 cpu_to_le16(KEY_INFO_AES_ENABLED); 632 cpu_to_le16(KEY_ENABLED);
638 else 633 else
639 key_material->key_param_set.key_info = 634 key_material->key_param_set.key_info =
640 cpu_to_le16(!KEY_INFO_AES_ENABLED); 635 cpu_to_le16(!KEY_ENABLED);
641 636
642 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) 637 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
643 /* AES pairwise key: unicast */ 638 /* AES pairwise key: unicast */
644 key_material->key_param_set.key_info |= 639 key_material->key_param_set.key_info |=
645 cpu_to_le16(KEY_INFO_AES_UNICAST); 640 cpu_to_le16(KEY_UNICAST);
646 else /* AES group key: multicast */ 641 else /* AES group key: multicast */
647 key_material->key_param_set.key_info |= 642 key_material->key_param_set.key_info |=
648 cpu_to_le16(KEY_INFO_AES_MCAST); 643 cpu_to_le16(KEY_MCAST);
649 } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { 644 } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
650 dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); 645 dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
651 key_material->key_param_set.key_type_id = 646 key_material->key_param_set.key_type_id =
652 cpu_to_le16(KEY_TYPE_ID_TKIP); 647 cpu_to_le16(KEY_TYPE_ID_TKIP);
653 key_material->key_param_set.key_info = 648 key_material->key_param_set.key_info =
654 cpu_to_le16(KEY_INFO_TKIP_ENABLED); 649 cpu_to_le16(KEY_ENABLED);
655 650
656 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) 651 if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
657 /* TKIP pairwise key: unicast */ 652 /* TKIP pairwise key: unicast */
658 key_material->key_param_set.key_info |= 653 key_material->key_param_set.key_info |=
659 cpu_to_le16(KEY_INFO_TKIP_UNICAST); 654 cpu_to_le16(KEY_UNICAST);
660 else /* TKIP group key: multicast */ 655 else /* TKIP group key: multicast */
661 key_material->key_param_set.key_info |= 656 key_material->key_param_set.key_info |=
662 cpu_to_le16(KEY_INFO_TKIP_MCAST); 657 cpu_to_le16(KEY_MCAST);
663 } 658 }
664 659
665 if (key_material->key_param_set.key_type_id) { 660 if (key_material->key_param_set.key_type_id) {
@@ -778,8 +773,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv,
778 * - Setting status to enable or disable (for SET only) 773 * - Setting status to enable or disable (for SET only)
779 * - Ensuring correct endian-ness 774 * - Ensuring correct endian-ness
780 */ 775 */
781static int mwifiex_cmd_ibss_coalescing_status(struct mwifiex_private *priv, 776static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd,
782 struct host_cmd_ds_command *cmd,
783 u16 cmd_action, void *data_buf) 777 u16 cmd_action, void *data_buf)
784{ 778{
785 struct host_cmd_ds_802_11_ibss_status *ibss_coal = 779 struct host_cmd_ds_802_11_ibss_status *ibss_coal =
@@ -947,7 +941,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
947 cmd_action); 941 cmd_action);
948 break; 942 break;
949 case HostCmd_CMD_MAC_MULTICAST_ADR: 943 case HostCmd_CMD_MAC_MULTICAST_ADR:
950 ret = mwifiex_cmd_mac_multicast_adr(priv, cmd_ptr, cmd_action, 944 ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action,
951 data_buf); 945 data_buf);
952 break; 946 break;
953 case HostCmd_CMD_TX_RATE_CFG: 947 case HostCmd_CMD_TX_RATE_CFG:
@@ -955,7 +949,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
955 data_buf); 949 data_buf);
956 break; 950 break;
957 case HostCmd_CMD_TXPWR_CFG: 951 case HostCmd_CMD_TXPWR_CFG:
958 ret = mwifiex_cmd_tx_power_cfg(priv, cmd_ptr, cmd_action, 952 ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action,
959 data_buf); 953 data_buf);
960 break; 954 break;
961 case HostCmd_CMD_802_11_PS_MODE_ENH: 955 case HostCmd_CMD_802_11_PS_MODE_ENH:
@@ -967,11 +961,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
967 (struct mwifiex_hs_config_param *) data_buf); 961 (struct mwifiex_hs_config_param *) data_buf);
968 break; 962 break;
969 case HostCmd_CMD_802_11_SCAN: 963 case HostCmd_CMD_802_11_SCAN:
970 ret = mwifiex_cmd_802_11_scan(priv, cmd_ptr, data_buf); 964 ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf);
971 break; 965 break;
972 case HostCmd_CMD_802_11_BG_SCAN_QUERY: 966 case HostCmd_CMD_802_11_BG_SCAN_QUERY:
973 ret = mwifiex_cmd_802_11_bg_scan_query(priv, cmd_ptr, 967 ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr);
974 data_buf);
975 break; 968 break;
976 case HostCmd_CMD_802_11_ASSOCIATE: 969 case HostCmd_CMD_802_11_ASSOCIATE:
977 ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); 970 ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf);
@@ -985,14 +978,14 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
985 data_buf); 978 data_buf);
986 break; 979 break;
987 case HostCmd_CMD_802_11_GET_LOG: 980 case HostCmd_CMD_802_11_GET_LOG:
988 ret = mwifiex_cmd_802_11_get_log(priv, cmd_ptr); 981 ret = mwifiex_cmd_802_11_get_log(cmd_ptr);
989 break; 982 break;
990 case HostCmd_CMD_802_11_AD_HOC_JOIN: 983 case HostCmd_CMD_802_11_AD_HOC_JOIN:
991 ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, 984 ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr,
992 data_buf); 985 data_buf);
993 break; 986 break;
994 case HostCmd_CMD_802_11_AD_HOC_STOP: 987 case HostCmd_CMD_802_11_AD_HOC_STOP:
995 ret = mwifiex_cmd_802_11_ad_hoc_stop(priv, cmd_ptr); 988 ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr);
996 break; 989 break;
997 case HostCmd_CMD_RSSI_INFO: 990 case HostCmd_CMD_RSSI_INFO:
998 ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); 991 ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action);
@@ -1037,10 +1030,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1037 cmd_ptr->size = cpu_to_le16(S_DS_GEN); 1030 cmd_ptr->size = cpu_to_le16(S_DS_GEN);
1038 break; 1031 break;
1039 case HostCmd_CMD_11N_ADDBA_REQ: 1032 case HostCmd_CMD_11N_ADDBA_REQ:
1040 ret = mwifiex_cmd_11n_addba_req(priv, cmd_ptr, data_buf); 1033 ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf);
1041 break; 1034 break;
1042 case HostCmd_CMD_11N_DELBA: 1035 case HostCmd_CMD_11N_DELBA:
1043 ret = mwifiex_cmd_11n_delba(priv, cmd_ptr, data_buf); 1036 ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf);
1044 break; 1037 break;
1045 case HostCmd_CMD_11N_ADDBA_RSP: 1038 case HostCmd_CMD_11N_ADDBA_RSP:
1046 ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); 1039 ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf);
@@ -1059,11 +1052,11 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1059 data_buf); 1052 data_buf);
1060 break; 1053 break;
1061 case HostCmd_CMD_AMSDU_AGGR_CTRL: 1054 case HostCmd_CMD_AMSDU_AGGR_CTRL:
1062 ret = mwifiex_cmd_amsdu_aggr_ctrl(priv, cmd_ptr, cmd_action, 1055 ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action,
1063 data_buf); 1056 data_buf);
1064 break; 1057 break;
1065 case HostCmd_CMD_11N_CFG: 1058 case HostCmd_CMD_11N_CFG:
1066 ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, 1059 ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action,
1067 data_buf); 1060 data_buf);
1068 break; 1061 break;
1069 case HostCmd_CMD_WMM_GET_STATUS: 1062 case HostCmd_CMD_WMM_GET_STATUS:
@@ -1076,8 +1069,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1076 ret = 0; 1069 ret = 0;
1077 break; 1070 break;
1078 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: 1071 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
1079 ret = mwifiex_cmd_ibss_coalescing_status(priv, cmd_ptr, 1072 ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action,
1080 cmd_action, data_buf); 1073 data_buf);
1081 break; 1074 break;
1082 case HostCmd_CMD_MAC_REG_ACCESS: 1075 case HostCmd_CMD_MAC_REG_ACCESS:
1083 case HostCmd_CMD_BBP_REG_ACCESS: 1076 case HostCmd_CMD_BBP_REG_ACCESS:
@@ -1136,65 +1129,66 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1136 1129
1137 if (first_sta) { 1130 if (first_sta) {
1138 1131
1139 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, 1132 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT,
1140 HostCmd_ACT_GEN_SET, 0, NULL, NULL); 1133 HostCmd_ACT_GEN_SET, 0, NULL);
1141 if (ret) 1134 if (ret)
1142 return -1; 1135 return -1;
1143 /* Read MAC address from HW */ 1136 /* Read MAC address from HW */
1144 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC, 1137 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC,
1145 HostCmd_ACT_GEN_GET, 0, NULL, NULL); 1138 HostCmd_ACT_GEN_GET, 0, NULL);
1146 if (ret) 1139 if (ret)
1147 return -1; 1140 return -1;
1148 1141
1149 /* Reconfigure tx buf size */ 1142 /* Reconfigure tx buf size */
1150 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, 1143 ret = mwifiex_send_cmd_async(priv,
1151 HostCmd_ACT_GEN_SET, 0, NULL, 1144 HostCmd_CMD_RECONFIGURE_TX_BUFF,
1152 &priv->adapter->tx_buf_size); 1145 HostCmd_ACT_GEN_SET, 0,
1146 &priv->adapter->tx_buf_size);
1153 if (ret) 1147 if (ret)
1154 return -1; 1148 return -1;
1155 1149
1156 /* Enable IEEE PS by default */ 1150 /* Enable IEEE PS by default */
1157 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; 1151 priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1158 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 1152 ret = mwifiex_send_cmd_async(priv,
1159 EN_AUTO_PS, BITMAP_STA_PS, NULL, 1153 HostCmd_CMD_802_11_PS_MODE_ENH,
1160 NULL); 1154 EN_AUTO_PS, BITMAP_STA_PS, NULL);
1161 if (ret) 1155 if (ret)
1162 return -1; 1156 return -1;
1163 } 1157 }
1164 1158
1165 /* get tx rate */ 1159 /* get tx rate */
1166 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, 1160 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG,
1167 HostCmd_ACT_GEN_GET, 0, NULL, NULL); 1161 HostCmd_ACT_GEN_GET, 0, NULL);
1168 if (ret) 1162 if (ret)
1169 return -1; 1163 return -1;
1170 priv->data_rate = 0; 1164 priv->data_rate = 0;
1171 1165
1172 /* get tx power */ 1166 /* get tx power */
1173 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, 1167 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG,
1174 HostCmd_ACT_GEN_GET, 0, NULL, NULL); 1168 HostCmd_ACT_GEN_GET, 0, NULL);
1175 if (ret) 1169 if (ret)
1176 return -1; 1170 return -1;
1177 1171
1178 /* set ibss coalescing_status */ 1172 /* set ibss coalescing_status */
1179 ret = mwifiex_prepare_cmd(priv, 1173 ret = mwifiex_send_cmd_async(priv,
1180 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 1174 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
1181 HostCmd_ACT_GEN_SET, 0, NULL, &enable); 1175 HostCmd_ACT_GEN_SET, 0, &enable);
1182 if (ret) 1176 if (ret)
1183 return -1; 1177 return -1;
1184 1178
1185 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); 1179 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
1186 amsdu_aggr_ctrl.enable = true; 1180 amsdu_aggr_ctrl.enable = true;
1187 /* Send request to firmware */ 1181 /* Send request to firmware */
1188 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, 1182 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
1189 HostCmd_ACT_GEN_SET, 0, NULL, 1183 HostCmd_ACT_GEN_SET, 0,
1190 (void *) &amsdu_aggr_ctrl); 1184 (void *) &amsdu_aggr_ctrl);
1191 if (ret) 1185 if (ret)
1192 return -1; 1186 return -1;
1193 /* MAC Control must be the last command in init_fw */ 1187 /* MAC Control must be the last command in init_fw */
1194 /* set MAC Control */ 1188 /* set MAC Control */
1195 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, 1189 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
1196 HostCmd_ACT_GEN_SET, 0, NULL, 1190 HostCmd_ACT_GEN_SET, 0,
1197 &priv->curr_pkt_filter); 1191 &priv->curr_pkt_filter);
1198 if (ret) 1192 if (ret)
1199 return -1; 1193 return -1;
1200 1194
@@ -1202,19 +1196,18 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1202 /* Enable auto deep sleep */ 1196 /* Enable auto deep sleep */
1203 auto_ds.auto_ds = DEEP_SLEEP_ON; 1197 auto_ds.auto_ds = DEEP_SLEEP_ON;
1204 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; 1198 auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
1205 ret = mwifiex_prepare_cmd(priv, 1199 ret = mwifiex_send_cmd_async(priv,
1206 HostCmd_CMD_802_11_PS_MODE_ENH, 1200 HostCmd_CMD_802_11_PS_MODE_ENH,
1207 EN_AUTO_PS, BITMAP_AUTO_DS, NULL, 1201 EN_AUTO_PS, BITMAP_AUTO_DS,
1208 &auto_ds); 1202 &auto_ds);
1209 if (ret) 1203 if (ret)
1210 return -1; 1204 return -1;
1211 } 1205 }
1212 1206
1213 /* Send cmd to FW to enable/disable 11D function */ 1207 /* Send cmd to FW to enable/disable 11D function */
1214 state_11d = ENABLE_11D; 1208 state_11d = ENABLE_11D;
1215 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, 1209 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB,
1216 HostCmd_ACT_GEN_SET, DOT11D_I, 1210 HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d);
1217 NULL, &state_11d);
1218 if (ret) 1211 if (ret)
1219 dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); 1212 dev_err(priv->adapter->dev, "11D: failed to enable 11D\n");
1220 1213
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 74add45b99b6..7f4f10b752fb 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -41,8 +41,7 @@
41 */ 41 */
42static void 42static void
43mwifiex_process_cmdresp_error(struct mwifiex_private *priv, 43mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
44 struct host_cmd_ds_command *resp, 44 struct host_cmd_ds_command *resp)
45 struct mwifiex_wait_queue *wq_buf)
46{ 45{
47 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 46 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
48 struct mwifiex_adapter *adapter = priv->adapter; 47 struct mwifiex_adapter *adapter = priv->adapter;
@@ -51,8 +50,9 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
51 50
52 dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", 51 dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n",
53 resp->command, resp->result); 52 resp->command, resp->result);
54 if (wq_buf) 53
55 wq_buf->status = MWIFIEX_ERROR_FW_CMDRESP; 54 if (adapter->curr_cmd->wait_q_enabled)
55 adapter->cmd_wait_q.status = -1;
56 56
57 switch (le16_to_cpu(resp->command)) { 57 switch (le16_to_cpu(resp->command)) {
58 case HostCmd_CMD_802_11_PS_MODE_ENH: 58 case HostCmd_CMD_802_11_PS_MODE_ENH:
@@ -103,8 +103,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
103 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 103 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
104 adapter->curr_cmd = NULL; 104 adapter->curr_cmd = NULL;
105 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 105 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
106
107 return;
108} 106}
109 107
110/* 108/*
@@ -282,7 +280,6 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
282 struct host_cmd_ds_command *resp, 280 struct host_cmd_ds_command *resp,
283 void *data_buf) 281 void *data_buf)
284{ 282{
285 struct mwifiex_adapter *adapter = priv->adapter;
286 struct mwifiex_rate_cfg *ds_rate = NULL; 283 struct mwifiex_rate_cfg *ds_rate = NULL;
287 struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; 284 struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg;
288 struct mwifiex_rate_scope *rate_scope; 285 struct mwifiex_rate_scope *rate_scope;
@@ -328,9 +325,9 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
328 if (priv->is_data_rate_auto) 325 if (priv->is_data_rate_auto)
329 priv->data_rate = 0; 326 priv->data_rate = 0;
330 else 327 else
331 ret = mwifiex_prepare_cmd(priv, 328 ret = mwifiex_send_cmd_async(priv,
332 HostCmd_CMD_802_11_TX_RATE_QUERY, 329 HostCmd_CMD_802_11_TX_RATE_QUERY,
333 HostCmd_ACT_GEN_GET, 0, NULL, NULL); 330 HostCmd_ACT_GEN_GET, 0, NULL);
334 331
335 if (data_buf) { 332 if (data_buf) {
336 ds_rate = (struct mwifiex_rate_cfg *) data_buf; 333 ds_rate = (struct mwifiex_rate_cfg *) data_buf;
@@ -338,9 +335,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
338 if (priv->is_data_rate_auto) { 335 if (priv->is_data_rate_auto) {
339 ds_rate->is_rate_auto = 1; 336 ds_rate->is_rate_auto = 1;
340 } else { 337 } else {
341 ds_rate->rate = 338 ds_rate->rate = mwifiex_get_rate_index(priv->
342 mwifiex_get_rate_index(adapter,
343 priv->
344 bitmap_rates, 339 bitmap_rates,
345 sizeof(priv-> 340 sizeof(priv->
346 bitmap_rates)); 341 bitmap_rates));
@@ -516,13 +511,11 @@ static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv,
516static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, 511static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv,
517 struct host_cmd_ds_command *resp) 512 struct host_cmd_ds_command *resp)
518{ 513{
519 struct mwifiex_adapter *adapter = priv->adapter;
520
521 priv->tx_rate = resp->params.tx_rate.tx_rate; 514 priv->tx_rate = resp->params.tx_rate.tx_rate;
522 priv->tx_htinfo = resp->params.tx_rate.ht_info; 515 priv->tx_htinfo = resp->params.tx_rate.ht_info;
523 if (!priv->is_data_rate_auto) 516 if (!priv->is_data_rate_auto)
524 priv->data_rate = 517 priv->data_rate =
525 mwifiex_index_to_data_rate(adapter, priv->tx_rate, 518 mwifiex_index_to_data_rate(priv->tx_rate,
526 priv->tx_htinfo); 519 priv->tx_htinfo);
527 520
528 return 0; 521 return 0;
@@ -574,8 +567,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
574 &resp->params.key_material; 567 &resp->params.key_material;
575 568
576 if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { 569 if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
577 if ((le16_to_cpu(key->key_param_set.key_info) & 570 if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
578 KEY_INFO_TKIP_MCAST)) {
579 dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); 571 dev_dbg(priv->adapter->dev, "info: key: GTK is set\n");
580 priv->wpa_is_gtk_set = true; 572 priv->wpa_is_gtk_set = true;
581 priv->scan_block = false; 573 priv->scan_block = false;
@@ -834,19 +826,17 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
834 * response handlers based on the command ID. 826 * response handlers based on the command ID.
835 */ 827 */
836int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, 828int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
837 u16 cmdresp_no, void *cmd_buf, void *wq_buf) 829 u16 cmdresp_no, void *cmd_buf)
838{ 830{
839 int ret = 0; 831 int ret = 0;
840 struct mwifiex_adapter *adapter = priv->adapter; 832 struct mwifiex_adapter *adapter = priv->adapter;
841 struct host_cmd_ds_command *resp = 833 struct host_cmd_ds_command *resp =
842 (struct host_cmd_ds_command *) cmd_buf; 834 (struct host_cmd_ds_command *) cmd_buf;
843 struct mwifiex_wait_queue *wait_queue =
844 (struct mwifiex_wait_queue *) wq_buf;
845 void *data_buf = adapter->curr_cmd->data_buf; 835 void *data_buf = adapter->curr_cmd->data_buf;
846 836
847 /* If the command is not successful, cleanup and return failure */ 837 /* If the command is not successful, cleanup and return failure */
848 if (resp->result != HostCmd_RESULT_OK) { 838 if (resp->result != HostCmd_RESULT_OK) {
849 mwifiex_process_cmdresp_error(priv, resp, wait_queue); 839 mwifiex_process_cmdresp_error(priv, resp);
850 return -1; 840 return -1;
851 } 841 }
852 /* Command successful, handle response */ 842 /* Command successful, handle response */
@@ -866,12 +856,11 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
866 ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); 856 ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf);
867 break; 857 break;
868 case HostCmd_CMD_802_11_SCAN: 858 case HostCmd_CMD_802_11_SCAN:
869 ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); 859 ret = mwifiex_ret_802_11_scan(priv, resp);
870 wait_queue = NULL; 860 adapter->curr_cmd->wait_q_enabled = false;
871 adapter->curr_cmd->wq_buf = NULL;
872 break; 861 break;
873 case HostCmd_CMD_802_11_BG_SCAN_QUERY: 862 case HostCmd_CMD_802_11_BG_SCAN_QUERY:
874 ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); 863 ret = mwifiex_ret_802_11_scan(priv, resp);
875 dev_dbg(adapter->dev, 864 dev_dbg(adapter->dev,
876 "info: CMD_RESP: BG_SCAN result is ready!\n"); 865 "info: CMD_RESP: BG_SCAN result is ready!\n");
877 break; 866 break;
@@ -885,14 +874,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
885 ret = mwifiex_ret_802_11_hs_cfg(priv, resp); 874 ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
886 break; 875 break;
887 case HostCmd_CMD_802_11_ASSOCIATE: 876 case HostCmd_CMD_802_11_ASSOCIATE:
888 ret = mwifiex_ret_802_11_associate(priv, resp, wait_queue); 877 ret = mwifiex_ret_802_11_associate(priv, resp);
889 break; 878 break;
890 case HostCmd_CMD_802_11_DEAUTHENTICATE: 879 case HostCmd_CMD_802_11_DEAUTHENTICATE:
891 ret = mwifiex_ret_802_11_deauthenticate(priv, resp); 880 ret = mwifiex_ret_802_11_deauthenticate(priv, resp);
892 break; 881 break;
893 case HostCmd_CMD_802_11_AD_HOC_START: 882 case HostCmd_CMD_802_11_AD_HOC_START:
894 case HostCmd_CMD_802_11_AD_HOC_JOIN: 883 case HostCmd_CMD_802_11_AD_HOC_JOIN:
895 ret = mwifiex_ret_802_11_ad_hoc(priv, resp, wait_queue); 884 ret = mwifiex_ret_802_11_ad_hoc(priv, resp);
896 break; 885 break;
897 case HostCmd_CMD_802_11_AD_HOC_STOP: 886 case HostCmd_CMD_802_11_AD_HOC_STOP:
898 ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); 887 ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp);
@@ -952,7 +941,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
952 mp_end_port)); 941 mp_end_port));
953 break; 942 break;
954 case HostCmd_CMD_AMSDU_AGGR_CTRL: 943 case HostCmd_CMD_AMSDU_AGGR_CTRL:
955 ret = mwifiex_ret_amsdu_aggr_ctrl(priv, resp, data_buf); 944 ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf);
956 break; 945 break;
957 case HostCmd_CMD_WMM_GET_STATUS: 946 case HostCmd_CMD_WMM_GET_STATUS:
958 ret = mwifiex_ret_wmm_get_status(priv, resp); 947 ret = mwifiex_ret_wmm_get_status(priv, resp);
@@ -971,7 +960,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
971 case HostCmd_CMD_SET_BSS_MODE: 960 case HostCmd_CMD_SET_BSS_MODE:
972 break; 961 break;
973 case HostCmd_CMD_11N_CFG: 962 case HostCmd_CMD_11N_CFG:
974 ret = mwifiex_ret_11n_cfg(priv, resp, data_buf); 963 ret = mwifiex_ret_11n_cfg(resp, data_buf);
975 break; 964 break;
976 default: 965 default:
977 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 966 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 936d7c175e75..fc265cab0907 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -271,8 +271,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
271 271
272 case EVENT_HS_ACT_REQ: 272 case EVENT_HS_ACT_REQ:
273 dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); 273 dev_dbg(adapter->dev, "event: HS_ACT_REQ\n");
274 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, 274 ret = mwifiex_send_cmd_async(priv,
275 0, 0, NULL, NULL); 275 HostCmd_CMD_802_11_HS_CFG_ENH,
276 0, 0, NULL);
276 break; 277 break;
277 278
278 case EVENT_MIC_ERR_UNICAST: 279 case EVENT_MIC_ERR_UNICAST:
@@ -303,9 +304,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
303 sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); 304 sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
304 adapter->num_in_scan_table = 0; 305 adapter->num_in_scan_table = 0;
305 adapter->bcn_buf_end = adapter->bcn_buf; 306 adapter->bcn_buf_end = adapter->bcn_buf;
306 ret = mwifiex_prepare_cmd(priv, 307 ret = mwifiex_send_cmd_async(priv,
307 HostCmd_CMD_802_11_BG_SCAN_QUERY, 308 HostCmd_CMD_802_11_BG_SCAN_QUERY,
308 HostCmd_ACT_GEN_GET, 0, NULL, NULL); 309 HostCmd_ACT_GEN_GET, 0, NULL);
309 break; 310 break;
310 311
311 case EVENT_PORT_RELEASE: 312 case EVENT_PORT_RELEASE:
@@ -314,8 +315,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
314 315
315 case EVENT_WMM_STATUS_CHANGE: 316 case EVENT_WMM_STATUS_CHANGE:
316 dev_dbg(adapter->dev, "event: WMM status changed\n"); 317 dev_dbg(adapter->dev, "event: WMM status changed\n");
317 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, 318 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS,
318 0, 0, NULL, NULL); 319 0, 0, NULL);
319 break; 320 break;
320 321
321 case EVENT_RSSI_LOW: 322 case EVENT_RSSI_LOW:
@@ -353,15 +354,15 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
353 break; 354 break;
354 case EVENT_IBSS_COALESCED: 355 case EVENT_IBSS_COALESCED:
355 dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); 356 dev_dbg(adapter->dev, "event: IBSS_COALESCED\n");
356 ret = mwifiex_prepare_cmd(priv, 357 ret = mwifiex_send_cmd_async(priv,
357 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, 358 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
358 HostCmd_ACT_GEN_GET, 0, NULL, NULL); 359 HostCmd_ACT_GEN_GET, 0, NULL);
359 break; 360 break;
360 case EVENT_ADDBA: 361 case EVENT_ADDBA:
361 dev_dbg(adapter->dev, "event: ADDBA Request\n"); 362 dev_dbg(adapter->dev, "event: ADDBA Request\n");
362 mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP, 363 mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP,
363 HostCmd_ACT_GEN_SET, 0, NULL, 364 HostCmd_ACT_GEN_SET, 0,
364 adapter->event_body); 365 adapter->event_body);
365 break; 366 break;
366 case EVENT_DELBA: 367 case EVENT_DELBA:
367 dev_dbg(adapter->dev, "event: DELBA Request\n"); 368 dev_dbg(adapter->dev, "event: DELBA Request\n");
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index b163507b1fe0..6489f264ef5f 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -33,9 +33,8 @@
33 * size, and the calling function must ensure enough memory is 33 * size, and the calling function must ensure enough memory is
34 * available. 34 * available.
35 */ 35 */
36static int 36int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
37mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, 37 struct net_device *dev)
38 struct net_device *dev)
39{ 38{
40 int i = 0; 39 int i = 0;
41 struct netdev_hw_addr *ha; 40 struct netdev_hw_addr *ha;
@@ -47,216 +46,51 @@ mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
47} 46}
48 47
49/* 48/*
50 * Allocate and fills a wait queue with proper parameters.
51 *
52 * This function needs to be called before an IOCTL request can be made.
53 * It can handle the following wait options:
54 * MWIFIEX_NO_WAIT - Waiting is disabled
55 * MWIFIEX_IOCTL_WAIT - Waiting is done on IOCTL wait queue
56 * MWIFIEX_CMD_WAIT - Waiting is done on command wait queue
57 * MWIFIEX_WSTATS_WAIT - Waiting is done on stats wait queue
58 */
59struct mwifiex_wait_queue *
60mwifiex_alloc_fill_wait_queue(struct mwifiex_private *priv,
61 u8 wait_option)
62{
63 struct mwifiex_wait_queue *wait = NULL;
64
65 wait = (struct mwifiex_wait_queue *)
66 kzalloc(sizeof(struct mwifiex_wait_queue), GFP_ATOMIC);
67 if (!wait) {
68 dev_err(priv->adapter->dev, "%s: fail to alloc buffer\n",
69 __func__);
70 return wait;
71 }
72
73 wait->bss_index = priv->bss_index;
74
75 switch (wait_option) {
76 case MWIFIEX_NO_WAIT:
77 wait->enabled = 0;
78 break;
79 case MWIFIEX_IOCTL_WAIT:
80 priv->ioctl_wait_q_woken = false;
81 wait->start_time = jiffies;
82 wait->wait = &priv->ioctl_wait_q;
83 wait->condition = &priv->ioctl_wait_q_woken;
84 wait->enabled = 1;
85 break;
86 case MWIFIEX_CMD_WAIT:
87 priv->cmd_wait_q_woken = false;
88 wait->start_time = jiffies;
89 wait->wait = &priv->cmd_wait_q;
90 wait->condition = &priv->cmd_wait_q_woken;
91 wait->enabled = 1;
92 break;
93 case MWIFIEX_WSTATS_WAIT:
94 priv->w_stats_wait_q_woken = false;
95 wait->start_time = jiffies;
96 wait->wait = &priv->w_stats_wait_q;
97 wait->condition = &priv->w_stats_wait_q_woken;
98 wait->enabled = 1;
99 break;
100 }
101
102 return wait;
103}
104
105/*
106 * Wait queue completion handler. 49 * Wait queue completion handler.
107 * 50 *
108 * This function waits on a particular wait queue. 51 * This function waits on a cmd wait queue. It also cancels the pending
109 * For NO_WAIT option, it returns immediately. It also cancels the 52 * request after waking up, in case of errors.
110 * pending IOCTL request after waking up, in case of errors.
111 */ 53 */
112static void 54int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
113mwifiex_wait_ioctl_complete(struct mwifiex_private *priv,
114 struct mwifiex_wait_queue *wait,
115 u8 wait_option)
116{ 55{
117 bool cancel_flag = false; 56 bool cancel_flag = false;
57 int status = adapter->cmd_wait_q.status;
118 58
119 switch (wait_option) { 59 dev_dbg(adapter->dev, "cmd pending\n");
120 case MWIFIEX_NO_WAIT: 60 atomic_inc(&adapter->cmd_pending);
121 break;
122 case MWIFIEX_IOCTL_WAIT:
123 wait_event_interruptible(priv->ioctl_wait_q,
124 priv->ioctl_wait_q_woken);
125 if (!priv->ioctl_wait_q_woken)
126 cancel_flag = true;
127 break;
128 case MWIFIEX_CMD_WAIT:
129 wait_event_interruptible(priv->cmd_wait_q,
130 priv->cmd_wait_q_woken);
131 if (!priv->cmd_wait_q_woken)
132 cancel_flag = true;
133 break;
134 case MWIFIEX_WSTATS_WAIT:
135 wait_event_interruptible(priv->w_stats_wait_q,
136 priv->w_stats_wait_q_woken);
137 if (!priv->w_stats_wait_q_woken)
138 cancel_flag = true;
139 break;
140 }
141 if (cancel_flag) {
142 mwifiex_cancel_pending_ioctl(priv->adapter, wait);
143 dev_dbg(priv->adapter->dev, "cmd: IOCTL cancel: wait=%p, wait_option=%d\n",
144 wait, wait_option);
145 }
146 61
147 return; 62 /* Status pending, wake up main process */
148} 63 queue_work(adapter->workqueue, &adapter->main_work);
149 64
150/* 65 /* Wait for completion */
151 * The function waits for the request to complete and issues the 66 wait_event_interruptible(adapter->cmd_wait_q.wait,
152 * completion handler, if required. 67 adapter->cmd_wait_q.condition);
153 */ 68 if (!adapter->cmd_wait_q.condition)
154int mwifiex_request_ioctl(struct mwifiex_private *priv, 69 cancel_flag = true;
155 struct mwifiex_wait_queue *wait,
156 int status, u8 wait_option)
157{
158 switch (status) {
159 case -EINPROGRESS:
160 dev_dbg(priv->adapter->dev, "cmd: IOCTL pending: wait=%p, wait_option=%d\n",
161 wait, wait_option);
162 atomic_inc(&priv->adapter->ioctl_pending);
163 /* Status pending, wake up main process */
164 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
165
166 /* Wait for completion */
167 if (wait_option) {
168 mwifiex_wait_ioctl_complete(priv, wait, wait_option);
169 status = wait->status;
170 }
171 break;
172 case 0:
173 case -1:
174 case -EBUSY:
175 default:
176 break;
177 }
178 return status;
179}
180EXPORT_SYMBOL_GPL(mwifiex_request_ioctl);
181 70
182/* 71 if (cancel_flag) {
183 * IOCTL request handler to set/get MAC address. 72 mwifiex_cancel_pending_ioctl(adapter);
184 * 73 dev_dbg(adapter->dev, "cmd cancel\n");
185 * This function prepares the correct firmware command and
186 * issues it to get the extended version information.
187 */
188static int mwifiex_bss_ioctl_mac_address(struct mwifiex_private *priv,
189 struct mwifiex_wait_queue *wait,
190 u8 action, u8 *mac)
191{
192 int ret = 0;
193
194 if ((action == HostCmd_ACT_GEN_GET) && mac) {
195 memcpy(mac, priv->curr_addr, ETH_ALEN);
196 return 0;
197 } 74 }
75 adapter->cmd_wait_q.status = 0;
198 76
199 /* Send request to firmware */
200 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
201 action, 0, wait, mac);
202 if (!ret)
203 ret = -EINPROGRESS;
204
205 return ret;
206}
207
208/*
209 * Sends IOCTL request to set MAC address.
210 *
211 * This function allocates the IOCTL request buffer, fills it
212 * with requisite parameters and calls the IOCTL handler.
213 */
214int mwifiex_request_set_mac_address(struct mwifiex_private *priv)
215{
216 struct mwifiex_wait_queue *wait = NULL;
217 int status = 0;
218 u8 wait_option = MWIFIEX_CMD_WAIT;
219
220 /* Allocate wait buffer */
221 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
222 if (!wait)
223 return -ENOMEM;
224
225 status = mwifiex_bss_ioctl_mac_address(priv, wait, HostCmd_ACT_GEN_SET,
226 NULL);
227
228 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
229 if (!status)
230 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
231 else
232 dev_err(priv->adapter->dev, "set mac address failed: status=%d"
233 " error_code=%#x\n", status, wait->status);
234
235 kfree(wait);
236 return status; 77 return status;
237} 78}
238 79
239/* 80/*
240 * IOCTL request handler to set multicast list.
241 *
242 * This function prepares the correct firmware command and 81 * This function prepares the correct firmware command and
243 * issues it to set the multicast list. 82 * issues it to set the multicast list.
244 * 83 *
245 * This function can be used to enable promiscuous mode, or enable all 84 * This function can be used to enable promiscuous mode, or enable all
246 * multicast packets, or to enable selective multicast. 85 * multicast packets, or to enable selective multicast.
247 */ 86 */
248static int 87int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
249mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, 88 struct mwifiex_multicast_list *mcast_list)
250 struct mwifiex_wait_queue *wait,
251 u16 action,
252 struct mwifiex_multicast_list *mcast_list)
253{ 89{
254 int ret = 0; 90 int ret = 0;
255 u16 old_pkt_filter; 91 u16 old_pkt_filter;
256 92
257 old_pkt_filter = priv->curr_pkt_filter; 93 old_pkt_filter = priv->curr_pkt_filter;
258 if (action == HostCmd_ACT_GEN_GET)
259 return -1;
260 94
261 if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { 95 if (mcast_list->mode == MWIFIEX_PROMISC_MODE) {
262 dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); 96 dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n");
@@ -281,16 +115,15 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv,
281 /* Set multicast addresses to firmware */ 115 /* Set multicast addresses to firmware */
282 if (old_pkt_filter == priv->curr_pkt_filter) { 116 if (old_pkt_filter == priv->curr_pkt_filter) {
283 /* Send request to firmware */ 117 /* Send request to firmware */
284 ret = mwifiex_prepare_cmd(priv, 118 ret = mwifiex_send_cmd_async(priv,
285 HostCmd_CMD_MAC_MULTICAST_ADR, 119 HostCmd_CMD_MAC_MULTICAST_ADR,
286 action, 0, wait, mcast_list); 120 HostCmd_ACT_GEN_SET, 0,
287 if (!ret) 121 mcast_list);
288 ret = -EINPROGRESS;
289 } else { 122 } else {
290 /* Send request to firmware */ 123 /* Send request to firmware */
291 ret = mwifiex_prepare_cmd(priv, 124 ret = mwifiex_send_cmd_async(priv,
292 HostCmd_CMD_MAC_MULTICAST_ADR, 125 HostCmd_CMD_MAC_MULTICAST_ADR,
293 action, 0, NULL, 126 HostCmd_ACT_GEN_SET, 0,
294 mcast_list); 127 mcast_list);
295 } 128 }
296 } 129 }
@@ -300,101 +133,21 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv,
300 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", 133 "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
301 old_pkt_filter, priv->curr_pkt_filter); 134 old_pkt_filter, priv->curr_pkt_filter);
302 if (old_pkt_filter != priv->curr_pkt_filter) { 135 if (old_pkt_filter != priv->curr_pkt_filter) {
303 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, action, 136 ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
304 0, wait, &priv->curr_pkt_filter); 137 HostCmd_ACT_GEN_SET,
305 if (!ret) 138 0, &priv->curr_pkt_filter);
306 ret = -EINPROGRESS;
307 } 139 }
308 140
309 return ret; 141 return ret;
310} 142}
311 143
312/* 144/*
313 * Sends IOCTL request to set multicast list.
314 *
315 * This function allocates the IOCTL request buffer, fills it
316 * with requisite parameters and calls the IOCTL handler.
317 */
318void
319mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
320 struct net_device *dev)
321{
322 struct mwifiex_wait_queue *wait = NULL;
323 struct mwifiex_multicast_list mcast_list;
324 u8 wait_option = MWIFIEX_NO_WAIT;
325 int status = 0;
326
327 /* Allocate wait buffer */
328 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
329 if (!wait)
330 return;
331
332 if (dev->flags & IFF_PROMISC) {
333 mcast_list.mode = MWIFIEX_PROMISC_MODE;
334 } else if (dev->flags & IFF_ALLMULTI ||
335 netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
336 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
337 } else {
338 mcast_list.mode = MWIFIEX_MULTICAST_MODE;
339 if (netdev_mc_count(dev))
340 mcast_list.num_multicast_addr =
341 mwifiex_copy_mcast_addr(&mcast_list, dev);
342 }
343 status = mwifiex_bss_ioctl_multicast_list(priv, wait,
344 HostCmd_ACT_GEN_SET,
345 &mcast_list);
346
347 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
348 if (wait && status != -EINPROGRESS)
349 kfree(wait);
350
351 return;
352}
353
354/*
355 * IOCTL request handler to disconnect from a BSS/IBSS.
356 */
357static int mwifiex_bss_ioctl_stop(struct mwifiex_private *priv,
358 struct mwifiex_wait_queue *wait, u8 *mac)
359{
360 return mwifiex_deauthenticate(priv, wait, mac);
361}
362
363/*
364 * Sends IOCTL request to disconnect from a BSS.
365 *
366 * This function allocates the IOCTL request buffer, fills it
367 * with requisite parameters and calls the IOCTL handler.
368 */
369int mwifiex_disconnect(struct mwifiex_private *priv, u8 wait_option, u8 *mac)
370{
371 struct mwifiex_wait_queue *wait = NULL;
372 int status = 0;
373
374 /* Allocate wait buffer */
375 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
376 if (!wait)
377 return -ENOMEM;
378
379 status = mwifiex_bss_ioctl_stop(priv, wait, mac);
380
381 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
382
383 kfree(wait);
384 return status;
385}
386EXPORT_SYMBOL_GPL(mwifiex_disconnect);
387
388/*
389 * IOCTL request handler to join a BSS/IBSS.
390 *
391 * In Ad-Hoc mode, the IBSS is created if not found in scan list. 145 * In Ad-Hoc mode, the IBSS is created if not found in scan list.
392 * In both Ad-Hoc and infra mode, an deauthentication is performed 146 * In both Ad-Hoc and infra mode, an deauthentication is performed
393 * first. 147 * first.
394 */ 148 */
395static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, 149int mwifiex_bss_start(struct mwifiex_private *priv,
396 struct mwifiex_wait_queue *wait, 150 struct mwifiex_ssid_bssid *ssid_bssid)
397 struct mwifiex_ssid_bssid *ssid_bssid)
398{ 151{
399 int ret = 0; 152 int ret = 0;
400 struct mwifiex_adapter *adapter = priv->adapter; 153 struct mwifiex_adapter *adapter = priv->adapter;
@@ -406,7 +159,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv,
406 159
407 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 160 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
408 /* Infra mode */ 161 /* Infra mode */
409 ret = mwifiex_deauthenticate(priv, NULL, NULL); 162 ret = mwifiex_deauthenticate(priv, NULL);
410 if (ret) 163 if (ret)
411 return ret; 164 return ret;
412 165
@@ -427,7 +180,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv,
427 /* Clear any past association response stored for 180 /* Clear any past association response stored for
428 * application retrieval */ 181 * application retrieval */
429 priv->assoc_rsp_size = 0; 182 priv->assoc_rsp_size = 0;
430 ret = mwifiex_associate(priv, wait, &adapter->scan_table[i]); 183 ret = mwifiex_associate(priv, &adapter->scan_table[i]);
431 if (ret) 184 if (ret)
432 return ret; 185 return ret;
433 } else { 186 } else {
@@ -441,7 +194,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv,
441 194
442 /* Exit Adhoc mode first */ 195 /* Exit Adhoc mode first */
443 dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); 196 dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
444 ret = mwifiex_deauthenticate(priv, NULL, NULL); 197 ret = mwifiex_deauthenticate(priv, NULL);
445 if (ret) 198 if (ret)
446 return ret; 199 return ret;
447 200
@@ -460,75 +213,39 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv,
460 if (i >= 0) { 213 if (i >= 0) {
461 dev_dbg(adapter->dev, "info: network found in scan" 214 dev_dbg(adapter->dev, "info: network found in scan"
462 " list. Joining...\n"); 215 " list. Joining...\n");
463 ret = mwifiex_adhoc_join(priv, wait, 216 ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]);
464 &adapter->scan_table[i]);
465 if (ret) 217 if (ret)
466 return ret; 218 return ret;
467 } else { /* i >= 0 */ 219 } else { /* i >= 0 */
468 dev_dbg(adapter->dev, "info: Network not found in " 220 dev_dbg(adapter->dev, "info: Network not found in "
469 "the list, creating adhoc with ssid = %s\n", 221 "the list, creating adhoc with ssid = %s\n",
470 ssid_bssid->ssid.ssid); 222 ssid_bssid->ssid.ssid);
471 ret = mwifiex_adhoc_start(priv, wait, 223 ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid);
472 &ssid_bssid->ssid);
473 if (ret) 224 if (ret)
474 return ret; 225 return ret;
475 } 226 }
476 } 227 }
477 228
478 if (!ret)
479 ret = -EINPROGRESS;
480
481 return ret; 229 return ret;
482} 230}
483 231
484/* 232/*
485 * Sends IOCTL request to connect with a BSS.
486 *
487 * This function allocates the IOCTL request buffer, fills it
488 * with requisite parameters and calls the IOCTL handler.
489 */
490int mwifiex_bss_start(struct mwifiex_private *priv, u8 wait_option,
491 struct mwifiex_ssid_bssid *ssid_bssid)
492{
493 struct mwifiex_wait_queue *wait = NULL;
494 struct mwifiex_ssid_bssid tmp_ssid_bssid;
495 int status = 0;
496
497 /* Stop the O.S. TX queue if needed */
498 if (!netif_queue_stopped(priv->netdev))
499 netif_stop_queue(priv->netdev);
500
501 /* Allocate wait buffer */
502 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
503 if (!wait)
504 return -ENOMEM;
505
506 if (ssid_bssid)
507 memcpy(&tmp_ssid_bssid, ssid_bssid,
508 sizeof(struct mwifiex_ssid_bssid));
509 status = mwifiex_bss_ioctl_start(priv, wait, &tmp_ssid_bssid);
510
511 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
512
513 kfree(wait);
514 return status;
515}
516
517/*
518 * IOCTL request handler to set host sleep configuration. 233 * IOCTL request handler to set host sleep configuration.
519 * 234 *
520 * This function prepares the correct firmware command and 235 * This function prepares the correct firmware command and
521 * issues it. 236 * issues it.
522 */ 237 */
523static int 238int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
524mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, 239 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
525 struct mwifiex_wait_queue *wait, 240
526 u16 action, struct mwifiex_ds_hs_cfg *hs_cfg)
527{ 241{
528 struct mwifiex_adapter *adapter = priv->adapter; 242 struct mwifiex_adapter *adapter = priv->adapter;
529 int status = 0; 243 int status = 0;
530 u32 prev_cond = 0; 244 u32 prev_cond = 0;
531 245
246 if (!hs_cfg)
247 return -ENOMEM;
248
532 switch (action) { 249 switch (action) {
533 case HostCmd_ACT_GEN_SET: 250 case HostCmd_ACT_GEN_SET:
534 if (adapter->pps_uapsd_mode) { 251 if (adapter->pps_uapsd_mode) {
@@ -561,12 +278,16 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv,
561 status = -1; 278 status = -1;
562 break; 279 break;
563 } 280 }
564 status = mwifiex_prepare_cmd(priv, 281 if (cmd_type == MWIFIEX_SYNC_CMD)
565 HostCmd_CMD_802_11_HS_CFG_ENH, 282 status = mwifiex_send_cmd_sync(priv,
566 HostCmd_ACT_GEN_SET, 283 HostCmd_CMD_802_11_HS_CFG_ENH,
567 0, wait, &adapter->hs_cfg); 284 HostCmd_ACT_GEN_SET, 0,
568 if (!status) 285 &adapter->hs_cfg);
569 status = -EINPROGRESS; 286 else
287 status = mwifiex_send_cmd_async(priv,
288 HostCmd_CMD_802_11_HS_CFG_ENH,
289 HostCmd_ACT_GEN_SET, 0,
290 &adapter->hs_cfg);
570 if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) 291 if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL)
571 /* Restore previous condition */ 292 /* Restore previous condition */
572 adapter->hs_cfg.conditions = 293 adapter->hs_cfg.conditions =
@@ -592,42 +313,12 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv,
592} 313}
593 314
594/* 315/*
595 * Sends IOCTL request to set Host Sleep parameters.
596 *
597 * This function allocates the IOCTL request buffer, fills it
598 * with requisite parameters and calls the IOCTL handler.
599 */
600int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
601 u8 wait_option,
602 struct mwifiex_ds_hs_cfg *hscfg)
603{
604 int ret = 0;
605 struct mwifiex_wait_queue *wait = NULL;
606
607 if (!hscfg)
608 return -ENOMEM;
609
610 /* Allocate wait buffer */
611 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
612 if (!wait)
613 return -ENOMEM;
614
615 ret = mwifiex_pm_ioctl_hs_cfg(priv, wait, action, hscfg);
616
617 ret = mwifiex_request_ioctl(priv, wait, ret, wait_option);
618
619 if (wait && (ret != -EINPROGRESS))
620 kfree(wait);
621 return ret;
622}
623
624/*
625 * Sends IOCTL request to cancel the existing Host Sleep configuration. 316 * Sends IOCTL request to cancel the existing Host Sleep configuration.
626 * 317 *
627 * This function allocates the IOCTL request buffer, fills it 318 * This function allocates the IOCTL request buffer, fills it
628 * with requisite parameters and calls the IOCTL handler. 319 * with requisite parameters and calls the IOCTL handler.
629 */ 320 */
630int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) 321int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type)
631{ 322{
632 int ret = 0; 323 int ret = 0;
633 struct mwifiex_ds_hs_cfg hscfg; 324 struct mwifiex_ds_hs_cfg hscfg;
@@ -636,7 +327,7 @@ int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option)
636 hscfg.conditions = HOST_SLEEP_CFG_CANCEL; 327 hscfg.conditions = HOST_SLEEP_CFG_CANCEL;
637 hscfg.is_invoke_hostcmd = true; 328 hscfg.is_invoke_hostcmd = true;
638 ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, 329 ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
639 wait_option, &hscfg); 330 cmd_type, &hscfg);
640 331
641 return ret; 332 return ret;
642} 333}
@@ -665,8 +356,8 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
665 356
666 if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, 357 if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
667 MWIFIEX_BSS_ROLE_STA), 358 MWIFIEX_BSS_ROLE_STA),
668 HostCmd_ACT_GEN_SET, 359 HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
669 MWIFIEX_IOCTL_WAIT, &hscfg)) { 360 &hscfg)) {
670 dev_err(adapter->dev, "IOCTL request HS enable failed\n"); 361 dev_err(adapter->dev, "IOCTL request HS enable failed\n");
671 return false; 362 return false;
672 } 363 }
@@ -679,69 +370,6 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
679EXPORT_SYMBOL_GPL(mwifiex_enable_hs); 370EXPORT_SYMBOL_GPL(mwifiex_enable_hs);
680 371
681/* 372/*
682 * IOCTL request handler to get signal information.
683 *
684 * This function prepares the correct firmware command and
685 * issues it to get the signal (RSSI) information.
686 *
687 * This only works in the connected mode.
688 */
689static int mwifiex_get_info_signal(struct mwifiex_private *priv,
690 struct mwifiex_wait_queue *wait,
691 struct mwifiex_ds_get_signal *signal)
692{
693 int ret = 0;
694
695 if (!wait) {
696 dev_err(priv->adapter->dev, "WAIT information is not present\n");
697 return -1;
698 }
699
700 /* Signal info can be obtained only if connected */
701 if (!priv->media_connected) {
702 dev_dbg(priv->adapter->dev,
703 "info: Can not get signal in disconnected state\n");
704 return -1;
705 }
706
707 /* Send request to firmware */
708 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RSSI_INFO,
709 HostCmd_ACT_GEN_GET, 0, wait, signal);
710
711 if (!ret)
712 ret = -EINPROGRESS;
713
714 return ret;
715}
716
717/*
718 * IOCTL request handler to get statistics.
719 *
720 * This function prepares the correct firmware command and
721 * issues it to get the statistics (RSSI) information.
722 */
723static int mwifiex_get_info_stats(struct mwifiex_private *priv,
724 struct mwifiex_wait_queue *wait,
725 struct mwifiex_ds_get_stats *log)
726{
727 int ret = 0;
728
729 if (!wait) {
730 dev_err(priv->adapter->dev, "MWIFIEX IOCTL information is not present\n");
731 return -1;
732 }
733
734 /* Send request to firmware */
735 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_GET_LOG,
736 HostCmd_ACT_GEN_GET, 0, wait, log);
737
738 if (!ret)
739 ret = -EINPROGRESS;
740
741 return ret;
742}
743
744/*
745 * IOCTL request handler to get BSS information. 373 * IOCTL request handler to get BSS information.
746 * 374 *
747 * This function collates the information from different driver structures 375 * This function collates the information from different driver structures
@@ -813,90 +441,20 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
813} 441}
814 442
815/* 443/*
816 * IOCTL request handler to get extended version information. 444 * The function sets band configurations.
817 *
818 * This function prepares the correct firmware command and
819 * issues it to get the extended version information.
820 */
821static int mwifiex_get_info_ver_ext(struct mwifiex_private *priv,
822 struct mwifiex_wait_queue *wait,
823 struct mwifiex_ver_ext *ver_ext)
824{
825 int ret = 0;
826
827 /* Send request to firmware */
828 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_VERSION_EXT,
829 HostCmd_ACT_GEN_GET, 0, wait, ver_ext);
830 if (!ret)
831 ret = -EINPROGRESS;
832
833 return ret;
834}
835
836/*
837 * IOCTL request handler to set/get SNMP MIB parameters.
838 *
839 * This function prepares the correct firmware command and
840 * issues it.
841 * 445 *
842 * Currently the following parameters are supported - 446 * it performs extra checks to make sure the Ad-Hoc
843 * Set/get RTS Threshold
844 * Set/get fragmentation threshold
845 * Set/get retry count
846 */
847int mwifiex_snmp_mib_ioctl(struct mwifiex_private *priv,
848 struct mwifiex_wait_queue *wait,
849 u32 cmd_oid, u16 action, u32 *value)
850{
851 int ret = 0;
852
853 if (!value)
854 return -1;
855
856 /* Send request to firmware */
857 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
858 action, cmd_oid, wait, value);
859
860 if (!ret)
861 ret = -EINPROGRESS;
862
863 return ret;
864}
865
866/*
867 * IOCTL request handler to set/get band configurations.
868 *
869 * For SET operation, it performs extra checks to make sure the Ad-Hoc
870 * band and channel are compatible. Otherwise it returns an error. 447 * band and channel are compatible. Otherwise it returns an error.
871 * 448 *
872 * For GET operation, this function retrieves the following information -
873 * - Infra bands
874 * - Ad-hoc band
875 * - Ad-hoc channel
876 * - Secondary channel offset
877 */ 449 */
878int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, 450int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv,
879 u16 action, 451 struct mwifiex_ds_band_cfg *radio_cfg)
880 struct mwifiex_ds_band_cfg *radio_cfg)
881{ 452{
882 struct mwifiex_adapter *adapter = priv->adapter; 453 struct mwifiex_adapter *adapter = priv->adapter;
883 u8 infra_band = 0; 454 u8 infra_band = 0;
884 u8 adhoc_band = 0; 455 u8 adhoc_band = 0;
885 u32 adhoc_channel = 0; 456 u32 adhoc_channel = 0;
886 457
887 if (action == HostCmd_ACT_GEN_GET) {
888 /* Infra Bands */
889 radio_cfg->config_bands = adapter->config_bands;
890 /* Adhoc Band */
891 radio_cfg->adhoc_start_band = adapter->adhoc_start_band;
892 /* Adhoc channel */
893 radio_cfg->adhoc_channel = priv->adhoc_channel;
894 /* Secondary channel offset */
895 radio_cfg->sec_chan_offset = adapter->chan_offset;
896 return 0;
897 }
898
899 /* For action = SET */
900 infra_band = (u8) radio_cfg->config_bands; 458 infra_band = (u8) radio_cfg->config_bands;
901 adhoc_band = (u8) radio_cfg->adhoc_start_band; 459 adhoc_band = (u8) radio_cfg->adhoc_start_band;
902 adhoc_channel = radio_cfg->adhoc_channel; 460 adhoc_channel = radio_cfg->adhoc_channel;
@@ -950,8 +508,8 @@ int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv,
950 * This function performs validity checking on channel/frequency 508 * This function performs validity checking on channel/frequency
951 * compatibility and returns failure if not valid. 509 * compatibility and returns failure if not valid.
952 */ 510 */
953int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, 511int mwifiex_bss_set_channel(struct mwifiex_private *priv,
954 struct mwifiex_chan_freq_power *chan) 512 struct mwifiex_chan_freq_power *chan)
955{ 513{
956 struct mwifiex_adapter *adapter = priv->adapter; 514 struct mwifiex_adapter *adapter = priv->adapter;
957 struct mwifiex_chan_freq_power *cfp = NULL; 515 struct mwifiex_chan_freq_power *cfp = NULL;
@@ -959,16 +517,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action,
959 if (!chan) 517 if (!chan)
960 return -1; 518 return -1;
961 519
962 if (action == HostCmd_ACT_GEN_GET) {
963 cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
964 priv->curr_bss_params.band,
965 (u16) priv->curr_bss_params.bss_descriptor.
966 channel);
967 chan->channel = cfp->channel;
968 chan->freq = cfp->freq;
969
970 return 0;
971 }
972 if (!chan->channel && !chan->freq) 520 if (!chan->channel && !chan->freq)
973 return -1; 521 return -1;
974 if (adapter->adhoc_start_band & BAND_AN) 522 if (adapter->adhoc_start_band & BAND_AN)
@@ -1024,7 +572,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action,
1024 * issues it to set or get the ad-hoc channel. 572 * issues it to set or get the ad-hoc channel.
1025 */ 573 */
1026static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, 574static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
1027 struct mwifiex_wait_queue *wait,
1028 u16 action, u16 *channel) 575 u16 action, u16 *channel)
1029{ 576{
1030 int ret = 0; 577 int ret = 0;
@@ -1039,10 +586,8 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
1039 } 586 }
1040 587
1041 /* Send request to firmware */ 588 /* Send request to firmware */
1042 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_RF_CHANNEL, 589 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL,
1043 action, 0, wait, channel); 590 action, 0, channel);
1044 if (!ret)
1045 ret = -EINPROGRESS;
1046 591
1047 return ret; 592 return ret;
1048} 593}
@@ -1054,7 +599,6 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
1054 * these are provided, just the best BSS (best RSSI) is returned. 599 * these are provided, just the best BSS (best RSSI) is returned.
1055 */ 600 */
1056int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, 601int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv,
1057 struct mwifiex_wait_queue *wait,
1058 struct mwifiex_ssid_bssid *ssid_bssid) 602 struct mwifiex_ssid_bssid *ssid_bssid)
1059{ 603{
1060 struct mwifiex_adapter *adapter = priv->adapter; 604 struct mwifiex_adapter *adapter = priv->adapter;
@@ -1114,10 +658,7 @@ int
1114mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) 658mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
1115{ 659{
1116 int ret = 0; 660 int ret = 0;
1117 int status = 0;
1118 struct mwifiex_bss_info bss_info; 661 struct mwifiex_bss_info bss_info;
1119 struct mwifiex_wait_queue *wait = NULL;
1120 u8 wait_option = MWIFIEX_IOCTL_WAIT;
1121 struct mwifiex_ssid_bssid ssid_bssid; 662 struct mwifiex_ssid_bssid ssid_bssid;
1122 u16 curr_chan = 0; 663 u16 curr_chan = 0;
1123 664
@@ -1127,19 +668,10 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
1127 if (mwifiex_get_bss_info(priv, &bss_info)) 668 if (mwifiex_get_bss_info(priv, &bss_info))
1128 return -1; 669 return -1;
1129 670
1130 /* Allocate wait buffer */
1131 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1132 if (!wait)
1133 return -ENOMEM;
1134
1135 /* Get current channel */ 671 /* Get current channel */
1136 status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_GET, 672 ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET,
1137 &curr_chan); 673 &curr_chan);
1138 674
1139 if (mwifiex_request_ioctl(priv, wait, status, wait_option)) {
1140 ret = -1;
1141 goto done;
1142 }
1143 if (curr_chan == channel) { 675 if (curr_chan == channel) {
1144 ret = 0; 676 ret = 0;
1145 goto done; 677 goto done;
@@ -1154,23 +686,13 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
1154 686
1155 /* Do disonnect */ 687 /* Do disonnect */
1156 memset(&ssid_bssid, 0, ETH_ALEN); 688 memset(&ssid_bssid, 0, ETH_ALEN);
1157 status = mwifiex_bss_ioctl_stop(priv, wait, ssid_bssid.bssid); 689 ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid);
1158 690
1159 if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { 691 ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET,
1160 ret = -1; 692 (u16 *) &channel);
1161 goto done;
1162 }
1163
1164 status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_SET,
1165 (u16 *) &channel);
1166
1167 if (mwifiex_request_ioctl(priv, wait, status, wait_option)) {
1168 ret = -1;
1169 goto done;
1170 }
1171 693
1172 /* Do specific SSID scanning */ 694 /* Do specific SSID scanning */
1173 if (mwifiex_request_scan(priv, wait_option, &bss_info.ssid)) { 695 if (mwifiex_request_scan(priv, &bss_info.ssid)) {
1174 ret = -1; 696 ret = -1;
1175 goto done; 697 goto done;
1176 } 698 }
@@ -1179,13 +701,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
1179 memcpy(&ssid_bssid.ssid, &bss_info.ssid, 701 memcpy(&ssid_bssid.ssid, &bss_info.ssid,
1180 sizeof(struct mwifiex_802_11_ssid)); 702 sizeof(struct mwifiex_802_11_ssid));
1181 703
1182 status = mwifiex_bss_ioctl_start(priv, wait, &ssid_bssid); 704 ret = mwifiex_bss_start(priv, &ssid_bssid);
1183
1184 if (mwifiex_request_ioctl(priv, wait, status, wait_option))
1185 ret = -1;
1186
1187done: 705done:
1188 kfree(wait);
1189 return ret; 706 return ret;
1190} 707}
1191 708
@@ -1198,7 +715,6 @@ done:
1198 * for the band. 715 * for the band.
1199 */ 716 */
1200static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, 717static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv,
1201 struct mwifiex_wait_queue *wait,
1202 struct mwifiex_rate_cfg *rate_cfg) 718 struct mwifiex_rate_cfg *rate_cfg)
1203{ 719{
1204 struct mwifiex_adapter *adapter = priv->adapter; 720 struct mwifiex_adapter *adapter = priv->adapter;
@@ -1242,11 +758,9 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv,
1242 } 758 }
1243 } else { 759 } else {
1244 /* Send request to firmware */ 760 /* Send request to firmware */
1245 ret = mwifiex_prepare_cmd(priv, 761 ret = mwifiex_send_cmd_sync(priv,
1246 HostCmd_CMD_802_11_TX_RATE_QUERY, 762 HostCmd_CMD_802_11_TX_RATE_QUERY,
1247 HostCmd_ACT_GEN_GET, 0, wait, NULL); 763 HostCmd_ACT_GEN_GET, 0, NULL);
1248 if (!ret)
1249 ret = -EINPROGRESS;
1250 } 764 }
1251 765
1252 return ret; 766 return ret;
@@ -1261,7 +775,6 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv,
1261 * The function also performs validation checking on the supplied value. 775 * The function also performs validation checking on the supplied value.
1262 */ 776 */
1263static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, 777static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
1264 struct mwifiex_wait_queue *wait,
1265 struct mwifiex_rate_cfg *rate_cfg) 778 struct mwifiex_rate_cfg *rate_cfg)
1266{ 779{
1267 u8 rates[MWIFIEX_SUPPORTED_RATES]; 780 u8 rates[MWIFIEX_SUPPORTED_RATES];
@@ -1299,8 +812,7 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
1299 } 812 }
1300 memset(bitmap_rates, 0, sizeof(bitmap_rates)); 813 memset(bitmap_rates, 0, sizeof(bitmap_rates));
1301 814
1302 rate_index = 815 rate_index = mwifiex_data_rate_to_index(rate_cfg->rate);
1303 mwifiex_data_rate_to_index(adapter, rate_cfg->rate);
1304 816
1305 /* Only allow b/g rates to be set */ 817 /* Only allow b/g rates to be set */
1306 if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && 818 if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 &&
@@ -1316,10 +828,8 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
1316 } 828 }
1317 829
1318 /* Send request to firmware */ 830 /* Send request to firmware */
1319 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, 831 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG,
1320 HostCmd_ACT_GEN_SET, 0, wait, bitmap_rates); 832 HostCmd_ACT_GEN_SET, 0, bitmap_rates);
1321 if (!ret)
1322 ret = -EINPROGRESS;
1323 833
1324 return ret; 834 return ret;
1325} 835}
@@ -1331,7 +841,6 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
1331 * rate index. 841 * rate index.
1332 */ 842 */
1333static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, 843static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv,
1334 struct mwifiex_wait_queue *wait,
1335 struct mwifiex_rate_cfg *rate_cfg) 844 struct mwifiex_rate_cfg *rate_cfg)
1336{ 845{
1337 int status = 0; 846 int status = 0;
@@ -1340,11 +849,9 @@ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv,
1340 return -1; 849 return -1;
1341 850
1342 if (rate_cfg->action == HostCmd_ACT_GEN_GET) 851 if (rate_cfg->action == HostCmd_ACT_GEN_GET)
1343 status = mwifiex_rate_ioctl_get_rate_value( 852 status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg);
1344 priv, wait, rate_cfg);
1345 else 853 else
1346 status = mwifiex_rate_ioctl_set_rate_value( 854 status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg);
1347 priv, wait, rate_cfg);
1348 855
1349 return status; 856 return status;
1350} 857}
@@ -1359,30 +866,21 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
1359 struct mwifiex_rate_cfg *rate) 866 struct mwifiex_rate_cfg *rate)
1360{ 867{
1361 int ret = 0; 868 int ret = 0;
1362 struct mwifiex_wait_queue *wait = NULL;
1363 u8 wait_option = MWIFIEX_IOCTL_WAIT;
1364
1365 /* Allocate wait buffer */
1366 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1367 if (!wait)
1368 return -ENOMEM;
1369 869
1370 memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); 870 memset(rate, 0, sizeof(struct mwifiex_rate_cfg));
1371 rate->action = HostCmd_ACT_GEN_GET; 871 rate->action = HostCmd_ACT_GEN_GET;
1372 ret = mwifiex_rate_ioctl_cfg(priv, wait, rate); 872 ret = mwifiex_rate_ioctl_cfg(priv, rate);
1373 873
1374 ret = mwifiex_request_ioctl(priv, wait, ret, wait_option);
1375 if (!ret) { 874 if (!ret) {
1376 if (rate && rate->is_rate_auto) 875 if (rate && rate->is_rate_auto)
1377 rate->rate = mwifiex_index_to_data_rate(priv->adapter, 876 rate->rate = mwifiex_index_to_data_rate(priv->tx_rate,
1378 priv->tx_rate, priv->tx_htinfo); 877 priv->tx_htinfo);
1379 else if (rate) 878 else if (rate)
1380 rate->rate = priv->data_rate; 879 rate->rate = priv->data_rate;
1381 } else { 880 } else {
1382 ret = -1; 881 ret = -1;
1383 } 882 }
1384 883
1385 kfree(wait);
1386 return ret; 884 return ret;
1387} 885}
1388 886
@@ -1398,9 +896,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
1398 * - Modulation class HTBW20 896 * - Modulation class HTBW20
1399 * - Modulation class HTBW40 897 * - Modulation class HTBW40
1400 */ 898 */
1401static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, 899int mwifiex_set_tx_power(struct mwifiex_private *priv,
1402 struct mwifiex_wait_queue *wait, 900 struct mwifiex_power_cfg *power_cfg)
1403 struct mwifiex_power_cfg *power_cfg)
1404{ 901{
1405 int ret = 0; 902 int ret = 0;
1406 struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; 903 struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL;
@@ -1473,12 +970,10 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv,
1473 pg->ht_bandwidth = HT_BW_40; 970 pg->ht_bandwidth = HT_BW_40;
1474 } 971 }
1475 /* Send request to firmware */ 972 /* Send request to firmware */
1476 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, 973 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG,
1477 HostCmd_ACT_GEN_SET, 0, wait, buf); 974 HostCmd_ACT_GEN_SET, 0, buf);
1478 if (!ret)
1479 ret = -EINPROGRESS;
1480 kfree(buf);
1481 975
976 kfree(buf);
1482 return ret; 977 return ret;
1483} 978}
1484 979
@@ -1488,33 +983,23 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv,
1488 * This function prepares the correct firmware command and 983 * This function prepares the correct firmware command and
1489 * issues it. 984 * issues it.
1490 */ 985 */
1491static int mwifiex_pm_ioctl_ps_mode(struct mwifiex_private *priv, 986int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
1492 struct mwifiex_wait_queue *wait,
1493 u32 *ps_mode, u16 action)
1494{ 987{
1495 int ret = 0; 988 int ret = 0;
1496 struct mwifiex_adapter *adapter = priv->adapter; 989 struct mwifiex_adapter *adapter = priv->adapter;
1497 u16 sub_cmd; 990 u16 sub_cmd;
1498 991
1499 if (action == HostCmd_ACT_GEN_SET) { 992 if (*ps_mode)
1500 if (*ps_mode) 993 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1501 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; 994 else
1502 else 995 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
1503 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; 996 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS;
1504 sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; 997 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1505 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, 998 sub_cmd, BITMAP_STA_PS, NULL);
1506 sub_cmd, BITMAP_STA_PS, wait, NULL); 999 if ((!ret) && (sub_cmd == DIS_AUTO_PS))
1507 if ((!ret) && (sub_cmd == DIS_AUTO_PS)) 1000 ret = mwifiex_send_cmd_async(priv,
1508 ret = mwifiex_prepare_cmd(priv, 1001 HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS,
1509 HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, 1002 0, NULL);
1510 0, NULL, NULL);
1511 } else {
1512 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
1513 GET_PS, 0, wait, NULL);
1514 }
1515
1516 if (!ret)
1517 ret = -EINPROGRESS;
1518 1003
1519 return ret; 1004 return ret;
1520} 1005}
@@ -1600,18 +1085,14 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
1600 * This function prepares the correct firmware command and 1085 * This function prepares the correct firmware command and
1601 * issues it. 1086 * issues it.
1602 */ 1087 */
1603static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, 1088static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
1604 struct mwifiex_wait_queue *wait,
1605 struct mwifiex_ds_encrypt_key *encrypt_key) 1089 struct mwifiex_ds_encrypt_key *encrypt_key)
1606{ 1090{
1607 int ret = 0; 1091 int ret = 0;
1608 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
1609 1092
1610 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 1093 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
1611 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, 1094 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
1612 wait, encrypt_key); 1095 encrypt_key);
1613 if (!ret)
1614 ret = -EINPROGRESS;
1615 1096
1616 return ret; 1097 return ret;
1617} 1098}
@@ -1622,12 +1103,10 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter,
1622 * This function prepares the correct firmware command and 1103 * This function prepares the correct firmware command and
1623 * issues it, after validation checks. 1104 * issues it, after validation checks.
1624 */ 1105 */
1625static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, 1106static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
1626 struct mwifiex_wait_queue *wait,
1627 struct mwifiex_ds_encrypt_key *encrypt_key) 1107 struct mwifiex_ds_encrypt_key *encrypt_key)
1628{ 1108{
1629 int ret = 0; 1109 int ret = 0;
1630 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
1631 struct mwifiex_wep_key *wep_key = NULL; 1110 struct mwifiex_wep_key *wep_key = NULL;
1632 int index; 1111 int index;
1633 1112
@@ -1641,7 +1120,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter,
1641 /* Copy the required key as the current key */ 1120 /* Copy the required key as the current key */
1642 wep_key = &priv->wep_key[index]; 1121 wep_key = &priv->wep_key[index];
1643 if (!wep_key->key_length) { 1122 if (!wep_key->key_length) {
1644 dev_err(adapter->dev, 1123 dev_err(priv->adapter->dev,
1645 "key not set, so cannot enable it\n"); 1124 "key not set, so cannot enable it\n");
1646 return -1; 1125 return -1;
1647 } 1126 }
@@ -1661,8 +1140,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter,
1661 } 1140 }
1662 if (wep_key->key_length) { 1141 if (wep_key->key_length) {
1663 /* Send request to firmware */ 1142 /* Send request to firmware */
1664 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 1143 ret = mwifiex_send_cmd_async(priv,
1665 HostCmd_ACT_GEN_SET, 0, NULL, NULL); 1144 HostCmd_CMD_802_11_KEY_MATERIAL,
1145 HostCmd_ACT_GEN_SET, 0, NULL);
1666 if (ret) 1146 if (ret)
1667 return ret; 1147 return ret;
1668 } 1148 }
@@ -1672,11 +1152,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter,
1672 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; 1152 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1673 1153
1674 /* Send request to firmware */ 1154 /* Send request to firmware */
1675 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, 1155 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
1676 HostCmd_ACT_GEN_SET, 0, wait, 1156 HostCmd_ACT_GEN_SET, 0,
1677 &priv->curr_pkt_filter); 1157 &priv->curr_pkt_filter);
1678 if (!ret)
1679 ret = -EINPROGRESS;
1680 1158
1681 return ret; 1159 return ret;
1682} 1160}
@@ -1691,18 +1169,16 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter,
1691 * 1169 *
1692 * This function can also be used to disable a currently set key. 1170 * This function can also be used to disable a currently set key.
1693 */ 1171 */
1694static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, 1172static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
1695 struct mwifiex_wait_queue *wait,
1696 struct mwifiex_ds_encrypt_key *encrypt_key) 1173 struct mwifiex_ds_encrypt_key *encrypt_key)
1697{ 1174{
1698 int ret = 0; 1175 int ret = 0;
1699 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
1700 u8 remove_key = false; 1176 u8 remove_key = false;
1701 struct host_cmd_ds_802_11_key_material *ibss_key; 1177 struct host_cmd_ds_802_11_key_material *ibss_key;
1702 1178
1703 /* Current driver only supports key length of up to 32 bytes */ 1179 /* Current driver only supports key length of up to 32 bytes */
1704 if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { 1180 if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) {
1705 dev_err(adapter->dev, "key length too long\n"); 1181 dev_err(priv->adapter->dev, "key length too long\n");
1706 return -1; 1182 return -1;
1707 } 1183 }
1708 1184
@@ -1713,9 +1189,10 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter,
1713 */ 1189 */
1714 /* Send the key as PTK to firmware */ 1190 /* Send the key as PTK to firmware */
1715 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; 1191 encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
1716 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 1192 ret = mwifiex_send_cmd_async(priv,
1717 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, 1193 HostCmd_CMD_802_11_KEY_MATERIAL,
1718 NULL, encrypt_key); 1194 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
1195 encrypt_key);
1719 if (ret) 1196 if (ret)
1720 return ret; 1197 return ret;
1721 1198
@@ -1729,8 +1206,7 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter,
1729 sizeof(ibss_key->key_param_set.key_len)); 1206 sizeof(ibss_key->key_param_set.key_len));
1730 ibss_key->key_param_set.key_type_id 1207 ibss_key->key_param_set.key_type_id
1731 = cpu_to_le16(KEY_TYPE_ID_TKIP); 1208 = cpu_to_le16(KEY_TYPE_ID_TKIP);
1732 ibss_key->key_param_set.key_info 1209 ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED);
1733 = cpu_to_le16(KEY_INFO_TKIP_ENABLED);
1734 1210
1735 /* Send the key as GTK to firmware */ 1211 /* Send the key as GTK to firmware */
1736 encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; 1212 encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST;
@@ -1741,18 +1217,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter,
1741 1217
1742 if (remove_key) 1218 if (remove_key)
1743 /* Send request to firmware */ 1219 /* Send request to firmware */
1744 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 1220 ret = mwifiex_send_cmd_sync(priv,
1745 HostCmd_ACT_GEN_SET, 1221 HostCmd_CMD_802_11_KEY_MATERIAL,
1746 !(KEY_INFO_ENABLED), 1222 HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED),
1747 wait, encrypt_key); 1223 encrypt_key);
1748 else 1224 else
1749 /* Send request to firmware */ 1225 /* Send request to firmware */
1750 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, 1226 ret = mwifiex_send_cmd_sync(priv,
1751 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, 1227 HostCmd_CMD_802_11_KEY_MATERIAL,
1752 wait, encrypt_key); 1228 HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
1753 1229 encrypt_key);
1754 if (!ret)
1755 ret = -EINPROGRESS;
1756 1230
1757 return ret; 1231 return ret;
1758} 1232}
@@ -1765,21 +1239,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter,
1765 */ 1239 */
1766static int 1240static int
1767mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, 1241mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv,
1768 struct mwifiex_wait_queue *wait,
1769 struct mwifiex_ds_encrypt_key *encrypt_key) 1242 struct mwifiex_ds_encrypt_key *encrypt_key)
1770{ 1243{
1771 int status = 0; 1244 int status = 0;
1772 struct mwifiex_adapter *adapter = priv->adapter;
1773 1245
1774 if (encrypt_key->is_wapi_key) 1246 if (encrypt_key->is_wapi_key)
1775 status = mwifiex_sec_ioctl_set_wapi_key(adapter, wait, 1247 status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key);
1776 encrypt_key);
1777 else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) 1248 else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104)
1778 status = mwifiex_sec_ioctl_set_wpa_key(adapter, wait, 1249 status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key);
1779 encrypt_key);
1780 else 1250 else
1781 status = mwifiex_sec_ioctl_set_wep_key(adapter, wait, 1251 status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key);
1782 encrypt_key);
1783 return status; 1252 return status;
1784} 1253}
1785 1254
@@ -1807,94 +1276,31 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
1807} 1276}
1808 1277
1809/* 1278/*
1810 * Sends IOCTL request to set Tx power. It can be set to either auto
1811 * or a fixed value.
1812 *
1813 * This function allocates the IOCTL request buffer, fills it
1814 * with requisite parameters and calls the IOCTL handler.
1815 */
1816int
1817mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm)
1818{
1819 struct mwifiex_power_cfg power_cfg;
1820 struct mwifiex_wait_queue *wait = NULL;
1821 int status = 0;
1822 int ret = 0;
1823
1824 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
1825 if (!wait)
1826 return -ENOMEM;
1827
1828 if (type == NL80211_TX_POWER_FIXED) {
1829 power_cfg.is_power_auto = 0;
1830 power_cfg.power_level = dbm;
1831 } else {
1832 power_cfg.is_power_auto = 1;
1833 }
1834 status = mwifiex_power_ioctl_set_power(priv, wait, &power_cfg);
1835
1836 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
1837
1838 kfree(wait);
1839 return ret;
1840}
1841
1842/*
1843 * Sends IOCTL request to get scan table.
1844 *
1845 * This function allocates the IOCTL request buffer, fills it
1846 * with requisite parameters and calls the IOCTL handler.
1847 */
1848int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option,
1849 struct mwifiex_scan_resp *scan_resp)
1850{
1851 struct mwifiex_wait_queue *wait = NULL;
1852 struct mwifiex_scan_resp scan;
1853 int status = 0;
1854
1855 /* Allocate wait buffer */
1856 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1857 if (!wait)
1858 return -ENOMEM;
1859
1860 status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_GET,
1861 NULL, &scan);
1862
1863 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
1864 if (!status) {
1865 if (scan_resp)
1866 memcpy(scan_resp, &scan,
1867 sizeof(struct mwifiex_scan_resp));
1868 }
1869
1870 if (wait && (status != -EINPROGRESS))
1871 kfree(wait);
1872 return status;
1873}
1874
1875/*
1876 * Sends IOCTL request to get signal information. 1279 * Sends IOCTL request to get signal information.
1877 * 1280 *
1878 * This function allocates the IOCTL request buffer, fills it 1281 * This function allocates the IOCTL request buffer, fills it
1879 * with requisite parameters and calls the IOCTL handler. 1282 * with requisite parameters and calls the IOCTL handler.
1880 */ 1283 */
1881int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, 1284int mwifiex_get_signal_info(struct mwifiex_private *priv,
1882 struct mwifiex_ds_get_signal *signal) 1285 struct mwifiex_ds_get_signal *signal)
1883{ 1286{
1884 struct mwifiex_ds_get_signal info; 1287 struct mwifiex_ds_get_signal info;
1885 struct mwifiex_wait_queue *wait = NULL;
1886 int status = 0; 1288 int status = 0;
1887 1289
1888 /* Allocate wait buffer */ 1290 memset(&info, 0, sizeof(struct mwifiex_ds_get_signal));
1889 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1890 if (!wait)
1891 return -ENOMEM;
1892
1893 info.selector = ALL_RSSI_INFO_MASK; 1291 info.selector = ALL_RSSI_INFO_MASK;
1894 1292
1895 status = mwifiex_get_info_signal(priv, wait, &info); 1293 /* Signal info can be obtained only if connected */
1294 if (!priv->media_connected) {
1295 dev_dbg(priv->adapter->dev,
1296 "info: Can not get signal in disconnected state\n");
1297 return -1;
1298 }
1299
1300 /* Send request to firmware */
1301 status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO,
1302 HostCmd_ACT_GEN_GET, 0, signal);
1896 1303
1897 status = mwifiex_request_ioctl(priv, wait, status, wait_option);
1898 if (!status) { 1304 if (!status) {
1899 if (signal) 1305 if (signal)
1900 memcpy(signal, &info, 1306 memcpy(signal, &info,
@@ -1905,8 +1311,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option,
1905 priv->w_stats.qual.noise = info.bcn_nf_avg; 1311 priv->w_stats.qual.noise = info.bcn_nf_avg;
1906 } 1312 }
1907 1313
1908 if (wait && (status != -EINPROGRESS))
1909 kfree(wait);
1910 return status; 1314 return status;
1911} 1315}
1912 1316
@@ -1919,15 +1323,9 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option,
1919int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, 1323int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
1920 int key_len, u8 key_index, int disable) 1324 int key_len, u8 key_index, int disable)
1921{ 1325{
1922 struct mwifiex_wait_queue *wait = NULL;
1923 struct mwifiex_ds_encrypt_key encrypt_key; 1326 struct mwifiex_ds_encrypt_key encrypt_key;
1924 int status = 0;
1925 int ret = 0; 1327 int ret = 0;
1926 1328
1927 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
1928 if (!wait)
1929 return -ENOMEM;
1930
1931 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); 1329 memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
1932 encrypt_key.key_len = key_len; 1330 encrypt_key.key_len = key_len;
1933 if (!disable) { 1331 if (!disable) {
@@ -1938,40 +1336,8 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
1938 encrypt_key.key_disable = true; 1336 encrypt_key.key_disable = true;
1939 } 1337 }
1940 1338
1941 status = mwifiex_sec_ioctl_encrypt_key(priv, wait, &encrypt_key); 1339 ret = mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);
1942
1943 if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT))
1944 ret = -EFAULT;
1945
1946 kfree(wait);
1947 return ret;
1948}
1949
1950/*
1951 * Sends IOCTL request to set power management parameters.
1952 *
1953 * This function allocates the IOCTL request buffer, fills it
1954 * with requisite parameters and calls the IOCTL handler.
1955 */
1956int
1957mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on)
1958{
1959 int ret = 0;
1960 int status = 0;
1961 struct mwifiex_wait_queue *wait = NULL;
1962 u32 ps_mode;
1963
1964 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
1965 if (!wait)
1966 return -ENOMEM;
1967
1968 ps_mode = power_on;
1969 status = mwifiex_pm_ioctl_ps_mode(priv, wait, &ps_mode,
1970 HostCmd_ACT_GEN_SET);
1971 1340
1972 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
1973
1974 kfree(wait);
1975 return ret; 1341 return ret;
1976} 1342}
1977 1343
@@ -1985,26 +1351,17 @@ int
1985mwifiex_get_ver_ext(struct mwifiex_private *priv) 1351mwifiex_get_ver_ext(struct mwifiex_private *priv)
1986{ 1352{
1987 struct mwifiex_ver_ext ver_ext; 1353 struct mwifiex_ver_ext ver_ext;
1988 struct mwifiex_wait_queue *wait = NULL;
1989 int status = 0;
1990 int ret = 0; 1354 int ret = 0;
1991 u8 wait_option = MWIFIEX_IOCTL_WAIT;
1992
1993 /* Allocate wait buffer */
1994 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
1995 if (!wait)
1996 return -ENOMEM;
1997 1355
1998 /* get fw version */ 1356 /* get fw version */
1999 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); 1357 memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
2000 status = mwifiex_get_info_ver_ext(priv, wait, &ver_ext); 1358 /* Send request to firmware */
2001 1359 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT,
2002 ret = mwifiex_request_ioctl(priv, wait, status, wait_option); 1360 HostCmd_ACT_GEN_GET, 0, &ver_ext);
2003 1361
2004 if (ret) 1362 if (ret)
2005 ret = -1; 1363 ret = -1;
2006 1364
2007 kfree(wait);
2008 return ret; 1365 return ret;
2009} 1366}
2010 1367
@@ -2019,21 +1376,13 @@ mwifiex_get_stats_info(struct mwifiex_private *priv,
2019 struct mwifiex_ds_get_stats *log) 1376 struct mwifiex_ds_get_stats *log)
2020{ 1377{
2021 int ret = 0; 1378 int ret = 0;
2022 int status = 0;
2023 struct mwifiex_wait_queue *wait = NULL;
2024 struct mwifiex_ds_get_stats get_log; 1379 struct mwifiex_ds_get_stats get_log;
2025 u8 wait_option = MWIFIEX_IOCTL_WAIT;
2026
2027 /* Allocate wait buffer */
2028 wait = mwifiex_alloc_fill_wait_queue(priv, wait_option);
2029 if (!wait)
2030 return -ENOMEM;
2031 1380
2032 memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); 1381 memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats));
2033 status = mwifiex_get_info_stats(priv, wait, &get_log); 1382 /* Send request to firmware */
1383 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
1384 HostCmd_ACT_GEN_GET, 0, &get_log);
2034 1385
2035 /* Send IOCTL request to MWIFIEX */
2036 ret = mwifiex_request_ioctl(priv, wait, status, wait_option);
2037 if (!ret) { 1386 if (!ret) {
2038 if (log) 1387 if (log)
2039 memcpy(log, &get_log, sizeof(struct 1388 memcpy(log, &get_log, sizeof(struct
@@ -2043,7 +1392,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv,
2043 priv->w_stats.discard.misc = get_log.ack_failure; 1392 priv->w_stats.discard.misc = get_log.ack_failure;
2044 } 1393 }
2045 1394
2046 kfree(wait);
2047 return ret; 1395 return ret;
2048} 1396}
2049 1397
@@ -2061,7 +1409,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv,
2061 * - CAU 1409 * - CAU
2062 */ 1410 */
2063static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, 1411static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
2064 struct mwifiex_wait_queue *wait,
2065 struct mwifiex_ds_reg_rw *reg_rw, 1412 struct mwifiex_ds_reg_rw *reg_rw,
2066 u16 action) 1413 u16 action)
2067{ 1414{
@@ -2089,10 +1436,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
2089 } 1436 }
2090 1437
2091 /* Send request to firmware */ 1438 /* Send request to firmware */
2092 ret = mwifiex_prepare_cmd(priv, cmd_no, action, 0, wait, reg_rw); 1439 ret = mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw);
2093
2094 if (!ret)
2095 ret = -EINPROGRESS;
2096 1440
2097 return ret; 1441 return ret;
2098} 1442}
@@ -2108,23 +1452,13 @@ mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type,
2108 u32 reg_offset, u32 reg_value) 1452 u32 reg_offset, u32 reg_value)
2109{ 1453{
2110 int ret = 0; 1454 int ret = 0;
2111 int status = 0;
2112 struct mwifiex_wait_queue *wait = NULL;
2113 struct mwifiex_ds_reg_rw reg_rw; 1455 struct mwifiex_ds_reg_rw reg_rw;
2114 1456
2115 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
2116 if (!wait)
2117 return -ENOMEM;
2118
2119 reg_rw.type = cpu_to_le32(reg_type); 1457 reg_rw.type = cpu_to_le32(reg_type);
2120 reg_rw.offset = cpu_to_le32(reg_offset); 1458 reg_rw.offset = cpu_to_le32(reg_offset);
2121 reg_rw.value = cpu_to_le32(reg_value); 1459 reg_rw.value = cpu_to_le32(reg_value);
2122 status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, &reg_rw, 1460 ret = mwifiex_reg_mem_ioctl_reg_rw(priv, &reg_rw, HostCmd_ACT_GEN_SET);
2123 HostCmd_ACT_GEN_SET);
2124 1461
2125 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
2126
2127 kfree(wait);
2128 return ret; 1462 return ret;
2129} 1463}
2130 1464
@@ -2139,50 +1473,18 @@ mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
2139 u32 reg_offset, u32 *value) 1473 u32 reg_offset, u32 *value)
2140{ 1474{
2141 int ret = 0; 1475 int ret = 0;
2142 int status = 0;
2143 struct mwifiex_wait_queue *wait = NULL;
2144 struct mwifiex_ds_reg_rw reg_rw; 1476 struct mwifiex_ds_reg_rw reg_rw;
2145 1477
2146 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
2147 if (!wait)
2148 return -ENOMEM;
2149
2150 reg_rw.type = cpu_to_le32(reg_type); 1478 reg_rw.type = cpu_to_le32(reg_type);
2151 reg_rw.offset = cpu_to_le32(reg_offset); 1479 reg_rw.offset = cpu_to_le32(reg_offset);
2152 status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, &reg_rw, 1480 ret = mwifiex_reg_mem_ioctl_reg_rw(priv, &reg_rw, HostCmd_ACT_GEN_GET);
2153 HostCmd_ACT_GEN_GET);
2154 1481
2155 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT);
2156 if (ret) 1482 if (ret)
2157 goto done; 1483 goto done;
2158 1484
2159 *value = le32_to_cpu(reg_rw.value); 1485 *value = le32_to_cpu(reg_rw.value);
2160 1486
2161done: 1487done:
2162 kfree(wait);
2163 return ret;
2164}
2165
2166/*
2167 * IOCTL request handler to read EEPROM.
2168 *
2169 * This function prepares the correct firmware command and
2170 * issues it.
2171 */
2172static int
2173mwifiex_reg_mem_ioctl_read_eeprom(struct mwifiex_private *priv,
2174 struct mwifiex_wait_queue *wait,
2175 struct mwifiex_ds_read_eeprom *rd_eeprom)
2176{
2177 int ret = 0;
2178
2179 /* Send request to firmware */
2180 ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
2181 HostCmd_ACT_GEN_GET, 0, wait, rd_eeprom);
2182
2183 if (!ret)
2184 ret = -EINPROGRESS;
2185
2186 return ret; 1488 return ret;
2187} 1489}
2188 1490
@@ -2197,25 +1499,17 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
2197 u8 *value) 1499 u8 *value)
2198{ 1500{
2199 int ret = 0; 1501 int ret = 0;
2200 int status = 0;
2201 struct mwifiex_wait_queue *wait = NULL;
2202 struct mwifiex_ds_read_eeprom rd_eeprom; 1502 struct mwifiex_ds_read_eeprom rd_eeprom;
2203 1503
2204 wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT);
2205 if (!wait)
2206 return -ENOMEM;
2207
2208 rd_eeprom.offset = cpu_to_le16((u16) offset); 1504 rd_eeprom.offset = cpu_to_le16((u16) offset);
2209 rd_eeprom.byte_count = cpu_to_le16((u16) bytes); 1505 rd_eeprom.byte_count = cpu_to_le16((u16) bytes);
2210 status = mwifiex_reg_mem_ioctl_read_eeprom(priv, wait, &rd_eeprom);
2211 1506
2212 ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); 1507 /* Send request to firmware */
2213 if (ret) 1508 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
2214 goto done; 1509 HostCmd_ACT_GEN_GET, 0, &rd_eeprom);
2215 1510
2216 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); 1511 if (!ret)
2217done: 1512 memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA);
2218 kfree(wait);
2219 return ret; 1513 return ret;
2220} 1514}
2221 1515
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index e8db6bd021c6..b261d812c4d3 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -51,7 +51,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
51 if (!skb->len) { 51 if (!skb->len) {
52 dev_err(adapter->dev, "Tx: bad packet length: %d\n", 52 dev_err(adapter->dev, "Tx: bad packet length: %d\n",
53 skb->len); 53 skb->len);
54 tx_info->status_code = MWIFIEX_ERROR_PKT_SIZE_INVALID; 54 tx_info->status_code = -1;
55 return skb->data; 55 return skb->data;
56 } 56 }
57 57
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 205022aa52f5..9f65587622fd 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -55,17 +55,12 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
55} 55}
56 56
57/* 57/*
58 * IOCTL request handler to send function init/shutdown command 58 * This function sends init/shutdown command
59 * to firmware. 59 * to firmware.
60 *
61 * This function prepares the correct firmware command and
62 * issues it.
63 */ 60 */
64int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, 61int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
65 struct mwifiex_wait_queue *wait, 62 u32 func_init_shutdown)
66 u32 func_init_shutdown)
67{ 63{
68 struct mwifiex_private *priv = adapter->priv[wait->bss_index];
69 int ret; 64 int ret;
70 u16 cmd; 65 u16 cmd;
71 66
@@ -74,19 +69,16 @@ int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter,
74 } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { 69 } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) {
75 cmd = HostCmd_CMD_FUNC_SHUTDOWN; 70 cmd = HostCmd_CMD_FUNC_SHUTDOWN;
76 } else { 71 } else {
77 dev_err(adapter->dev, "unsupported parameter\n"); 72 dev_err(priv->adapter->dev, "unsupported parameter\n");
78 return -1; 73 return -1;
79 } 74 }
80 75
81 /* Send command to firmware */ 76 /* Send command to firmware */
82 ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET, 77 ret = mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL);
83 0, wait, NULL);
84
85 if (!ret)
86 ret = -EINPROGRESS;
87 78
88 return ret; 79 return ret;
89} 80}
81EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw);
90 82
91/* 83/*
92 * IOCTL request handler to set/get debug information. 84 * IOCTL request handler to set/get debug information.
@@ -222,31 +214,18 @@ int mwifiex_recv_complete(struct mwifiex_adapter *adapter,
222 * corresponding waiting function. Otherwise, it processes the 214 * corresponding waiting function. Otherwise, it processes the
223 * IOCTL response and frees the response buffer. 215 * IOCTL response and frees the response buffer.
224 */ 216 */
225int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, 217int mwifiex_complete_cmd(struct mwifiex_adapter *adapter)
226 struct mwifiex_wait_queue *wait_queue,
227 int status)
228{ 218{
229 enum mwifiex_error_code status_code = 219 atomic_dec(&adapter->cmd_pending);
230 (enum mwifiex_error_code) wait_queue->status; 220 dev_dbg(adapter->dev, "cmd completed: status=%d\n",
231 221 adapter->cmd_wait_q.status);
232 atomic_dec(&adapter->ioctl_pending);
233 222
234 dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d," 223 adapter->cmd_wait_q.condition = true;
235 " status_code=%#x\n", status, status_code);
236 224
237 if (wait_queue->enabled) { 225 if (adapter->cmd_wait_q.status == -ETIMEDOUT)
238 *wait_queue->condition = true; 226 dev_err(adapter->dev, "cmd timeout\n");
239 wait_queue->status = status; 227 else
240 if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT)) 228 wake_up_interruptible(&adapter->cmd_wait_q.wait);
241 dev_err(adapter->dev, "cmd timeout\n");
242 else
243 wake_up_interruptible(wait_queue->wait);
244 } else {
245 if (status)
246 dev_err(adapter->dev, "cmd failed: status_code=%#x\n",
247 status_code);
248 kfree(wait_queue);
249 }
250 229
251 return 0; 230 return 0;
252} 231}
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 1cfbc6bed692..99e8431c1e93 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -177,8 +177,7 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
177 * This function map ACs to TIDs. 177 * This function map ACs to TIDs.
178 */ 178 */
179static void 179static void
180mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv, 180mwifiex_wmm_queue_priorities_tid(u8 queue_priority[])
181 u8 queue_priority[])
182{ 181{
183 int i; 182 int i;
184 183
@@ -247,7 +246,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
247 } 246 }
248 } 247 }
249 248
250 mwifiex_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority); 249 mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority);
251} 250}
252 251
253/* 252/*
@@ -416,7 +415,7 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
416 priv = adapter->priv[j]; 415 priv = adapter->priv[j];
417 if (priv) { 416 if (priv) {
418 for (i = 0; i < MAX_NUM_TID; i++) 417 for (i = 0; i < MAX_NUM_TID; i++)
419 if (!mwifiex_wmm_is_ra_list_empty(adapter, 418 if (!mwifiex_wmm_is_ra_list_empty(
420 &priv->wmm.tid_tbl_ptr[i].ra_list)) 419 &priv->wmm.tid_tbl_ptr[i].ra_list))
421 return false; 420 return false;
422 } 421 }
@@ -1161,7 +1160,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1161 if (!ptr) 1160 if (!ptr)
1162 return -1; 1161 return -1;
1163 1162
1164 tid = mwifiex_get_tid(priv->adapter, ptr); 1163 tid = mwifiex_get_tid(ptr);
1165 1164
1166 dev_dbg(adapter->dev, "data: tid=%d\n", tid); 1165 dev_dbg(adapter->dev, "data: tid=%d\n", tid);
1167 1166
@@ -1186,14 +1185,14 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1186 /* ra_list_spinlock has been freed in 1185 /* ra_list_spinlock has been freed in
1187 mwifiex_send_single_packet() */ 1186 mwifiex_send_single_packet() */
1188 } else { 1187 } else {
1189 if (mwifiex_is_ampdu_allowed(priv, ptr, tid)) { 1188 if (mwifiex_is_ampdu_allowed(priv, tid)) {
1190 if (mwifiex_is_ba_stream_avail(priv)) { 1189 if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
1191 mwifiex_11n_create_tx_ba_stream_tbl(priv, 1190 mwifiex_11n_create_tx_ba_stream_tbl(priv,
1192 ptr->ra, tid, 1191 ptr->ra, tid,
1193 BA_STREAM_SETUP_INPROGRESS); 1192 BA_STREAM_SETUP_INPROGRESS);
1194 mwifiex_send_addba(priv, tid, ptr->ra); 1193 mwifiex_send_addba(priv, tid, ptr->ra);
1195 } else if (mwifiex_find_stream_to_delete 1194 } else if (mwifiex_find_stream_to_delete
1196 (priv, ptr, tid, &tid_del, ra)) { 1195 (priv, tid, &tid_del, ra)) {
1197 mwifiex_11n_create_tx_ba_stream_tbl(priv, 1196 mwifiex_11n_create_tx_ba_stream_tbl(priv,
1198 ptr->ra, tid, 1197 ptr->ra, tid,
1199 BA_STREAM_SETUP_INPROGRESS); 1198 BA_STREAM_SETUP_INPROGRESS);
@@ -1202,7 +1201,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1202 } 1201 }
1203/* Minimum number of AMSDU */ 1202/* Minimum number of AMSDU */
1204#define MIN_NUM_AMSDU 2 1203#define MIN_NUM_AMSDU 2
1205 if (mwifiex_is_amsdu_allowed(priv, ptr, tid) && 1204 if (mwifiex_is_amsdu_allowed(priv, tid) &&
1206 (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= 1205 (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >=
1207 MIN_NUM_AMSDU)) 1206 MIN_NUM_AMSDU))
1208 mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, 1207 mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
@@ -1232,6 +1231,4 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
1232 if (mwifiex_dequeue_tx_packet(adapter)) 1231 if (mwifiex_dequeue_tx_packet(adapter))
1233 break; 1232 break;
1234 } while (true); 1233 } while (true);
1235
1236 return;
1237} 1234}
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index 241f1b0b77f9..fcea1f68792f 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -35,8 +35,7 @@ enum ieee_types_wmm_ecw_bitmasks {
35 * This function retrieves the TID of the given RA list. 35 * This function retrieves the TID of the given RA list.
36 */ 36 */
37static inline int 37static inline int
38mwifiex_get_tid(struct mwifiex_adapter *adapter, 38mwifiex_get_tid(struct mwifiex_ra_list_tbl *ptr)
39 struct mwifiex_ra_list_tbl *ptr)
40{ 39{
41 struct sk_buff *skb; 40 struct sk_buff *skb;
42 41
@@ -52,7 +51,7 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter,
52 * This function gets the length of a list. 51 * This function gets the length of a list.
53 */ 52 */
54static inline int 53static inline int
55mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) 54mwifiex_wmm_list_len(struct list_head *head)
56{ 55{
57 struct list_head *pos; 56 struct list_head *pos;
58 int count = 0; 57 int count = 0;
@@ -67,8 +66,7 @@ mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head)
67 * This function checks if a RA list is empty or not. 66 * This function checks if a RA list is empty or not.
68 */ 67 */
69static inline u8 68static inline u8
70mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter, 69mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead)
71 struct list_head *ra_list_hhead)
72{ 70{
73 struct mwifiex_ra_list_tbl *ra_list; 71 struct mwifiex_ra_list_tbl *ra_list;
74 int is_list_empty; 72 int is_list_empty;
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 8913180a7bd3..28ebaec80be6 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -289,10 +289,17 @@ struct mwl8k_vif {
289#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) 289#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
290#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) 290#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
291 291
292struct tx_traffic_info {
293 u32 start_time;
294 u32 pkts;
295};
296
297#define MWL8K_MAX_TID 8
292struct mwl8k_sta { 298struct mwl8k_sta {
293 /* Index into station database. Returned by UPDATE_STADB. */ 299 /* Index into station database. Returned by UPDATE_STADB. */
294 u8 peer_id; 300 u8 peer_id;
295 u8 is_ampdu_allowed; 301 u8 is_ampdu_allowed;
302 struct tx_traffic_info tx_stats[MWL8K_MAX_TID];
296}; 303};
297#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) 304#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
298 305
@@ -701,7 +708,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
701 "helper image\n", pci_name(priv->pdev)); 708 "helper image\n", pci_name(priv->pdev));
702 return rc; 709 return rc;
703 } 710 }
704 msleep(5); 711 msleep(20);
705 712
706 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); 713 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
707 } else { 714 } else {
@@ -823,8 +830,8 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
823 /* 830 /*
824 * Make sure the packet header is in the DMA header format (4-address 831 * Make sure the packet header is in the DMA header format (4-address
825 * without QoS), the necessary crypto padding between the header and the 832 * without QoS), the necessary crypto padding between the header and the
826 * payload has already been provided by mac80211, but it doesn't add tail 833 * payload has already been provided by mac80211, but it doesn't add
827 * padding when HW crypto is enabled. 834 * tail padding when HW crypto is enabled.
828 * 835 *
829 * We have the following trailer padding requirements: 836 * We have the following trailer padding requirements:
830 * - WEP: 4 trailer bytes (ICV) 837 * - WEP: 4 trailer bytes (ICV)
@@ -1487,9 +1494,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1487 1494
1488 if (timeout) { 1495 if (timeout) {
1489 WARN_ON(priv->pending_tx_pkts); 1496 WARN_ON(priv->pending_tx_pkts);
1490 if (retry) { 1497 if (retry)
1491 wiphy_notice(hw->wiphy, "tx rings drained\n"); 1498 wiphy_notice(hw->wiphy, "tx rings drained\n");
1492 }
1493 break; 1499 break;
1494 } 1500 }
1495 1501
@@ -1649,8 +1655,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1649 /* Rate control is happening in the firmware. 1655 /* Rate control is happening in the firmware.
1650 * Ensure no tx rate is being reported. 1656 * Ensure no tx rate is being reported.
1651 */ 1657 */
1652 info->status.rates[0].idx = -1; 1658 info->status.rates[0].idx = -1;
1653 info->status.rates[0].count = 1; 1659 info->status.rates[0].count = 1;
1654 1660
1655 if (MWL8K_TXD_SUCCESS(status)) 1661 if (MWL8K_TXD_SUCCESS(status))
1656 info->flags |= IEEE80211_TX_STAT_ACK; 1662 info->flags |= IEEE80211_TX_STAT_ACK;
@@ -1688,7 +1694,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1688} 1694}
1689 1695
1690/* caller must hold priv->stream_lock when calling the stream functions */ 1696/* caller must hold priv->stream_lock when calling the stream functions */
1691struct mwl8k_ampdu_stream * 1697static struct mwl8k_ampdu_stream *
1692mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) 1698mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid)
1693{ 1699{
1694 struct mwl8k_ampdu_stream *stream; 1700 struct mwl8k_ampdu_stream *stream;
@@ -1755,6 +1761,41 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid)
1755 return NULL; 1761 return NULL;
1756} 1762}
1757 1763
1764#define MWL8K_AMPDU_PACKET_THRESHOLD 64
1765static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid)
1766{
1767 struct mwl8k_sta *sta_info = MWL8K_STA(sta);
1768 struct tx_traffic_info *tx_stats;
1769
1770 BUG_ON(tid >= MWL8K_MAX_TID);
1771 tx_stats = &sta_info->tx_stats[tid];
1772
1773 return sta_info->is_ampdu_allowed &&
1774 tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD;
1775}
1776
1777static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
1778{
1779 struct mwl8k_sta *sta_info = MWL8K_STA(sta);
1780 struct tx_traffic_info *tx_stats;
1781
1782 BUG_ON(tid >= MWL8K_MAX_TID);
1783 tx_stats = &sta_info->tx_stats[tid];
1784
1785 if (tx_stats->start_time == 0)
1786 tx_stats->start_time = jiffies;
1787
1788 /* reset the packet count after each second elapses. If the number of
1789 * packets ever exceeds the ampdu_min_traffic threshold, we will allow
1790 * an ampdu stream to be started.
1791 */
1792 if (jiffies - tx_stats->start_time > HZ) {
1793 tx_stats->pkts = 0;
1794 tx_stats->start_time = 0;
1795 } else
1796 tx_stats->pkts++;
1797}
1798
1758static void 1799static void
1759mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) 1800mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1760{ 1801{
@@ -1841,6 +1882,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1841 skb->protocol != cpu_to_be16(ETH_P_PAE) && 1882 skb->protocol != cpu_to_be16(ETH_P_PAE) &&
1842 sta->ht_cap.ht_supported && priv->ap_fw) { 1883 sta->ht_cap.ht_supported && priv->ap_fw) {
1843 tid = qos & 0xf; 1884 tid = qos & 0xf;
1885 mwl8k_tx_count_packet(sta, tid);
1844 spin_lock(&priv->stream_lock); 1886 spin_lock(&priv->stream_lock);
1845 stream = mwl8k_lookup_stream(hw, sta->addr, tid); 1887 stream = mwl8k_lookup_stream(hw, sta->addr, tid);
1846 if (stream != NULL) { 1888 if (stream != NULL) {
@@ -1881,7 +1923,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1881 * prevents sequence number mismatch at the recepient 1923 * prevents sequence number mismatch at the recepient
1882 * as described above. 1924 * as described above.
1883 */ 1925 */
1884 if (MWL8K_STA(sta)->is_ampdu_allowed) { 1926 if (mwl8k_ampdu_allowed(sta, tid)) {
1885 stream = mwl8k_add_stream(hw, sta, tid); 1927 stream = mwl8k_add_stream(hw, sta, tid);
1886 if (stream != NULL) 1928 if (stream != NULL)
1887 start_ba_session = true; 1929 start_ba_session = true;
@@ -2657,7 +2699,7 @@ struct mwl8k_cmd_tx_power {
2657 __le16 bw; 2699 __le16 bw;
2658 __le16 sub_ch; 2700 __le16 sub_ch;
2659 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; 2701 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
2660} __attribute__((packed)); 2702} __packed;
2661 2703
2662static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, 2704static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
2663 struct ieee80211_conf *conf, 2705 struct ieee80211_conf *conf,
@@ -3520,13 +3562,13 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3520#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 3562#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00
3521#define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 3563#define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01
3522 3564
3523enum { 3565enum ba_stream_action_type {
3524 MWL8K_BA_CREATE, 3566 MWL8K_BA_CREATE,
3525 MWL8K_BA_UPDATE, 3567 MWL8K_BA_UPDATE,
3526 MWL8K_BA_DESTROY, 3568 MWL8K_BA_DESTROY,
3527 MWL8K_BA_FLUSH, 3569 MWL8K_BA_FLUSH,
3528 MWL8K_BA_CHECK, 3570 MWL8K_BA_CHECK,
3529} ba_stream_action_type; 3571};
3530 3572
3531 3573
3532struct mwl8k_create_ba_stream { 3574struct mwl8k_create_ba_stream {
@@ -3780,7 +3822,7 @@ struct mwl8k_cmd_update_encryption {
3780 __u8 mac_addr[6]; 3822 __u8 mac_addr[6];
3781 __u8 encr_type; 3823 __u8 encr_type;
3782 3824
3783} __attribute__((packed)); 3825} __packed;
3784 3826
3785struct mwl8k_cmd_set_key { 3827struct mwl8k_cmd_set_key {
3786 struct mwl8k_cmd_pkt header; 3828 struct mwl8k_cmd_pkt header;
@@ -3800,7 +3842,7 @@ struct mwl8k_cmd_set_key {
3800 __le16 tkip_tsc_low; 3842 __le16 tkip_tsc_low;
3801 __le32 tkip_tsc_high; 3843 __le32 tkip_tsc_high;
3802 __u8 mac_addr[6]; 3844 __u8 mac_addr[6];
3803} __attribute__((packed)); 3845} __packed;
3804 3846
3805enum { 3847enum {
3806 MWL8K_ENCR_ENABLE, 3848 MWL8K_ENCR_ENABLE,
@@ -4285,6 +4327,8 @@ static int mwl8k_start(struct ieee80211_hw *hw)
4285 4327
4286 /* Enable interrupts */ 4328 /* Enable interrupts */
4287 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4329 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4330 iowrite32(MWL8K_A2H_EVENTS,
4331 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
4288 4332
4289 rc = mwl8k_fw_lock(hw); 4333 rc = mwl8k_fw_lock(hw);
4290 if (!rc) { 4334 if (!rc) {
@@ -4502,7 +4546,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4502 struct ieee80211_bss_conf *info, u32 changed) 4546 struct ieee80211_bss_conf *info, u32 changed)
4503{ 4547{
4504 struct mwl8k_priv *priv = hw->priv; 4548 struct mwl8k_priv *priv = hw->priv;
4505 u32 ap_legacy_rates; 4549 u32 ap_legacy_rates = 0;
4506 u8 ap_mcs_rates[16]; 4550 u8 ap_mcs_rates[16];
4507 int rc; 4551 int rc;
4508 4552
@@ -5283,7 +5327,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
5283 iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| 5327 iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY|
5284 MWL8K_A2H_INT_BA_WATCHDOG, 5328 MWL8K_A2H_INT_BA_WATCHDOG,
5285 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 5329 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
5286 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 5330 iowrite32(MWL8K_A2H_INT_OPC_DONE,
5331 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
5287 5332
5288 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, 5333 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
5289 IRQF_SHARED, MWL8K_NAME, hw); 5334 IRQF_SHARED, MWL8K_NAME, hw);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 6ba31a0e8f78..d2f5c87305a4 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -710,6 +710,16 @@ static struct usb_device_id rt2800usb_device_table[] = {
710 { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) }, 710 { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
711 { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, 711 { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
712 { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, 712 { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
713 /* Alpha Networks */
714 { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
715 { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
716 { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
717 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
718 { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
719 { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
720 { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
721 { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
722 { USB_DEVICE(0x14b2, 0x3c2c), USB_DEVICE_DATA(&rt2800usb_ops) },
713 /* Amit */ 723 /* Amit */
714 { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, 724 { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
715 /* Askey */ 725 /* Askey */
@@ -736,15 +746,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
736 /* Buffalo */ 746 /* Buffalo */
737 { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, 747 { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
738 { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, 748 { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) },
739 /* Conceptronic */ 749 { USB_DEVICE(0x0411, 0x01a2), USB_DEVICE_DATA(&rt2800usb_ops) },
740 { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
741 { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
742 { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
743 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
744 { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
745 { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
746 { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
747 { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
748 /* Corega */ 750 /* Corega */
749 { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, 751 { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
750 { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, 752 { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -776,6 +778,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
776 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, 778 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
777 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, 779 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
778 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, 780 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
781 /* Gemtek */
782 { USB_DEVICE(0x15a9, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
779 /* Gigabyte */ 783 /* Gigabyte */
780 { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, 784 { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
781 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, 785 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -792,6 +796,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
792 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, 796 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
793 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, 797 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
794 /* Linksys */ 798 /* Linksys */
799 { USB_DEVICE(0x13b1, 0x0031), USB_DEVICE_DATA(&rt2800usb_ops) },
795 { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, 800 { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
796 { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, 801 { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
797 /* Logitec */ 802 /* Logitec */
@@ -870,8 +875,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
870 { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, 875 { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
871 /* Sweex */ 876 /* Sweex */
872 { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, 877 { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
873 /* U-Media*/ 878 /* U-Media */
874 { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, 879 { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
880 { USB_DEVICE(0x157e, 0x3013), USB_DEVICE_DATA(&rt2800usb_ops) },
875 /* ZCOM */ 881 /* ZCOM */
876 { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, 882 { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
877 { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, 883 { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -883,6 +889,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
883 /* Zyxel */ 889 /* Zyxel */
884 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, 890 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
885 { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, 891 { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) },
892 { USB_DEVICE(0x0586, 0x341e), USB_DEVICE_DATA(&rt2800usb_ops) },
886#ifdef CONFIG_RT2800USB_RT33XX 893#ifdef CONFIG_RT2800USB_RT33XX
887 /* Ralink */ 894 /* Ralink */
888 { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, 895 { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -901,6 +908,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
901 { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, 908 { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
902 /* I-O DATA */ 909 /* I-O DATA */
903 { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, 910 { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
911 /* Linksys */
912 { USB_DEVICE(0x13b1, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
904 /* Ralink */ 913 /* Ralink */
905 { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, 914 { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
906 /* Sitecom */ 915 /* Sitecom */
@@ -915,6 +924,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
915 * Unclear what kind of devices these are (they aren't supported by the 924 * Unclear what kind of devices these are (they aren't supported by the
916 * vendor linux driver). 925 * vendor linux driver).
917 */ 926 */
927 /* Alpha Networks */
928 { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
929 { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
918 /* Amigo */ 930 /* Amigo */
919 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, 931 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
920 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, 932 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -933,9 +945,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
933 { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) }, 945 { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) },
934 { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) }, 946 { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) },
935 { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) }, 947 { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) },
936 /* Conceptronic */
937 { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
938 { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
939 /* Corega */ 948 /* Corega */
940 { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, 949 { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
941 { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, 950 { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index dd5318ed7872..9477785f1168 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -251,14 +251,16 @@ void rtl_init_rfkill(struct ieee80211_hw *hw)
251 bool blocked; 251 bool blocked;
252 u8 valid = 0; 252 u8 valid = 0;
253 253
254 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); 254 /*set init state to on */
255 rtlpriv->rfkill.rfkill_state = 1;
256 wiphy_rfkill_set_hw_state(hw->wiphy, 0);
255 257
256 /*set init state to that of switch */ 258 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
257 rtlpriv->rfkill.rfkill_state = radio_state;
258 printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
259 rtlpriv->rfkill.rfkill_state ? "on" : "off");
260 259
261 if (valid) { 260 if (valid) {
261 printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
262 rtlpriv->rfkill.rfkill_state ? "on" : "off");
263
262 rtlpriv->rfkill.rfkill_state = radio_state; 264 rtlpriv->rfkill.rfkill_state = radio_state;
263 265
264 blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; 266 blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index efded435d596..59a150ce3064 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1785,7 +1785,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
1785 1785
1786 rtl_pci_deinit(hw); 1786 rtl_pci_deinit(hw);
1787 rtl_deinit_core(hw); 1787 rtl_deinit_core(hw);
1788 rtlpriv->cfg->ops->deinit_sw_leds(hw); 1788 if (rtlpriv->cfg->ops->deinit_sw_leds)
1789 rtlpriv->cfg->ops->deinit_sw_leds(hw);
1789 _rtl_pci_io_handler_release(hw); 1790 _rtl_pci_io_handler_release(hw);
1790 rtlpriv->cfg->ops->deinit_sw_vars(hw); 1791 rtlpriv->cfg->ops->deinit_sw_vars(hw);
1791 1792
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index bb023274414c..c228b9ee3711 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -634,7 +634,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
634 u8 thermalvalue, delta, delta_lck, delta_iqk; 634 u8 thermalvalue, delta, delta_lck, delta_iqk;
635 long ele_a, ele_d, temp_cck, val_x, value32; 635 long ele_a, ele_d, temp_cck, val_x, value32;
636 long val_y, ele_c; 636 long val_y, ele_c;
637 u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; 637 u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0;
638 int i; 638 int i;
639 bool is2t = IS_92C_SERIAL(rtlhal->version); 639 bool is2t = IS_92C_SERIAL(rtlhal->version);
640 u8 txpwr_level[2] = {0, 0}; 640 u8 txpwr_level[2] = {0, 0};
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index f107660f545d..bc9d24134ac4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -293,7 +293,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
293 struct rtl_priv *rtlpriv = rtl_priv(hw); 293 struct rtl_priv *rtlpriv = rtl_priv(hw);
294 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 294 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
295 u8 boxnum; 295 u8 boxnum;
296 u16 box_reg, box_extreg; 296 u16 box_reg = 0, box_extreg = 0;
297 u8 u1b_tmp; 297 u8 u1b_tmp;
298 bool isfw_read = false; 298 bool isfw_read = false;
299 bool bwrite_sucess = false; 299 bool bwrite_sucess = false;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
index 7b1da8d7508f..d21b934b5c33 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
@@ -32,6 +32,14 @@
32#include "reg.h" 32#include "reg.h"
33#include "led.h" 33#include "led.h"
34 34
35static void _rtl92ce_init_led(struct ieee80211_hw *hw,
36 struct rtl_led *pled, enum rtl_led_pin ledpin)
37{
38 pled->hw = hw;
39 pled->ledpin = ledpin;
40 pled->ledon = false;
41}
42
35void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) 43void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
36{ 44{
37 u8 ledcfg; 45 u8 ledcfg;
@@ -97,10 +105,10 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
97 105
98void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) 106void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)
99{ 107{
100} 108 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
101 109
102void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) 110 _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
103{ 111 _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
104} 112}
105 113
106void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, 114void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
index 10da3018f4b7..94332b3af5b1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
@@ -31,7 +31,6 @@
31#define __RTL92CE_LED_H__ 31#define __RTL92CE_LED_H__
32 32
33void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); 33void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);
34void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw);
35void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); 34void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
36void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); 35void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
37void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); 36void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
index 669b1168dbec..e301b12e281a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
@@ -202,7 +202,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
202 struct rtl_priv *rtlpriv = rtl_priv(hw); 202 struct rtl_priv *rtlpriv = rtl_priv(hw);
203 struct rtl_phy *rtlphy = &(rtlpriv->phy); 203 struct rtl_phy *rtlphy = &(rtlpriv->phy);
204 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 204 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
205 u8 i, chnlgroup, pwr_diff_limit[4]; 205 u8 i, chnlgroup = 0, pwr_diff_limit[4];
206 u32 writeVal, customer_limit, rf; 206 u32 writeVal, customer_limit, rf;
207 207
208 for (rf = 0; rf < 2; rf++) { 208 for (rf = 0; rf < 2; rf++) {
@@ -447,7 +447,7 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
447{ 447{
448 struct rtl_priv *rtlpriv = rtl_priv(hw); 448 struct rtl_priv *rtlpriv = rtl_priv(hw);
449 struct rtl_phy *rtlphy = &(rtlpriv->phy); 449 struct rtl_phy *rtlphy = &(rtlpriv->phy);
450 u32 u4_regvalue; 450 u32 u4_regvalue = 0;
451 u8 rfpath; 451 u8 rfpath;
452 bool rtstatus; 452 bool rtstatus;
453 struct bb_reg_def *pphyreg; 453 struct bb_reg_def *pphyreg;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index b1cc4d44f534..f4e2f3dcccae 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -131,7 +131,6 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
131 .enable_hw_sec = rtl92ce_enable_hw_security_config, 131 .enable_hw_sec = rtl92ce_enable_hw_security_config,
132 .set_key = rtl92ce_set_key, 132 .set_key = rtl92ce_set_key,
133 .init_sw_leds = rtl92ce_init_sw_leds, 133 .init_sw_leds = rtl92ce_init_sw_leds,
134 .deinit_sw_leds = rtl92ce_deinit_sw_leds,
135 .get_bbreg = rtl92c_phy_query_bb_reg, 134 .get_bbreg = rtl92c_phy_query_bb_reg,
136 .set_bbreg = rtl92c_phy_set_bb_reg, 135 .set_bbreg = rtl92c_phy_set_bb_reg,
137 .get_rfreg = rtl92ce_phy_query_rf_reg, 136 .get_rfreg = rtl92ce_phy_query_rf_reg,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 9444e76838cf..e43be2547827 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -921,7 +921,7 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw,
921 u8 out_ep_num, 921 u8 out_ep_num,
922 u8 queue_sel) 922 u8 queue_sel)
923{ 923{
924 u8 hq_sele; 924 u8 hq_sele = 0;
925 struct rtl_priv *rtlpriv = rtl_priv(hw); 925 struct rtl_priv *rtlpriv = rtl_priv(hw);
926 926
927 switch (out_ep_num) { 927 switch (out_ep_num) {
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 16eea7229e99..be8df57b789d 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -410,6 +410,16 @@
410 * notification. This event is used to indicate that an unprotected 410 * notification. This event is used to indicate that an unprotected
411 * disassociation frame was dropped when MFP is in use. 411 * disassociation frame was dropped when MFP is in use.
412 * 412 *
413 * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a
414 * beacon or probe response from a compatible mesh peer. This is only
415 * sent while no station information (sta_info) exists for the new peer
416 * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On
417 * reception of this notification, userspace may decide to create a new
418 * station (@NL80211_CMD_NEW_STATION). To stop this notification from
419 * reoccurring, the userspace authentication daemon may want to create the
420 * new station with the AUTHENTICATED flag unset and maybe change it later
421 * depending on the authentication result.
422 *
413 * @NL80211_CMD_MAX: highest used command number 423 * @NL80211_CMD_MAX: highest used command number
414 * @__NL80211_CMD_AFTER_LAST: internal use 424 * @__NL80211_CMD_AFTER_LAST: internal use
415 */ 425 */
@@ -522,6 +532,8 @@ enum nl80211_commands {
522 NL80211_CMD_UNPROT_DEAUTHENTICATE, 532 NL80211_CMD_UNPROT_DEAUTHENTICATE,
523 NL80211_CMD_UNPROT_DISASSOCIATE, 533 NL80211_CMD_UNPROT_DISASSOCIATE,
524 534
535 NL80211_CMD_NEW_PEER_CANDIDATE,
536
525 /* add new commands above here */ 537 /* add new commands above here */
526 538
527 /* used to define NL80211_CMD_MAX below */ 539 /* used to define NL80211_CMD_MAX below */
@@ -545,6 +557,7 @@ enum nl80211_commands {
545/* source-level API compatibility */ 557/* source-level API compatibility */
546#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG 558#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG
547#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG 559#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG
560#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE
548 561
549/** 562/**
550 * enum nl80211_attrs - nl80211 netlink attributes 563 * enum nl80211_attrs - nl80211 netlink attributes
@@ -886,6 +899,9 @@ enum nl80211_commands {
886 * changed once the mesh is active. 899 * changed once the mesh is active.
887 * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute 900 * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute
888 * containing attributes from &enum nl80211_meshconf_params. 901 * containing attributes from &enum nl80211_meshconf_params.
902 * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver
903 * allows auth frames in a mesh to be passed to userspace for processing via
904 * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag.
889 * 905 *
890 * @NL80211_ATTR_MAX: highest attribute number currently defined 906 * @NL80211_ATTR_MAX: highest attribute number currently defined
891 * @__NL80211_ATTR_AFTER_LAST: internal use 907 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1074,6 +1090,8 @@ enum nl80211_attrs {
1074 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, 1090 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1075 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, 1091 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1076 1092
1093 NL80211_ATTR_SUPPORT_MESH_AUTH,
1094
1077 /* add attributes here, update the policy in nl80211.c */ 1095 /* add attributes here, update the policy in nl80211.c */
1078 1096
1079 __NL80211_ATTR_AFTER_LAST, 1097 __NL80211_ATTR_AFTER_LAST,
@@ -1168,6 +1186,7 @@ enum nl80211_iftype {
1168 * with short barker preamble 1186 * with short barker preamble
1169 * @NL80211_STA_FLAG_WME: station is WME/QoS capable 1187 * @NL80211_STA_FLAG_WME: station is WME/QoS capable
1170 * @NL80211_STA_FLAG_MFP: station uses management frame protection 1188 * @NL80211_STA_FLAG_MFP: station uses management frame protection
1189 * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated
1171 * @NL80211_STA_FLAG_MAX: highest station flag number currently defined 1190 * @NL80211_STA_FLAG_MAX: highest station flag number currently defined
1172 * @__NL80211_STA_FLAG_AFTER_LAST: internal use 1191 * @__NL80211_STA_FLAG_AFTER_LAST: internal use
1173 */ 1192 */
@@ -1177,6 +1196,7 @@ enum nl80211_sta_flags {
1177 NL80211_STA_FLAG_SHORT_PREAMBLE, 1196 NL80211_STA_FLAG_SHORT_PREAMBLE,
1178 NL80211_STA_FLAG_WME, 1197 NL80211_STA_FLAG_WME,
1179 NL80211_STA_FLAG_MFP, 1198 NL80211_STA_FLAG_MFP,
1199 NL80211_STA_FLAG_AUTHENTICATED,
1180 1200
1181 /* keep last */ 1201 /* keep last */
1182 __NL80211_STA_FLAG_AFTER_LAST, 1202 __NL80211_STA_FLAG_AFTER_LAST,
@@ -1277,6 +1297,7 @@ enum nl80211_sta_bss_param {
1277 * attribute, like NL80211_STA_INFO_TX_BITRATE. 1297 * attribute, like NL80211_STA_INFO_TX_BITRATE.
1278 * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute 1298 * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute
1279 * containing info as possible, see &enum nl80211_sta_bss_param 1299 * containing info as possible, see &enum nl80211_sta_bss_param
1300 * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
1280 * @__NL80211_STA_INFO_AFTER_LAST: internal 1301 * @__NL80211_STA_INFO_AFTER_LAST: internal
1281 * @NL80211_STA_INFO_MAX: highest possible station info attribute 1302 * @NL80211_STA_INFO_MAX: highest possible station info attribute
1282 */ 1303 */
@@ -1297,6 +1318,7 @@ enum nl80211_sta_info {
1297 NL80211_STA_INFO_SIGNAL_AVG, 1318 NL80211_STA_INFO_SIGNAL_AVG,
1298 NL80211_STA_INFO_RX_BITRATE, 1319 NL80211_STA_INFO_RX_BITRATE,
1299 NL80211_STA_INFO_BSS_PARAM, 1320 NL80211_STA_INFO_BSS_PARAM,
1321 NL80211_STA_INFO_CONNECTED_TIME,
1300 1322
1301 /* keep last */ 1323 /* keep last */
1302 __NL80211_STA_INFO_AFTER_LAST, 1324 __NL80211_STA_INFO_AFTER_LAST,
@@ -1719,9 +1741,12 @@ enum nl80211_meshconf_params {
1719 * vendor specific path metric or disable it to use the default Airtime 1741 * vendor specific path metric or disable it to use the default Airtime
1720 * metric. 1742 * metric.
1721 * 1743 *
1722 * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information 1744 * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a
1723 * element that vendors will use to identify the path selection methods and 1745 * robust security network ie, or a vendor specific information element that
1724 * metrics in use. 1746 * vendors will use to identify the path selection methods and metrics in use.
1747 *
1748 * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication
1749 * daemon will be authenticating mesh candidates.
1725 * 1750 *
1726 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number 1751 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
1727 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use 1752 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
@@ -1730,7 +1755,8 @@ enum nl80211_mesh_setup_params {
1730 __NL80211_MESH_SETUP_INVALID, 1755 __NL80211_MESH_SETUP_INVALID,
1731 NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, 1756 NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
1732 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, 1757 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
1733 NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE, 1758 NL80211_MESH_SETUP_IE,
1759 NL80211_MESH_SETUP_USERSPACE_AUTH,
1734 1760
1735 /* keep last */ 1761 /* keep last */
1736 __NL80211_MESH_SETUP_ATTR_AFTER_LAST, 1762 __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ba7384acf4e0..d30eada7c6cd 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -423,6 +423,7 @@ struct station_parameters {
423 * @STATION_INFO_SIGNAL_AVG: @signal_avg filled 423 * @STATION_INFO_SIGNAL_AVG: @signal_avg filled
424 * @STATION_INFO_RX_BITRATE: @rxrate fields are filled 424 * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
425 * @STATION_INFO_BSS_PARAM: @bss_param filled 425 * @STATION_INFO_BSS_PARAM: @bss_param filled
426 * @STATION_INFO_CONNECTED_TIME: @connected_time filled
426 */ 427 */
427enum station_info_flags { 428enum station_info_flags {
428 STATION_INFO_INACTIVE_TIME = 1<<0, 429 STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -441,6 +442,7 @@ enum station_info_flags {
441 STATION_INFO_SIGNAL_AVG = 1<<13, 442 STATION_INFO_SIGNAL_AVG = 1<<13,
442 STATION_INFO_RX_BITRATE = 1<<14, 443 STATION_INFO_RX_BITRATE = 1<<14,
443 STATION_INFO_BSS_PARAM = 1<<15, 444 STATION_INFO_BSS_PARAM = 1<<15,
445 STATION_INFO_CONNECTED_TIME = 1<<16
444}; 446};
445 447
446/** 448/**
@@ -511,6 +513,7 @@ struct sta_bss_parameters {
511 * Station information filled by driver for get_station() and dump_station. 513 * Station information filled by driver for get_station() and dump_station.
512 * 514 *
513 * @filled: bitflag of flags from &enum station_info_flags 515 * @filled: bitflag of flags from &enum station_info_flags
516 * @connected_time: time(in secs) since a station is last connected
514 * @inactive_time: time since last station activity (tx/rx) in milliseconds 517 * @inactive_time: time since last station activity (tx/rx) in milliseconds
515 * @rx_bytes: bytes received from this station 518 * @rx_bytes: bytes received from this station
516 * @tx_bytes: bytes transmitted to this station 519 * @tx_bytes: bytes transmitted to this station
@@ -533,6 +536,7 @@ struct sta_bss_parameters {
533 */ 536 */
534struct station_info { 537struct station_info {
535 u32 filled; 538 u32 filled;
539 u32 connected_time;
536 u32 inactive_time; 540 u32 inactive_time;
537 u32 rx_bytes; 541 u32 rx_bytes;
538 u32 tx_bytes; 542 u32 tx_bytes;
@@ -689,8 +693,9 @@ struct mesh_config {
689 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes 693 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
690 * @path_sel_proto: which path selection protocol to use 694 * @path_sel_proto: which path selection protocol to use
691 * @path_metric: which metric to use 695 * @path_metric: which metric to use
692 * @vendor_ie: vendor information elements (optional) 696 * @ie: vendor information elements (optional)
693 * @vendor_ie_len: length of vendor information elements 697 * @ie_len: length of vendor information elements
698 * @is_secure: or not
694 * 699 *
695 * These parameters are fixed when the mesh is created. 700 * These parameters are fixed when the mesh is created.
696 */ 701 */
@@ -699,8 +704,9 @@ struct mesh_setup {
699 u8 mesh_id_len; 704 u8 mesh_id_len;
700 u8 path_sel_proto; 705 u8 path_sel_proto;
701 u8 path_metric; 706 u8 path_metric;
702 const u8 *vendor_ie; 707 const u8 *ie;
703 u8 vendor_ie_len; 708 u8 ie_len;
709 bool is_secure;
704}; 710};
705 711
706/** 712/**
@@ -1451,6 +1457,8 @@ struct cfg80211_ops {
1451 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. 1457 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
1452 * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate 1458 * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
1453 * unicast and multicast TX keys. 1459 * unicast and multicast TX keys.
1460 * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing
1461 * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH.
1454 */ 1462 */
1455enum wiphy_flags { 1463enum wiphy_flags {
1456 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 1464 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1463,6 +1471,7 @@ enum wiphy_flags {
1463 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), 1471 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
1464 WIPHY_FLAG_IBSS_RSN = BIT(8), 1472 WIPHY_FLAG_IBSS_RSN = BIT(8),
1465 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), 1473 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
1474 WIPHY_FLAG_MESH_AUTH = BIT(10),
1466}; 1475};
1467 1476
1468struct mac_address { 1477struct mac_address {
@@ -2484,6 +2493,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
2484void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); 2493void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
2485 2494
2486/** 2495/**
2496 * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
2497 *
2498 * @dev: network device
2499 * @macaddr: the MAC address of the new candidate
2500 * @ie: information elements advertised by the peer candidate
2501 * @ie_len: lenght of the information elements buffer
2502 * @gfp: allocation flags
2503 *
2504 * This function notifies cfg80211 that the mesh peer candidate has been
2505 * detected, most likely via a beacon or, less likely, via a probe response.
2506 * cfg80211 then sends a notification to userspace.
2507 */
2508void cfg80211_notify_new_peer_candidate(struct net_device *dev,
2509 const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp);
2510
2511/**
2487 * DOC: RFkill integration 2512 * DOC: RFkill integration
2488 * 2513 *
2489 * RFkill integration in cfg80211 is almost invisible to drivers, 2514 * RFkill integration in cfg80211 is almost invisible to drivers,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 965f1b16e53a..361bc5d85b1a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1819,6 +1819,9 @@ enum ieee80211_ampdu_mlme_action {
1819 * @set_ringparam: Set tx and rx ring sizes. 1819 * @set_ringparam: Set tx and rx ring sizes.
1820 * 1820 *
1821 * @get_ringparam: Get tx and rx ring current and maximum sizes. 1821 * @get_ringparam: Get tx and rx ring current and maximum sizes.
1822 *
1823 * @tx_frames_pending: Check if there is any pending frame in the hardware
1824 * queues before entering power save.
1822 */ 1825 */
1823struct ieee80211_ops { 1826struct ieee80211_ops {
1824 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); 1827 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1906,6 +1909,7 @@ struct ieee80211_ops {
1906 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); 1909 int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx);
1907 void (*get_ringparam)(struct ieee80211_hw *hw, 1910 void (*get_ringparam)(struct ieee80211_hw *hw,
1908 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); 1911 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
1912 bool (*tx_frames_pending)(struct ieee80211_hw *hw);
1909}; 1913};
1910 1914
1911/** 1915/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bf5d28da46e6..a6d191f2a0fe 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -330,6 +330,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
330static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 330static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
331{ 331{
332 struct ieee80211_sub_if_data *sdata = sta->sdata; 332 struct ieee80211_sub_if_data *sdata = sta->sdata;
333 struct timespec uptime;
333 334
334 sinfo->generation = sdata->local->sta_generation; 335 sinfo->generation = sdata->local->sta_generation;
335 336
@@ -343,7 +344,11 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
343 STATION_INFO_TX_BITRATE | 344 STATION_INFO_TX_BITRATE |
344 STATION_INFO_RX_BITRATE | 345 STATION_INFO_RX_BITRATE |
345 STATION_INFO_RX_DROP_MISC | 346 STATION_INFO_RX_DROP_MISC |
346 STATION_INFO_BSS_PARAM; 347 STATION_INFO_BSS_PARAM |
348 STATION_INFO_CONNECTED_TIME;
349
350 do_posix_clock_monotonic_gettime(&uptime);
351 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
347 352
348 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 353 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
349 sinfo->rx_bytes = sta->rx_bytes; 354 sinfo->rx_bytes = sta->rx_bytes;
@@ -686,6 +691,12 @@ static void sta_apply_parameters(struct ieee80211_local *local,
686 if (set & BIT(NL80211_STA_FLAG_MFP)) 691 if (set & BIT(NL80211_STA_FLAG_MFP))
687 sta->flags |= WLAN_STA_MFP; 692 sta->flags |= WLAN_STA_MFP;
688 } 693 }
694
695 if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
696 sta->flags &= ~WLAN_STA_AUTH;
697 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
698 sta->flags |= WLAN_STA_AUTH;
699 }
689 spin_unlock_irqrestore(&sta->flaglock, flags); 700 spin_unlock_irqrestore(&sta->flaglock, flags);
690 701
691 /* 702 /*
@@ -1034,26 +1045,26 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1034 u8 *new_ie; 1045 u8 *new_ie;
1035 const u8 *old_ie; 1046 const u8 *old_ie;
1036 1047
1037 /* first allocate the new vendor information element */ 1048 /* allocate information elements */
1038 new_ie = NULL; 1049 new_ie = NULL;
1039 old_ie = ifmsh->vendor_ie; 1050 old_ie = ifmsh->ie;
1040 1051
1041 ifmsh->vendor_ie_len = setup->vendor_ie_len; 1052 if (setup->ie_len) {
1042 if (setup->vendor_ie_len) { 1053 new_ie = kmemdup(setup->ie, setup->ie_len,
1043 new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
1044 GFP_KERNEL); 1054 GFP_KERNEL);
1045 if (!new_ie) 1055 if (!new_ie)
1046 return -ENOMEM; 1056 return -ENOMEM;
1047 } 1057 }
1058 ifmsh->ie_len = setup->ie_len;
1059 ifmsh->ie = new_ie;
1060 kfree(old_ie);
1048 1061
1049 /* now copy the rest of the setup parameters */ 1062 /* now copy the rest of the setup parameters */
1050 ifmsh->mesh_id_len = setup->mesh_id_len; 1063 ifmsh->mesh_id_len = setup->mesh_id_len;
1051 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1064 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1052 ifmsh->mesh_pp_id = setup->path_sel_proto; 1065 ifmsh->mesh_pp_id = setup->path_sel_proto;
1053 ifmsh->mesh_pm_id = setup->path_metric; 1066 ifmsh->mesh_pm_id = setup->path_metric;
1054 ifmsh->vendor_ie = new_ie; 1067 ifmsh->is_secure = setup->is_secure;
1055
1056 kfree(old_ie);
1057 1068
1058 return 0; 1069 return 0;
1059} 1070}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index c04a1396cf8d..c008232731eb 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -92,6 +92,31 @@ static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
92} 92}
93STA_OPS(inactive_ms); 93STA_OPS(inactive_ms);
94 94
95
96static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf,
97 size_t count, loff_t *ppos)
98{
99 struct sta_info *sta = file->private_data;
100 struct timespec uptime;
101 struct tm result;
102 long connected_time_secs;
103 char buf[100];
104 int res;
105 do_posix_clock_monotonic_gettime(&uptime);
106 connected_time_secs = uptime.tv_sec - sta->last_connected;
107 time_to_tm(connected_time_secs, 0, &result);
108 result.tm_year -= 70;
109 result.tm_mday -= 1;
110 res = scnprintf(buf, sizeof(buf),
111 "years - %d\nmonths - %d\ndays - %d\nclock - %d:%d:%d\n\n",
112 result.tm_year, result.tm_mon, result.tm_mday,
113 result.tm_hour, result.tm_min, result.tm_sec);
114 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
115}
116STA_OPS(connected_time);
117
118
119
95static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, 120static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
96 size_t count, loff_t *ppos) 121 size_t count, loff_t *ppos)
97{ 122{
@@ -324,6 +349,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
324 DEBUGFS_ADD(flags); 349 DEBUGFS_ADD(flags);
325 DEBUGFS_ADD(num_ps_buf_frames); 350 DEBUGFS_ADD(num_ps_buf_frames);
326 DEBUGFS_ADD(inactive_ms); 351 DEBUGFS_ADD(inactive_ms);
352 DEBUGFS_ADD(connected_time);
327 DEBUGFS_ADD(last_seq_ctrl); 353 DEBUGFS_ADD(last_seq_ctrl);
328 DEBUGFS_ADD(agg_status); 354 DEBUGFS_ADD(agg_status);
329 DEBUGFS_ADD(dev); 355 DEBUGFS_ADD(dev);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 9c0d62bb0ea3..00a0685f2403 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -552,4 +552,17 @@ static inline void drv_get_ringparam(struct ieee80211_local *local,
552 trace_drv_return_void(local); 552 trace_drv_return_void(local);
553} 553}
554 554
555static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
556{
557 bool ret = false;
558
559 might_sleep();
560
561 trace_drv_tx_frames_pending(local);
562 if (local->ops->tx_frames_pending)
563 ret = local->ops->tx_frames_pending(&local->hw);
564 trace_drv_return_bool(local, ret);
565
566 return ret;
567}
555#endif /* __MAC80211_DRIVER_OPS */ 568#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 45aab80738e2..c8c934d48b7a 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -74,6 +74,21 @@ TRACE_EVENT(drv_return_int,
74 TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret) 74 TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret)
75); 75);
76 76
77TRACE_EVENT(drv_return_bool,
78 TP_PROTO(struct ieee80211_local *local, bool ret),
79 TP_ARGS(local, ret),
80 TP_STRUCT__entry(
81 LOCAL_ENTRY
82 __field(bool, ret)
83 ),
84 TP_fast_assign(
85 LOCAL_ASSIGN;
86 __entry->ret = ret;
87 ),
88 TP_printk(LOCAL_PR_FMT " - %s", LOCAL_PR_ARG, (__entry->ret) ?
89 "true" : "false")
90);
91
77TRACE_EVENT(drv_return_u64, 92TRACE_EVENT(drv_return_u64,
78 TP_PROTO(struct ieee80211_local *local, u64 ret), 93 TP_PROTO(struct ieee80211_local *local, u64 ret),
79 TP_ARGS(local, ret), 94 TP_ARGS(local, ret),
@@ -964,6 +979,11 @@ TRACE_EVENT(drv_get_ringparam,
964 ) 979 )
965); 980);
966 981
982DEFINE_EVENT(local_only_evt, drv_tx_frames_pending,
983 TP_PROTO(struct ieee80211_local *local),
984 TP_ARGS(local)
985);
986
967DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, 987DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait,
968 TP_PROTO(struct ieee80211_local *local), 988 TP_PROTO(struct ieee80211_local *local),
969 TP_ARGS(local) 989 TP_ARGS(local)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6eb2c8523eeb..8d6d6e3d95da 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -488,8 +488,9 @@ struct ieee80211_if_mesh {
488 struct mesh_config mshcfg; 488 struct mesh_config mshcfg;
489 u32 mesh_seqnum; 489 u32 mesh_seqnum;
490 bool accepting_plinks; 490 bool accepting_plinks;
491 const u8 *vendor_ie; 491 const u8 *ie;
492 u8 vendor_ie_len; 492 u8 ie_len;
493 bool is_secure;
493}; 494};
494 495
495#ifdef CONFIG_MAC80211_MESH 496#ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index dc50fc3153e5..0ab2a8df312d 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -545,7 +545,9 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
545 }, 545 },
546 [NL80211_IFTYPE_MESH_POINT] = { 546 [NL80211_IFTYPE_MESH_POINT] = {
547 .tx = 0xffff, 547 .tx = 0xffff,
548 .rx = BIT(IEEE80211_STYPE_ACTION >> 4), 548 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
549 BIT(IEEE80211_STYPE_AUTH >> 4) |
550 BIT(IEEE80211_STYPE_DEAUTH >> 4),
549 }, 551 },
550}; 552};
551 553
@@ -760,6 +762,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
760 local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); 762 local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT);
761#endif 763#endif
762 764
765 /* if the underlying driver supports mesh, mac80211 will (at least)
766 * provide routing of mesh authentication frames to userspace */
767 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
768 local->hw.wiphy->flags |= WIPHY_FLAG_MESH_AUTH;
769
763 /* mac80211 supports control port protocol changing */ 770 /* mac80211 supports control port protocol changing */
764 local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; 771 local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL;
765 772
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 2a57cc02c618..11207979e2e2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -279,9 +279,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
279 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 279 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
280 *pos++ = 0x00; 280 *pos++ = 0x00;
281 281
282 if (sdata->u.mesh.vendor_ie) { 282 if (sdata->u.mesh.ie) {
283 int len = sdata->u.mesh.vendor_ie_len; 283 int len = sdata->u.mesh.ie_len;
284 const u8 *data = sdata->u.mesh.vendor_ie; 284 const u8 *data = sdata->u.mesh.ie;
285 if (skb_tailroom(skb) > len) 285 if (skb_tailroom(skb) > len)
286 memcpy(skb_put(skb, len), data, len); 286 memcpy(skb_put(skb, len), data, len);
287 } 287 }
@@ -573,6 +573,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
573 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, 573 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
574 &elems); 574 &elems);
575 575
576 /* ignore beacons from secure mesh peers if our security is off */
577 if (elems.rsn_len && !sdata->u.mesh.is_secure)
578 return;
579
576 if (elems.ds_params && elems.ds_params_len == 1) 580 if (elems.ds_params && elems.ds_params_len == 1)
577 freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); 581 freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
578 else 582 else
@@ -586,9 +590,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
586 if (elems.mesh_id && elems.mesh_config && 590 if (elems.mesh_id && elems.mesh_config &&
587 mesh_matches_local(&elems, sdata)) { 591 mesh_matches_local(&elems, sdata)) {
588 supp_rates = ieee80211_sta_get_rates(local, &elems, band); 592 supp_rates = ieee80211_sta_get_rates(local, &elems, band);
589 593 mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems);
590 mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
591 mesh_peer_accepts_plinks(&elems));
592 } 594 }
593} 595}
594 596
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index b99e230fe31c..10acf1cc8082 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -226,7 +226,8 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
226int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); 226int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
227/* Mesh plinks */ 227/* Mesh plinks */
228void mesh_neighbour_update(u8 *hw_addr, u32 rates, 228void mesh_neighbour_update(u8 *hw_addr, u32 rates,
229 struct ieee80211_sub_if_data *sdata, bool add); 229 struct ieee80211_sub_if_data *sdata,
230 struct ieee802_11_elems *ie);
230bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 231bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
231void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 232void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
232void mesh_plink_broken(struct sta_info *sta); 233void mesh_plink_broken(struct sta_info *sta);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 8d65b47d9837..7776ae5a8f15 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -65,42 +65,37 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
65 __mesh_table_free(tbl); 65 __mesh_table_free(tbl);
66} 66}
67 67
68static struct mesh_table *mesh_table_grow(struct mesh_table *tbl) 68static int mesh_table_grow(struct mesh_table *oldtbl,
69 struct mesh_table *newtbl)
69{ 70{
70 struct mesh_table *newtbl;
71 struct hlist_head *oldhash; 71 struct hlist_head *oldhash;
72 struct hlist_node *p, *q; 72 struct hlist_node *p, *q;
73 int i; 73 int i;
74 74
75 if (atomic_read(&tbl->entries) 75 if (atomic_read(&oldtbl->entries)
76 < tbl->mean_chain_len * (tbl->hash_mask + 1)) 76 < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1))
77 goto endgrow; 77 return -EAGAIN;
78 78
79 newtbl = mesh_table_alloc(tbl->size_order + 1);
80 if (!newtbl)
81 goto endgrow;
82 79
83 newtbl->free_node = tbl->free_node; 80 newtbl->free_node = oldtbl->free_node;
84 newtbl->mean_chain_len = tbl->mean_chain_len; 81 newtbl->mean_chain_len = oldtbl->mean_chain_len;
85 newtbl->copy_node = tbl->copy_node; 82 newtbl->copy_node = oldtbl->copy_node;
86 atomic_set(&newtbl->entries, atomic_read(&tbl->entries)); 83 atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries));
87 84
88 oldhash = tbl->hash_buckets; 85 oldhash = oldtbl->hash_buckets;
89 for (i = 0; i <= tbl->hash_mask; i++) 86 for (i = 0; i <= oldtbl->hash_mask; i++)
90 hlist_for_each(p, &oldhash[i]) 87 hlist_for_each(p, &oldhash[i])
91 if (tbl->copy_node(p, newtbl) < 0) 88 if (oldtbl->copy_node(p, newtbl) < 0)
92 goto errcopy; 89 goto errcopy;
93 90
94 return newtbl; 91 return 0;
95 92
96errcopy: 93errcopy:
97 for (i = 0; i <= newtbl->hash_mask; i++) { 94 for (i = 0; i <= newtbl->hash_mask; i++) {
98 hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) 95 hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
99 tbl->free_node(p, 0); 96 oldtbl->free_node(p, 0);
100 } 97 }
101 __mesh_table_free(newtbl); 98 return -ENOMEM;
102endgrow:
103 return NULL;
104} 99}
105 100
106 101
@@ -334,10 +329,13 @@ void mesh_mpath_table_grow(void)
334{ 329{
335 struct mesh_table *oldtbl, *newtbl; 330 struct mesh_table *oldtbl, *newtbl;
336 331
332 newtbl = mesh_table_alloc(mesh_paths->size_order + 1);
333 if (!newtbl)
334 return;
337 write_lock(&pathtbl_resize_lock); 335 write_lock(&pathtbl_resize_lock);
338 oldtbl = mesh_paths; 336 oldtbl = mesh_paths;
339 newtbl = mesh_table_grow(mesh_paths); 337 if (mesh_table_grow(mesh_paths, newtbl) < 0) {
340 if (!newtbl) { 338 __mesh_table_free(newtbl);
341 write_unlock(&pathtbl_resize_lock); 339 write_unlock(&pathtbl_resize_lock);
342 return; 340 return;
343 } 341 }
@@ -352,10 +350,13 @@ void mesh_mpp_table_grow(void)
352{ 350{
353 struct mesh_table *oldtbl, *newtbl; 351 struct mesh_table *oldtbl, *newtbl;
354 352
353 newtbl = mesh_table_alloc(mpp_paths->size_order + 1);
354 if (!newtbl)
355 return;
355 write_lock(&pathtbl_resize_lock); 356 write_lock(&pathtbl_resize_lock);
356 oldtbl = mpp_paths; 357 oldtbl = mpp_paths;
357 newtbl = mesh_table_grow(mpp_paths); 358 if (mesh_table_grow(mpp_paths, newtbl) < 0) {
358 if (!newtbl) { 359 __mesh_table_free(newtbl);
359 write_unlock(&pathtbl_resize_lock); 360 write_unlock(&pathtbl_resize_lock);
360 return; 361 return;
361 } 362 }
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 44b53931ba5e..84e5b056af02 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
105 if (!sta) 105 if (!sta)
106 return NULL; 106 return NULL;
107 107
108 sta->flags = WLAN_STA_AUTHORIZED; 108 sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH;
109 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 109 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
110 rate_control_rate_init(sta); 110 rate_control_rate_init(sta);
111 111
@@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
161 __le16 reason) { 161 __le16 reason) {
162 struct ieee80211_local *local = sdata->local; 162 struct ieee80211_local *local = sdata->local;
163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + 163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
164 sdata->u.mesh.vendor_ie_len); 164 sdata->u.mesh.ie_len);
165 struct ieee80211_mgmt *mgmt; 165 struct ieee80211_mgmt *mgmt;
166 bool include_plid = false; 166 bool include_plid = false;
167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; 167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
@@ -237,8 +237,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
237 return 0; 237 return 0;
238} 238}
239 239
240void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata, 240void mesh_neighbour_update(u8 *hw_addr, u32 rates,
241 bool peer_accepting_plinks) 241 struct ieee80211_sub_if_data *sdata,
242 struct ieee802_11_elems *elems)
242{ 243{
243 struct ieee80211_local *local = sdata->local; 244 struct ieee80211_local *local = sdata->local;
244 struct sta_info *sta; 245 struct sta_info *sta;
@@ -248,8 +249,14 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
248 sta = sta_info_get(sdata, hw_addr); 249 sta = sta_info_get(sdata, hw_addr);
249 if (!sta) { 250 if (!sta) {
250 rcu_read_unlock(); 251 rcu_read_unlock();
251 252 /* Userspace handles peer allocation when security is enabled
252 sta = mesh_plink_alloc(sdata, hw_addr, rates); 253 * */
254 if (sdata->u.mesh.is_secure)
255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
256 elems->ie_start, elems->total_len,
257 GFP_KERNEL);
258 else
259 sta = mesh_plink_alloc(sdata, hw_addr, rates);
253 if (!sta) 260 if (!sta)
254 return; 261 return;
255 if (sta_info_insert_rcu(sta)) { 262 if (sta_info_insert_rcu(sta)) {
@@ -260,7 +267,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data
260 267
261 sta->last_rx = jiffies; 268 sta->last_rx = jiffies;
262 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 269 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
263 if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN && 270 if (mesh_peer_accepts_plinks(elems) &&
271 sta->plink_state == PLINK_LISTEN &&
264 sdata->u.mesh.accepting_plinks && 272 sdata->u.mesh.accepting_plinks &&
265 sdata->u.mesh.mshcfg.auto_open_plinks) 273 sdata->u.mesh.mshcfg.auto_open_plinks)
266 mesh_plink_open(sta); 274 mesh_plink_open(sta);
@@ -372,6 +380,9 @@ int mesh_plink_open(struct sta_info *sta)
372 __le16 llid; 380 __le16 llid;
373 struct ieee80211_sub_if_data *sdata = sta->sdata; 381 struct ieee80211_sub_if_data *sdata = sta->sdata;
374 382
383 if (!test_sta_flags(sta, WLAN_STA_AUTH))
384 return -EPERM;
385
375 spin_lock_bh(&sta->lock); 386 spin_lock_bh(&sta->lock);
376 get_random_bytes(&llid, 2); 387 get_random_bytes(&llid, 2);
377 sta->llid = llid; 388 sta->llid = llid;
@@ -449,6 +460,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
449 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 460 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
450 return; 461 return;
451 } 462 }
463 if (elems.rsn_len && !sdata->u.mesh.is_secure) {
464 mpl_dbg("Mesh plink: can't establish link with secure peer\n");
465 return;
466 }
452 467
453 ftype = mgmt->u.action.u.plink_action.action_code; 468 ftype = mgmt->u.action.u.plink_action.action_code;
454 ie_len = elems.peer_link_len; 469 ie_len = elems.peer_link_len;
@@ -480,6 +495,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
480 return; 495 return;
481 } 496 }
482 497
498 if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) {
499 mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
500 rcu_read_unlock();
501 return;
502 }
503
483 if (sta && sta->plink_state == PLINK_BLOCKED) { 504 if (sta && sta->plink_state == PLINK_BLOCKED) {
484 rcu_read_unlock(); 505 rcu_read_unlock();
485 return; 506 return;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 865fed4cc18b..a41f234bd486 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -761,15 +761,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
761 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 761 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
762 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { 762 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
763 netif_tx_stop_all_queues(sdata->dev); 763 netif_tx_stop_all_queues(sdata->dev);
764 /*
765 * Flush all the frames queued in the driver before
766 * going to power save
767 */
768 drv_flush(local, false);
769 ieee80211_send_nullfunc(local, sdata, 1);
770 764
771 /* Flush once again to get the tx status of nullfunc frame */ 765 if (drv_tx_frames_pending(local))
772 drv_flush(local, false); 766 mod_timer(&local->dynamic_ps_timer, jiffies +
767 msecs_to_jiffies(
768 local->hw.conf.dynamic_ps_timeout));
769 else {
770 ieee80211_send_nullfunc(local, sdata, 1);
771 /* Flush to get the tx status of nullfunc frame */
772 drv_flush(local, false);
773 }
773 } 774 }
774 775
775 if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && 776 if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fc2ff78582ca..54858a68abd7 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -502,7 +502,8 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
502 502
503 if (ieee80211_is_probe_req(hdr->frame_control) || 503 if (ieee80211_is_probe_req(hdr->frame_control) ||
504 ieee80211_is_probe_resp(hdr->frame_control) || 504 ieee80211_is_probe_resp(hdr->frame_control) ||
505 ieee80211_is_beacon(hdr->frame_control)) 505 ieee80211_is_beacon(hdr->frame_control) ||
506 ieee80211_is_auth(hdr->frame_control))
506 return RX_CONTINUE; 507 return RX_CONTINUE;
507 508
508 return RX_DROP_MONITOR; 509 return RX_DROP_MONITOR;
@@ -1585,7 +1586,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1585} 1586}
1586 1587
1587static int 1588static int
1588__ieee80211_data_to_8023(struct ieee80211_rx_data *rx) 1589__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
1589{ 1590{
1590 struct ieee80211_sub_if_data *sdata = rx->sdata; 1591 struct ieee80211_sub_if_data *sdata = rx->sdata;
1591 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1592 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
@@ -1593,6 +1594,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1593 struct ethhdr *ehdr; 1594 struct ethhdr *ehdr;
1594 int ret; 1595 int ret;
1595 1596
1597 *port_control = false;
1596 if (ieee80211_has_a4(hdr->frame_control) && 1598 if (ieee80211_has_a4(hdr->frame_control) &&
1597 sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) 1599 sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta)
1598 return -1; 1600 return -1;
@@ -1611,11 +1613,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1611 return -1; 1613 return -1;
1612 1614
1613 ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); 1615 ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type);
1614 if (ret < 0 || !check_port_control) 1616 if (ret < 0)
1615 return ret; 1617 return ret;
1616 1618
1617 ehdr = (struct ethhdr *) rx->skb->data; 1619 ehdr = (struct ethhdr *) rx->skb->data;
1618 if (ehdr->h_proto != rx->sdata->control_port_protocol) 1620 if (ehdr->h_proto == rx->sdata->control_port_protocol)
1621 *port_control = true;
1622 else if (check_port_control)
1619 return -1; 1623 return -1;
1620 1624
1621 return 0; 1625 return 0;
@@ -1916,6 +1920,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1916 struct net_device *dev = sdata->dev; 1920 struct net_device *dev = sdata->dev;
1917 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1921 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1918 __le16 fc = hdr->frame_control; 1922 __le16 fc = hdr->frame_control;
1923 bool port_control;
1919 int err; 1924 int err;
1920 1925
1921 if (unlikely(!ieee80211_is_data(hdr->frame_control))) 1926 if (unlikely(!ieee80211_is_data(hdr->frame_control)))
@@ -1932,13 +1937,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1932 sdata->vif.type == NL80211_IFTYPE_AP) 1937 sdata->vif.type == NL80211_IFTYPE_AP)
1933 return RX_DROP_MONITOR; 1938 return RX_DROP_MONITOR;
1934 1939
1935 err = __ieee80211_data_to_8023(rx); 1940 err = __ieee80211_data_to_8023(rx, &port_control);
1936 if (unlikely(err)) 1941 if (unlikely(err))
1937 return RX_DROP_UNUSABLE; 1942 return RX_DROP_UNUSABLE;
1938 1943
1939 if (!ieee80211_frame_allowed(rx, fc)) 1944 if (!ieee80211_frame_allowed(rx, fc))
1940 return RX_DROP_MONITOR; 1945 return RX_DROP_MONITOR;
1941 1946
1947 if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1948 unlikely(port_control) && sdata->bss) {
1949 sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
1950 u.ap);
1951 dev = sdata->dev;
1952 rx->sdata = sdata;
1953 }
1954
1942 rx->skb->dev = dev; 1955 rx->skb->dev = dev;
1943 1956
1944 dev->stats.rx_packets++; 1957 dev->stats.rx_packets++;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 999f8fbf0b4b..8a9068ac0673 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -228,6 +228,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
228{ 228{
229 struct ieee80211_local *local = sdata->local; 229 struct ieee80211_local *local = sdata->local;
230 struct sta_info *sta; 230 struct sta_info *sta;
231 struct timespec uptime;
231 int i; 232 int i;
232 233
233 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); 234 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
@@ -245,6 +246,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
245 sta->sdata = sdata; 246 sta->sdata = sdata;
246 sta->last_rx = jiffies; 247 sta->last_rx = jiffies;
247 248
249 do_posix_clock_monotonic_gettime(&uptime);
250 sta->last_connected = uptime.tv_sec;
248 ewma_init(&sta->avg_signal, 1024, 8); 251 ewma_init(&sta->avg_signal, 1024, 8);
249 252
250 if (sta_prepare_rate_control(local, sta, gfp)) { 253 if (sta_prepare_rate_control(local, sta, gfp)) {
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 43238e99cfb3..984a03db3553 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -226,6 +226,7 @@ enum plink_state {
226 * @rx_bytes: Number of bytes received from this STA 226 * @rx_bytes: Number of bytes received from this STA
227 * @wep_weak_iv_count: number of weak WEP IVs received from this station 227 * @wep_weak_iv_count: number of weak WEP IVs received from this station
228 * @last_rx: time (in jiffies) when last frame was received from this STA 228 * @last_rx: time (in jiffies) when last frame was received from this STA
229 * @last_connected: time (in seconds) when a station got connected
229 * @num_duplicates: number of duplicate frames received from this STA 230 * @num_duplicates: number of duplicate frames received from this STA
230 * @rx_fragments: number of received MPDUs 231 * @rx_fragments: number of received MPDUs
231 * @rx_dropped: number of dropped MPDUs from this STA 232 * @rx_dropped: number of dropped MPDUs from this STA
@@ -295,6 +296,7 @@ struct sta_info {
295 unsigned long rx_packets, rx_bytes; 296 unsigned long rx_packets, rx_bytes;
296 unsigned long wep_weak_iv_count; 297 unsigned long wep_weak_iv_count;
297 unsigned long last_rx; 298 unsigned long last_rx;
299 long last_connected;
298 unsigned long num_duplicates; 300 unsigned long num_duplicates;
299 unsigned long rx_fragments; 301 unsigned long rx_fragments;
300 unsigned long rx_dropped; 302 unsigned long rx_dropped;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ce4596ed1268..17b10be31f55 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2262,7 +2262,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2262 2262
2263 /* headroom, head length, tail length and maximum TIM length */ 2263 /* headroom, head length, tail length and maximum TIM length */
2264 skb = dev_alloc_skb(local->tx_headroom + 400 + 2264 skb = dev_alloc_skb(local->tx_headroom + 400 +
2265 sdata->u.mesh.vendor_ie_len); 2265 sdata->u.mesh.ie_len);
2266 if (!skb) 2266 if (!skb)
2267 goto out; 2267 goto out;
2268 2268
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 73e39c171ffb..5c116083eeca 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -1,5 +1,6 @@
1#include <linux/ieee80211.h> 1#include <linux/ieee80211.h>
2#include <net/cfg80211.h> 2#include <net/cfg80211.h>
3#include "nl80211.h"
3#include "core.h" 4#include "core.h"
4 5
5/* Default values, timeouts in ms */ 6/* Default values, timeouts in ms */
@@ -53,8 +54,9 @@ const struct mesh_config default_mesh_config = {
53const struct mesh_setup default_mesh_setup = { 54const struct mesh_setup default_mesh_setup = {
54 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 55 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
55 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 56 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
56 .vendor_ie = NULL, 57 .ie = NULL,
57 .vendor_ie_len = 0, 58 .ie_len = 0,
59 .is_secure = false,
58}; 60};
59 61
60int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 62int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
@@ -72,6 +74,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
72 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) 74 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
73 return -EOPNOTSUPP; 75 return -EOPNOTSUPP;
74 76
77 if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
78 setup->is_secure)
79 return -EOPNOTSUPP;
80
75 if (wdev->mesh_id_len) 81 if (wdev->mesh_id_len)
76 return -EALREADY; 82 return -EALREADY;
77 83
@@ -105,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
105 return err; 111 return err;
106} 112}
107 113
114void cfg80211_notify_new_peer_candidate(struct net_device *dev,
115 const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp)
116{
117 struct wireless_dev *wdev = dev->ieee80211_ptr;
118
119 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
120 return;
121
122 nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev,
123 macaddr, ie, ie_len, gfp);
124}
125EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
126
108static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 127static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
109 struct net_device *dev) 128 struct net_device *dev)
110{ 129{
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 297d7ce4117b..0efa7fd01150 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, 124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
125 125
126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
127 128
128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 129 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
129 .len = NL80211_HT_CAPABILITY_LEN }, 130 .len = NL80211_HT_CAPABILITY_LEN },
@@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
594 595
595 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) 596 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
596 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); 597 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
598 if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
599 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
597 600
598 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, 601 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
599 sizeof(u32) * dev->wiphy.n_cipher_suites, 602 sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -1922,6 +1925,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
1922 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, 1925 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
1923 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, 1926 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
1924 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, 1927 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
1928 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
1925}; 1929};
1926 1930
1927static int parse_station_flags(struct genl_info *info, 1931static int parse_station_flags(struct genl_info *info,
@@ -2016,6 +2020,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2016 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); 2020 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
2017 if (!sinfoattr) 2021 if (!sinfoattr)
2018 goto nla_put_failure; 2022 goto nla_put_failure;
2023 if (sinfo->filled & STATION_INFO_CONNECTED_TIME)
2024 NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME,
2025 sinfo->connected_time);
2019 if (sinfo->filled & STATION_INFO_INACTIVE_TIME) 2026 if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
2020 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, 2027 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
2021 sinfo->inactive_time); 2028 sinfo->inactive_time);
@@ -2281,7 +2288,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2281 err = -EINVAL; 2288 err = -EINVAL;
2282 if (params.supported_rates) 2289 if (params.supported_rates)
2283 err = -EINVAL; 2290 err = -EINVAL;
2284 if (params.sta_flags_mask) 2291 if (params.sta_flags_mask &
2292 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2293 BIT(NL80211_STA_FLAG_AUTHORIZED)))
2285 err = -EINVAL; 2294 err = -EINVAL;
2286 break; 2295 break;
2287 default: 2296 default:
@@ -2343,11 +2352,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2343 params.ht_capa = 2352 params.ht_capa =
2344 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 2353 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
2345 2354
2355 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2356 params.plink_action =
2357 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2358
2346 if (parse_station_flags(info, &params)) 2359 if (parse_station_flags(info, &params))
2347 return -EINVAL; 2360 return -EINVAL;
2348 2361
2349 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2362 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2350 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2363 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2364 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
2351 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 2365 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2352 return -EINVAL; 2366 return -EINVAL;
2353 2367
@@ -2823,7 +2837,8 @@ static const struct nla_policy
2823 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { 2837 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
2824 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, 2838 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
2825 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 2839 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
2826 [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY, 2840 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
2841 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
2827 .len = IEEE80211_MAX_DATA_LEN }, 2842 .len = IEEE80211_MAX_DATA_LEN },
2828}; 2843};
2829 2844
@@ -2925,14 +2940,16 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
2925 IEEE80211_PATH_METRIC_VENDOR : 2940 IEEE80211_PATH_METRIC_VENDOR :
2926 IEEE80211_PATH_METRIC_AIRTIME; 2941 IEEE80211_PATH_METRIC_AIRTIME;
2927 2942
2928 if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { 2943
2944 if (tb[NL80211_MESH_SETUP_IE]) {
2929 struct nlattr *ieattr = 2945 struct nlattr *ieattr =
2930 tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; 2946 tb[NL80211_MESH_SETUP_IE];
2931 if (!is_valid_ie_attr(ieattr)) 2947 if (!is_valid_ie_attr(ieattr))
2932 return -EINVAL; 2948 return -EINVAL;
2933 setup->vendor_ie = nla_data(ieattr); 2949 setup->ie = nla_data(ieattr);
2934 setup->vendor_ie_len = nla_len(ieattr); 2950 setup->ie_len = nla_len(ieattr);
2935 } 2951 }
2952 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
2936 2953
2937 return 0; 2954 return 0;
2938} 2955}
@@ -5804,6 +5821,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
5804 nlmsg_free(msg); 5821 nlmsg_free(msg);
5805} 5822}
5806 5823
5824void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
5825 struct net_device *netdev,
5826 const u8 *macaddr, const u8* ie, u8 ie_len,
5827 gfp_t gfp)
5828{
5829 struct sk_buff *msg;
5830 void *hdr;
5831
5832 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5833 if (!msg)
5834 return;
5835
5836 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
5837 if (!hdr) {
5838 nlmsg_free(msg);
5839 return;
5840 }
5841
5842 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5843 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5844 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr);
5845 if (ie_len && ie)
5846 NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie);
5847
5848 if (genlmsg_end(msg, hdr) < 0) {
5849 nlmsg_free(msg);
5850 return;
5851 }
5852
5853 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5854 nl80211_mlme_mcgrp.id, gfp);
5855 return;
5856
5857 nla_put_failure:
5858 genlmsg_cancel(msg, hdr);
5859 nlmsg_free(msg);
5860}
5861
5807void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 5862void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
5808 struct net_device *netdev, const u8 *addr, 5863 struct net_device *netdev, const u8 *addr,
5809 enum nl80211_key_type key_type, int key_id, 5864 enum nl80211_key_type key_type, int key_id,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index dcac5cd6f017..f2af6955a665 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
50 struct net_device *netdev, u16 reason, 50 struct net_device *netdev, u16 reason,
51 const u8 *ie, size_t ie_len, bool from_ap); 51 const u8 *ie, size_t ie_len, bool from_ap);
52 52
53void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
54 struct net_device *netdev,
55 const u8 *macaddr, const u8* ie, u8 ie_len,
56 gfp_t gfp);
53void 57void
54nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, 58nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
55 struct net_device *netdev, const u8 *addr, 59 struct net_device *netdev, const u8 *addr,