aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-06-28 13:18:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-28 13:18:21 -0400
commit57ed5cd695d7373b8ae0ae9f10fe945e774d58f0 (patch)
tree7ee6244ea7c0be81a541d4e57783f83c4dfd7d66
parent5e6700b3bf98fe98d630bf9c939ad4c85ce95592 (diff)
parent0f817ed52d07873cd39c9d3f6d87fae962dc742f (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: net/wireless/nl80211.c
-rw-r--r--drivers/bcma/bcma_private.h2
-rw-r--r--drivers/bcma/driver_chipcommon.c11
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c123
-rw-r--r--drivers/bcma/host_pci.c1
-rw-r--r--drivers/bcma/main.c19
-rw-r--r--drivers/bcma/sprom.c1
-rw-r--r--drivers/bluetooth/btusb.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c53
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c62
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h63
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h1774
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c97
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c46
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c16
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c12
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h4
-rw-r--r--drivers/net/wireless/b43/Kconfig6
-rw-r--r--drivers/net/wireless/b43/main.c12
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c165
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c29
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c260
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h5
-rw-r--r--drivers/net/wireless/cw1200/cw1200.h2
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c32
-rw-r--r--drivers/net/wireless/cw1200/hwio.c18
-rw-r--r--drivers/net/wireless/cw1200/hwio.h31
-rw-r--r--drivers/net/wireless/cw1200/main.c4
-rw-r--r--drivers/net/wireless/cw1200/queue.c2
-rw-r--r--drivers/net/wireless/cw1200/sta.c23
-rw-r--r--drivers/net/wireless/cw1200/txrx.c9
-rw-r--r--drivers/net/wireless/cw1200/wsm.c33
-rw-r--r--drivers/net/wireless/cw1200/wsm.h45
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c1
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h37
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h13
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c15
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c43
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c40
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/testmode.c471
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.c852
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.h161
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h309
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c56
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c30
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c22
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c71
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c53
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c6
-rw-r--r--include/linux/bcma/bcma.h1
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h55
-rw-r--r--include/linux/platform_data/brcmfmac-sdio.h5
-rw-r--r--include/net/bluetooth/hci.h1
-rw-r--r--include/net/bluetooth/hci_core.h29
-rw-r--r--include/net/bluetooth/l2cap.h2
-rw-r--r--include/net/cfg80211.h46
-rw-r--r--include/net/mac80211.h2
-rw-r--r--include/uapi/linux/nl80211.h4
-rw-r--r--net/bluetooth/hci_core.c192
-rw-r--r--net/bluetooth/hci_event.c71
-rw-r--r--net/bluetooth/hidp/core.c14
-rw-r--r--net/bluetooth/l2cap_core.c123
-rw-r--r--net/bluetooth/l2cap_sock.c4
-rw-r--r--net/bluetooth/mgmt.c229
-rw-r--r--net/mac80211/cfg.c14
-rw-r--r--net/mac80211/ht.c4
-rw-r--r--net/mac80211/ibss.c65
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/mesh.c57
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_plink.c8
-rw-r--r--net/mac80211/mlme.c35
-rw-r--r--net/mac80211/rate.c8
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/sta_info.h1
-rw-r--r--net/mac80211/vht.c2
-rw-r--r--net/wireless/chan.c57
-rw-r--r--net/wireless/core.c6
-rw-r--r--net/wireless/mlme.c12
-rw-r--r--net/wireless/nl80211.c287
-rw-r--r--net/wireless/scan.c4
-rw-r--r--net/wireless/sme.c23
-rw-r--r--net/wireless/sysfs.c2
119 files changed, 3772 insertions, 3098 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 79595a001204..0215f9ad755c 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -22,6 +22,8 @@
22struct bcma_bus; 22struct bcma_bus;
23 23
24/* main.c */ 24/* main.c */
25bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
26 int timeout);
25int bcma_bus_register(struct bcma_bus *bus); 27int bcma_bus_register(struct bcma_bus *bus);
26void bcma_bus_unregister(struct bcma_bus *bus); 28void bcma_bus_unregister(struct bcma_bus *bus);
27int __init bcma_bus_early_register(struct bcma_bus *bus, 29int __init bcma_bus_early_register(struct bcma_bus *bus,
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 036c6744b39b..b068f98920a8 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
140 bcma_core_chipcommon_early_init(cc); 140 bcma_core_chipcommon_early_init(cc);
141 141
142 if (cc->core->id.rev >= 20) { 142 if (cc->core->id.rev >= 20) {
143 bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); 143 u32 pullup = 0, pulldown = 0;
144 bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); 144
145 if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
146 pullup = 0x402e0;
147 pulldown = 0x20500;
148 }
149
150 bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
151 bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
145 } 152 }
146 153
147 if (cc->capabilities & BCMA_CC_CAP_PMU) 154 if (cc->capabilities & BCMA_CC_CAP_PMU)
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index edca73af3cc0..5081a8c439cc 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
56} 56}
57EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); 57EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
58 58
59static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
60{
61 u32 ilp_ctl, alp_hz;
62
63 if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
64 BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
65 return 0;
66
67 bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
68 BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
69 usleep_range(1000, 2000);
70
71 ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
72 ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
73
74 bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
75
76 alp_hz = ilp_ctl * 32768 / 4;
77 return (alp_hz + 50000) / 100000 * 100;
78}
79
80static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
81{
82 struct bcma_bus *bus = cc->core->bus;
83 u32 freq_tgt_target = 0, freq_tgt_current;
84 u32 pll0, mask;
85
86 switch (bus->chipinfo.id) {
87 case BCMA_CHIP_ID_BCM43142:
88 /* pmu2_xtaltab0_adfll_485 */
89 switch (xtalfreq) {
90 case 12000:
91 freq_tgt_target = 0x50D52;
92 break;
93 case 20000:
94 freq_tgt_target = 0x307FE;
95 break;
96 case 26000:
97 freq_tgt_target = 0x254EA;
98 break;
99 case 37400:
100 freq_tgt_target = 0x19EF8;
101 break;
102 case 52000:
103 freq_tgt_target = 0x12A75;
104 break;
105 }
106 break;
107 }
108
109 if (!freq_tgt_target) {
110 bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
111 xtalfreq);
112 return;
113 }
114
115 pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
116 freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
117 BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
118
119 if (freq_tgt_current == freq_tgt_target) {
120 bcma_debug(bus, "Target TGT frequency already set\n");
121 return;
122 }
123
124 /* Turn off PLL */
125 switch (bus->chipinfo.id) {
126 case BCMA_CHIP_ID_BCM43142:
127 mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
128 BCMA_RES_4314_MACPHY_CLK_AVAIL);
129
130 bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
131 bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
132 bcma_wait_value(cc->core, BCMA_CLKCTLST,
133 BCMA_CLKCTLST_HAVEHT, 0, 20000);
134 break;
135 }
136
137 pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
138 pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
139 bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
140
141 /* Flush */
142 if (cc->pmu.rev >= 2)
143 bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
144
145 /* TODO: Do we need to update OTP? */
146}
147
148static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
149{
150 struct bcma_bus *bus = cc->core->bus;
151 u32 xtalfreq = bcma_pmu_xtalfreq(cc);
152
153 switch (bus->chipinfo.id) {
154 case BCMA_CHIP_ID_BCM43142:
155 if (xtalfreq == 0)
156 xtalfreq = 20000;
157 bcma_pmu2_pll_init0(cc, xtalfreq);
158 break;
159 }
160}
161
59static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) 162static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
60{ 163{
61 struct bcma_bus *bus = cc->core->bus; 164 struct bcma_bus *bus = cc->core->bus;
@@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
66 min_msk = 0x200D; 169 min_msk = 0x200D;
67 max_msk = 0xFFFF; 170 max_msk = 0xFFFF;
68 break; 171 break;
172 case BCMA_CHIP_ID_BCM43142:
173 min_msk = BCMA_RES_4314_LPLDO_PU |
174 BCMA_RES_4314_PMU_SLEEP_DIS |
175 BCMA_RES_4314_PMU_BG_PU |
176 BCMA_RES_4314_CBUCK_LPOM_PU |
177 BCMA_RES_4314_CBUCK_PFM_PU |
178 BCMA_RES_4314_CLDO_PU |
179 BCMA_RES_4314_LPLDO2_LVM |
180 BCMA_RES_4314_WL_PMU_PU |
181 BCMA_RES_4314_LDO3P3_PU |
182 BCMA_RES_4314_OTP_PU |
183 BCMA_RES_4314_WL_PWRSW_PU |
184 BCMA_RES_4314_LQ_AVAIL |
185 BCMA_RES_4314_LOGIC_RET |
186 BCMA_RES_4314_MEM_SLEEP |
187 BCMA_RES_4314_MACPHY_RET |
188 BCMA_RES_4314_WL_CORE_READY;
189 max_msk = 0x3FFFFFFF;
190 break;
69 default: 191 default:
70 bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", 192 bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
71 bus->chipinfo.id); 193 bus->chipinfo.id);
@@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
165 bcma_cc_set32(cc, BCMA_CC_PMU_CTL, 287 bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
166 BCMA_CC_PMU_CTL_NOILPONW); 288 BCMA_CC_PMU_CTL_NOILPONW);
167 289
290 bcma_pmu_pll_init(cc);
168 bcma_pmu_resources_init(cc); 291 bcma_pmu_resources_init(cc);
169 bcma_pmu_workarounds(cc); 292 bcma_pmu_workarounds(cc);
170} 293}
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index fbf2759e7e4e..a355e63a3838 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
275 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, 275 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
276 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, 276 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
277 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, 277 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
278 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
278 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, 279 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
279 { 0, }, 280 { 0, },
280}; 281};
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index f72f52b4b1dd..0067422ec17d 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
93 return NULL; 93 return NULL;
94} 94}
95 95
96bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
97 int timeout)
98{
99 unsigned long deadline = jiffies + timeout;
100 u32 val;
101
102 do {
103 val = bcma_read32(core, reg);
104 if ((val & mask) == value)
105 return true;
106 cpu_relax();
107 udelay(10);
108 } while (!time_after_eq(jiffies, deadline));
109
110 bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
111
112 return false;
113}
114
96static void bcma_release_core_dev(struct device *dev) 115static void bcma_release_core_dev(struct device *dev)
97{ 116{
98 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 117 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index de15b4f4b237..72bf4540f565 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -503,6 +503,7 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
503 case BCMA_CHIP_ID_BCM4331: 503 case BCMA_CHIP_ID_BCM4331:
504 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; 504 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
505 break; 505 break;
506 case BCMA_CHIP_ID_BCM43142:
506 case BCMA_CHIP_ID_BCM43224: 507 case BCMA_CHIP_ID_BCM43224:
507 case BCMA_CHIP_ID_BCM43225: 508 case BCMA_CHIP_ID_BCM43225:
508 /* for these chips OTP is always available */ 509 /* for these chips OTP is always available */
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 81f12757a842..de4cf4daa2f4 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1619,6 +1619,7 @@ static struct usb_driver btusb_driver = {
1619#ifdef CONFIG_PM 1619#ifdef CONFIG_PM
1620 .suspend = btusb_suspend, 1620 .suspend = btusb_suspend,
1621 .resume = btusb_resume, 1621 .resume = btusb_resume,
1622 .reset_resume = btusb_resume,
1622#endif 1623#endif
1623 .id_table = btusb_table, 1624 .id_table = btusb_table,
1624 .supports_autosuspend = 1, 1625 .supports_autosuspend = 1,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 3446c989d6a6..da5c333d0d4b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -54,7 +54,6 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
54 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; 54 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
55 break; 55 break;
56 case WLAN_CIPHER_SUITE_TKIP: 56 case WLAN_CIPHER_SUITE_TKIP:
57 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
58 arg.key_cipher = WMI_CIPHER_TKIP; 57 arg.key_cipher = WMI_CIPHER_TKIP;
59 arg.key_txmic_len = 8; 58 arg.key_txmic_len = 8;
60 arg.key_rxmic_len = 8; 59 arg.key_rxmic_len = 8;
@@ -237,6 +236,8 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
237 case NL80211_CHAN_WIDTH_40: 236 case NL80211_CHAN_WIDTH_40:
238 phymode = MODE_11NG_HT40; 237 phymode = MODE_11NG_HT40;
239 break; 238 break;
239 case NL80211_CHAN_WIDTH_5:
240 case NL80211_CHAN_WIDTH_10:
240 case NL80211_CHAN_WIDTH_80: 241 case NL80211_CHAN_WIDTH_80:
241 case NL80211_CHAN_WIDTH_80P80: 242 case NL80211_CHAN_WIDTH_80P80:
242 case NL80211_CHAN_WIDTH_160: 243 case NL80211_CHAN_WIDTH_160:
@@ -258,6 +259,8 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
258 case NL80211_CHAN_WIDTH_80: 259 case NL80211_CHAN_WIDTH_80:
259 phymode = MODE_11AC_VHT80; 260 phymode = MODE_11AC_VHT80;
260 break; 261 break;
262 case NL80211_CHAN_WIDTH_5:
263 case NL80211_CHAN_WIDTH_10:
261 case NL80211_CHAN_WIDTH_80P80: 264 case NL80211_CHAN_WIDTH_80P80:
262 case NL80211_CHAN_WIDTH_160: 265 case NL80211_CHAN_WIDTH_160:
263 phymode = MODE_UNKNOWN; 266 phymode = MODE_UNKNOWN;
@@ -2721,30 +2724,30 @@ static const struct ieee80211_channel ath10k_2ghz_channels[] = {
2721}; 2724};
2722 2725
2723static const struct ieee80211_channel ath10k_5ghz_channels[] = { 2726static const struct ieee80211_channel ath10k_5ghz_channels[] = {
2724 CHAN5G(36, 5180, 14), 2727 CHAN5G(36, 5180, 0),
2725 CHAN5G(40, 5200, 15), 2728 CHAN5G(40, 5200, 0),
2726 CHAN5G(44, 5220, 16), 2729 CHAN5G(44, 5220, 0),
2727 CHAN5G(48, 5240, 17), 2730 CHAN5G(48, 5240, 0),
2728 CHAN5G(52, 5260, 18), 2731 CHAN5G(52, 5260, 0),
2729 CHAN5G(56, 5280, 19), 2732 CHAN5G(56, 5280, 0),
2730 CHAN5G(60, 5300, 20), 2733 CHAN5G(60, 5300, 0),
2731 CHAN5G(64, 5320, 21), 2734 CHAN5G(64, 5320, 0),
2732 CHAN5G(100, 5500, 22), 2735 CHAN5G(100, 5500, 0),
2733 CHAN5G(104, 5520, 23), 2736 CHAN5G(104, 5520, 0),
2734 CHAN5G(108, 5540, 24), 2737 CHAN5G(108, 5540, 0),
2735 CHAN5G(112, 5560, 25), 2738 CHAN5G(112, 5560, 0),
2736 CHAN5G(116, 5580, 26), 2739 CHAN5G(116, 5580, 0),
2737 CHAN5G(120, 5600, 27), 2740 CHAN5G(120, 5600, 0),
2738 CHAN5G(124, 5620, 28), 2741 CHAN5G(124, 5620, 0),
2739 CHAN5G(128, 5640, 29), 2742 CHAN5G(128, 5640, 0),
2740 CHAN5G(132, 5660, 30), 2743 CHAN5G(132, 5660, 0),
2741 CHAN5G(136, 5680, 31), 2744 CHAN5G(136, 5680, 0),
2742 CHAN5G(140, 5700, 32), 2745 CHAN5G(140, 5700, 0),
2743 CHAN5G(149, 5745, 33), 2746 CHAN5G(149, 5745, 0),
2744 CHAN5G(153, 5765, 34), 2747 CHAN5G(153, 5765, 0),
2745 CHAN5G(157, 5785, 35), 2748 CHAN5G(157, 5785, 0),
2746 CHAN5G(161, 5805, 36), 2749 CHAN5G(161, 5805, 0),
2747 CHAN5G(165, 5825, 37), 2750 CHAN5G(165, 5825, 0),
2748}; 2751};
2749 2752
2750static struct ieee80211_rate ath10k_rates[] = { 2753static struct ieee80211_rate ath10k_rates[] = {
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index c8e905669701..33af4672c909 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1883,9 +1883,10 @@ static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num)
1883 ath10k_warn("request_irq(%d) failed %d\n", 1883 ath10k_warn("request_irq(%d) failed %d\n",
1884 ar_pci->pdev->irq + i, ret); 1884 ar_pci->pdev->irq + i, ret);
1885 1885
1886 for (; i >= MSI_ASSIGN_CE_INITIAL; i--) 1886 for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--)
1887 free_irq(ar_pci->pdev->irq, ar); 1887 free_irq(ar_pci->pdev->irq + i, ar);
1888 1888
1889 free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar);
1889 pci_disable_msi(ar_pci->pdev); 1890 pci_disable_msi(ar_pci->pdev);
1890 return ret; 1891 return ret;
1891 } 1892 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 1e86977d3322..d105e43d22e1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3606,7 +3606,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3606 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE 3606 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3607 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE 3607 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3608 */ 3608 */
3609 if (AR_SREV_9462_20(ah) || AR_SREV_9565(ah)) { 3609 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3610 value = ar9003_switch_com_spdt_get(ah, is2ghz); 3610 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3611 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, 3611 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3612 AR_SWITCH_TABLE_COM_SPDT_ALL, value); 3612 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
@@ -4059,8 +4059,9 @@ static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4059{ 4059{
4060 u32 data, ko, kg; 4060 u32 data, ko, kg;
4061 4061
4062 if (!AR_SREV_9462_20(ah)) 4062 if (!AR_SREV_9462_20_OR_LATER(ah))
4063 return; 4063 return;
4064
4064 ar9300_otp_read_word(ah, 1, &data); 4065 ar9300_otp_read_word(ah, 1, &data);
4065 ko = data & 0xff; 4066 ko = data & 0xff;
4066 kg = (data >> 8) & 0xff; 4067 kg = (data >> 8) & 0xff;
@@ -4752,7 +4753,7 @@ tempslope:
4752 AR_PHY_TPC_19_ALPHA_THERM, temp_slope); 4753 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4753 } 4754 }
4754 4755
4755 if (AR_SREV_9462_20(ah)) 4756 if (AR_SREV_9462_20_OR_LATER(ah))
4756 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, 4757 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4757 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope); 4758 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4758 4759
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 671aaa7e7337..d402cb32283f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -24,6 +24,7 @@
24#include "ar955x_1p0_initvals.h" 24#include "ar955x_1p0_initvals.h"
25#include "ar9580_1p0_initvals.h" 25#include "ar9580_1p0_initvals.h"
26#include "ar9462_2p0_initvals.h" 26#include "ar9462_2p0_initvals.h"
27#include "ar9462_2p1_initvals.h"
27#include "ar9565_1p0_initvals.h" 28#include "ar9565_1p0_initvals.h"
28 29
29/* General hardware code for the AR9003 hadware family */ 30/* General hardware code for the AR9003 hadware family */
@@ -197,6 +198,31 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
197 198
198 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 199 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
199 ar9485_1_1_pcie_phy_clkreq_disable_L1); 200 ar9485_1_1_pcie_phy_clkreq_disable_L1);
201 } else if (AR_SREV_9462_21(ah)) {
202 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
203 ar9462_2p1_mac_core);
204 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
205 ar9462_2p1_mac_postamble);
206 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
207 ar9462_2p1_baseband_core);
208 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
209 ar9462_2p1_baseband_postamble);
210 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
211 ar9462_2p1_radio_core);
212 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
213 ar9462_2p1_radio_postamble);
214 INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant,
215 ar9462_2p1_radio_postamble_sys2ant);
216 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
217 ar9462_2p1_soc_preamble);
218 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
219 ar9462_2p1_soc_postamble);
220 INIT_INI_ARRAY(&ah->iniModesRxGain,
221 ar9462_2p1_common_rx_gain);
222 INIT_INI_ARRAY(&ah->iniModesFastClock,
223 ar9462_2p1_modes_fast_clock);
224 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
225 ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
200 } else if (AR_SREV_9462_20(ah)) { 226 } else if (AR_SREV_9462_20(ah)) {
201 227
202 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); 228 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
@@ -407,6 +433,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
407 else if (AR_SREV_9580(ah)) 433 else if (AR_SREV_9580(ah))
408 INIT_INI_ARRAY(&ah->iniModesTxGain, 434 INIT_INI_ARRAY(&ah->iniModesTxGain,
409 ar9580_1p0_lowest_ob_db_tx_gain_table); 435 ar9580_1p0_lowest_ob_db_tx_gain_table);
436 else if (AR_SREV_9462_21(ah))
437 INIT_INI_ARRAY(&ah->iniModesTxGain,
438 ar9462_2p1_modes_low_ob_db_tx_gain);
410 else if (AR_SREV_9462_20(ah)) 439 else if (AR_SREV_9462_20(ah))
411 INIT_INI_ARRAY(&ah->iniModesTxGain, 440 INIT_INI_ARRAY(&ah->iniModesTxGain,
412 ar9462_modes_low_ob_db_tx_gain_table_2p0); 441 ar9462_modes_low_ob_db_tx_gain_table_2p0);
@@ -438,6 +467,9 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
438 else if (AR_SREV_9550(ah)) 467 else if (AR_SREV_9550(ah))
439 INIT_INI_ARRAY(&ah->iniModesTxGain, 468 INIT_INI_ARRAY(&ah->iniModesTxGain,
440 ar955x_1p0_modes_no_xpa_tx_gain_table); 469 ar955x_1p0_modes_no_xpa_tx_gain_table);
470 else if (AR_SREV_9462_21(ah))
471 INIT_INI_ARRAY(&ah->iniModesTxGain,
472 ar9462_2p1_modes_high_ob_db_tx_gain);
441 else if (AR_SREV_9462_20(ah)) 473 else if (AR_SREV_9462_20(ah))
442 INIT_INI_ARRAY(&ah->iniModesTxGain, 474 INIT_INI_ARRAY(&ah->iniModesTxGain,
443 ar9462_modes_high_ob_db_tx_gain_table_2p0); 475 ar9462_modes_high_ob_db_tx_gain_table_2p0);
@@ -507,6 +539,12 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
507 else if (AR_SREV_9580(ah)) 539 else if (AR_SREV_9580(ah))
508 INIT_INI_ARRAY(&ah->iniModesTxGain, 540 INIT_INI_ARRAY(&ah->iniModesTxGain,
509 ar9580_1p0_mixed_ob_db_tx_gain_table); 541 ar9580_1p0_mixed_ob_db_tx_gain_table);
542 else if (AR_SREV_9462_21(ah))
543 INIT_INI_ARRAY(&ah->iniModesTxGain,
544 ar9462_2p1_modes_mix_ob_db_tx_gain);
545 else if (AR_SREV_9462_20(ah))
546 INIT_INI_ARRAY(&ah->iniModesTxGain,
547 ar9462_modes_mix_ob_db_tx_gain_table_2p0);
510 else 548 else
511 INIT_INI_ARRAY(&ah->iniModesTxGain, 549 INIT_INI_ARRAY(&ah->iniModesTxGain,
512 ar9300Modes_mixed_ob_db_tx_gain_table_2p2); 550 ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
@@ -584,6 +622,9 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
584 } else if (AR_SREV_9580(ah)) 622 } else if (AR_SREV_9580(ah))
585 INIT_INI_ARRAY(&ah->iniModesRxGain, 623 INIT_INI_ARRAY(&ah->iniModesRxGain,
586 ar9580_1p0_rx_gain_table); 624 ar9580_1p0_rx_gain_table);
625 else if (AR_SREV_9462_21(ah))
626 INIT_INI_ARRAY(&ah->iniModesRxGain,
627 ar9462_2p1_common_rx_gain);
587 else if (AR_SREV_9462_20(ah)) 628 else if (AR_SREV_9462_20(ah))
588 INIT_INI_ARRAY(&ah->iniModesRxGain, 629 INIT_INI_ARRAY(&ah->iniModesRxGain,
589 ar9462_common_rx_gain_table_2p0); 630 ar9462_common_rx_gain_table_2p0);
@@ -606,6 +647,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
606 else if (AR_SREV_9485_11(ah)) 647 else if (AR_SREV_9485_11(ah))
607 INIT_INI_ARRAY(&ah->iniModesRxGain, 648 INIT_INI_ARRAY(&ah->iniModesRxGain,
608 ar9485Common_wo_xlna_rx_gain_1_1); 649 ar9485Common_wo_xlna_rx_gain_1_1);
650 else if (AR_SREV_9462_21(ah))
651 INIT_INI_ARRAY(&ah->iniModesRxGain,
652 ar9462_2p1_common_wo_xlna_rx_gain);
609 else if (AR_SREV_9462_20(ah)) 653 else if (AR_SREV_9462_20(ah))
610 INIT_INI_ARRAY(&ah->iniModesRxGain, 654 INIT_INI_ARRAY(&ah->iniModesRxGain,
611 ar9462_common_wo_xlna_rx_gain_table_2p0); 655 ar9462_common_wo_xlna_rx_gain_table_2p0);
@@ -627,7 +671,16 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
627 671
628static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) 672static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
629{ 673{
630 if (AR_SREV_9462_20(ah)) { 674 if (AR_SREV_9462_21(ah)) {
675 INIT_INI_ARRAY(&ah->iniModesRxGain,
676 ar9462_2p1_common_mixed_rx_gain);
677 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
678 ar9462_2p1_baseband_core_mix_rxgain);
679 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
680 ar9462_2p1_baseband_postamble_mix_rxgain);
681 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
682 ar9462_2p1_baseband_postamble_5g_xlna);
683 } else if (AR_SREV_9462_20(ah)) {
631 INIT_INI_ARRAY(&ah->iniModesRxGain, 684 INIT_INI_ARRAY(&ah->iniModesRxGain,
632 ar9462_common_mixed_rx_gain_table_2p0); 685 ar9462_common_mixed_rx_gain_table_2p0);
633 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, 686 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
@@ -641,7 +694,12 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
641 694
642static void ar9003_rx_gain_table_mode3(struct ath_hw *ah) 695static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
643{ 696{
644 if (AR_SREV_9462_20(ah)) { 697 if (AR_SREV_9462_21(ah)) {
698 INIT_INI_ARRAY(&ah->iniModesRxGain,
699 ar9462_2p1_common_5g_xlna_only_rx_gain);
700 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
701 ar9462_2p1_baseband_postamble_5g_xlna);
702 } else if (AR_SREV_9462_20(ah)) {
645 INIT_INI_ARRAY(&ah->iniModesRxGain, 703 INIT_INI_ARRAY(&ah->iniModesRxGain,
646 ar9462_2p0_5g_xlna_only_rxgain); 704 ar9462_2p0_5g_xlna_only_rxgain);
647 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 705 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index df84d20e1092..1f694ab3cc78 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -743,7 +743,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
743 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); 743 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
744 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); 744 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
745 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); 745 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
746 if (i == ATH_INI_POST && AR_SREV_9462_20(ah)) 746 if (i == ATH_INI_POST && AR_SREV_9462_20_OR_LATER(ah))
747 ar9003_hw_prog_ini(ah, 747 ar9003_hw_prog_ini(ah,
748 &ah->ini_radio_post_sys2ant, 748 &ah->ini_radio_post_sys2ant,
749 modesIndex); 749 modesIndex);
@@ -754,7 +754,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
754 */ 754 */
755 REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); 755 REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
756 756
757 if (AR_SREV_9462_20(ah)) { 757 if (AR_SREV_9462_20_OR_LATER(ah)) {
758 /* 758 /*
759 * CUS217 mix LNA mode. 759 * CUS217 mix LNA mode.
760 */ 760 */
@@ -1512,7 +1512,7 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
1512 ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex); 1512 ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex);
1513 ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex); 1513 ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex);
1514 1514
1515 if (AR_SREV_9462_20(ah)) 1515 if (AR_SREV_9462_20_OR_LATER(ah))
1516 ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant, 1516 ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant,
1517 modesIndex); 1517 modesIndex);
1518 1518
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 5013c731f9f6..d4d39f305a0b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -954,7 +954,7 @@
954#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) 954#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
955#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) 955#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
956#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) 956#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
957#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \ 957#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_9462_20_OR_LATER(ah) ? \
958 0x280 : 0x240)) 958 0x280 : 0x240))
959#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240) 959#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240)
960#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff 960#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff
@@ -1048,7 +1048,7 @@
1048#define AR_GLB_GPIO_CONTROL (AR_GLB_BASE) 1048#define AR_GLB_GPIO_CONTROL (AR_GLB_BASE)
1049#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44) 1049#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44)
1050#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \ 1050#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \
1051 (AR_SREV_9462_20(_ah) ? 0x4c : 0x50)) 1051 (AR_SREV_9462_20_OR_LATER(_ah) ? 0x4c : 0x50))
1052#define AR_GLB_STATUS (AR_GLB_BASE + 0x48) 1052#define AR_GLB_STATUS (AR_GLB_BASE + 0x48)
1053 1053
1054/* 1054/*
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index 1d6b705ba110..092b9d412e7f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -879,6 +879,69 @@ static const u32 ar9462_2p0_radio_postamble[][5] = {
879 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 879 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
880}; 880};
881 881
882static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
883 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
884 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
885 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
886 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
887 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
888 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
889 {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
890 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
891 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
892 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
893 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
894 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
895 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
896 {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
897 {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
898 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
899 {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
900 {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
901 {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
902 {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
903 {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
904 {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
905 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
906 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
907 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
908 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
909 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
910 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
911 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
912 {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
913 {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
914 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
915 {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
916 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
917 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
918 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
919 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
920 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
921 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
922 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
923 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
924 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
925 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
926 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
927 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
928 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
929 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
930 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
931 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
932 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
933 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
934 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
935 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
936 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
937 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
938 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
939 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
940 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
941 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
942 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
943};
944
882static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { 945static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
883 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 946 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
884 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 947 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
new file mode 100644
index 000000000000..4dbc294df7e3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
@@ -0,0 +1,1774 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef INITVALS_9462_2P1_H
19#define INITVALS_9462_2P1_H
20
21/* AR9462 2.1 */
22
23static const u32 ar9462_2p1_mac_core[][2] = {
24 /* Addr allmodes */
25 {0x00000008, 0x00000000},
26 {0x00000030, 0x000e0085},
27 {0x00000034, 0x00000005},
28 {0x00000040, 0x00000000},
29 {0x00000044, 0x00000000},
30 {0x00000048, 0x00000008},
31 {0x0000004c, 0x00000010},
32 {0x00000050, 0x00000000},
33 {0x00001040, 0x002ffc0f},
34 {0x00001044, 0x002ffc0f},
35 {0x00001048, 0x002ffc0f},
36 {0x0000104c, 0x002ffc0f},
37 {0x00001050, 0x002ffc0f},
38 {0x00001054, 0x002ffc0f},
39 {0x00001058, 0x002ffc0f},
40 {0x0000105c, 0x002ffc0f},
41 {0x00001060, 0x002ffc0f},
42 {0x00001064, 0x002ffc0f},
43 {0x000010f0, 0x00000100},
44 {0x00001270, 0x00000000},
45 {0x000012b0, 0x00000000},
46 {0x000012f0, 0x00000000},
47 {0x0000143c, 0x00000000},
48 {0x0000147c, 0x00000000},
49 {0x00001810, 0x0f000003},
50 {0x00008000, 0x00000000},
51 {0x00008004, 0x00000000},
52 {0x00008008, 0x00000000},
53 {0x0000800c, 0x00000000},
54 {0x00008018, 0x00000000},
55 {0x00008020, 0x00000000},
56 {0x00008038, 0x00000000},
57 {0x0000803c, 0x00080000},
58 {0x00008040, 0x00000000},
59 {0x00008044, 0x00000000},
60 {0x00008048, 0x00000000},
61 {0x0000804c, 0xffffffff},
62 {0x00008054, 0x00000000},
63 {0x00008058, 0x00000000},
64 {0x0000805c, 0x000fc78f},
65 {0x00008060, 0x0000000f},
66 {0x00008064, 0x00000000},
67 {0x00008070, 0x00000310},
68 {0x00008074, 0x00000020},
69 {0x00008078, 0x00000000},
70 {0x0000809c, 0x0000000f},
71 {0x000080a0, 0x00000000},
72 {0x000080a4, 0x02ff0000},
73 {0x000080a8, 0x0e070605},
74 {0x000080ac, 0x0000000d},
75 {0x000080b0, 0x00000000},
76 {0x000080b4, 0x00000000},
77 {0x000080b8, 0x00000000},
78 {0x000080bc, 0x00000000},
79 {0x000080c0, 0x2a800000},
80 {0x000080c4, 0x06900168},
81 {0x000080c8, 0x13881c20},
82 {0x000080cc, 0x01f40000},
83 {0x000080d0, 0x00252500},
84 {0x000080d4, 0x00b00005},
85 {0x000080d8, 0x00400002},
86 {0x000080dc, 0x00000000},
87 {0x000080e0, 0xffffffff},
88 {0x000080e4, 0x0000ffff},
89 {0x000080e8, 0x3f3f3f3f},
90 {0x000080ec, 0x00000000},
91 {0x000080f0, 0x00000000},
92 {0x000080f4, 0x00000000},
93 {0x000080fc, 0x00020000},
94 {0x00008100, 0x00000000},
95 {0x00008108, 0x00000052},
96 {0x0000810c, 0x00000000},
97 {0x00008110, 0x00000000},
98 {0x00008114, 0x000007ff},
99 {0x00008118, 0x000000aa},
100 {0x0000811c, 0x00003210},
101 {0x00008124, 0x00000000},
102 {0x00008128, 0x00000000},
103 {0x0000812c, 0x00000000},
104 {0x00008130, 0x00000000},
105 {0x00008134, 0x00000000},
106 {0x00008138, 0x00000000},
107 {0x0000813c, 0x0000ffff},
108 {0x00008144, 0xffffffff},
109 {0x00008168, 0x00000000},
110 {0x0000816c, 0x00000000},
111 {0x00008170, 0x18486e00},
112 {0x00008174, 0x33332210},
113 {0x00008178, 0x00000000},
114 {0x0000817c, 0x00020000},
115 {0x000081c4, 0x33332210},
116 {0x000081c8, 0x00000000},
117 {0x000081cc, 0x00000000},
118 {0x000081d4, 0x00000000},
119 {0x000081ec, 0x00000000},
120 {0x000081f0, 0x00000000},
121 {0x000081f4, 0x00000000},
122 {0x000081f8, 0x00000000},
123 {0x000081fc, 0x00000000},
124 {0x00008240, 0x00100000},
125 {0x00008244, 0x0010f400},
126 {0x00008248, 0x00000800},
127 {0x0000824c, 0x0001e800},
128 {0x00008250, 0x00000000},
129 {0x00008254, 0x00000000},
130 {0x00008258, 0x00000000},
131 {0x0000825c, 0x40000000},
132 {0x00008260, 0x00080922},
133 {0x00008264, 0x99c00010},
134 {0x00008268, 0xffffffff},
135 {0x0000826c, 0x0000ffff},
136 {0x00008270, 0x00000000},
137 {0x00008274, 0x40000000},
138 {0x00008278, 0x003e4180},
139 {0x0000827c, 0x00000004},
140 {0x00008284, 0x0000002c},
141 {0x00008288, 0x0000002c},
142 {0x0000828c, 0x000000ff},
143 {0x00008294, 0x00000000},
144 {0x00008298, 0x00000000},
145 {0x0000829c, 0x00000000},
146 {0x00008300, 0x00000140},
147 {0x00008314, 0x00000000},
148 {0x0000831c, 0x0000010d},
149 {0x00008328, 0x00000000},
150 {0x0000832c, 0x0000001f},
151 {0x00008330, 0x00000302},
152 {0x00008334, 0x00000700},
153 {0x00008338, 0xffff0000},
154 {0x0000833c, 0x02400000},
155 {0x00008340, 0x000107ff},
156 {0x00008344, 0xaa48107b},
157 {0x00008348, 0x008f0000},
158 {0x0000835c, 0x00000000},
159 {0x00008360, 0xffffffff},
160 {0x00008364, 0xffffffff},
161 {0x00008368, 0x00000000},
162 {0x00008370, 0x00000000},
163 {0x00008374, 0x000000ff},
164 {0x00008378, 0x00000000},
165 {0x0000837c, 0x00000000},
166 {0x00008380, 0xffffffff},
167 {0x00008384, 0xffffffff},
168 {0x00008390, 0xffffffff},
169 {0x00008394, 0xffffffff},
170 {0x00008398, 0x00000000},
171 {0x0000839c, 0x00000000},
172 {0x000083a4, 0x0000fa14},
173 {0x000083a8, 0x000f0c00},
174 {0x000083ac, 0x33332210},
175 {0x000083b0, 0x33332210},
176 {0x000083b4, 0x33332210},
177 {0x000083b8, 0x33332210},
178 {0x000083bc, 0x00000000},
179 {0x000083c0, 0x00000000},
180 {0x000083c4, 0x00000000},
181 {0x000083c8, 0x00000000},
182 {0x000083cc, 0x00000200},
183 {0x000083d0, 0x000301ff},
184};
185
186static const u32 ar9462_2p1_mac_postamble[][5] = {
187 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
188 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
189 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
190 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
191 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
192 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
193 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
194 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
195 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
196};
197
198static const u32 ar9462_2p1_baseband_core[][2] = {
199 /* Addr allmodes */
200 {0x00009800, 0xafe68e30},
201 {0x00009804, 0xfd14e000},
202 {0x00009808, 0x9c0a9f6b},
203 {0x0000980c, 0x04900000},
204 {0x00009814, 0x9280c00a},
205 {0x00009818, 0x00000000},
206 {0x0000981c, 0x00020028},
207 {0x00009834, 0x6400a290},
208 {0x00009838, 0x0108ecff},
209 {0x0000983c, 0x0d000600},
210 {0x00009880, 0x201fff00},
211 {0x00009884, 0x00001042},
212 {0x000098a4, 0x00200400},
213 {0x000098b0, 0x32440bbe},
214 {0x000098d0, 0x004b6a8e},
215 {0x000098d4, 0x00000820},
216 {0x000098dc, 0x00000000},
217 {0x000098e4, 0x01ffffff},
218 {0x000098e8, 0x01ffffff},
219 {0x000098ec, 0x01ffffff},
220 {0x000098f0, 0x00000000},
221 {0x000098f4, 0x00000000},
222 {0x00009bf0, 0x80000000},
223 {0x00009c04, 0xff55ff55},
224 {0x00009c08, 0x0320ff55},
225 {0x00009c0c, 0x00000000},
226 {0x00009c10, 0x00000000},
227 {0x00009c14, 0x00046384},
228 {0x00009c18, 0x05b6b440},
229 {0x00009c1c, 0x00b6b440},
230 {0x00009d00, 0xc080a333},
231 {0x00009d04, 0x40206c10},
232 {0x00009d08, 0x009c4060},
233 {0x00009d0c, 0x9883800a},
234 {0x00009d10, 0x01834061},
235 {0x00009d14, 0x00c0040b},
236 {0x00009d18, 0x00000000},
237 {0x00009e08, 0x0038230c},
238 {0x00009e24, 0x990bb515},
239 {0x00009e28, 0x0c6f0000},
240 {0x00009e30, 0x06336f77},
241 {0x00009e34, 0x6af6532f},
242 {0x00009e38, 0x0cc80c00},
243 {0x00009e40, 0x15262820},
244 {0x00009e4c, 0x00001004},
245 {0x00009e50, 0x00ff03f1},
246 {0x00009e54, 0xe4c555c2},
247 {0x00009e58, 0xfd857722},
248 {0x00009e5c, 0xe9198724},
249 {0x00009fc0, 0x803e4788},
250 {0x00009fc4, 0x0001efb5},
251 {0x00009fcc, 0x40000014},
252 {0x00009fd0, 0x0a193b93},
253 {0x0000a20c, 0x00000000},
254 {0x0000a220, 0x00000000},
255 {0x0000a224, 0x00000000},
256 {0x0000a228, 0x10002310},
257 {0x0000a23c, 0x00000000},
258 {0x0000a244, 0x0c000000},
259 {0x0000a2a0, 0x00000001},
260 {0x0000a2c0, 0x00000001},
261 {0x0000a2c8, 0x00000000},
262 {0x0000a2cc, 0x18c43433},
263 {0x0000a2d4, 0x00000000},
264 {0x0000a2ec, 0x00000000},
265 {0x0000a2f0, 0x00000000},
266 {0x0000a2f4, 0x00000000},
267 {0x0000a2f8, 0x00000000},
268 {0x0000a344, 0x00000000},
269 {0x0000a34c, 0x00000000},
270 {0x0000a350, 0x0000a000},
271 {0x0000a364, 0x00000000},
272 {0x0000a370, 0x00000000},
273 {0x0000a390, 0x00000001},
274 {0x0000a394, 0x00000444},
275 {0x0000a398, 0x001f0e0f},
276 {0x0000a39c, 0x0075393f},
277 {0x0000a3a0, 0xb79f6427},
278 {0x0000a3c0, 0x20202020},
279 {0x0000a3c4, 0x22222220},
280 {0x0000a3c8, 0x20200020},
281 {0x0000a3cc, 0x20202020},
282 {0x0000a3d0, 0x20202020},
283 {0x0000a3d4, 0x20202020},
284 {0x0000a3d8, 0x20202020},
285 {0x0000a3dc, 0x20202020},
286 {0x0000a3e0, 0x20202020},
287 {0x0000a3e4, 0x20202020},
288 {0x0000a3e8, 0x20202020},
289 {0x0000a3ec, 0x20202020},
290 {0x0000a3f0, 0x00000000},
291 {0x0000a3f4, 0x00000006},
292 {0x0000a3f8, 0x0c9bd380},
293 {0x0000a3fc, 0x000f0f01},
294 {0x0000a400, 0x8fa91f01},
295 {0x0000a404, 0x00000000},
296 {0x0000a408, 0x0e79e5c6},
297 {0x0000a40c, 0x00820820},
298 {0x0000a414, 0x1ce739ce},
299 {0x0000a418, 0x2d001dce},
300 {0x0000a434, 0x00000000},
301 {0x0000a438, 0x00001801},
302 {0x0000a43c, 0x00100000},
303 {0x0000a444, 0x00000000},
304 {0x0000a448, 0x05000080},
305 {0x0000a44c, 0x00000001},
306 {0x0000a450, 0x00010000},
307 {0x0000a454, 0x07000000},
308 {0x0000a644, 0xbfad9d74},
309 {0x0000a648, 0x0048060a},
310 {0x0000a64c, 0x00002037},
311 {0x0000a670, 0x03020100},
312 {0x0000a674, 0x09080504},
313 {0x0000a678, 0x0d0c0b0a},
314 {0x0000a67c, 0x13121110},
315 {0x0000a680, 0x31301514},
316 {0x0000a684, 0x35343332},
317 {0x0000a688, 0x00000036},
318 {0x0000a690, 0x00000838},
319 {0x0000a6b0, 0x0000000a},
320 {0x0000a6b4, 0x00512c01},
321 {0x0000a7c0, 0x00000000},
322 {0x0000a7c4, 0xfffffffc},
323 {0x0000a7c8, 0x00000000},
324 {0x0000a7cc, 0x00000000},
325 {0x0000a7d0, 0x00000000},
326 {0x0000a7d4, 0x00000004},
327 {0x0000a7dc, 0x00000000},
328 {0x0000a7f0, 0x80000000},
329 {0x0000a8d0, 0x004b6a8e},
330 {0x0000a8d4, 0x00000820},
331 {0x0000a8dc, 0x00000000},
332 {0x0000a8f0, 0x00000000},
333 {0x0000a8f4, 0x00000000},
334 {0x0000abf0, 0x80000000},
335 {0x0000b2d0, 0x00000080},
336 {0x0000b2d4, 0x00000000},
337 {0x0000b2ec, 0x00000000},
338 {0x0000b2f0, 0x00000000},
339 {0x0000b2f4, 0x00000000},
340 {0x0000b2f8, 0x00000000},
341 {0x0000b408, 0x0e79e5c0},
342 {0x0000b40c, 0x00820820},
343 {0x0000b420, 0x00000000},
344 {0x0000b6b0, 0x0000000a},
345 {0x0000b6b4, 0x00000001},
346};
347
348static const u32 ar9462_2p1_baseband_postamble[][5] = {
349 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
350 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
351 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae},
352 {0x00009824, 0x63c640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
353 {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81},
354 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
355 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
356 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
357 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a2},
358 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
359 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8},
360 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
361 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e},
362 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
363 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
364 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
365 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
366 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
367 {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
368 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
369 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
370 {0x0000a204, 0x01318fc0, 0x01318fc4, 0x01318fc4, 0x01318fc0},
371 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
372 {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f},
373 {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
374 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
375 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
376 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
377 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
378 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
379 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
380 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
381 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
382 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
383 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
384 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
385 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
386 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
387 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
388 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
389 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
390 {0x0000a3a4, 0x00000050, 0x00000050, 0x00000000, 0x00000000},
391 {0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa},
392 {0x0000a3ac, 0xaaaaaa00, 0xaa30aa30, 0xaaaaaa00, 0xaaaaaa00},
393 {0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
394 {0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
395 {0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
396 {0x0000a428, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
397 {0x0000a42c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
398 {0x0000a430, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
399 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
400 {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000},
401 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
402 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
403 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
404 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
405};
406
407static const u32 ar9462_2p1_radio_core[][2] = {
408 /* Addr allmodes */
409 {0x00016000, 0x36db6db6},
410 {0x00016004, 0x6db6db40},
411 {0x00016008, 0x73f00000},
412 {0x0001600c, 0x00000000},
413 {0x00016010, 0x6d820001},
414 {0x00016040, 0x7f80fff8},
415 {0x0001604c, 0x2699e04f},
416 {0x00016050, 0x6db6db6c},
417 {0x00016058, 0x6c200000},
418 {0x00016080, 0x000c0000},
419 {0x00016084, 0x9a68048c},
420 {0x00016088, 0x54214514},
421 {0x0001608c, 0x1203040b},
422 {0x00016090, 0x24926490},
423 {0x00016098, 0xd2888888},
424 {0x000160a0, 0x0a108ffe},
425 {0x000160a4, 0x812fc491},
426 {0x000160a8, 0x423c8000},
427 {0x000160b4, 0x92000000},
428 {0x000160b8, 0x0285dddc},
429 {0x000160bc, 0x02908888},
430 {0x000160c0, 0x00adb6d0},
431 {0x000160c4, 0x6db6db60},
432 {0x000160c8, 0x6db6db6c},
433 {0x000160cc, 0x0de6c1b0},
434 {0x00016100, 0x3fffbe04},
435 {0x00016104, 0xfff80000},
436 {0x00016108, 0x00200400},
437 {0x00016110, 0x00000000},
438 {0x00016144, 0x02084080},
439 {0x00016148, 0x000080c0},
440 {0x00016280, 0x050a0001},
441 {0x00016284, 0x3d841418},
442 {0x00016288, 0x00000000},
443 {0x0001628c, 0xe3000000},
444 {0x00016290, 0xa1005080},
445 {0x00016294, 0x00000020},
446 {0x00016298, 0x54a82900},
447 {0x00016340, 0x121e4276},
448 {0x00016344, 0x00300000},
449 {0x00016400, 0x36db6db6},
450 {0x00016404, 0x6db6db40},
451 {0x00016408, 0x73f00000},
452 {0x0001640c, 0x00000000},
453 {0x00016410, 0x6c800001},
454 {0x00016440, 0x7f80fff8},
455 {0x0001644c, 0x4699e04f},
456 {0x00016450, 0x6db6db6c},
457 {0x00016500, 0x3fffbe04},
458 {0x00016504, 0xfff80000},
459 {0x00016508, 0x00200400},
460 {0x00016510, 0x00000000},
461 {0x00016544, 0x02084080},
462 {0x00016548, 0x000080c0},
463};
464
465static const u32 ar9462_2p1_radio_postamble[][5] = {
466 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
467 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
468 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
469 {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
470 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
471};
472
473static const u32 ar9462_2p1_soc_preamble[][2] = {
474 /* Addr allmodes */
475 {0x000040a4, 0x00a0c1c9},
476 {0x00007020, 0x00000000},
477 {0x00007034, 0x00000002},
478 {0x00007038, 0x000004c2},
479};
480
481static const u32 ar9462_2p1_soc_postamble[][5] = {
482 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
483 {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033},
484};
485
486static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = {
487 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
488 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
489 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
490 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
491};
492
493static const u32 ar9462_2p1_common_rx_gain[][2] = {
494 /* Addr allmodes */
495 {0x0000a000, 0x00010000},
496 {0x0000a004, 0x00030002},
497 {0x0000a008, 0x00050004},
498 {0x0000a00c, 0x00810080},
499 {0x0000a010, 0x00830082},
500 {0x0000a014, 0x01810180},
501 {0x0000a018, 0x01830182},
502 {0x0000a01c, 0x01850184},
503 {0x0000a020, 0x01890188},
504 {0x0000a024, 0x018b018a},
505 {0x0000a028, 0x018d018c},
506 {0x0000a02c, 0x01910190},
507 {0x0000a030, 0x01930192},
508 {0x0000a034, 0x01950194},
509 {0x0000a038, 0x038a0196},
510 {0x0000a03c, 0x038c038b},
511 {0x0000a040, 0x0390038d},
512 {0x0000a044, 0x03920391},
513 {0x0000a048, 0x03940393},
514 {0x0000a04c, 0x03960395},
515 {0x0000a050, 0x00000000},
516 {0x0000a054, 0x00000000},
517 {0x0000a058, 0x00000000},
518 {0x0000a05c, 0x00000000},
519 {0x0000a060, 0x00000000},
520 {0x0000a064, 0x00000000},
521 {0x0000a068, 0x00000000},
522 {0x0000a06c, 0x00000000},
523 {0x0000a070, 0x00000000},
524 {0x0000a074, 0x00000000},
525 {0x0000a078, 0x00000000},
526 {0x0000a07c, 0x00000000},
527 {0x0000a080, 0x22222229},
528 {0x0000a084, 0x1d1d1d1d},
529 {0x0000a088, 0x1d1d1d1d},
530 {0x0000a08c, 0x1d1d1d1d},
531 {0x0000a090, 0x171d1d1d},
532 {0x0000a094, 0x11111717},
533 {0x0000a098, 0x00030311},
534 {0x0000a09c, 0x00000000},
535 {0x0000a0a0, 0x00000000},
536 {0x0000a0a4, 0x00000000},
537 {0x0000a0a8, 0x00000000},
538 {0x0000a0ac, 0x00000000},
539 {0x0000a0b0, 0x00000000},
540 {0x0000a0b4, 0x00000000},
541 {0x0000a0b8, 0x00000000},
542 {0x0000a0bc, 0x00000000},
543 {0x0000a0c0, 0x001f0000},
544 {0x0000a0c4, 0x01000101},
545 {0x0000a0c8, 0x011e011f},
546 {0x0000a0cc, 0x011c011d},
547 {0x0000a0d0, 0x02030204},
548 {0x0000a0d4, 0x02010202},
549 {0x0000a0d8, 0x021f0200},
550 {0x0000a0dc, 0x0302021e},
551 {0x0000a0e0, 0x03000301},
552 {0x0000a0e4, 0x031e031f},
553 {0x0000a0e8, 0x0402031d},
554 {0x0000a0ec, 0x04000401},
555 {0x0000a0f0, 0x041e041f},
556 {0x0000a0f4, 0x0502041d},
557 {0x0000a0f8, 0x05000501},
558 {0x0000a0fc, 0x051e051f},
559 {0x0000a100, 0x06010602},
560 {0x0000a104, 0x061f0600},
561 {0x0000a108, 0x061d061e},
562 {0x0000a10c, 0x07020703},
563 {0x0000a110, 0x07000701},
564 {0x0000a114, 0x00000000},
565 {0x0000a118, 0x00000000},
566 {0x0000a11c, 0x00000000},
567 {0x0000a120, 0x00000000},
568 {0x0000a124, 0x00000000},
569 {0x0000a128, 0x00000000},
570 {0x0000a12c, 0x00000000},
571 {0x0000a130, 0x00000000},
572 {0x0000a134, 0x00000000},
573 {0x0000a138, 0x00000000},
574 {0x0000a13c, 0x00000000},
575 {0x0000a140, 0x001f0000},
576 {0x0000a144, 0x01000101},
577 {0x0000a148, 0x011e011f},
578 {0x0000a14c, 0x011c011d},
579 {0x0000a150, 0x02030204},
580 {0x0000a154, 0x02010202},
581 {0x0000a158, 0x021f0200},
582 {0x0000a15c, 0x0302021e},
583 {0x0000a160, 0x03000301},
584 {0x0000a164, 0x031e031f},
585 {0x0000a168, 0x0402031d},
586 {0x0000a16c, 0x04000401},
587 {0x0000a170, 0x041e041f},
588 {0x0000a174, 0x0502041d},
589 {0x0000a178, 0x05000501},
590 {0x0000a17c, 0x051e051f},
591 {0x0000a180, 0x06010602},
592 {0x0000a184, 0x061f0600},
593 {0x0000a188, 0x061d061e},
594 {0x0000a18c, 0x07020703},
595 {0x0000a190, 0x07000701},
596 {0x0000a194, 0x00000000},
597 {0x0000a198, 0x00000000},
598 {0x0000a19c, 0x00000000},
599 {0x0000a1a0, 0x00000000},
600 {0x0000a1a4, 0x00000000},
601 {0x0000a1a8, 0x00000000},
602 {0x0000a1ac, 0x00000000},
603 {0x0000a1b0, 0x00000000},
604 {0x0000a1b4, 0x00000000},
605 {0x0000a1b8, 0x00000000},
606 {0x0000a1bc, 0x00000000},
607 {0x0000a1c0, 0x00000000},
608 {0x0000a1c4, 0x00000000},
609 {0x0000a1c8, 0x00000000},
610 {0x0000a1cc, 0x00000000},
611 {0x0000a1d0, 0x00000000},
612 {0x0000a1d4, 0x00000000},
613 {0x0000a1d8, 0x00000000},
614 {0x0000a1dc, 0x00000000},
615 {0x0000a1e0, 0x00000000},
616 {0x0000a1e4, 0x00000000},
617 {0x0000a1e8, 0x00000000},
618 {0x0000a1ec, 0x00000000},
619 {0x0000a1f0, 0x00000396},
620 {0x0000a1f4, 0x00000396},
621 {0x0000a1f8, 0x00000396},
622 {0x0000a1fc, 0x00000196},
623 {0x0000b000, 0x00010000},
624 {0x0000b004, 0x00030002},
625 {0x0000b008, 0x00050004},
626 {0x0000b00c, 0x00810080},
627 {0x0000b010, 0x00830082},
628 {0x0000b014, 0x01810180},
629 {0x0000b018, 0x01830182},
630 {0x0000b01c, 0x01850184},
631 {0x0000b020, 0x02810280},
632 {0x0000b024, 0x02830282},
633 {0x0000b028, 0x02850284},
634 {0x0000b02c, 0x02890288},
635 {0x0000b030, 0x028b028a},
636 {0x0000b034, 0x0388028c},
637 {0x0000b038, 0x038a0389},
638 {0x0000b03c, 0x038c038b},
639 {0x0000b040, 0x0390038d},
640 {0x0000b044, 0x03920391},
641 {0x0000b048, 0x03940393},
642 {0x0000b04c, 0x03960395},
643 {0x0000b050, 0x00000000},
644 {0x0000b054, 0x00000000},
645 {0x0000b058, 0x00000000},
646 {0x0000b05c, 0x00000000},
647 {0x0000b060, 0x00000000},
648 {0x0000b064, 0x00000000},
649 {0x0000b068, 0x00000000},
650 {0x0000b06c, 0x00000000},
651 {0x0000b070, 0x00000000},
652 {0x0000b074, 0x00000000},
653 {0x0000b078, 0x00000000},
654 {0x0000b07c, 0x00000000},
655 {0x0000b080, 0x2a2d2f32},
656 {0x0000b084, 0x21232328},
657 {0x0000b088, 0x19191c1e},
658 {0x0000b08c, 0x12141417},
659 {0x0000b090, 0x07070e0e},
660 {0x0000b094, 0x03030305},
661 {0x0000b098, 0x00000003},
662 {0x0000b09c, 0x00000000},
663 {0x0000b0a0, 0x00000000},
664 {0x0000b0a4, 0x00000000},
665 {0x0000b0a8, 0x00000000},
666 {0x0000b0ac, 0x00000000},
667 {0x0000b0b0, 0x00000000},
668 {0x0000b0b4, 0x00000000},
669 {0x0000b0b8, 0x00000000},
670 {0x0000b0bc, 0x00000000},
671 {0x0000b0c0, 0x003f0020},
672 {0x0000b0c4, 0x00400041},
673 {0x0000b0c8, 0x0140005f},
674 {0x0000b0cc, 0x0160015f},
675 {0x0000b0d0, 0x017e017f},
676 {0x0000b0d4, 0x02410242},
677 {0x0000b0d8, 0x025f0240},
678 {0x0000b0dc, 0x027f0260},
679 {0x0000b0e0, 0x0341027e},
680 {0x0000b0e4, 0x035f0340},
681 {0x0000b0e8, 0x037f0360},
682 {0x0000b0ec, 0x04400441},
683 {0x0000b0f0, 0x0460045f},
684 {0x0000b0f4, 0x0541047f},
685 {0x0000b0f8, 0x055f0540},
686 {0x0000b0fc, 0x057f0560},
687 {0x0000b100, 0x06400641},
688 {0x0000b104, 0x0660065f},
689 {0x0000b108, 0x067e067f},
690 {0x0000b10c, 0x07410742},
691 {0x0000b110, 0x075f0740},
692 {0x0000b114, 0x077f0760},
693 {0x0000b118, 0x07800781},
694 {0x0000b11c, 0x07a0079f},
695 {0x0000b120, 0x07c107bf},
696 {0x0000b124, 0x000007c0},
697 {0x0000b128, 0x00000000},
698 {0x0000b12c, 0x00000000},
699 {0x0000b130, 0x00000000},
700 {0x0000b134, 0x00000000},
701 {0x0000b138, 0x00000000},
702 {0x0000b13c, 0x00000000},
703 {0x0000b140, 0x003f0020},
704 {0x0000b144, 0x00400041},
705 {0x0000b148, 0x0140005f},
706 {0x0000b14c, 0x0160015f},
707 {0x0000b150, 0x017e017f},
708 {0x0000b154, 0x02410242},
709 {0x0000b158, 0x025f0240},
710 {0x0000b15c, 0x027f0260},
711 {0x0000b160, 0x0341027e},
712 {0x0000b164, 0x035f0340},
713 {0x0000b168, 0x037f0360},
714 {0x0000b16c, 0x04400441},
715 {0x0000b170, 0x0460045f},
716 {0x0000b174, 0x0541047f},
717 {0x0000b178, 0x055f0540},
718 {0x0000b17c, 0x057f0560},
719 {0x0000b180, 0x06400641},
720 {0x0000b184, 0x0660065f},
721 {0x0000b188, 0x067e067f},
722 {0x0000b18c, 0x07410742},
723 {0x0000b190, 0x075f0740},
724 {0x0000b194, 0x077f0760},
725 {0x0000b198, 0x07800781},
726 {0x0000b19c, 0x07a0079f},
727 {0x0000b1a0, 0x07c107bf},
728 {0x0000b1a4, 0x000007c0},
729 {0x0000b1a8, 0x00000000},
730 {0x0000b1ac, 0x00000000},
731 {0x0000b1b0, 0x00000000},
732 {0x0000b1b4, 0x00000000},
733 {0x0000b1b8, 0x00000000},
734 {0x0000b1bc, 0x00000000},
735 {0x0000b1c0, 0x00000000},
736 {0x0000b1c4, 0x00000000},
737 {0x0000b1c8, 0x00000000},
738 {0x0000b1cc, 0x00000000},
739 {0x0000b1d0, 0x00000000},
740 {0x0000b1d4, 0x00000000},
741 {0x0000b1d8, 0x00000000},
742 {0x0000b1dc, 0x00000000},
743 {0x0000b1e0, 0x00000000},
744 {0x0000b1e4, 0x00000000},
745 {0x0000b1e8, 0x00000000},
746 {0x0000b1ec, 0x00000000},
747 {0x0000b1f0, 0x00000396},
748 {0x0000b1f4, 0x00000396},
749 {0x0000b1f8, 0x00000396},
750 {0x0000b1fc, 0x00000196},
751};
752
753static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = {
754 /* Addr allmodes */
755 {0x0000a000, 0x00010000},
756 {0x0000a004, 0x00030002},
757 {0x0000a008, 0x00050004},
758 {0x0000a00c, 0x00810080},
759 {0x0000a010, 0x00830082},
760 {0x0000a014, 0x01810180},
761 {0x0000a018, 0x01830182},
762 {0x0000a01c, 0x01850184},
763 {0x0000a020, 0x01890188},
764 {0x0000a024, 0x018b018a},
765 {0x0000a028, 0x018d018c},
766 {0x0000a02c, 0x03820190},
767 {0x0000a030, 0x03840383},
768 {0x0000a034, 0x03880385},
769 {0x0000a038, 0x038a0389},
770 {0x0000a03c, 0x038c038b},
771 {0x0000a040, 0x0390038d},
772 {0x0000a044, 0x03920391},
773 {0x0000a048, 0x03940393},
774 {0x0000a04c, 0x03960395},
775 {0x0000a050, 0x00000000},
776 {0x0000a054, 0x00000000},
777 {0x0000a058, 0x00000000},
778 {0x0000a05c, 0x00000000},
779 {0x0000a060, 0x00000000},
780 {0x0000a064, 0x00000000},
781 {0x0000a068, 0x00000000},
782 {0x0000a06c, 0x00000000},
783 {0x0000a070, 0x00000000},
784 {0x0000a074, 0x00000000},
785 {0x0000a078, 0x00000000},
786 {0x0000a07c, 0x00000000},
787 {0x0000a080, 0x29292929},
788 {0x0000a084, 0x29292929},
789 {0x0000a088, 0x29292929},
790 {0x0000a08c, 0x29292929},
791 {0x0000a090, 0x22292929},
792 {0x0000a094, 0x1d1d2222},
793 {0x0000a098, 0x0c111117},
794 {0x0000a09c, 0x00030303},
795 {0x0000a0a0, 0x00000000},
796 {0x0000a0a4, 0x00000000},
797 {0x0000a0a8, 0x00000000},
798 {0x0000a0ac, 0x00000000},
799 {0x0000a0b0, 0x00000000},
800 {0x0000a0b4, 0x00000000},
801 {0x0000a0b8, 0x00000000},
802 {0x0000a0bc, 0x00000000},
803 {0x0000a0c0, 0x001f0000},
804 {0x0000a0c4, 0x01000101},
805 {0x0000a0c8, 0x011e011f},
806 {0x0000a0cc, 0x011c011d},
807 {0x0000a0d0, 0x02030204},
808 {0x0000a0d4, 0x02010202},
809 {0x0000a0d8, 0x021f0200},
810 {0x0000a0dc, 0x0302021e},
811 {0x0000a0e0, 0x03000301},
812 {0x0000a0e4, 0x031e031f},
813 {0x0000a0e8, 0x0402031d},
814 {0x0000a0ec, 0x04000401},
815 {0x0000a0f0, 0x041e041f},
816 {0x0000a0f4, 0x0502041d},
817 {0x0000a0f8, 0x05000501},
818 {0x0000a0fc, 0x051e051f},
819 {0x0000a100, 0x06010602},
820 {0x0000a104, 0x061f0600},
821 {0x0000a108, 0x061d061e},
822 {0x0000a10c, 0x07020703},
823 {0x0000a110, 0x07000701},
824 {0x0000a114, 0x00000000},
825 {0x0000a118, 0x00000000},
826 {0x0000a11c, 0x00000000},
827 {0x0000a120, 0x00000000},
828 {0x0000a124, 0x00000000},
829 {0x0000a128, 0x00000000},
830 {0x0000a12c, 0x00000000},
831 {0x0000a130, 0x00000000},
832 {0x0000a134, 0x00000000},
833 {0x0000a138, 0x00000000},
834 {0x0000a13c, 0x00000000},
835 {0x0000a140, 0x001f0000},
836 {0x0000a144, 0x01000101},
837 {0x0000a148, 0x011e011f},
838 {0x0000a14c, 0x011c011d},
839 {0x0000a150, 0x02030204},
840 {0x0000a154, 0x02010202},
841 {0x0000a158, 0x021f0200},
842 {0x0000a15c, 0x0302021e},
843 {0x0000a160, 0x03000301},
844 {0x0000a164, 0x031e031f},
845 {0x0000a168, 0x0402031d},
846 {0x0000a16c, 0x04000401},
847 {0x0000a170, 0x041e041f},
848 {0x0000a174, 0x0502041d},
849 {0x0000a178, 0x05000501},
850 {0x0000a17c, 0x051e051f},
851 {0x0000a180, 0x06010602},
852 {0x0000a184, 0x061f0600},
853 {0x0000a188, 0x061d061e},
854 {0x0000a18c, 0x07020703},
855 {0x0000a190, 0x07000701},
856 {0x0000a194, 0x00000000},
857 {0x0000a198, 0x00000000},
858 {0x0000a19c, 0x00000000},
859 {0x0000a1a0, 0x00000000},
860 {0x0000a1a4, 0x00000000},
861 {0x0000a1a8, 0x00000000},
862 {0x0000a1ac, 0x00000000},
863 {0x0000a1b0, 0x00000000},
864 {0x0000a1b4, 0x00000000},
865 {0x0000a1b8, 0x00000000},
866 {0x0000a1bc, 0x00000000},
867 {0x0000a1c0, 0x00000000},
868 {0x0000a1c4, 0x00000000},
869 {0x0000a1c8, 0x00000000},
870 {0x0000a1cc, 0x00000000},
871 {0x0000a1d0, 0x00000000},
872 {0x0000a1d4, 0x00000000},
873 {0x0000a1d8, 0x00000000},
874 {0x0000a1dc, 0x00000000},
875 {0x0000a1e0, 0x00000000},
876 {0x0000a1e4, 0x00000000},
877 {0x0000a1e8, 0x00000000},
878 {0x0000a1ec, 0x00000000},
879 {0x0000a1f0, 0x00000396},
880 {0x0000a1f4, 0x00000396},
881 {0x0000a1f8, 0x00000396},
882 {0x0000a1fc, 0x00000196},
883 {0x0000b000, 0x00010000},
884 {0x0000b004, 0x00030002},
885 {0x0000b008, 0x00050004},
886 {0x0000b00c, 0x00810080},
887 {0x0000b010, 0x00830082},
888 {0x0000b014, 0x01810180},
889 {0x0000b018, 0x01830182},
890 {0x0000b01c, 0x01850184},
891 {0x0000b020, 0x02810280},
892 {0x0000b024, 0x02830282},
893 {0x0000b028, 0x02850284},
894 {0x0000b02c, 0x02890288},
895 {0x0000b030, 0x028b028a},
896 {0x0000b034, 0x0388028c},
897 {0x0000b038, 0x038a0389},
898 {0x0000b03c, 0x038c038b},
899 {0x0000b040, 0x0390038d},
900 {0x0000b044, 0x03920391},
901 {0x0000b048, 0x03940393},
902 {0x0000b04c, 0x03960395},
903 {0x0000b050, 0x00000000},
904 {0x0000b054, 0x00000000},
905 {0x0000b058, 0x00000000},
906 {0x0000b05c, 0x00000000},
907 {0x0000b060, 0x00000000},
908 {0x0000b064, 0x00000000},
909 {0x0000b068, 0x00000000},
910 {0x0000b06c, 0x00000000},
911 {0x0000b070, 0x00000000},
912 {0x0000b074, 0x00000000},
913 {0x0000b078, 0x00000000},
914 {0x0000b07c, 0x00000000},
915 {0x0000b080, 0x2a2d2f32},
916 {0x0000b084, 0x21232328},
917 {0x0000b088, 0x19191c1e},
918 {0x0000b08c, 0x12141417},
919 {0x0000b090, 0x07070e0e},
920 {0x0000b094, 0x03030305},
921 {0x0000b098, 0x00000003},
922 {0x0000b09c, 0x00000000},
923 {0x0000b0a0, 0x00000000},
924 {0x0000b0a4, 0x00000000},
925 {0x0000b0a8, 0x00000000},
926 {0x0000b0ac, 0x00000000},
927 {0x0000b0b0, 0x00000000},
928 {0x0000b0b4, 0x00000000},
929 {0x0000b0b8, 0x00000000},
930 {0x0000b0bc, 0x00000000},
931 {0x0000b0c0, 0x003f0020},
932 {0x0000b0c4, 0x00400041},
933 {0x0000b0c8, 0x0140005f},
934 {0x0000b0cc, 0x0160015f},
935 {0x0000b0d0, 0x017e017f},
936 {0x0000b0d4, 0x02410242},
937 {0x0000b0d8, 0x025f0240},
938 {0x0000b0dc, 0x027f0260},
939 {0x0000b0e0, 0x0341027e},
940 {0x0000b0e4, 0x035f0340},
941 {0x0000b0e8, 0x037f0360},
942 {0x0000b0ec, 0x04400441},
943 {0x0000b0f0, 0x0460045f},
944 {0x0000b0f4, 0x0541047f},
945 {0x0000b0f8, 0x055f0540},
946 {0x0000b0fc, 0x057f0560},
947 {0x0000b100, 0x06400641},
948 {0x0000b104, 0x0660065f},
949 {0x0000b108, 0x067e067f},
950 {0x0000b10c, 0x07410742},
951 {0x0000b110, 0x075f0740},
952 {0x0000b114, 0x077f0760},
953 {0x0000b118, 0x07800781},
954 {0x0000b11c, 0x07a0079f},
955 {0x0000b120, 0x07c107bf},
956 {0x0000b124, 0x000007c0},
957 {0x0000b128, 0x00000000},
958 {0x0000b12c, 0x00000000},
959 {0x0000b130, 0x00000000},
960 {0x0000b134, 0x00000000},
961 {0x0000b138, 0x00000000},
962 {0x0000b13c, 0x00000000},
963 {0x0000b140, 0x003f0020},
964 {0x0000b144, 0x00400041},
965 {0x0000b148, 0x0140005f},
966 {0x0000b14c, 0x0160015f},
967 {0x0000b150, 0x017e017f},
968 {0x0000b154, 0x02410242},
969 {0x0000b158, 0x025f0240},
970 {0x0000b15c, 0x027f0260},
971 {0x0000b160, 0x0341027e},
972 {0x0000b164, 0x035f0340},
973 {0x0000b168, 0x037f0360},
974 {0x0000b16c, 0x04400441},
975 {0x0000b170, 0x0460045f},
976 {0x0000b174, 0x0541047f},
977 {0x0000b178, 0x055f0540},
978 {0x0000b17c, 0x057f0560},
979 {0x0000b180, 0x06400641},
980 {0x0000b184, 0x0660065f},
981 {0x0000b188, 0x067e067f},
982 {0x0000b18c, 0x07410742},
983 {0x0000b190, 0x075f0740},
984 {0x0000b194, 0x077f0760},
985 {0x0000b198, 0x07800781},
986 {0x0000b19c, 0x07a0079f},
987 {0x0000b1a0, 0x07c107bf},
988 {0x0000b1a4, 0x000007c0},
989 {0x0000b1a8, 0x00000000},
990 {0x0000b1ac, 0x00000000},
991 {0x0000b1b0, 0x00000000},
992 {0x0000b1b4, 0x00000000},
993 {0x0000b1b8, 0x00000000},
994 {0x0000b1bc, 0x00000000},
995 {0x0000b1c0, 0x00000000},
996 {0x0000b1c4, 0x00000000},
997 {0x0000b1c8, 0x00000000},
998 {0x0000b1cc, 0x00000000},
999 {0x0000b1d0, 0x00000000},
1000 {0x0000b1d4, 0x00000000},
1001 {0x0000b1d8, 0x00000000},
1002 {0x0000b1dc, 0x00000000},
1003 {0x0000b1e0, 0x00000000},
1004 {0x0000b1e4, 0x00000000},
1005 {0x0000b1e8, 0x00000000},
1006 {0x0000b1ec, 0x00000000},
1007 {0x0000b1f0, 0x00000396},
1008 {0x0000b1f4, 0x00000396},
1009 {0x0000b1f8, 0x00000396},
1010 {0x0000b1fc, 0x00000196},
1011};
1012
1013static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = {
1014 /* Addr allmodes */
1015 {0x00009fd0, 0x0a2d6b93},
1016};
1017
1018static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = {
1019 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1020 {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
1021 {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
1022 {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
1023 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
1024 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
1025 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
1026};
1027
1028static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = {
1029 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1030 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
1031};
1032
1033static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = {
1034 /* Addr allmodes */
1035 {0x0000a000, 0x00010000},
1036 {0x0000a004, 0x00030002},
1037 {0x0000a008, 0x00050004},
1038 {0x0000a00c, 0x00810080},
1039 {0x0000a010, 0x00830082},
1040 {0x0000a014, 0x01810180},
1041 {0x0000a018, 0x01830182},
1042 {0x0000a01c, 0x01850184},
1043 {0x0000a020, 0x01890188},
1044 {0x0000a024, 0x018b018a},
1045 {0x0000a028, 0x018d018c},
1046 {0x0000a02c, 0x03820190},
1047 {0x0000a030, 0x03840383},
1048 {0x0000a034, 0x03880385},
1049 {0x0000a038, 0x038a0389},
1050 {0x0000a03c, 0x038c038b},
1051 {0x0000a040, 0x0390038d},
1052 {0x0000a044, 0x03920391},
1053 {0x0000a048, 0x03940393},
1054 {0x0000a04c, 0x03960395},
1055 {0x0000a050, 0x00000000},
1056 {0x0000a054, 0x00000000},
1057 {0x0000a058, 0x00000000},
1058 {0x0000a05c, 0x00000000},
1059 {0x0000a060, 0x00000000},
1060 {0x0000a064, 0x00000000},
1061 {0x0000a068, 0x00000000},
1062 {0x0000a06c, 0x00000000},
1063 {0x0000a070, 0x00000000},
1064 {0x0000a074, 0x00000000},
1065 {0x0000a078, 0x00000000},
1066 {0x0000a07c, 0x00000000},
1067 {0x0000a080, 0x29292929},
1068 {0x0000a084, 0x29292929},
1069 {0x0000a088, 0x29292929},
1070 {0x0000a08c, 0x29292929},
1071 {0x0000a090, 0x22292929},
1072 {0x0000a094, 0x1d1d2222},
1073 {0x0000a098, 0x0c111117},
1074 {0x0000a09c, 0x00030303},
1075 {0x0000a0a0, 0x00000000},
1076 {0x0000a0a4, 0x00000000},
1077 {0x0000a0a8, 0x00000000},
1078 {0x0000a0ac, 0x00000000},
1079 {0x0000a0b0, 0x00000000},
1080 {0x0000a0b4, 0x00000000},
1081 {0x0000a0b8, 0x00000000},
1082 {0x0000a0bc, 0x00000000},
1083 {0x0000a0c0, 0x001f0000},
1084 {0x0000a0c4, 0x01000101},
1085 {0x0000a0c8, 0x011e011f},
1086 {0x0000a0cc, 0x011c011d},
1087 {0x0000a0d0, 0x02030204},
1088 {0x0000a0d4, 0x02010202},
1089 {0x0000a0d8, 0x021f0200},
1090 {0x0000a0dc, 0x0302021e},
1091 {0x0000a0e0, 0x03000301},
1092 {0x0000a0e4, 0x031e031f},
1093 {0x0000a0e8, 0x0402031d},
1094 {0x0000a0ec, 0x04000401},
1095 {0x0000a0f0, 0x041e041f},
1096 {0x0000a0f4, 0x0502041d},
1097 {0x0000a0f8, 0x05000501},
1098 {0x0000a0fc, 0x051e051f},
1099 {0x0000a100, 0x06010602},
1100 {0x0000a104, 0x061f0600},
1101 {0x0000a108, 0x061d061e},
1102 {0x0000a10c, 0x07020703},
1103 {0x0000a110, 0x07000701},
1104 {0x0000a114, 0x00000000},
1105 {0x0000a118, 0x00000000},
1106 {0x0000a11c, 0x00000000},
1107 {0x0000a120, 0x00000000},
1108 {0x0000a124, 0x00000000},
1109 {0x0000a128, 0x00000000},
1110 {0x0000a12c, 0x00000000},
1111 {0x0000a130, 0x00000000},
1112 {0x0000a134, 0x00000000},
1113 {0x0000a138, 0x00000000},
1114 {0x0000a13c, 0x00000000},
1115 {0x0000a140, 0x001f0000},
1116 {0x0000a144, 0x01000101},
1117 {0x0000a148, 0x011e011f},
1118 {0x0000a14c, 0x011c011d},
1119 {0x0000a150, 0x02030204},
1120 {0x0000a154, 0x02010202},
1121 {0x0000a158, 0x021f0200},
1122 {0x0000a15c, 0x0302021e},
1123 {0x0000a160, 0x03000301},
1124 {0x0000a164, 0x031e031f},
1125 {0x0000a168, 0x0402031d},
1126 {0x0000a16c, 0x04000401},
1127 {0x0000a170, 0x041e041f},
1128 {0x0000a174, 0x0502041d},
1129 {0x0000a178, 0x05000501},
1130 {0x0000a17c, 0x051e051f},
1131 {0x0000a180, 0x06010602},
1132 {0x0000a184, 0x061f0600},
1133 {0x0000a188, 0x061d061e},
1134 {0x0000a18c, 0x07020703},
1135 {0x0000a190, 0x07000701},
1136 {0x0000a194, 0x00000000},
1137 {0x0000a198, 0x00000000},
1138 {0x0000a19c, 0x00000000},
1139 {0x0000a1a0, 0x00000000},
1140 {0x0000a1a4, 0x00000000},
1141 {0x0000a1a8, 0x00000000},
1142 {0x0000a1ac, 0x00000000},
1143 {0x0000a1b0, 0x00000000},
1144 {0x0000a1b4, 0x00000000},
1145 {0x0000a1b8, 0x00000000},
1146 {0x0000a1bc, 0x00000000},
1147 {0x0000a1c0, 0x00000000},
1148 {0x0000a1c4, 0x00000000},
1149 {0x0000a1c8, 0x00000000},
1150 {0x0000a1cc, 0x00000000},
1151 {0x0000a1d0, 0x00000000},
1152 {0x0000a1d4, 0x00000000},
1153 {0x0000a1d8, 0x00000000},
1154 {0x0000a1dc, 0x00000000},
1155 {0x0000a1e0, 0x00000000},
1156 {0x0000a1e4, 0x00000000},
1157 {0x0000a1e8, 0x00000000},
1158 {0x0000a1ec, 0x00000000},
1159 {0x0000a1f0, 0x00000396},
1160 {0x0000a1f4, 0x00000396},
1161 {0x0000a1f8, 0x00000396},
1162 {0x0000a1fc, 0x00000196},
1163 {0x0000b000, 0x00010000},
1164 {0x0000b004, 0x00030002},
1165 {0x0000b008, 0x00050004},
1166 {0x0000b00c, 0x00810080},
1167 {0x0000b010, 0x00830082},
1168 {0x0000b014, 0x01810180},
1169 {0x0000b018, 0x01830182},
1170 {0x0000b01c, 0x01850184},
1171 {0x0000b020, 0x02810280},
1172 {0x0000b024, 0x02830282},
1173 {0x0000b028, 0x02850284},
1174 {0x0000b02c, 0x02890288},
1175 {0x0000b030, 0x028b028a},
1176 {0x0000b034, 0x0388028c},
1177 {0x0000b038, 0x038a0389},
1178 {0x0000b03c, 0x038c038b},
1179 {0x0000b040, 0x0390038d},
1180 {0x0000b044, 0x03920391},
1181 {0x0000b048, 0x03940393},
1182 {0x0000b04c, 0x03960395},
1183 {0x0000b050, 0x00000000},
1184 {0x0000b054, 0x00000000},
1185 {0x0000b058, 0x00000000},
1186 {0x0000b05c, 0x00000000},
1187 {0x0000b060, 0x00000000},
1188 {0x0000b064, 0x00000000},
1189 {0x0000b068, 0x00000000},
1190 {0x0000b06c, 0x00000000},
1191 {0x0000b070, 0x00000000},
1192 {0x0000b074, 0x00000000},
1193 {0x0000b078, 0x00000000},
1194 {0x0000b07c, 0x00000000},
1195 {0x0000b080, 0x32323232},
1196 {0x0000b084, 0x2f2f3232},
1197 {0x0000b088, 0x23282a2d},
1198 {0x0000b08c, 0x1c1e2123},
1199 {0x0000b090, 0x14171919},
1200 {0x0000b094, 0x0e0e1214},
1201 {0x0000b098, 0x03050707},
1202 {0x0000b09c, 0x00030303},
1203 {0x0000b0a0, 0x00000000},
1204 {0x0000b0a4, 0x00000000},
1205 {0x0000b0a8, 0x00000000},
1206 {0x0000b0ac, 0x00000000},
1207 {0x0000b0b0, 0x00000000},
1208 {0x0000b0b4, 0x00000000},
1209 {0x0000b0b8, 0x00000000},
1210 {0x0000b0bc, 0x00000000},
1211 {0x0000b0c0, 0x003f0020},
1212 {0x0000b0c4, 0x00400041},
1213 {0x0000b0c8, 0x0140005f},
1214 {0x0000b0cc, 0x0160015f},
1215 {0x0000b0d0, 0x017e017f},
1216 {0x0000b0d4, 0x02410242},
1217 {0x0000b0d8, 0x025f0240},
1218 {0x0000b0dc, 0x027f0260},
1219 {0x0000b0e0, 0x0341027e},
1220 {0x0000b0e4, 0x035f0340},
1221 {0x0000b0e8, 0x037f0360},
1222 {0x0000b0ec, 0x04400441},
1223 {0x0000b0f0, 0x0460045f},
1224 {0x0000b0f4, 0x0541047f},
1225 {0x0000b0f8, 0x055f0540},
1226 {0x0000b0fc, 0x057f0560},
1227 {0x0000b100, 0x06400641},
1228 {0x0000b104, 0x0660065f},
1229 {0x0000b108, 0x067e067f},
1230 {0x0000b10c, 0x07410742},
1231 {0x0000b110, 0x075f0740},
1232 {0x0000b114, 0x077f0760},
1233 {0x0000b118, 0x07800781},
1234 {0x0000b11c, 0x07a0079f},
1235 {0x0000b120, 0x07c107bf},
1236 {0x0000b124, 0x000007c0},
1237 {0x0000b128, 0x00000000},
1238 {0x0000b12c, 0x00000000},
1239 {0x0000b130, 0x00000000},
1240 {0x0000b134, 0x00000000},
1241 {0x0000b138, 0x00000000},
1242 {0x0000b13c, 0x00000000},
1243 {0x0000b140, 0x003f0020},
1244 {0x0000b144, 0x00400041},
1245 {0x0000b148, 0x0140005f},
1246 {0x0000b14c, 0x0160015f},
1247 {0x0000b150, 0x017e017f},
1248 {0x0000b154, 0x02410242},
1249 {0x0000b158, 0x025f0240},
1250 {0x0000b15c, 0x027f0260},
1251 {0x0000b160, 0x0341027e},
1252 {0x0000b164, 0x035f0340},
1253 {0x0000b168, 0x037f0360},
1254 {0x0000b16c, 0x04400441},
1255 {0x0000b170, 0x0460045f},
1256 {0x0000b174, 0x0541047f},
1257 {0x0000b178, 0x055f0540},
1258 {0x0000b17c, 0x057f0560},
1259 {0x0000b180, 0x06400641},
1260 {0x0000b184, 0x0660065f},
1261 {0x0000b188, 0x067e067f},
1262 {0x0000b18c, 0x07410742},
1263 {0x0000b190, 0x075f0740},
1264 {0x0000b194, 0x077f0760},
1265 {0x0000b198, 0x07800781},
1266 {0x0000b19c, 0x07a0079f},
1267 {0x0000b1a0, 0x07c107bf},
1268 {0x0000b1a4, 0x000007c0},
1269 {0x0000b1a8, 0x00000000},
1270 {0x0000b1ac, 0x00000000},
1271 {0x0000b1b0, 0x00000000},
1272 {0x0000b1b4, 0x00000000},
1273 {0x0000b1b8, 0x00000000},
1274 {0x0000b1bc, 0x00000000},
1275 {0x0000b1c0, 0x00000000},
1276 {0x0000b1c4, 0x00000000},
1277 {0x0000b1c8, 0x00000000},
1278 {0x0000b1cc, 0x00000000},
1279 {0x0000b1d0, 0x00000000},
1280 {0x0000b1d4, 0x00000000},
1281 {0x0000b1d8, 0x00000000},
1282 {0x0000b1dc, 0x00000000},
1283 {0x0000b1e0, 0x00000000},
1284 {0x0000b1e4, 0x00000000},
1285 {0x0000b1e8, 0x00000000},
1286 {0x0000b1ec, 0x00000000},
1287 {0x0000b1f0, 0x00000396},
1288 {0x0000b1f4, 0x00000396},
1289 {0x0000b1f8, 0x00000396},
1290 {0x0000b1fc, 0x00000196},
1291};
1292
1293static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = {
1294 /* Addr allmodes */
1295 {0x0000a000, 0x00010000},
1296 {0x0000a004, 0x00030002},
1297 {0x0000a008, 0x00050004},
1298 {0x0000a00c, 0x00810080},
1299 {0x0000a010, 0x00830082},
1300 {0x0000a014, 0x01810180},
1301 {0x0000a018, 0x01830182},
1302 {0x0000a01c, 0x01850184},
1303 {0x0000a020, 0x01890188},
1304 {0x0000a024, 0x018b018a},
1305 {0x0000a028, 0x018d018c},
1306 {0x0000a02c, 0x03820190},
1307 {0x0000a030, 0x03840383},
1308 {0x0000a034, 0x03880385},
1309 {0x0000a038, 0x038a0389},
1310 {0x0000a03c, 0x038c038b},
1311 {0x0000a040, 0x0390038d},
1312 {0x0000a044, 0x03920391},
1313 {0x0000a048, 0x03940393},
1314 {0x0000a04c, 0x03960395},
1315 {0x0000a050, 0x00000000},
1316 {0x0000a054, 0x00000000},
1317 {0x0000a058, 0x00000000},
1318 {0x0000a05c, 0x00000000},
1319 {0x0000a060, 0x00000000},
1320 {0x0000a064, 0x00000000},
1321 {0x0000a068, 0x00000000},
1322 {0x0000a06c, 0x00000000},
1323 {0x0000a070, 0x00000000},
1324 {0x0000a074, 0x00000000},
1325 {0x0000a078, 0x00000000},
1326 {0x0000a07c, 0x00000000},
1327 {0x0000a080, 0x29292929},
1328 {0x0000a084, 0x29292929},
1329 {0x0000a088, 0x29292929},
1330 {0x0000a08c, 0x29292929},
1331 {0x0000a090, 0x22292929},
1332 {0x0000a094, 0x1d1d2222},
1333 {0x0000a098, 0x0c111117},
1334 {0x0000a09c, 0x00030303},
1335 {0x0000a0a0, 0x00000000},
1336 {0x0000a0a4, 0x00000000},
1337 {0x0000a0a8, 0x00000000},
1338 {0x0000a0ac, 0x00000000},
1339 {0x0000a0b0, 0x00000000},
1340 {0x0000a0b4, 0x00000000},
1341 {0x0000a0b8, 0x00000000},
1342 {0x0000a0bc, 0x00000000},
1343 {0x0000a0c0, 0x001f0000},
1344 {0x0000a0c4, 0x01000101},
1345 {0x0000a0c8, 0x011e011f},
1346 {0x0000a0cc, 0x011c011d},
1347 {0x0000a0d0, 0x02030204},
1348 {0x0000a0d4, 0x02010202},
1349 {0x0000a0d8, 0x021f0200},
1350 {0x0000a0dc, 0x0302021e},
1351 {0x0000a0e0, 0x03000301},
1352 {0x0000a0e4, 0x031e031f},
1353 {0x0000a0e8, 0x0402031d},
1354 {0x0000a0ec, 0x04000401},
1355 {0x0000a0f0, 0x041e041f},
1356 {0x0000a0f4, 0x0502041d},
1357 {0x0000a0f8, 0x05000501},
1358 {0x0000a0fc, 0x051e051f},
1359 {0x0000a100, 0x06010602},
1360 {0x0000a104, 0x061f0600},
1361 {0x0000a108, 0x061d061e},
1362 {0x0000a10c, 0x07020703},
1363 {0x0000a110, 0x07000701},
1364 {0x0000a114, 0x00000000},
1365 {0x0000a118, 0x00000000},
1366 {0x0000a11c, 0x00000000},
1367 {0x0000a120, 0x00000000},
1368 {0x0000a124, 0x00000000},
1369 {0x0000a128, 0x00000000},
1370 {0x0000a12c, 0x00000000},
1371 {0x0000a130, 0x00000000},
1372 {0x0000a134, 0x00000000},
1373 {0x0000a138, 0x00000000},
1374 {0x0000a13c, 0x00000000},
1375 {0x0000a140, 0x001f0000},
1376 {0x0000a144, 0x01000101},
1377 {0x0000a148, 0x011e011f},
1378 {0x0000a14c, 0x011c011d},
1379 {0x0000a150, 0x02030204},
1380 {0x0000a154, 0x02010202},
1381 {0x0000a158, 0x021f0200},
1382 {0x0000a15c, 0x0302021e},
1383 {0x0000a160, 0x03000301},
1384 {0x0000a164, 0x031e031f},
1385 {0x0000a168, 0x0402031d},
1386 {0x0000a16c, 0x04000401},
1387 {0x0000a170, 0x041e041f},
1388 {0x0000a174, 0x0502041d},
1389 {0x0000a178, 0x05000501},
1390 {0x0000a17c, 0x051e051f},
1391 {0x0000a180, 0x06010602},
1392 {0x0000a184, 0x061f0600},
1393 {0x0000a188, 0x061d061e},
1394 {0x0000a18c, 0x07020703},
1395 {0x0000a190, 0x07000701},
1396 {0x0000a194, 0x00000000},
1397 {0x0000a198, 0x00000000},
1398 {0x0000a19c, 0x00000000},
1399 {0x0000a1a0, 0x00000000},
1400 {0x0000a1a4, 0x00000000},
1401 {0x0000a1a8, 0x00000000},
1402 {0x0000a1ac, 0x00000000},
1403 {0x0000a1b0, 0x00000000},
1404 {0x0000a1b4, 0x00000000},
1405 {0x0000a1b8, 0x00000000},
1406 {0x0000a1bc, 0x00000000},
1407 {0x0000a1c0, 0x00000000},
1408 {0x0000a1c4, 0x00000000},
1409 {0x0000a1c8, 0x00000000},
1410 {0x0000a1cc, 0x00000000},
1411 {0x0000a1d0, 0x00000000},
1412 {0x0000a1d4, 0x00000000},
1413 {0x0000a1d8, 0x00000000},
1414 {0x0000a1dc, 0x00000000},
1415 {0x0000a1e0, 0x00000000},
1416 {0x0000a1e4, 0x00000000},
1417 {0x0000a1e8, 0x00000000},
1418 {0x0000a1ec, 0x00000000},
1419 {0x0000a1f0, 0x00000396},
1420 {0x0000a1f4, 0x00000396},
1421 {0x0000a1f8, 0x00000396},
1422 {0x0000a1fc, 0x00000196},
1423 {0x0000b000, 0x00010000},
1424 {0x0000b004, 0x00030002},
1425 {0x0000b008, 0x00050004},
1426 {0x0000b00c, 0x00810080},
1427 {0x0000b010, 0x00830082},
1428 {0x0000b014, 0x01810180},
1429 {0x0000b018, 0x01830182},
1430 {0x0000b01c, 0x01850184},
1431 {0x0000b020, 0x02810280},
1432 {0x0000b024, 0x02830282},
1433 {0x0000b028, 0x02850284},
1434 {0x0000b02c, 0x02890288},
1435 {0x0000b030, 0x028b028a},
1436 {0x0000b034, 0x0388028c},
1437 {0x0000b038, 0x038a0389},
1438 {0x0000b03c, 0x038c038b},
1439 {0x0000b040, 0x0390038d},
1440 {0x0000b044, 0x03920391},
1441 {0x0000b048, 0x03940393},
1442 {0x0000b04c, 0x03960395},
1443 {0x0000b050, 0x00000000},
1444 {0x0000b054, 0x00000000},
1445 {0x0000b058, 0x00000000},
1446 {0x0000b05c, 0x00000000},
1447 {0x0000b060, 0x00000000},
1448 {0x0000b064, 0x00000000},
1449 {0x0000b068, 0x00000000},
1450 {0x0000b06c, 0x00000000},
1451 {0x0000b070, 0x00000000},
1452 {0x0000b074, 0x00000000},
1453 {0x0000b078, 0x00000000},
1454 {0x0000b07c, 0x00000000},
1455 {0x0000b080, 0x2a2d2f32},
1456 {0x0000b084, 0x21232328},
1457 {0x0000b088, 0x19191c1e},
1458 {0x0000b08c, 0x12141417},
1459 {0x0000b090, 0x07070e0e},
1460 {0x0000b094, 0x03030305},
1461 {0x0000b098, 0x00000003},
1462 {0x0000b09c, 0x00000000},
1463 {0x0000b0a0, 0x00000000},
1464 {0x0000b0a4, 0x00000000},
1465 {0x0000b0a8, 0x00000000},
1466 {0x0000b0ac, 0x00000000},
1467 {0x0000b0b0, 0x00000000},
1468 {0x0000b0b4, 0x00000000},
1469 {0x0000b0b8, 0x00000000},
1470 {0x0000b0bc, 0x00000000},
1471 {0x0000b0c0, 0x003f0020},
1472 {0x0000b0c4, 0x00400041},
1473 {0x0000b0c8, 0x0140005f},
1474 {0x0000b0cc, 0x0160015f},
1475 {0x0000b0d0, 0x017e017f},
1476 {0x0000b0d4, 0x02410242},
1477 {0x0000b0d8, 0x025f0240},
1478 {0x0000b0dc, 0x027f0260},
1479 {0x0000b0e0, 0x0341027e},
1480 {0x0000b0e4, 0x035f0340},
1481 {0x0000b0e8, 0x037f0360},
1482 {0x0000b0ec, 0x04400441},
1483 {0x0000b0f0, 0x0460045f},
1484 {0x0000b0f4, 0x0541047f},
1485 {0x0000b0f8, 0x055f0540},
1486 {0x0000b0fc, 0x057f0560},
1487 {0x0000b100, 0x06400641},
1488 {0x0000b104, 0x0660065f},
1489 {0x0000b108, 0x067e067f},
1490 {0x0000b10c, 0x07410742},
1491 {0x0000b110, 0x075f0740},
1492 {0x0000b114, 0x077f0760},
1493 {0x0000b118, 0x07800781},
1494 {0x0000b11c, 0x07a0079f},
1495 {0x0000b120, 0x07c107bf},
1496 {0x0000b124, 0x000007c0},
1497 {0x0000b128, 0x00000000},
1498 {0x0000b12c, 0x00000000},
1499 {0x0000b130, 0x00000000},
1500 {0x0000b134, 0x00000000},
1501 {0x0000b138, 0x00000000},
1502 {0x0000b13c, 0x00000000},
1503 {0x0000b140, 0x003f0020},
1504 {0x0000b144, 0x00400041},
1505 {0x0000b148, 0x0140005f},
1506 {0x0000b14c, 0x0160015f},
1507 {0x0000b150, 0x017e017f},
1508 {0x0000b154, 0x02410242},
1509 {0x0000b158, 0x025f0240},
1510 {0x0000b15c, 0x027f0260},
1511 {0x0000b160, 0x0341027e},
1512 {0x0000b164, 0x035f0340},
1513 {0x0000b168, 0x037f0360},
1514 {0x0000b16c, 0x04400441},
1515 {0x0000b170, 0x0460045f},
1516 {0x0000b174, 0x0541047f},
1517 {0x0000b178, 0x055f0540},
1518 {0x0000b17c, 0x057f0560},
1519 {0x0000b180, 0x06400641},
1520 {0x0000b184, 0x0660065f},
1521 {0x0000b188, 0x067e067f},
1522 {0x0000b18c, 0x07410742},
1523 {0x0000b190, 0x075f0740},
1524 {0x0000b194, 0x077f0760},
1525 {0x0000b198, 0x07800781},
1526 {0x0000b19c, 0x07a0079f},
1527 {0x0000b1a0, 0x07c107bf},
1528 {0x0000b1a4, 0x000007c0},
1529 {0x0000b1a8, 0x00000000},
1530 {0x0000b1ac, 0x00000000},
1531 {0x0000b1b0, 0x00000000},
1532 {0x0000b1b4, 0x00000000},
1533 {0x0000b1b8, 0x00000000},
1534 {0x0000b1bc, 0x00000000},
1535 {0x0000b1c0, 0x00000000},
1536 {0x0000b1c4, 0x00000000},
1537 {0x0000b1c8, 0x00000000},
1538 {0x0000b1cc, 0x00000000},
1539 {0x0000b1d0, 0x00000000},
1540 {0x0000b1d4, 0x00000000},
1541 {0x0000b1d8, 0x00000000},
1542 {0x0000b1dc, 0x00000000},
1543 {0x0000b1e0, 0x00000000},
1544 {0x0000b1e4, 0x00000000},
1545 {0x0000b1e8, 0x00000000},
1546 {0x0000b1ec, 0x00000000},
1547 {0x0000b1f0, 0x00000396},
1548 {0x0000b1f4, 0x00000396},
1549 {0x0000b1f8, 0x00000396},
1550 {0x0000b1fc, 0x00000196},
1551};
1552
1553static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = {
1554 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1555 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1556 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1557 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1558 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1559 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1560 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1561 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1562 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1563 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1564 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1565 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1566 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1567 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
1568 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
1569 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
1570 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
1571 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
1572 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
1573 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
1574 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
1575 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
1576 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1577 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1578 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1579 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
1580 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
1581 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
1582 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
1583 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
1584 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
1585 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
1586 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
1587 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1588 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1589 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1590 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1591 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1592 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1593 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1594 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1595 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1596 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1597 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1598 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1599 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
1600 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
1601 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
1602 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
1603 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
1604 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
1605 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
1606 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1607 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1608 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1609 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1610 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1611 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1612 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1613 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1614 {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1615 {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060},
1616 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1617 {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1618 {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
1619 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1620};
1621
1622static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = {
1623 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1624 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1625 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1626 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1627 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1628 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1629 {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
1630 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1631 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1632 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1633 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1634 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1635 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1636 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
1637 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
1638 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1639 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
1640 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
1641 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
1642 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
1643 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
1644 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
1645 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
1646 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
1647 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
1648 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
1649 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
1650 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
1651 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
1652 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
1653 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
1654 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
1655 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
1656 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
1657 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
1658 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
1659 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1660 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1661 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1662 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1663 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1664 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1665 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1666 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1667 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1668 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1669 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1670 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1671 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1672 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1673 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1674 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1675 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1676 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1677 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1678 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1679 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1680 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1681 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1682 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1683 {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1684 {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
1685 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1686 {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1687 {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
1688 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1689};
1690
1691static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = {
1692 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1693 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1694 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1695 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1696 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1697 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1698 {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
1699 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1700 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1701 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1702 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1703 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1704 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1705 {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
1706 {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
1707 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1708 {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
1709 {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
1710 {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
1711 {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
1712 {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
1713 {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
1714 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
1715 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
1716 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
1717 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
1718 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
1719 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
1720 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
1721 {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
1722 {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
1723 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
1724 {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
1725 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
1726 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
1727 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
1728 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1729 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1730 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1731 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1732 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1733 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1734 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1735 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1736 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1737 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1738 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1739 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1740 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1741 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1742 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1743 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1744 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1745 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1746 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1747 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1748 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1749 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1750 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1751 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1752};
1753
1754static const u32 ar9462_2p1_modes_fast_clock[][3] = {
1755 /* Addr 5G_HT20 5G_HT40 */
1756 {0x00001030, 0x00000268, 0x000004d0},
1757 {0x00001070, 0x0000018c, 0x00000318},
1758 {0x000010b0, 0x00000fd0, 0x00001fa0},
1759 {0x00008014, 0x044c044c, 0x08980898},
1760 {0x0000801c, 0x148ec02b, 0x148ec057},
1761 {0x00008318, 0x000044c0, 0x00008980},
1762 {0x00009e00, 0x0372131c, 0x0372131c},
1763 {0x0000a230, 0x0000400b, 0x00004016},
1764 {0x0000a254, 0x00000898, 0x00001130},
1765};
1766
1767static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = {
1768 /* Addr allmodes */
1769 {0x0000a398, 0x00000000},
1770 {0x0000a39c, 0x6f7f0301},
1771 {0x0000a3a0, 0xca9228ee},
1772};
1773
1774#endif /* INITVALS_9462_2P1_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 04b2d3ea728f..c1224b5a257b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -634,6 +634,7 @@ void ath_ant_comb_update(struct ath_softc *sc);
634#define ATH9K_PCI_CUS198 0x0001 634#define ATH9K_PCI_CUS198 0x0001
635#define ATH9K_PCI_CUS230 0x0002 635#define ATH9K_PCI_CUS230 0x0002
636#define ATH9K_PCI_CUS217 0x0004 636#define ATH9K_PCI_CUS217 0x0004
637#define ATH9K_PCI_WOW 0x0008
637 638
638/* 639/*
639 * Default cache line size, in bytes. 640 * Default cache line size, in bytes.
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index f5dda84176c3..9e582e14da74 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -234,10 +234,15 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,
234 struct sk_buff *skb; 234 struct sk_buff *skb;
235 235
236 while ((skb = __skb_dequeue(queue)) != NULL) { 236 while ((skb = __skb_dequeue(queue)) != NULL) {
237#ifdef CONFIG_ATH9K_HTC_DEBUGFS
238 int ln = skb->len;
239#endif
237 ath9k_htc_txcompletion_cb(hif_dev->htc_handle, 240 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
238 skb, txok); 241 skb, txok);
239 if (txok) 242 if (txok) {
240 TX_STAT_INC(skb_success); 243 TX_STAT_INC(skb_success);
244 TX_STAT_ADD(skb_success_bytes, ln);
245 }
241 else 246 else
242 TX_STAT_INC(skb_failed); 247 TX_STAT_INC(skb_failed);
243 } 248 }
@@ -620,6 +625,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
620 625
621err: 626err:
622 for (i = 0; i < pool_index; i++) { 627 for (i = 0; i < pool_index; i++) {
628 RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len);
623 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], 629 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
624 skb_pool[i]->len, USB_WLAN_RX_PIPE); 630 skb_pool[i]->len, USB_WLAN_RX_PIPE);
625 RX_STAT_INC(skb_completed); 631 RX_STAT_INC(skb_completed);
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 69581031f2cd..055d7c25e090 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -324,7 +324,9 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
324#ifdef CONFIG_ATH9K_HTC_DEBUGFS 324#ifdef CONFIG_ATH9K_HTC_DEBUGFS
325 325
326#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) 326#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
327#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
327#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 RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c += a)
328#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ 330#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
329 331
330#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) 332#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
@@ -337,6 +339,7 @@ struct ath_tx_stats {
337 u32 buf_completed; 339 u32 buf_completed;
338 u32 skb_queued; 340 u32 skb_queued;
339 u32 skb_success; 341 u32 skb_success;
342 u32 skb_success_bytes;
340 u32 skb_failed; 343 u32 skb_failed;
341 u32 cab_queued; 344 u32 cab_queued;
342 u32 queue_stats[IEEE80211_NUM_ACS]; 345 u32 queue_stats[IEEE80211_NUM_ACS];
@@ -345,6 +348,7 @@ struct ath_tx_stats {
345struct ath_rx_stats { 348struct ath_rx_stats {
346 u32 skb_allocated; 349 u32 skb_allocated;
347 u32 skb_completed; 350 u32 skb_completed;
351 u32 skb_completed_bytes;
348 u32 skb_dropped; 352 u32 skb_dropped;
349 u32 err_crc; 353 u32 err_crc;
350 u32 err_decrypt_crc; 354 u32 err_decrypt_crc;
@@ -362,10 +366,20 @@ struct ath9k_debug {
362 struct ath_rx_stats rx_stats; 366 struct ath_rx_stats rx_stats;
363}; 367};
364 368
369void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
370 struct ieee80211_vif *vif,
371 u32 sset, u8 *data);
372int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
373 struct ieee80211_vif *vif, int sset);
374void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
375 struct ieee80211_vif *vif,
376 struct ethtool_stats *stats, u64 *data);
365#else 377#else
366 378
367#define TX_STAT_INC(c) do { } while (0) 379#define TX_STAT_INC(c) do { } while (0)
380#define TX_STAT_ADD(c, a) do { } while (0)
368#define RX_STAT_INC(c) do { } while (0) 381#define RX_STAT_INC(c) do { } while (0)
382#define RX_STAT_ADD(c, a) do { } while (0)
369#define CAB_STAT_INC do { } while (0) 383#define CAB_STAT_INC do { } while (0)
370 384
371#define TX_QSTAT_INC(c) do { } while (0) 385#define TX_QSTAT_INC(c) do { } while (0)
@@ -583,6 +597,8 @@ bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
583void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); 597void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
584void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); 598void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
585 599
600struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv);
601
586#ifdef CONFIG_MAC80211_LEDS 602#ifdef CONFIG_MAC80211_LEDS
587void ath9k_init_leds(struct ath9k_htc_priv *priv); 603void ath9k_init_leds(struct ath9k_htc_priv *priv);
588void ath9k_deinit_leds(struct ath9k_htc_priv *priv); 604void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index d08ef24e9696..c1b45e2f8481 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -496,21 +496,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
496 ssize_t retval = 0; 496 ssize_t retval = 0;
497 char *buf; 497 char *buf;
498 498
499 /* 499 pBase = ath9k_htc_get_eeprom_base(priv);
500 * This can be done since all the 3 EEPROM families have the
501 * same base header upto a certain point, and we are interested in
502 * the data only upto that point.
503 */
504
505 if (AR_SREV_9271(priv->ah))
506 pBase = (struct base_eep_header *)
507 &priv->ah->eeprom.map4k.baseEepHeader;
508 else if (priv->ah->hw_version.usbdev == AR9280_USB)
509 pBase = (struct base_eep_header *)
510 &priv->ah->eeprom.def.baseEepHeader;
511 else if (priv->ah->hw_version.usbdev == AR9287_USB)
512 pBase = (struct base_eep_header *)
513 &priv->ah->eeprom.map9287.baseEepHeader;
514 500
515 if (pBase == NULL) { 501 if (pBase == NULL) {
516 ath_err(common, "Unknown EEPROM type\n"); 502 ath_err(common, "Unknown EEPROM type\n");
@@ -916,6 +902,87 @@ static const struct file_operations fops_modal_eeprom = {
916 .llseek = default_llseek, 902 .llseek = default_llseek,
917}; 903};
918 904
905
906/* Ethtool support for get-stats */
907#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
908static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
909 "tx_pkts_nic",
910 "tx_bytes_nic",
911 "rx_pkts_nic",
912 "rx_bytes_nic",
913
914 AMKSTR(d_tx_pkts),
915
916 "d_rx_crc_err",
917 "d_rx_decrypt_crc_err",
918 "d_rx_phy_err",
919 "d_rx_mic_err",
920 "d_rx_pre_delim_crc_err",
921 "d_rx_post_delim_crc_err",
922 "d_rx_decrypt_busy_err",
923
924 "d_rx_phyerr_radar",
925 "d_rx_phyerr_ofdm_timing",
926 "d_rx_phyerr_cck_timing",
927
928};
929#define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats)
930
931void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
932 struct ieee80211_vif *vif,
933 u32 sset, u8 *data)
934{
935 if (sset == ETH_SS_STATS)
936 memcpy(data, *ath9k_htc_gstrings_stats,
937 sizeof(ath9k_htc_gstrings_stats));
938}
939
940int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
941 struct ieee80211_vif *vif, int sset)
942{
943 if (sset == ETH_SS_STATS)
944 return ATH9K_HTC_SSTATS_LEN;
945 return 0;
946}
947
948#define STXBASE priv->debug.tx_stats
949#define SRXBASE priv->debug.rx_stats
950#define ASTXQ(a) \
951 data[i++] = STXBASE.a[IEEE80211_AC_BE]; \
952 data[i++] = STXBASE.a[IEEE80211_AC_BK]; \
953 data[i++] = STXBASE.a[IEEE80211_AC_VI]; \
954 data[i++] = STXBASE.a[IEEE80211_AC_VO]
955
956void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
957 struct ieee80211_vif *vif,
958 struct ethtool_stats *stats, u64 *data)
959{
960 struct ath9k_htc_priv *priv = hw->priv;
961 int i = 0;
962
963 data[i++] = STXBASE.skb_success;
964 data[i++] = STXBASE.skb_success_bytes;
965 data[i++] = SRXBASE.skb_completed;
966 data[i++] = SRXBASE.skb_completed_bytes;
967
968 ASTXQ(queue_stats);
969
970 data[i++] = SRXBASE.err_crc;
971 data[i++] = SRXBASE.err_decrypt_crc;
972 data[i++] = SRXBASE.err_phy;
973 data[i++] = SRXBASE.err_mic;
974 data[i++] = SRXBASE.err_pre_delim;
975 data[i++] = SRXBASE.err_post_delim;
976 data[i++] = SRXBASE.err_decrypt_busy;
977
978 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_RADAR];
979 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_OFDM_TIMING];
980 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_CCK_TIMING];
981
982 WARN_ON(i != ATH9K_HTC_SSTATS_LEN);
983}
984
985
919int ath9k_htc_init_debug(struct ath_hw *ah) 986int ath9k_htc_init_debug(struct ath_hw *ah)
920{ 987{
921 struct ath_common *common = ath9k_hw_common(ah); 988 struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index bb0ba9e3e083..71a183ffc77f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -701,8 +701,10 @@ static const struct ieee80211_iface_limit if_limits[] = {
701 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | 701 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
702 BIT(NL80211_IFTYPE_P2P_CLIENT) }, 702 BIT(NL80211_IFTYPE_P2P_CLIENT) },
703 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | 703 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) |
704 BIT(NL80211_IFTYPE_P2P_GO) | 704#ifdef CONFIG_MAC80211_MESH
705 BIT(NL80211_IFTYPE_MESH_POINT) }, 705 BIT(NL80211_IFTYPE_MESH_POINT) |
706#endif
707 BIT(NL80211_IFTYPE_P2P_GO) },
706}; 708};
707 709
708static const struct ieee80211_iface_combination if_comb = { 710static const struct ieee80211_iface_combination if_comb = {
@@ -716,6 +718,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
716 struct ieee80211_hw *hw) 718 struct ieee80211_hw *hw)
717{ 719{
718 struct ath_common *common = ath9k_hw_common(priv->ah); 720 struct ath_common *common = ath9k_hw_common(priv->ah);
721 struct base_eep_header *pBase;
719 722
720 hw->flags = IEEE80211_HW_SIGNAL_DBM | 723 hw->flags = IEEE80211_HW_SIGNAL_DBM |
721 IEEE80211_HW_AMPDU_AGGREGATION | 724 IEEE80211_HW_AMPDU_AGGREGATION |
@@ -771,6 +774,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
771 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); 774 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
772 } 775 }
773 776
777 pBase = ath9k_htc_get_eeprom_base(priv);
778 if (pBase) {
779 hw->wiphy->available_antennas_rx = pBase->rxMask;
780 hw->wiphy->available_antennas_tx = pBase->txMask;
781 }
782
774 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 783 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
775} 784}
776 785
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index eaa94feb4333..5c1bec18c9e3 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1183,7 +1183,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1183 mutex_lock(&priv->htc_pm_lock); 1183 mutex_lock(&priv->htc_pm_lock);
1184 1184
1185 priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); 1185 priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1186 if (priv->ps_idle) 1186 if (!priv->ps_idle)
1187 chip_reset = true; 1187 chip_reset = true;
1188 1188
1189 mutex_unlock(&priv->htc_pm_lock); 1189 mutex_unlock(&priv->htc_pm_lock);
@@ -1774,6 +1774,43 @@ static int ath9k_htc_get_stats(struct ieee80211_hw *hw,
1774 return 0; 1774 return 0;
1775} 1775}
1776 1776
1777struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)
1778{
1779 struct base_eep_header *pBase = NULL;
1780 /*
1781 * This can be done since all the 3 EEPROM families have the
1782 * same base header upto a certain point, and we are interested in
1783 * the data only upto that point.
1784 */
1785
1786 if (AR_SREV_9271(priv->ah))
1787 pBase = (struct base_eep_header *)
1788 &priv->ah->eeprom.map4k.baseEepHeader;
1789 else if (priv->ah->hw_version.usbdev == AR9280_USB)
1790 pBase = (struct base_eep_header *)
1791 &priv->ah->eeprom.def.baseEepHeader;
1792 else if (priv->ah->hw_version.usbdev == AR9287_USB)
1793 pBase = (struct base_eep_header *)
1794 &priv->ah->eeprom.map9287.baseEepHeader;
1795 return pBase;
1796}
1797
1798
1799static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
1800 u32 *rx_ant)
1801{
1802 struct ath9k_htc_priv *priv = hw->priv;
1803 struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
1804 if (pBase) {
1805 *tx_ant = pBase->txMask;
1806 *rx_ant = pBase->rxMask;
1807 } else {
1808 *tx_ant = 0;
1809 *rx_ant = 0;
1810 }
1811 return 0;
1812}
1813
1777struct ieee80211_ops ath9k_htc_ops = { 1814struct ieee80211_ops ath9k_htc_ops = {
1778 .tx = ath9k_htc_tx, 1815 .tx = ath9k_htc_tx,
1779 .start = ath9k_htc_start, 1816 .start = ath9k_htc_start,
@@ -1799,4 +1836,11 @@ struct ieee80211_ops ath9k_htc_ops = {
1799 .set_coverage_class = ath9k_htc_set_coverage_class, 1836 .set_coverage_class = ath9k_htc_set_coverage_class,
1800 .set_bitrate_mask = ath9k_htc_set_bitrate_mask, 1837 .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
1801 .get_stats = ath9k_htc_get_stats, 1838 .get_stats = ath9k_htc_get_stats,
1839 .get_antenna = ath9k_htc_get_antenna,
1840
1841#ifdef CONFIG_ATH9K_HTC_DEBUGFS
1842 .get_et_sset_count = ath9k_htc_get_et_sset_count,
1843 .get_et_stats = ath9k_htc_get_et_stats,
1844 .get_et_strings = ath9k_htc_get_et_strings,
1845#endif
1802}; 1846};
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5324c3346af8..4ca0cb060106 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2599,7 +2599,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2599 if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) 2599 if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE))
2600 pCap->hw_caps |= ATH9K_HW_CAP_MCI; 2600 pCap->hw_caps |= ATH9K_HW_CAP_MCI;
2601 2601
2602 if (AR_SREV_9462_20(ah)) 2602 if (AR_SREV_9462_20_OR_LATER(ah))
2603 pCap->hw_caps |= ATH9K_HW_CAP_RTT; 2603 pCap->hw_caps |= ATH9K_HW_CAP_RTT;
2604 } 2604 }
2605 2605
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 1e555d899469..16f8b201642b 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -837,6 +837,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
837 837
838#ifdef CONFIG_PM_SLEEP 838#ifdef CONFIG_PM_SLEEP
839 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 839 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
840 (sc->driver_data & ATH9K_PCI_WOW) &&
840 device_can_wakeup(sc->dev)) 841 device_can_wakeup(sc->dev))
841 hw->wiphy->wowlan = &ath9k_wowlan_support; 842 hw->wiphy->wowlan = &ath9k_wowlan_support;
842 843
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index b096bb2c28c8..c585c9b35973 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -79,6 +79,63 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
79 0x6661), 79 0x6661),
80 .driver_data = ATH9K_PCI_CUS217 }, 80 .driver_data = ATH9K_PCI_CUS217 },
81 81
82 /* AR9462 with WoW support */
83 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
84 0x0034,
85 PCI_VENDOR_ID_ATHEROS,
86 0x3117),
87 .driver_data = ATH9K_PCI_WOW },
88 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
89 0x0034,
90 PCI_VENDOR_ID_LENOVO,
91 0x3214),
92 .driver_data = ATH9K_PCI_WOW },
93 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
94 0x0034,
95 PCI_VENDOR_ID_ATTANSIC,
96 0x0091),
97 .driver_data = ATH9K_PCI_WOW },
98 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
99 0x0034,
100 PCI_VENDOR_ID_AZWAVE,
101 0x2110),
102 .driver_data = ATH9K_PCI_WOW },
103 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
104 0x0034,
105 PCI_VENDOR_ID_ASUSTEK,
106 0x850E),
107 .driver_data = ATH9K_PCI_WOW },
108 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
109 0x0034,
110 0x11AD, /* LITEON */
111 0x6631),
112 .driver_data = ATH9K_PCI_WOW },
113 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
114 0x0034,
115 0x11AD, /* LITEON */
116 0x6641),
117 .driver_data = ATH9K_PCI_WOW },
118 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
119 0x0034,
120 PCI_VENDOR_ID_HP,
121 0x1864),
122 .driver_data = ATH9K_PCI_WOW },
123 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
124 0x0034,
125 0x14CD, /* USI */
126 0x0063),
127 .driver_data = ATH9K_PCI_WOW },
128 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
129 0x0034,
130 0x14CD, /* USI */
131 0x0064),
132 .driver_data = ATH9K_PCI_WOW },
133 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
134 0x0034,
135 0x10CF, /* Fujitsu */
136 0x1783),
137 .driver_data = ATH9K_PCI_WOW },
138
82 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ 139 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
83 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ 140 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */
84 { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */ 141 { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index f7c90cc58d56..5af97442ac37 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -806,6 +806,7 @@
806#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ 806#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
807#define AR_SREV_VERSION_9462 0x280 807#define AR_SREV_VERSION_9462 0x280
808#define AR_SREV_REVISION_9462_20 2 808#define AR_SREV_REVISION_9462_20 2
809#define AR_SREV_REVISION_9462_21 3
809#define AR_SREV_VERSION_9565 0x2C0 810#define AR_SREV_VERSION_9565 0x2C0
810#define AR_SREV_REVISION_9565_10 0 811#define AR_SREV_REVISION_9565_10 0
811#define AR_SREV_VERSION_9550 0x400 812#define AR_SREV_VERSION_9550 0x400
@@ -911,10 +912,18 @@
911 912
912#define AR_SREV_9462(_ah) \ 913#define AR_SREV_9462(_ah) \
913 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) 914 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
914
915#define AR_SREV_9462_20(_ah) \ 915#define AR_SREV_9462_20(_ah) \
916 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ 916 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
917 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) 917 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
918#define AR_SREV_9462_21(_ah) \
919 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
920 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21))
921#define AR_SREV_9462_20_OR_LATER(_ah) \
922 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
923 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
924#define AR_SREV_9462_21_OR_LATER(_ah) \
925 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
926 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21))
918 927
919#define AR_SREV_9565(_ah) \ 928#define AR_SREV_9565(_ah) \
920 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) 929 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7e19d9b5214e..c59ae43b9b35 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1673,6 +1673,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1673 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) 1673 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
1674 return; 1674 return;
1675 1675
1676 rcu_read_lock();
1677
1676 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); 1678 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
1677 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); 1679 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
1678 1680
@@ -1711,8 +1713,10 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1711 1713
1712 if (ac == last_ac || 1714 if (ac == last_ac ||
1713 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) 1715 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
1714 return; 1716 break;
1715 } 1717 }
1718
1719 rcu_read_unlock();
1716} 1720}
1717 1721
1718/***********/ 1722/***********/
@@ -1778,9 +1782,13 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1778 } 1782 }
1779 1783
1780 if (!internal) { 1784 if (!internal) {
1781 txq->axq_depth++; 1785 while (bf) {
1782 if (bf_is_ampdu_not_probing(bf)) 1786 txq->axq_depth++;
1783 txq->axq_ampdu_depth++; 1787 if (bf_is_ampdu_not_probing(bf))
1788 txq->axq_ampdu_depth++;
1789
1790 bf = bf->bf_lastbf->bf_next;
1791 }
1784 } 1792 }
1785} 1793}
1786 1794
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index e1c492b9dfef..d240b24e1ccf 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -621,7 +621,8 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
621 return NULL; 621 return NULL;
622} 622}
623 623
624static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len) 624static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
625 int vring_index)
625{ 626{
626 wil_desc_addr_set(&d->dma.addr, pa); 627 wil_desc_addr_set(&d->dma.addr, pa);
627 d->dma.ip_length = 0; 628 d->dma.ip_length = 0;
@@ -630,7 +631,7 @@ static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len)
630 d->dma.error = 0; 631 d->dma.error = 0;
631 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ 632 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
632 d->dma.length = cpu_to_le16((u16)len); 633 d->dma.length = cpu_to_le16((u16)len);
633 d->dma.d0 = 0; 634 d->dma.d0 = (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
634 d->mac.d[0] = 0; 635 d->mac.d[0] = 0;
635 d->mac.d[1] = 0; 636 d->mac.d[1] = 0;
636 d->mac.d[2] = 0; 637 d->mac.d[2] = 0;
@@ -684,7 +685,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
684 if (unlikely(dma_mapping_error(dev, pa))) 685 if (unlikely(dma_mapping_error(dev, pa)))
685 return -EINVAL; 686 return -EINVAL;
686 /* 1-st segment */ 687 /* 1-st segment */
687 wil_tx_desc_map(d, pa, skb_headlen(skb)); 688 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
688 d->mac.d[2] |= ((nr_frags + 1) << 689 d->mac.d[2] |= ((nr_frags + 1) <<
689 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); 690 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
690 if (nr_frags) 691 if (nr_frags)
@@ -701,15 +702,14 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
701 DMA_TO_DEVICE); 702 DMA_TO_DEVICE);
702 if (unlikely(dma_mapping_error(dev, pa))) 703 if (unlikely(dma_mapping_error(dev, pa)))
703 goto dma_error; 704 goto dma_error;
704 wil_tx_desc_map(d, pa, len); 705 wil_tx_desc_map(d, pa, len, vring_index);
705 vring->ctx[i] = NULL; 706 vring->ctx[i] = NULL;
706 *_d = *d; 707 *_d = *d;
707 } 708 }
708 /* for the last seg only */ 709 /* for the last seg only */
709 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); 710 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
710 d->dma.d0 |= BIT(9); /* BUG: undocumented bit */ 711 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS);
711 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 712 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
712 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
713 *_d = *d; 713 *_d = *d;
714 714
715 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, 715 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 23c0781cdb93..859aea68a1fa 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -201,6 +201,10 @@ struct vring_tx_mac {
201#define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1 201#define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1
202#define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100 202#define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100
203 203
204#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS 9
205#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_LEN 1
206#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_MSK 0x200
207
204#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10 208#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10
205#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1 209#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1
206#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400 210#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 3f21e0ba39ba..51ff0b198d0a 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -31,12 +31,6 @@ config B43_BCMA
31 depends on B43 && (BCMA = y || BCMA = B43) 31 depends on B43 && (BCMA = y || BCMA = B43)
32 default y 32 default y
33 33
34config B43_BCMA_EXTRA
35 bool "Hardware support that overlaps with the brcmsmac driver"
36 depends on B43_BCMA
37 default n if BRCMSMAC
38 default y
39
40config B43_SSB 34config B43_SSB
41 bool 35 bool
42 depends on B43 && (SSB = y || SSB = B43) 36 depends on B43 && (SSB = y || SSB = B43)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a95b77ab360e..0e933bb71543 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -113,13 +113,15 @@ static int b43_modparam_pio = 0;
113module_param_named(pio, b43_modparam_pio, int, 0644); 113module_param_named(pio, b43_modparam_pio, int, 0644);
114MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); 114MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
115 115
116static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);
117module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
118MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
119
116#ifdef CONFIG_B43_BCMA 120#ifdef CONFIG_B43_BCMA
117static const struct bcma_device_id b43_bcma_tbl[] = { 121static const struct bcma_device_id b43_bcma_tbl[] = {
118 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS), 122 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
119#ifdef CONFIG_B43_BCMA_EXTRA
120 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), 123 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
121 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), 124 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
122#endif
123 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), 125 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
124 BCMA_CORETABLE_END 126 BCMA_CORETABLE_END
125}; 127};
@@ -5396,6 +5398,12 @@ static int b43_bcma_probe(struct bcma_device *core)
5396 struct b43_wl *wl; 5398 struct b43_wl *wl;
5397 int err; 5399 int err;
5398 5400
5401 if (!modparam_allhwsupport &&
5402 (core->id.rev == 0x17 || core->id.rev == 0x18)) {
5403 pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n");
5404 return -ENOTSUPP;
5405 }
5406
5399 dev = b43_bus_dev_bcma_init(core); 5407 dev = b43_bus_dev_bcma_init(core);
5400 if (!dev) 5408 if (!dev)
5401 return -ENODEV; 5409 return -ENODEV;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3f8e69c29146..e3f3c48f86d4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -162,7 +162,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
162 return 0; 162 return 0;
163} 163}
164 164
165int 165static int
166brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) 166brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
167{ 167{
168 int err = 0, i; 168 int err = 0, i;
@@ -193,12 +193,33 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
193 return err; 193 return err;
194} 194}
195 195
196static int
197brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
198{
199 uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
200 int err = 0;
201
202 if (bar0 != sdiodev->sbwad) {
203 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
204 if (err)
205 return err;
206
207 sdiodev->sbwad = bar0;
208 }
209
210 *addr &= SBSDIO_SB_OFT_ADDR_MASK;
211
212 if (width == 4)
213 *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
214
215 return 0;
216}
217
196int 218int
197brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 219brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
198 void *data, bool write) 220 void *data, bool write)
199{ 221{
200 u8 func_num, reg_size; 222 u8 func_num, reg_size;
201 u32 bar;
202 s32 retry = 0; 223 s32 retry = 0;
203 int ret; 224 int ret;
204 225
@@ -218,18 +239,7 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
218 func_num = SDIO_FUNC_1; 239 func_num = SDIO_FUNC_1;
219 reg_size = 4; 240 reg_size = 4;
220 241
221 /* Set the window for SB core register */ 242 brcmf_sdio_addrprep(sdiodev, reg_size, &addr);
222 bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
223 if (bar != sdiodev->sbwad) {
224 ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
225 if (ret != 0) {
226 memset(data, 0xFF, reg_size);
227 return ret;
228 }
229 sdiodev->sbwad = bar;
230 }
231 addr &= SBSDIO_SB_OFT_ADDR_MASK;
232 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
233 } 243 }
234 244
235 do { 245 do {
@@ -321,10 +331,11 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
321 bool write, u32 addr, struct sk_buff_head *pktlist) 331 bool write, u32 addr, struct sk_buff_head *pktlist)
322{ 332{
323 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; 333 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
324 unsigned int max_blks, max_req_sz; 334 unsigned int max_blks, max_req_sz, orig_offset, dst_offset;
325 unsigned short max_seg_sz, seg_sz; 335 unsigned short max_seg_sz, seg_sz;
326 unsigned char *pkt_data; 336 unsigned char *pkt_data, *orig_data, *dst_data;
327 struct sk_buff *pkt_next = NULL; 337 struct sk_buff *pkt_next = NULL, *local_pkt_next;
338 struct sk_buff_head local_list, *target_list;
328 struct mmc_request mmc_req; 339 struct mmc_request mmc_req;
329 struct mmc_command mmc_cmd; 340 struct mmc_command mmc_cmd;
330 struct mmc_data mmc_dat; 341 struct mmc_data mmc_dat;
@@ -361,6 +372,32 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
361 req_sz); 372 req_sz);
362 } 373 }
363 374
375 target_list = pktlist;
376 /* for host with broken sg support, prepare a page aligned list */
377 __skb_queue_head_init(&local_list);
378 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
379 req_sz = 0;
380 skb_queue_walk(pktlist, pkt_next)
381 req_sz += pkt_next->len;
382 req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
383 while (req_sz > PAGE_SIZE) {
384 pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
385 if (pkt_next == NULL) {
386 ret = -ENOMEM;
387 goto exit;
388 }
389 __skb_queue_tail(&local_list, pkt_next);
390 req_sz -= PAGE_SIZE;
391 }
392 pkt_next = brcmu_pkt_buf_get_skb(req_sz);
393 if (pkt_next == NULL) {
394 ret = -ENOMEM;
395 goto exit;
396 }
397 __skb_queue_tail(&local_list, pkt_next);
398 target_list = &local_list;
399 }
400
364 host = sdiodev->func[fn]->card->host; 401 host = sdiodev->func[fn]->card->host;
365 func_blk_sz = sdiodev->func[fn]->cur_blksize; 402 func_blk_sz = sdiodev->func[fn]->cur_blksize;
366 /* Blocks per command is limited by host count, host transfer 403 /* Blocks per command is limited by host count, host transfer
@@ -370,13 +407,15 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
370 max_req_sz = min_t(unsigned int, host->max_req_size, 407 max_req_sz = min_t(unsigned int, host->max_req_size,
371 max_blks * func_blk_sz); 408 max_blks * func_blk_sz);
372 max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC); 409 max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC);
373 max_seg_sz = min_t(unsigned short, max_seg_sz, pktlist->qlen); 410 max_seg_sz = min_t(unsigned short, max_seg_sz, target_list->qlen);
374 seg_sz = pktlist->qlen; 411 seg_sz = target_list->qlen;
375 pkt_offset = 0; 412 pkt_offset = 0;
376 pkt_next = pktlist->next; 413 pkt_next = target_list->next;
377 414
378 if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) 415 if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) {
379 return -ENOMEM; 416 ret = -ENOMEM;
417 goto exit;
418 }
380 419
381 while (seg_sz) { 420 while (seg_sz) {
382 req_sz = 0; 421 req_sz = 0;
@@ -386,7 +425,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
386 memset(&mmc_dat, 0, sizeof(struct mmc_data)); 425 memset(&mmc_dat, 0, sizeof(struct mmc_data));
387 sgl = st.sgl; 426 sgl = st.sgl;
388 /* prep sg table */ 427 /* prep sg table */
389 while (pkt_next != (struct sk_buff *)pktlist) { 428 while (pkt_next != (struct sk_buff *)target_list) {
390 pkt_data = pkt_next->data + pkt_offset; 429 pkt_data = pkt_next->data + pkt_offset;
391 sg_data_sz = pkt_next->len - pkt_offset; 430 sg_data_sz = pkt_next->len - pkt_offset;
392 if (sg_data_sz > host->max_seg_size) 431 if (sg_data_sz > host->max_seg_size)
@@ -413,8 +452,8 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
413 if (req_sz % func_blk_sz != 0) { 452 if (req_sz % func_blk_sz != 0) {
414 brcmf_err("sg request length %u is not %u aligned\n", 453 brcmf_err("sg request length %u is not %u aligned\n",
415 req_sz, func_blk_sz); 454 req_sz, func_blk_sz);
416 sg_free_table(&st); 455 ret = -ENOTBLK;
417 return -ENOTBLK; 456 goto exit;
418 } 457 }
419 mmc_dat.sg = st.sgl; 458 mmc_dat.sg = st.sgl;
420 mmc_dat.sg_len = sg_cnt; 459 mmc_dat.sg_len = sg_cnt;
@@ -447,35 +486,36 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
447 } 486 }
448 } 487 }
449 488
450 sg_free_table(&st); 489 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
451 490 local_pkt_next = local_list.next;
452 return ret; 491 orig_offset = 0;
453} 492 skb_queue_walk(pktlist, pkt_next) {
454 493 dst_offset = 0;
455static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, 494 do {
456 uint flags, uint width, u32 *addr) 495 req_sz = local_pkt_next->len - orig_offset;
457{ 496 req_sz = min_t(uint, pkt_next->len - dst_offset,
458 uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; 497 req_sz);
459 int err = 0; 498 orig_data = local_pkt_next->data + orig_offset;
460 499 dst_data = pkt_next->data + dst_offset;
461 /* Async not implemented yet */ 500 memcpy(dst_data, orig_data, req_sz);
462 if (flags & SDIO_REQ_ASYNC) 501 orig_offset += req_sz;
463 return -ENOTSUPP; 502 dst_offset += req_sz;
464 503 if (orig_offset == local_pkt_next->len) {
465 if (bar0 != sdiodev->sbwad) { 504 orig_offset = 0;
466 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); 505 local_pkt_next = local_pkt_next->next;
467 if (err) 506 }
468 return err; 507 if (dst_offset == pkt_next->len)
469 508 break;
470 sdiodev->sbwad = bar0; 509 } while (!skb_queue_empty(&local_list));
510 }
471 } 511 }
472 512
473 *addr &= SBSDIO_SB_OFT_ADDR_MASK; 513exit:
474 514 sg_free_table(&st);
475 if (width == 4) 515 while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
476 *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; 516 brcmu_pkt_buf_free_skb(pkt_next);
477 517
478 return 0; 518 return ret;
479} 519}
480 520
481int 521int
@@ -512,7 +552,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
512 fn, addr, pkt->len); 552 fn, addr, pkt->len);
513 553
514 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 554 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
515 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 555 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
516 if (err) 556 if (err)
517 goto done; 557 goto done;
518 558
@@ -536,7 +576,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
536 fn, addr, pktq->qlen); 576 fn, addr, pktq->qlen);
537 577
538 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 578 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
539 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 579 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
540 if (err) 580 if (err)
541 goto done; 581 goto done;
542 582
@@ -574,37 +614,20 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
574 uint flags, struct sk_buff *pkt) 614 uint flags, struct sk_buff *pkt)
575{ 615{
576 uint width; 616 uint width;
577 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
578 int err = 0; 617 int err = 0;
579 struct sk_buff_head pkt_list; 618 struct sk_buff_head pkt_list;
580 619
581 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", 620 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
582 fn, addr, pkt->len); 621 fn, addr, pkt->len);
583 622
584 /* Async not implemented yet */
585 if (flags & SDIO_REQ_ASYNC)
586 return -ENOTSUPP;
587
588 if (bar0 != sdiodev->sbwad) {
589 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
590 if (err)
591 goto done;
592
593 sdiodev->sbwad = bar0;
594 }
595
596 addr &= SBSDIO_SB_OFT_ADDR_MASK;
597
598 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 623 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
599 if (width == 4) 624 brcmf_sdio_addrprep(sdiodev, width, &addr);
600 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
601 625
602 skb_queue_head_init(&pkt_list); 626 skb_queue_head_init(&pkt_list);
603 skb_queue_tail(&pkt_list, pkt); 627 skb_queue_tail(&pkt_list, pkt);
604 err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list); 628 err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list);
605 skb_dequeue_tail(&pkt_list); 629 skb_dequeue_tail(&pkt_list);
606 630
607done:
608 return err; 631 return err;
609} 632}
610 633
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 8c402e7b97eb..8e8975562ec3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -281,8 +281,6 @@ void brcmf_txflowblock(struct device *dev, bool state)
281 281
282void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) 282void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
283{ 283{
284 unsigned char *eth;
285 uint len;
286 struct sk_buff *skb, *pnext; 284 struct sk_buff *skb, *pnext;
287 struct brcmf_if *ifp; 285 struct brcmf_if *ifp;
288 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 286 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -306,33 +304,12 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
306 continue; 304 continue;
307 } 305 }
308 306
309 /* Get the protocol, maintain skb around eth_type_trans()
310 * The main reason for this hack is for the limitation of
311 * Linux 2.4 where 'eth_type_trans' uses the
312 * 'net->hard_header_len'
313 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
314 * coping of the packet coming from the network stack to add
315 * BDC, Hardware header etc, during network interface
316 * registration
317 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
318 * required
319 * for BDC, Hardware header etc. and not just the ETH_HLEN
320 */
321 eth = skb->data;
322 len = skb->len;
323
324 skb->dev = ifp->ndev; 307 skb->dev = ifp->ndev;
325 skb->protocol = eth_type_trans(skb, skb->dev); 308 skb->protocol = eth_type_trans(skb, skb->dev);
326 309
327 if (skb->pkt_type == PACKET_MULTICAST) 310 if (skb->pkt_type == PACKET_MULTICAST)
328 ifp->stats.multicast++; 311 ifp->stats.multicast++;
329 312
330 skb->data = eth;
331 skb->len = len;
332
333 /* Strip header, count, deliver upward */
334 skb_pull(skb, ETH_HLEN);
335
336 /* Process special event packets */ 313 /* Process special event packets */
337 brcmf_fweh_process_skb(drvr, skb); 314 brcmf_fweh_process_skb(drvr, skb);
338 315
@@ -348,10 +325,8 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
348 netif_rx(skb); 325 netif_rx(skb);
349 else 326 else
350 /* If the receive is not processed inside an ISR, 327 /* If the receive is not processed inside an ISR,
351 * the softirqd must be woken explicitly to service 328 * the softirqd must be woken explicitly to service the
352 * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled 329 * NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
353 * by netif_rx_ni(), but in earlier kernels, we need
354 * to do it manually.
355 */ 330 */
356 netif_rx_ni(skb); 331 netif_rx_ni(skb);
357 } 332 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 13e75c4b1a6b..f0d9f7f6c83d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -796,9 +796,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
796 u8 fillers; 796 u8 fillers;
797 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); 797 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
798 798
799 brcmf_dbg(TRACE, "enter: ea=%pM, ifidx=%u (%u), pkttag=0x%08X, hslot=%d\n", 799 brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n",
800 entry->ea, entry->interface_id, 800 entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
801 brcmf_skb_if_flags_get_field(skb, INDEX),
802 le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); 801 le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
803 if (entry->send_tim_signal) 802 if (entry->send_tim_signal)
804 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; 803 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
@@ -822,8 +821,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
822 wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; 821 wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
823 wlh[2] = entry->mac_handle; 822 wlh[2] = entry->mac_handle;
824 wlh[3] = entry->traffic_pending_bmp; 823 wlh[3] = entry->traffic_pending_bmp;
825 brcmf_dbg(TRACE, "adding TIM info: %02X:%02X:%02X:%02X\n", 824 brcmf_dbg(TRACE, "adding TIM info: handle %d bmp 0x%X\n",
826 wlh[0], wlh[1], wlh[2], wlh[3]); 825 entry->mac_handle, entry->traffic_pending_bmp);
827 wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2; 826 wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
828 entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; 827 entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
829 } 828 }
@@ -906,10 +905,26 @@ static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi)
906 return 0; 905 return 0;
907} 906}
908 907
908/* using macro so sparse checking does not complain
909 * about locking imbalance.
910 */
911#define brcmf_fws_lock(drvr, flags) \
912do { \
913 flags = 0; \
914 spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
915} while (0)
916
917/* using macro so sparse checking does not complain
918 * about locking imbalance.
919 */
920#define brcmf_fws_unlock(drvr, flags) \
921 spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
922
909static 923static
910int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) 924int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
911{ 925{
912 struct brcmf_fws_mac_descriptor *entry, *existing; 926 struct brcmf_fws_mac_descriptor *entry, *existing;
927 ulong flags;
913 u8 mac_handle; 928 u8 mac_handle;
914 u8 ifidx; 929 u8 ifidx;
915 u8 *addr; 930 u8 *addr;
@@ -923,8 +938,10 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
923 if (entry->occupied) { 938 if (entry->occupied) {
924 brcmf_dbg(TRACE, "deleting %s mac %pM\n", 939 brcmf_dbg(TRACE, "deleting %s mac %pM\n",
925 entry->name, addr); 940 entry->name, addr);
941 brcmf_fws_lock(fws->drvr, flags);
926 brcmf_fws_macdesc_cleanup(fws, entry, -1); 942 brcmf_fws_macdesc_cleanup(fws, entry, -1);
927 brcmf_fws_macdesc_deinit(entry); 943 brcmf_fws_macdesc_deinit(entry);
944 brcmf_fws_unlock(fws->drvr, flags);
928 } else 945 } else
929 fws->stats.mac_update_failed++; 946 fws->stats.mac_update_failed++;
930 return 0; 947 return 0;
@@ -933,11 +950,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
933 existing = brcmf_fws_macdesc_lookup(fws, addr); 950 existing = brcmf_fws_macdesc_lookup(fws, addr);
934 if (IS_ERR(existing)) { 951 if (IS_ERR(existing)) {
935 if (!entry->occupied) { 952 if (!entry->occupied) {
953 brcmf_fws_lock(fws->drvr, flags);
936 entry->mac_handle = mac_handle; 954 entry->mac_handle = mac_handle;
937 brcmf_fws_macdesc_init(entry, addr, ifidx); 955 brcmf_fws_macdesc_init(entry, addr, ifidx);
938 brcmf_fws_macdesc_set_name(fws, entry); 956 brcmf_fws_macdesc_set_name(fws, entry);
939 brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT, 957 brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
940 BRCMF_FWS_PSQ_LEN); 958 BRCMF_FWS_PSQ_LEN);
959 brcmf_fws_unlock(fws->drvr, flags);
941 brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr); 960 brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr);
942 } else { 961 } else {
943 fws->stats.mac_update_failed++; 962 fws->stats.mac_update_failed++;
@@ -945,11 +964,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
945 } else { 964 } else {
946 if (entry != existing) { 965 if (entry != existing) {
947 brcmf_dbg(TRACE, "copy mac %s\n", existing->name); 966 brcmf_dbg(TRACE, "copy mac %s\n", existing->name);
967 brcmf_fws_lock(fws->drvr, flags);
948 memcpy(entry, existing, 968 memcpy(entry, existing,
949 offsetof(struct brcmf_fws_mac_descriptor, psq)); 969 offsetof(struct brcmf_fws_mac_descriptor, psq));
950 entry->mac_handle = mac_handle; 970 entry->mac_handle = mac_handle;
951 brcmf_fws_macdesc_deinit(existing); 971 brcmf_fws_macdesc_deinit(existing);
952 brcmf_fws_macdesc_set_name(fws, entry); 972 brcmf_fws_macdesc_set_name(fws, entry);
973 brcmf_fws_unlock(fws->drvr, flags);
953 brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name, 974 brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name,
954 addr); 975 addr);
955 } else { 976 } else {
@@ -965,7 +986,9 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
965 u8 type, u8 *data) 986 u8 type, u8 *data)
966{ 987{
967 struct brcmf_fws_mac_descriptor *entry; 988 struct brcmf_fws_mac_descriptor *entry;
989 ulong flags;
968 u8 mac_handle; 990 u8 mac_handle;
991 int ret;
969 992
970 mac_handle = data[0]; 993 mac_handle = data[0];
971 entry = &fws->desc.nodes[mac_handle & 0x1F]; 994 entry = &fws->desc.nodes[mac_handle & 0x1F];
@@ -973,26 +996,30 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
973 fws->stats.mac_ps_update_failed++; 996 fws->stats.mac_ps_update_failed++;
974 return -ESRCH; 997 return -ESRCH;
975 } 998 }
999 brcmf_fws_lock(fws->drvr, flags);
976 /* a state update should wipe old credits */ 1000 /* a state update should wipe old credits */
977 entry->requested_credit = 0; 1001 entry->requested_credit = 0;
978 entry->requested_packet = 0; 1002 entry->requested_packet = 0;
979 if (type == BRCMF_FWS_TYPE_MAC_OPEN) { 1003 if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
980 entry->state = BRCMF_FWS_STATE_OPEN; 1004 entry->state = BRCMF_FWS_STATE_OPEN;
981 return BRCMF_FWS_RET_OK_SCHEDULE; 1005 ret = BRCMF_FWS_RET_OK_SCHEDULE;
982 } else { 1006 } else {
983 entry->state = BRCMF_FWS_STATE_CLOSE; 1007 entry->state = BRCMF_FWS_STATE_CLOSE;
984 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false); 1008 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false);
985 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false); 1009 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false);
986 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false); 1010 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false);
987 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true); 1011 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true);
1012 ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
988 } 1013 }
989 return BRCMF_FWS_RET_OK_NOSCHEDULE; 1014 brcmf_fws_unlock(fws->drvr, flags);
1015 return ret;
990} 1016}
991 1017
992static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, 1018static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
993 u8 type, u8 *data) 1019 u8 type, u8 *data)
994{ 1020{
995 struct brcmf_fws_mac_descriptor *entry; 1021 struct brcmf_fws_mac_descriptor *entry;
1022 ulong flags;
996 u8 ifidx; 1023 u8 ifidx;
997 int ret; 1024 int ret;
998 1025
@@ -1011,17 +1038,24 @@ static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
1011 1038
1012 brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type, 1039 brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type,
1013 entry->name); 1040 entry->name);
1041 brcmf_fws_lock(fws->drvr, flags);
1014 switch (type) { 1042 switch (type) {
1015 case BRCMF_FWS_TYPE_INTERFACE_OPEN: 1043 case BRCMF_FWS_TYPE_INTERFACE_OPEN:
1016 entry->state = BRCMF_FWS_STATE_OPEN; 1044 entry->state = BRCMF_FWS_STATE_OPEN;
1017 return BRCMF_FWS_RET_OK_SCHEDULE; 1045 ret = BRCMF_FWS_RET_OK_SCHEDULE;
1046 break;
1018 case BRCMF_FWS_TYPE_INTERFACE_CLOSE: 1047 case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
1019 entry->state = BRCMF_FWS_STATE_CLOSE; 1048 entry->state = BRCMF_FWS_STATE_CLOSE;
1020 return BRCMF_FWS_RET_OK_NOSCHEDULE; 1049 ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
1050 break;
1021 default: 1051 default:
1022 ret = -EINVAL; 1052 ret = -EINVAL;
1023 break; 1053 brcmf_fws_unlock(fws->drvr, flags);
1054 goto fail;
1024 } 1055 }
1056 brcmf_fws_unlock(fws->drvr, flags);
1057 return ret;
1058
1025fail: 1059fail:
1026 fws->stats.if_update_failed++; 1060 fws->stats.if_update_failed++;
1027 return ret; 1061 return ret;
@@ -1031,6 +1065,7 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
1031 u8 *data) 1065 u8 *data)
1032{ 1066{
1033 struct brcmf_fws_mac_descriptor *entry; 1067 struct brcmf_fws_mac_descriptor *entry;
1068 ulong flags;
1034 1069
1035 entry = &fws->desc.nodes[data[1] & 0x1F]; 1070 entry = &fws->desc.nodes[data[1] & 0x1F];
1036 if (!entry->occupied) { 1071 if (!entry->occupied) {
@@ -1044,12 +1079,14 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
1044 brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n", 1079 brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n",
1045 brcmf_fws_get_tlv_name(type), type, entry->name, 1080 brcmf_fws_get_tlv_name(type), type, entry->name,
1046 data[0], data[2]); 1081 data[0], data[2]);
1082 brcmf_fws_lock(fws->drvr, flags);
1047 if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT) 1083 if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT)
1048 entry->requested_credit = data[0]; 1084 entry->requested_credit = data[0];
1049 else 1085 else
1050 entry->requested_packet = data[0]; 1086 entry->requested_packet = data[0];
1051 1087
1052 entry->ac_bitmap = data[2]; 1088 entry->ac_bitmap = data[2];
1089 brcmf_fws_unlock(fws->drvr, flags);
1053 return BRCMF_FWS_RET_OK_SCHEDULE; 1090 return BRCMF_FWS_RET_OK_SCHEDULE;
1054} 1091}
1055 1092
@@ -1346,6 +1383,7 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1346static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, 1383static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1347 u8 *data) 1384 u8 *data)
1348{ 1385{
1386 ulong flags;
1349 int i; 1387 int i;
1350 1388
1351 if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { 1389 if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
@@ -1354,16 +1392,19 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1354 } 1392 }
1355 1393
1356 brcmf_dbg(DATA, "enter: data %pM\n", data); 1394 brcmf_dbg(DATA, "enter: data %pM\n", data);
1395 brcmf_fws_lock(fws->drvr, flags);
1357 for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++) 1396 for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++)
1358 brcmf_fws_return_credits(fws, i, data[i]); 1397 brcmf_fws_return_credits(fws, i, data[i]);
1359 1398
1360 brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map, 1399 brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map,
1361 fws->fifo_delay_map); 1400 fws->fifo_delay_map);
1401 brcmf_fws_unlock(fws->drvr, flags);
1362 return BRCMF_FWS_RET_OK_SCHEDULE; 1402 return BRCMF_FWS_RET_OK_SCHEDULE;
1363} 1403}
1364 1404
1365static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) 1405static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1366{ 1406{
1407 ulong lflags;
1367 __le32 status_le; 1408 __le32 status_le;
1368 u32 status; 1409 u32 status;
1369 u32 hslot; 1410 u32 hslot;
@@ -1377,7 +1418,10 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1377 hslot = brcmf_txstatus_get_field(status, HSLOT); 1418 hslot = brcmf_txstatus_get_field(status, HSLOT);
1378 genbit = brcmf_txstatus_get_field(status, GENERATION); 1419 genbit = brcmf_txstatus_get_field(status, GENERATION);
1379 1420
1380 return brcmf_fws_txs_process(fws, flags, hslot, genbit); 1421 brcmf_fws_lock(fws->drvr, lflags);
1422 brcmf_fws_txs_process(fws, flags, hslot, genbit);
1423 brcmf_fws_unlock(fws->drvr, lflags);
1424 return BRCMF_FWS_RET_OK_NOSCHEDULE;
1381} 1425}
1382 1426
1383static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data) 1427static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
@@ -1390,21 +1434,6 @@ static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
1390 return 0; 1434 return 0;
1391} 1435}
1392 1436
1393/* using macro so sparse checking does not complain
1394 * about locking imbalance.
1395 */
1396#define brcmf_fws_lock(drvr, flags) \
1397do { \
1398 flags = 0; \
1399 spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
1400} while (0)
1401
1402/* using macro so sparse checking does not complain
1403 * about locking imbalance.
1404 */
1405#define brcmf_fws_unlock(drvr, flags) \
1406 spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
1407
1408static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp, 1437static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
1409 const struct brcmf_event_msg *e, 1438 const struct brcmf_event_msg *e,
1410 void *data) 1439 void *data)
@@ -1455,7 +1484,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1455 struct sk_buff *skb) 1484 struct sk_buff *skb)
1456{ 1485{
1457 struct brcmf_fws_info *fws = drvr->fws; 1486 struct brcmf_fws_info *fws = drvr->fws;
1458 ulong flags;
1459 u8 *signal_data; 1487 u8 *signal_data;
1460 s16 data_len; 1488 s16 data_len;
1461 u8 type; 1489 u8 type;
@@ -1475,9 +1503,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1475 return 0; 1503 return 0;
1476 } 1504 }
1477 1505
1478 /* lock during tlv parsing */
1479 brcmf_fws_lock(drvr, flags);
1480
1481 fws->stats.header_pulls++; 1506 fws->stats.header_pulls++;
1482 data_len = signal_len; 1507 data_len = signal_len;
1483 signal_data = skb->data; 1508 signal_data = skb->data;
@@ -1571,25 +1596,17 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1571 if (skb->len == 0) 1596 if (skb->len == 0)
1572 fws->stats.header_only_pkt++; 1597 fws->stats.header_only_pkt++;
1573 1598
1574 brcmf_fws_unlock(drvr, flags);
1575 return 0; 1599 return 0;
1576} 1600}
1577 1601
1578static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, 1602static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1579 struct sk_buff *p) 1603 struct sk_buff *p)
1580{ 1604{
1581 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); 1605 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1582 struct brcmf_fws_mac_descriptor *entry = skcb->mac; 1606 struct brcmf_fws_mac_descriptor *entry = skcb->mac;
1583 int rc = 0;
1584 bool first_time;
1585 int hslot = BRCMF_FWS_HANGER_MAXITEMS;
1586 u8 free_ctr;
1587 u8 flags; 1607 u8 flags;
1588 1608
1589 first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
1590
1591 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); 1609 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
1592 brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
1593 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); 1610 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
1594 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; 1611 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
1595 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { 1612 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
@@ -1600,80 +1617,36 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1600 flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED; 1617 flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED;
1601 } 1618 }
1602 brcmf_skb_htod_tag_set_field(p, FLAGS, flags); 1619 brcmf_skb_htod_tag_set_field(p, FLAGS, flags);
1603 if (first_time) { 1620 brcmf_fws_hdrpush(fws, p);
1604 /* obtaining free slot may fail, but that will be caught
1605 * by the hanger push. This assures the packet has a BDC
1606 * header upon return.
1607 */
1608 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
1609 free_ctr = entry->seq[fifo];
1610 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1611 brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
1612 rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
1613 if (rc)
1614 brcmf_err("hanger push failed: rc=%d\n", rc);
1615 }
1616
1617 if (rc == 0)
1618 brcmf_fws_hdrpush(fws, p);
1619
1620 return rc;
1621} 1621}
1622 1622
1623static void 1623static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
1624brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, 1624 struct sk_buff *skb, int fifo)
1625 struct sk_buff *skb, int fifo)
1626{ 1625{
1627 /*
1628 put the packet back to the head of queue
1629
1630 - suppressed packet goes back to suppress sub-queue
1631 - pull out the header, if new or delayed packet
1632
1633 Note: hslot is used only when header removal is done.
1634 */
1635 struct brcmf_fws_mac_descriptor *entry; 1626 struct brcmf_fws_mac_descriptor *entry;
1636 enum brcmf_fws_skb_state state;
1637 struct sk_buff *pktout; 1627 struct sk_buff *pktout;
1628 int qidx, hslot;
1638 int rc = 0; 1629 int rc = 0;
1639 int hslot;
1640 1630
1641 state = brcmf_skbcb(skb)->state;
1642 entry = brcmf_skbcb(skb)->mac; 1631 entry = brcmf_skbcb(skb)->mac;
1643 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1632 if (entry->occupied) {
1644 1633 qidx = 2 * fifo;
1645 if (entry != NULL) { 1634 if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_SUPPRESSED)
1646 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) { 1635 qidx++;
1647 /* wl-header is saved for suppressed packets */ 1636
1648 pktout = brcmu_pktq_penq_head(&entry->psq, 2 * fifo + 1, 1637 pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb);
1649 skb); 1638 if (pktout == NULL) {
1650 if (pktout == NULL) { 1639 brcmf_err("%s queue %d full\n", entry->name, qidx);
1651 brcmf_err("suppress queue full\n"); 1640 rc = -ENOSPC;
1652 rc = -ENOSPC;
1653 }
1654 } else {
1655 /* delay-q packets are going to delay-q */
1656 pktout = brcmu_pktq_penq_head(&entry->psq,
1657 2 * fifo, skb);
1658 if (pktout == NULL) {
1659 brcmf_err("delay queue full\n");
1660 rc = -ENOSPC;
1661 }
1662
1663 /* free the hanger slot */
1664 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &pktout,
1665 true);
1666
1667 /* decrement sequence count */
1668 entry->seq[fifo]--;
1669 } 1641 }
1670 } else { 1642 } else {
1671 brcmf_err("no mac entry linked\n"); 1643 brcmf_err("%s entry removed\n", entry->name);
1672 rc = -ENOENT; 1644 rc = -ENOENT;
1673 } 1645 }
1674 1646
1675 if (rc) { 1647 if (rc) {
1676 fws->stats.rollback_failed++; 1648 fws->stats.rollback_failed++;
1649 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1677 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, 1650 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
1678 hslot, 0); 1651 hslot, 0);
1679 } else { 1652 } else {
@@ -1707,37 +1680,6 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
1707 return -ENAVAIL; 1680 return -ENAVAIL;
1708} 1681}
1709 1682
1710static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo,
1711 struct sk_buff *skb)
1712{
1713 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1714 int *credit = &fws->fifo_credit[fifo];
1715
1716 if (fifo != BRCMF_FWS_FIFO_AC_BE)
1717 fws->borrow_defer_timestamp = jiffies +
1718 BRCMF_FWS_BORROW_DEFER_PERIOD;
1719
1720 if (!(*credit)) {
1721 /* Try to borrow a credit from other queue */
1722 if (fifo != BRCMF_FWS_FIFO_AC_BE ||
1723 (brcmf_fws_borrow_credit(fws) != 0)) {
1724 brcmf_dbg(DATA, "ac=%d, credits depleted\n", fifo);
1725 return -ENAVAIL;
1726 }
1727 } else {
1728 (*credit)--;
1729 if (!(*credit))
1730 fws->fifo_credit_map &= ~(1 << fifo);
1731 }
1732
1733 brcmf_fws_macdesc_use_req_credit(entry, skb);
1734
1735 brcmf_dbg(DATA, "ac=%d, credits=%02d:%02d:%02d:%02d\n", fifo,
1736 fws->fifo_credit[0], fws->fifo_credit[1],
1737 fws->fifo_credit[2], fws->fifo_credit[3]);
1738 return 0;
1739}
1740
1741static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, 1683static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1742 struct sk_buff *skb) 1684 struct sk_buff *skb)
1743{ 1685{
@@ -1751,15 +1693,10 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1751 if (IS_ERR(entry)) 1693 if (IS_ERR(entry))
1752 return PTR_ERR(entry); 1694 return PTR_ERR(entry);
1753 1695
1754 rc = brcmf_fws_precommit_skb(fws, fifo, skb); 1696 brcmf_fws_precommit_skb(fws, fifo, skb);
1755 if (rc < 0) {
1756 fws->stats.generic_error++;
1757 goto rollback;
1758 }
1759
1760 brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
1761 skcb->htod);
1762 rc = brcmf_bus_txdata(bus, skb); 1697 rc = brcmf_bus_txdata(bus, skb);
1698 brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name,
1699 skcb->if_flags, skcb->htod, rc);
1763 if (rc < 0) { 1700 if (rc < 0) {
1764 brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); 1701 brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1765 goto rollback; 1702 goto rollback;
@@ -1768,7 +1705,6 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1768 entry->transit_count++; 1705 entry->transit_count++;
1769 if (entry->suppressed) 1706 if (entry->suppressed)
1770 entry->suppr_transit_count++; 1707 entry->suppr_transit_count++;
1771 entry->seq[fifo]++;
1772 fws->stats.pkt2bus++; 1708 fws->stats.pkt2bus++;
1773 fws->stats.send_pkts[fifo]++; 1709 fws->stats.send_pkts[fifo]++;
1774 if (brcmf_skb_if_flags_get_field(skb, REQUESTED)) 1710 if (brcmf_skb_if_flags_get_field(skb, REQUESTED))
@@ -1781,6 +1717,24 @@ rollback:
1781 return rc; 1717 return rc;
1782} 1718}
1783 1719
1720static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
1721 int fifo)
1722{
1723 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1724 int rc, hslot;
1725
1726 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
1727 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1728 brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
1729 brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
1730 rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
1731 if (!rc)
1732 skcb->mac->seq[fifo]++;
1733 else
1734 fws->stats.generic_error++;
1735 return rc;
1736}
1737
1784int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) 1738int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1785{ 1739{
1786 struct brcmf_pub *drvr = ifp->drvr; 1740 struct brcmf_pub *drvr = ifp->drvr;
@@ -1809,33 +1763,25 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1809 1763
1810 /* set control buffer information */ 1764 /* set control buffer information */
1811 skcb->if_flags = 0; 1765 skcb->if_flags = 0;
1812 skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
1813 skcb->state = BRCMF_FWS_SKBSTATE_NEW; 1766 skcb->state = BRCMF_FWS_SKBSTATE_NEW;
1814 brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx); 1767 brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx);
1815 if (!multicast) 1768 if (!multicast)
1816 fifo = brcmf_fws_prio2fifo[skb->priority]; 1769 fifo = brcmf_fws_prio2fifo[skb->priority];
1817 1770
1771 brcmf_fws_lock(drvr, flags);
1772 if (fifo != BRCMF_FWS_FIFO_AC_BE && fifo < BRCMF_FWS_FIFO_BCMC)
1773 fws->borrow_defer_timestamp = jiffies +
1774 BRCMF_FWS_BORROW_DEFER_PERIOD;
1775
1776 skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
1818 brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name, 1777 brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name,
1819 eh->h_dest, multicast, fifo); 1778 eh->h_dest, multicast, fifo);
1820 1779 if (!brcmf_fws_assign_htod(fws, skb, fifo)) {
1821 brcmf_fws_lock(drvr, flags);
1822 /* multicast credit support is conditional, setting
1823 * flag to false to assure credit is consumed below.
1824 */
1825 if (fws->bcmc_credit_check)
1826 multicast = false;
1827
1828 if (skcb->mac->suppressed ||
1829 fws->bus_flow_blocked ||
1830 brcmf_fws_macdesc_closed(fws, skcb->mac, fifo) ||
1831 brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) ||
1832 (!multicast &&
1833 brcmf_fws_consume_credit(fws, fifo, skb) < 0)) {
1834 /* enqueue the packet in delayQ */
1835 drvr->fws->fifo_delay_map |= 1 << fifo;
1836 brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); 1780 brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
1781 brcmf_fws_schedule_deq(fws);
1837 } else { 1782 } else {
1838 brcmf_fws_commit_skb(fws, fifo, skb); 1783 brcmf_err("drop skb: no hanger slot\n");
1784 brcmu_pkt_buf_free_skb(skb);
1839 } 1785 }
1840 brcmf_fws_unlock(drvr, flags); 1786 brcmf_fws_unlock(drvr, flags);
1841 return 0; 1787 return 0;
@@ -1895,7 +1841,7 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
1895 fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work); 1841 fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work);
1896 1842
1897 brcmf_fws_lock(fws->drvr, flags); 1843 brcmf_fws_lock(fws->drvr, flags);
1898 for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked; 1844 for (fifo = BRCMF_FWS_FIFO_BCMC; fifo >= 0 && !fws->bus_flow_blocked;
1899 fifo--) { 1845 fifo--) {
1900 while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) && 1846 while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
1901 (fifo == BRCMF_FWS_FIFO_BCMC))) { 1847 (fifo == BRCMF_FWS_FIFO_BCMC))) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 793df66fe0bf..09786a539950 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -229,8 +229,6 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
229#define SDIO_REQ_4BYTE 0x1 229#define SDIO_REQ_4BYTE 0x1
230/* Fixed address (FIFO) (vs. incrementing address) */ 230/* Fixed address (FIFO) (vs. incrementing address) */
231#define SDIO_REQ_FIXED 0x2 231#define SDIO_REQ_FIXED 0x2
232/* Async request (vs. sync request) */
233#define SDIO_REQ_ASYNC 0x4
234 232
235/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). 233/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
236 * rw: read or write (0/1) 234 * rw: read or write (0/1)
@@ -251,9 +249,6 @@ extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
251extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); 249extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
252extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); 250extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
253 251
254extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
255 u32 address);
256
257/* attach, return handler on success, NULL if failed. 252/* attach, return handler on success, NULL if failed.
258 * The handler shall be provided by all subsequent calls. No local cache 253 * The handler shall be provided by all subsequent calls. No local cache
259 * cfghdl points to the starting address of pci device mapped memory 254 * cfghdl points to the starting address of pci device mapped memory
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
index 243e96353d13..1ad7d3602520 100644
--- a/drivers/net/wireless/cw1200/cw1200.h
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -267,7 +267,7 @@ struct cw1200_common {
267 struct delayed_work bss_loss_work; 267 struct delayed_work bss_loss_work;
268 spinlock_t bss_loss_lock; /* Protect BSS loss state */ 268 spinlock_t bss_loss_lock; /* Protect BSS loss state */
269 int bss_loss_state; 269 int bss_loss_state;
270 int bss_loss_confirm_id; 270 u32 bss_loss_confirm_id;
271 int delayed_link_loss; 271 int delayed_link_loss;
272 struct work_struct bss_params_work; 272 struct work_struct bss_params_work;
273 273
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 953bd1904d3d..d06376014bcd 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -61,7 +61,7 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
61 void *dst, int count) 61 void *dst, int count)
62{ 62{
63 int ret, i; 63 int ret, i;
64 uint16_t regaddr; 64 u16 regaddr;
65 struct spi_message m; 65 struct spi_message m;
66 66
67 struct spi_transfer t_addr = { 67 struct spi_transfer t_addr = {
@@ -76,15 +76,18 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
76 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; 76 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
77 regaddr |= SET_READ; 77 regaddr |= SET_READ;
78 regaddr |= (count>>1); 78 regaddr |= (count>>1);
79 regaddr = cpu_to_le16(regaddr);
80 79
81#ifdef SPI_DEBUG 80#ifdef SPI_DEBUG
82 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, 81 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, regaddr);
83 le16_to_cpu(regaddr));
84#endif 82#endif
85 83
84 /* Header is LE16 */
85 regaddr = cpu_to_le16(regaddr);
86
87 /* We have to byteswap if the SPI bus is limited to 8b operation
88 or we are running on a Big Endian system
89 */
86#if defined(__LITTLE_ENDIAN) 90#if defined(__LITTLE_ENDIAN)
87 /* We have to byteswap if the SPI bus is limited to 8b operation */
88 if (self->func->bits_per_word == 8) 91 if (self->func->bits_per_word == 8)
89#endif 92#endif
90 regaddr = swab16(regaddr); 93 regaddr = swab16(regaddr);
@@ -104,8 +107,10 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
104 printk("\n"); 107 printk("\n");
105#endif 108#endif
106 109
110 /* We have to byteswap if the SPI bus is limited to 8b operation
111 or we are running on a Big Endian system
112 */
107#if defined(__LITTLE_ENDIAN) 113#if defined(__LITTLE_ENDIAN)
108 /* We have to byteswap if the SPI bus is limited to 8b operation */
109 if (self->func->bits_per_word == 8) 114 if (self->func->bits_per_word == 8)
110#endif 115#endif
111 { 116 {
@@ -122,7 +127,7 @@ static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
122 const void *src, int count) 127 const void *src, int count)
123{ 128{
124 int rval, i; 129 int rval, i;
125 uint16_t regaddr; 130 u16 regaddr;
126 struct spi_transfer t_addr = { 131 struct spi_transfer t_addr = {
127 .tx_buf = &regaddr, 132 .tx_buf = &regaddr,
128 .len = sizeof(regaddr), 133 .len = sizeof(regaddr),
@@ -136,20 +141,23 @@ static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
136 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; 141 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
137 regaddr &= SET_WRITE; 142 regaddr &= SET_WRITE;
138 regaddr |= (count>>1); 143 regaddr |= (count>>1);
139 regaddr = cpu_to_le16(regaddr);
140 144
141#ifdef SPI_DEBUG 145#ifdef SPI_DEBUG
142 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, 146 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, regaddr);
143 le16_to_cpu(regaddr));
144#endif 147#endif
145 148
149 /* Header is LE16 */
150 regaddr = cpu_to_le16(regaddr);
151
152 /* We have to byteswap if the SPI bus is limited to 8b operation
153 or we are running on a Big Endian system
154 */
146#if defined(__LITTLE_ENDIAN) 155#if defined(__LITTLE_ENDIAN)
147 /* We have to byteswap if the SPI bus is limited to 8b operation */
148 if (self->func->bits_per_word == 8) 156 if (self->func->bits_per_word == 8)
149#endif 157#endif
150 { 158 {
151 uint16_t *buf = (uint16_t *)src; 159 uint16_t *buf = (uint16_t *)src;
152 regaddr = swab16(regaddr); 160 regaddr = swab16(regaddr);
153 for (i = 0; i < ((count + 1) >> 1); i++) 161 for (i = 0; i < ((count + 1) >> 1); i++)
154 buf[i] = swab16(buf[i]); 162 buf[i] = swab16(buf[i]);
155 } 163 }
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
index dad3fb331818..ff230b7aeedd 100644
--- a/drivers/net/wireless/cw1200/hwio.c
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -69,31 +69,33 @@ static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
69static inline int __cw1200_reg_read_32(struct cw1200_common *priv, 69static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
70 u16 addr, u32 *val) 70 u16 addr, u32 *val)
71{ 71{
72 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0); 72 __le32 tmp;
73 *val = le32_to_cpu(*val); 73 int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
74 *val = le32_to_cpu(tmp);
74 return i; 75 return i;
75} 76}
76 77
77static inline int __cw1200_reg_write_32(struct cw1200_common *priv, 78static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
78 u16 addr, u32 val) 79 u16 addr, u32 val)
79{ 80{
80 val = cpu_to_le32(val); 81 __le32 tmp = cpu_to_le32(val);
81 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0); 82 return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
82} 83}
83 84
84static inline int __cw1200_reg_read_16(struct cw1200_common *priv, 85static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
85 u16 addr, u16 *val) 86 u16 addr, u16 *val)
86{ 87{
87 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0); 88 __le16 tmp;
88 *val = le16_to_cpu(*val); 89 int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
90 *val = le16_to_cpu(tmp);
89 return i; 91 return i;
90} 92}
91 93
92static inline int __cw1200_reg_write_16(struct cw1200_common *priv, 94static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
93 u16 addr, u16 val) 95 u16 addr, u16 val)
94{ 96{
95 val = cpu_to_le16(val); 97 __le16 tmp = cpu_to_le16(val);
96 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0); 98 return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
97} 99}
98 100
99int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf, 101int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
diff --git a/drivers/net/wireless/cw1200/hwio.h b/drivers/net/wireless/cw1200/hwio.h
index 563329cfead6..ddf52669dc5b 100644
--- a/drivers/net/wireless/cw1200/hwio.h
+++ b/drivers/net/wireless/cw1200/hwio.h
@@ -169,35 +169,34 @@ int cw1200_reg_write(struct cw1200_common *priv, u16 addr,
169static inline int cw1200_reg_read_16(struct cw1200_common *priv, 169static inline int cw1200_reg_read_16(struct cw1200_common *priv,
170 u16 addr, u16 *val) 170 u16 addr, u16 *val)
171{ 171{
172 u32 tmp; 172 __le32 tmp;
173 int i; 173 int i;
174 i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); 174 i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
175 tmp = le32_to_cpu(tmp); 175 *val = le32_to_cpu(tmp) & 0xfffff;
176 *val = tmp & 0xffff;
177 return i; 176 return i;
178} 177}
179 178
180static inline int cw1200_reg_write_16(struct cw1200_common *priv, 179static inline int cw1200_reg_write_16(struct cw1200_common *priv,
181 u16 addr, u16 val) 180 u16 addr, u16 val)
182{ 181{
183 u32 tmp = val; 182 __le32 tmp = cpu_to_le32((u32)val);
184 tmp = cpu_to_le32(tmp);
185 return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp)); 183 return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp));
186} 184}
187 185
188static inline int cw1200_reg_read_32(struct cw1200_common *priv, 186static inline int cw1200_reg_read_32(struct cw1200_common *priv,
189 u16 addr, u32 *val) 187 u16 addr, u32 *val)
190{ 188{
191 int i = cw1200_reg_read(priv, addr, val, sizeof(*val)); 189 __le32 tmp;
192 *val = le32_to_cpu(*val); 190 int i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
191 *val = le32_to_cpu(tmp);
193 return i; 192 return i;
194} 193}
195 194
196static inline int cw1200_reg_write_32(struct cw1200_common *priv, 195static inline int cw1200_reg_write_32(struct cw1200_common *priv,
197 u16 addr, u32 val) 196 u16 addr, u32 val)
198{ 197{
199 val = cpu_to_le32(val); 198 __le32 tmp = cpu_to_le32(val);
200 return cw1200_reg_write(priv, addr, &val, sizeof(val)); 199 return cw1200_reg_write(priv, addr, &tmp, sizeof(val));
201} 200}
202 201
203int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf, 202int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
@@ -224,22 +223,24 @@ static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr,
224static inline int cw1200_apb_read_32(struct cw1200_common *priv, 223static inline int cw1200_apb_read_32(struct cw1200_common *priv,
225 u32 addr, u32 *val) 224 u32 addr, u32 *val)
226{ 225{
227 int i = cw1200_apb_read(priv, addr, val, sizeof(*val)); 226 __le32 tmp;
228 *val = le32_to_cpu(*val); 227 int i = cw1200_apb_read(priv, addr, &tmp, sizeof(tmp));
228 *val = le32_to_cpu(tmp);
229 return i; 229 return i;
230} 230}
231 231
232static inline int cw1200_apb_write_32(struct cw1200_common *priv, 232static inline int cw1200_apb_write_32(struct cw1200_common *priv,
233 u32 addr, u32 val) 233 u32 addr, u32 val)
234{ 234{
235 val = cpu_to_le32(val); 235 __le32 tmp = cpu_to_le32(val);
236 return cw1200_apb_write(priv, addr, &val, sizeof(val)); 236 return cw1200_apb_write(priv, addr, &tmp, sizeof(val));
237} 237}
238static inline int cw1200_ahb_read_32(struct cw1200_common *priv, 238static inline int cw1200_ahb_read_32(struct cw1200_common *priv,
239 u32 addr, u32 *val) 239 u32 addr, u32 *val)
240{ 240{
241 int i = cw1200_ahb_read(priv, addr, val, sizeof(*val)); 241 __le32 tmp;
242 *val = le32_to_cpu(*val); 242 int i = cw1200_ahb_read(priv, addr, &tmp, sizeof(tmp));
243 *val = le32_to_cpu(tmp);
243 return i; 244 return i;
244} 245}
245 246
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index da885036ca5f..3724e739cbf4 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -238,8 +238,8 @@ static const struct ieee80211_ops cw1200_ops = {
238 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */ 238 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */
239}; 239};
240 240
241int cw1200_ba_rx_tids = -1; 241static int cw1200_ba_rx_tids = -1;
242int cw1200_ba_tx_tids = -1; 242static int cw1200_ba_tx_tids = -1;
243module_param(cw1200_ba_rx_tids, int, 0644); 243module_param(cw1200_ba_rx_tids, int, 0644);
244module_param(cw1200_ba_tx_tids, int, 0644); 244module_param(cw1200_ba_tx_tids, int, 0644);
245MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs"); 245MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
diff --git a/drivers/net/wireless/cw1200/queue.c b/drivers/net/wireless/cw1200/queue.c
index 8510454d5db1..9c3925f58d79 100644
--- a/drivers/net/wireless/cw1200/queue.c
+++ b/drivers/net/wireless/cw1200/queue.c
@@ -355,7 +355,7 @@ int cw1200_queue_get(struct cw1200_queue *queue,
355 *tx = (struct wsm_tx *)item->skb->data; 355 *tx = (struct wsm_tx *)item->skb->data;
356 *tx_info = IEEE80211_SKB_CB(item->skb); 356 *tx_info = IEEE80211_SKB_CB(item->skb);
357 *txpriv = &item->txpriv; 357 *txpriv = &item->txpriv;
358 (*tx)->packet_id = __cpu_to_le32(item->packet_id); 358 (*tx)->packet_id = item->packet_id;
359 list_move_tail(&item->head, &queue->pending); 359 list_move_tail(&item->head, &queue->pending);
360 ++queue->num_pending; 360 ++queue->num_pending;
361 --queue->link_map_cache[item->txpriv.link_id]; 361 --queue->link_map_cache[item->txpriv.link_id];
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index 4cd0352b508d..7365674366f4 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -621,7 +621,7 @@ int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
621 mutex_lock(&priv->conf_mutex); 621 mutex_lock(&priv->conf_mutex);
622 622
623 if (queue < dev->queues) { 623 if (queue < dev->queues) {
624 old_uapsd_flags = priv->uapsd_info.uapsd_flags; 624 old_uapsd_flags = le16_to_cpu(priv->uapsd_info.uapsd_flags);
625 625
626 WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0); 626 WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
627 ret = wsm_set_tx_queue_params(priv, 627 ret = wsm_set_tx_queue_params(priv,
@@ -645,7 +645,7 @@ int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
645 ret = cw1200_set_uapsd_param(priv, &priv->edca); 645 ret = cw1200_set_uapsd_param(priv, &priv->edca);
646 if (!ret && priv->setbssparams_done && 646 if (!ret && priv->setbssparams_done &&
647 (priv->join_status == CW1200_JOIN_STATUS_STA) && 647 (priv->join_status == CW1200_JOIN_STATUS_STA) &&
648 (old_uapsd_flags != priv->uapsd_info.uapsd_flags)) 648 (old_uapsd_flags != le16_to_cpu(priv->uapsd_info.uapsd_flags)))
649 ret = cw1200_set_pm(priv, &priv->powersave_mode); 649 ret = cw1200_set_pm(priv, &priv->powersave_mode);
650 } 650 }
651 } else { 651 } else {
@@ -1089,18 +1089,18 @@ static int cw1200_parse_sdd_file(struct cw1200_common *priv)
1089 ret = -1; 1089 ret = -1;
1090 break; 1090 break;
1091 } 1091 }
1092 v = le16_to_cpu(*((u16 *)(p + 2))); 1092 v = le16_to_cpu(*((__le16 *)(p + 2)));
1093 if (!v) /* non-zero means this is enabled */ 1093 if (!v) /* non-zero means this is enabled */
1094 break; 1094 break;
1095 1095
1096 v = le16_to_cpu(*((u16 *)(p + 4))); 1096 v = le16_to_cpu(*((__le16 *)(p + 4)));
1097 priv->conf_listen_interval = (v >> 7) & 0x1F; 1097 priv->conf_listen_interval = (v >> 7) & 0x1F;
1098 pr_debug("PTA found; Listen Interval %d\n", 1098 pr_debug("PTA found; Listen Interval %d\n",
1099 priv->conf_listen_interval); 1099 priv->conf_listen_interval);
1100 break; 1100 break;
1101 } 1101 }
1102 case SDD_REFERENCE_FREQUENCY_ELT_ID: { 1102 case SDD_REFERENCE_FREQUENCY_ELT_ID: {
1103 u16 clk = le16_to_cpu(*((u16 *)(p + 2))); 1103 u16 clk = le16_to_cpu(*((__le16 *)(p + 2)));
1104 if (clk != priv->hw_refclk) 1104 if (clk != priv->hw_refclk)
1105 pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n", 1105 pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n",
1106 clk, priv->hw_refclk); 1106 clk, priv->hw_refclk);
@@ -1785,9 +1785,9 @@ static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
1785 } else { 1785 } else {
1786 pr_debug("[STA] STA has non ERP rates\n"); 1786 pr_debug("[STA] STA has non ERP rates\n");
1787 /* B only mode */ 1787 /* B only mode */
1788 arg.internalTxRate = (__ffs(priv->association_mode.basic_rate_set)); 1788 arg.internalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
1789 } 1789 }
1790 arg.nonErpInternalTxRate = (__ffs(priv->association_mode.basic_rate_set)); 1790 arg.nonErpInternalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
1791 } else { 1791 } else {
1792 /* P2P mode */ 1792 /* P2P mode */
1793 arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF)); 1793 arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
@@ -1908,7 +1908,7 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1908 1908
1909 if (info->assoc || info->ibss_joined) { 1909 if (info->assoc || info->ibss_joined) {
1910 struct ieee80211_sta *sta = NULL; 1910 struct ieee80211_sta *sta = NULL;
1911 u32 val = 0; 1911 __le32 htprot = 0;
1912 1912
1913 if (info->dtim_period) 1913 if (info->dtim_period)
1914 priv->join_dtim_period = info->dtim_period; 1914 priv->join_dtim_period = info->dtim_period;
@@ -1935,19 +1935,18 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1935 /* Non Greenfield stations present */ 1935 /* Non Greenfield stations present */
1936 if (priv->ht_info.operation_mode & 1936 if (priv->ht_info.operation_mode &
1937 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) 1937 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
1938 val |= WSM_NON_GREENFIELD_STA_PRESENT; 1938 htprot |= cpu_to_le32(WSM_NON_GREENFIELD_STA_PRESENT);
1939 1939
1940 /* Set HT protection method */ 1940 /* Set HT protection method */
1941 val |= (priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2; 1941 htprot |= cpu_to_le32((priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2);
1942 1942
1943 /* TODO: 1943 /* TODO:
1944 * STBC_param.dual_cts 1944 * STBC_param.dual_cts
1945 * STBC_param.LSIG_TXOP_FILL 1945 * STBC_param.LSIG_TXOP_FILL
1946 */ 1946 */
1947 1947
1948 val = cpu_to_le32(val);
1949 wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION, 1948 wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION,
1950 &val, sizeof(val)); 1949 &htprot, sizeof(htprot));
1951 1950
1952 priv->association_mode.greenfield = 1951 priv->association_mode.greenfield =
1953 cw1200_ht_greenfield(&priv->ht_info); 1952 cw1200_ht_greenfield(&priv->ht_info);
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
index 44ca10cb0d39..5862c373d714 100644
--- a/drivers/net/wireless/cw1200/txrx.c
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -599,15 +599,15 @@ cw1200_tx_h_bt(struct cw1200_common *priv,
599 } else if (ieee80211_is_data(t->hdr->frame_control)) { 599 } else if (ieee80211_is_data(t->hdr->frame_control)) {
600 /* Skip LLC SNAP header (+6) */ 600 /* Skip LLC SNAP header (+6) */
601 u8 *payload = &t->skb->data[t->hdrlen]; 601 u8 *payload = &t->skb->data[t->hdrlen];
602 u16 *ethertype = (u16 *)&payload[6]; 602 __be16 *ethertype = (__be16 *)&payload[6];
603 if (*ethertype == __be16_to_cpu(ETH_P_PAE)) 603 if (be16_to_cpu(*ethertype) == ETH_P_PAE)
604 priority = WSM_EPTA_PRIORITY_EAPOL; 604 priority = WSM_EPTA_PRIORITY_EAPOL;
605 } else if (ieee80211_is_assoc_req(t->hdr->frame_control) || 605 } else if (ieee80211_is_assoc_req(t->hdr->frame_control) ||
606 ieee80211_is_reassoc_req(t->hdr->frame_control)) { 606 ieee80211_is_reassoc_req(t->hdr->frame_control)) {
607 struct ieee80211_mgmt *mgt_frame = 607 struct ieee80211_mgmt *mgt_frame =
608 (struct ieee80211_mgmt *)t->hdr; 608 (struct ieee80211_mgmt *)t->hdr;
609 609
610 if (mgt_frame->u.assoc_req.listen_interval < 610 if (le16_to_cpu(mgt_frame->u.assoc_req.listen_interval) <
611 priv->listen_interval) { 611 priv->listen_interval) {
612 pr_debug("Modified Listen Interval to %d from %d\n", 612 pr_debug("Modified Listen Interval to %d from %d\n",
613 priv->listen_interval, 613 priv->listen_interval,
@@ -615,8 +615,7 @@ cw1200_tx_h_bt(struct cw1200_common *priv,
615 /* Replace listen interval derieved from 615 /* Replace listen interval derieved from
616 * the one read from SDD 616 * the one read from SDD
617 */ 617 */
618 mgt_frame->u.assoc_req.listen_interval = 618 mgt_frame->u.assoc_req.listen_interval = cpu_to_le16(priv->listen_interval);
619 priv->listen_interval;
620 } 619 }
621 } 620 }
622 621
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index d95094fdcc50..cbb74d7a9be5 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -42,19 +42,19 @@
42 (buf)->data += size; \ 42 (buf)->data += size; \
43 } while (0) 43 } while (0)
44 44
45#define __WSM_GET(buf, type, cvt) \ 45#define __WSM_GET(buf, type, type2, cvt) \
46 ({ \ 46 ({ \
47 type val; \ 47 type val; \
48 if ((buf)->data + sizeof(type) > (buf)->end) \ 48 if ((buf)->data + sizeof(type) > (buf)->end) \
49 goto underflow; \ 49 goto underflow; \
50 val = cvt(*(type *)(buf)->data); \ 50 val = cvt(*(type2 *)(buf)->data); \
51 (buf)->data += sizeof(type); \ 51 (buf)->data += sizeof(type); \
52 val; \ 52 val; \
53 }) 53 })
54 54
55#define WSM_GET8(buf) __WSM_GET(buf, u8, (u8)) 55#define WSM_GET8(buf) __WSM_GET(buf, u8, u8, (u8))
56#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16_to_cpu) 56#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16, __le16_to_cpu)
57#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32_to_cpu) 57#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32, __le32_to_cpu)
58 58
59#define WSM_PUT(buf, ptr, size) \ 59#define WSM_PUT(buf, ptr, size) \
60 do { \ 60 do { \
@@ -65,18 +65,18 @@
65 (buf)->data += size; \ 65 (buf)->data += size; \
66 } while (0) 66 } while (0)
67 67
68#define __WSM_PUT(buf, val, type, cvt) \ 68#define __WSM_PUT(buf, val, type, type2, cvt) \
69 do { \ 69 do { \
70 if ((buf)->data + sizeof(type) > (buf)->end) \ 70 if ((buf)->data + sizeof(type) > (buf)->end) \
71 if (wsm_buf_reserve((buf), sizeof(type))) \ 71 if (wsm_buf_reserve((buf), sizeof(type))) \
72 goto nomem; \ 72 goto nomem; \
73 *(type *)(buf)->data = cvt(val); \ 73 *(type2 *)(buf)->data = cvt(val); \
74 (buf)->data += sizeof(type); \ 74 (buf)->data += sizeof(type); \
75 } while (0) 75 } while (0)
76 76
77#define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, (u8)) 77#define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, u8, (u8))
78#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __cpu_to_le16) 78#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __le16, __cpu_to_le16)
79#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __cpu_to_le32) 79#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __le32, __cpu_to_le32)
80 80
81static void wsm_buf_reset(struct wsm_buf *buf); 81static void wsm_buf_reset(struct wsm_buf *buf);
82static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size); 82static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
@@ -931,8 +931,8 @@ static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
931 if (!event) 931 if (!event)
932 return -ENOMEM; 932 return -ENOMEM;
933 933
934 event->evt.id = __le32_to_cpu(WSM_GET32(buf)); 934 event->evt.id = WSM_GET32(buf);
935 event->evt.data = __le32_to_cpu(WSM_GET32(buf)); 935 event->evt.data = WSM_GET32(buf);
936 936
937 pr_debug("[WSM] Event: %d(%d)\n", 937 pr_debug("[WSM] Event: %d(%d)\n",
938 event->evt.id, event->evt.data); 938 event->evt.id, event->evt.data);
@@ -1311,7 +1311,7 @@ int wsm_handle_rx(struct cw1200_common *priv, u16 id,
1311 1311
1312 wsm_buf.begin = (u8 *)&wsm[0]; 1312 wsm_buf.begin = (u8 *)&wsm[0];
1313 wsm_buf.data = (u8 *)&wsm[1]; 1313 wsm_buf.data = (u8 *)&wsm[1];
1314 wsm_buf.end = &wsm_buf.begin[__le32_to_cpu(wsm->len)]; 1314 wsm_buf.end = &wsm_buf.begin[__le16_to_cpu(wsm->len)];
1315 1315
1316 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id, 1316 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
1317 wsm_buf.end - wsm_buf.begin); 1317 wsm_buf.end - wsm_buf.begin);
@@ -1550,7 +1550,7 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
1550 */ 1550 */
1551 pr_debug("[WSM] Convert probe request to scan.\n"); 1551 pr_debug("[WSM] Convert probe request to scan.\n");
1552 wsm_lock_tx_async(priv); 1552 wsm_lock_tx_async(priv);
1553 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id); 1553 priv->pending_frame_id = wsm->packet_id;
1554 if (queue_delayed_work(priv->workqueue, 1554 if (queue_delayed_work(priv->workqueue,
1555 &priv->scan.probe_work, 0) <= 0) 1555 &priv->scan.probe_work, 0) <= 0)
1556 wsm_unlock_tx(priv); 1556 wsm_unlock_tx(priv);
@@ -1558,15 +1558,14 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
1558 break; 1558 break;
1559 case do_drop: 1559 case do_drop:
1560 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl); 1560 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl);
1561 BUG_ON(cw1200_queue_remove(queue, 1561 BUG_ON(cw1200_queue_remove(queue, wsm->packet_id));
1562 __le32_to_cpu(wsm->packet_id)));
1563 handled = true; 1562 handled = true;
1564 break; 1563 break;
1565 case do_wep: 1564 case do_wep:
1566 pr_debug("[WSM] Issue set_default_wep_key.\n"); 1565 pr_debug("[WSM] Issue set_default_wep_key.\n");
1567 wsm_lock_tx_async(priv); 1566 wsm_lock_tx_async(priv);
1568 priv->wep_default_key_id = tx_info->control.hw_key->keyidx; 1567 priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
1569 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id); 1568 priv->pending_frame_id = wsm->packet_id;
1570 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0) 1569 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
1571 wsm_unlock_tx(priv); 1570 wsm_unlock_tx(priv);
1572 handled = true; 1571 handled = true;
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
index 2816171f7a1d..7afc613c3706 100644
--- a/drivers/net/wireless/cw1200/wsm.h
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -806,7 +806,7 @@ struct wsm_tx {
806 struct wsm_hdr hdr; 806 struct wsm_hdr hdr;
807 807
808 /* Packet identifier that meant to be used in completion. */ 808 /* Packet identifier that meant to be used in completion. */
809 __le32 packet_id; 809 u32 packet_id; /* Note this is actually a cookie */
810 810
811 /* WSM_TRANSMIT_RATE_... */ 811 /* WSM_TRANSMIT_RATE_... */
812 u8 max_tx_rate; 812 u8 max_tx_rate;
@@ -825,18 +825,18 @@ struct wsm_tx {
825 u8 flags; 825 u8 flags;
826 826
827 /* Should be 0. */ 827 /* Should be 0. */
828 __le32 reserved; 828 u32 reserved;
829 829
830 /* The elapsed time in TUs, after the initial transmission */ 830 /* The elapsed time in TUs, after the initial transmission */
831 /* of an MSDU, after which further attempts to transmit */ 831 /* of an MSDU, after which further attempts to transmit */
832 /* the MSDU shall be terminated. Overrides the global */ 832 /* the MSDU shall be terminated. Overrides the global */
833 /* dot11MaxTransmitMsduLifeTime setting [optional] */ 833 /* dot11MaxTransmitMsduLifeTime setting [optional] */
834 /* Device will set the default value if this is 0. */ 834 /* Device will set the default value if this is 0. */
835 __le32 expire_time; 835 u32 expire_time;
836 836
837 /* WSM_HT_TX_... */ 837 /* WSM_HT_TX_... */
838 __le32 ht_tx_parameters; 838 __le32 ht_tx_parameters;
839}; 839} __packed;
840 840
841/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */ 841/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */
842#define WSM_TX_EXTRA_HEADROOM (28) 842#define WSM_TX_EXTRA_HEADROOM (28)
@@ -846,10 +846,10 @@ struct wsm_tx {
846 846
847struct wsm_rx { 847struct wsm_rx {
848 /* WSM_STATUS_... */ 848 /* WSM_STATUS_... */
849 __le32 status; 849 u32 status;
850 850
851 /* Specifies the channel of the received packet. */ 851 /* Specifies the channel of the received packet. */
852 __le16 channel_number; 852 u16 channel_number;
853 853
854 /* WSM_TRANSMIT_RATE_... */ 854 /* WSM_TRANSMIT_RATE_... */
855 u8 rx_rate; 855 u8 rx_rate;
@@ -859,11 +859,8 @@ struct wsm_rx {
859 u8 rcpi_rssi; 859 u8 rcpi_rssi;
860 860
861 /* WSM_RX_STATUS_... */ 861 /* WSM_RX_STATUS_... */
862 __le32 flags; 862 u32 flags;
863 863};
864 /* Payload */
865 u8 data[0];
866} __packed;
867 864
868/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */ 865/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */
869#define WSM_RX_EXTRA_HEADROOM (16) 866#define WSM_RX_EXTRA_HEADROOM (16)
@@ -1119,22 +1116,22 @@ int wsm_set_tx_queue_params(struct cw1200_common *priv,
1119#define WSM_EDCA_PARAMS_RESP_ID 0x0413 1116#define WSM_EDCA_PARAMS_RESP_ID 0x0413
1120struct wsm_edca_queue_params { 1117struct wsm_edca_queue_params {
1121 /* CWmin (in slots) for the access class. */ 1118 /* CWmin (in slots) for the access class. */
1122 __le16 cwmin; 1119 u16 cwmin;
1123 1120
1124 /* CWmax (in slots) for the access class. */ 1121 /* CWmax (in slots) for the access class. */
1125 __le16 cwmax; 1122 u16 cwmax;
1126 1123
1127 /* AIFS (in slots) for the access class. */ 1124 /* AIFS (in slots) for the access class. */
1128 __le16 aifns; 1125 u16 aifns;
1129 1126
1130 /* TX OP Limit (in microseconds) for the access class. */ 1127 /* TX OP Limit (in microseconds) for the access class. */
1131 __le16 txop_limit; 1128 u16 txop_limit;
1132 1129
1133 /* dot11MaxReceiveLifetime to be used for the specified */ 1130 /* dot11MaxReceiveLifetime to be used for the specified */
1134 /* the access class. Overrides the global */ 1131 /* the access class. Overrides the global */
1135 /* dot11MaxReceiveLifetime value */ 1132 /* dot11MaxReceiveLifetime value */
1136 __le32 max_rx_lifetime; 1133 u32 max_rx_lifetime;
1137} __packed; 1134};
1138 1135
1139struct wsm_edca_params { 1136struct wsm_edca_params {
1140 /* NOTE: index is a linux queue id. */ 1137 /* NOTE: index is a linux queue id. */
@@ -1147,12 +1144,12 @@ struct wsm_edca_params {
1147 __uapsd) \ 1144 __uapsd) \
1148 do { \ 1145 do { \
1149 struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \ 1146 struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \
1150 p->cwmin = (__cw_min); \ 1147 p->cwmin = __cw_min; \
1151 p->cwmax = (__cw_max); \ 1148 p->cwmax = __cw_max; \
1152 p->aifns = (__aifs); \ 1149 p->aifns = __aifs; \
1153 p->txop_limit = ((__txop) * TXOP_UNIT); \ 1150 p->txop_limit = ((__txop) * TXOP_UNIT); \
1154 p->max_rx_lifetime = (__lifetime); \ 1151 p->max_rx_lifetime = __lifetime; \
1155 (__edca)->uapsd_enable[__queue] = (__uapsd); \ 1152 (__edca)->uapsd_enable[__queue] = (__uapsd); \
1156 } while (0) 1153 } while (0)
1157 1154
1158int wsm_set_edca_params(struct cw1200_common *priv, 1155int wsm_set_edca_params(struct cw1200_common *priv,
@@ -1475,7 +1472,7 @@ static inline int wsm_set_template_frame(struct cw1200_common *priv,
1475 u8 *p = skb_push(arg->skb, 4); 1472 u8 *p = skb_push(arg->skb, 4);
1476 p[0] = arg->frame_type; 1473 p[0] = arg->frame_type;
1477 p[1] = arg->rate; 1474 p[1] = arg->rate;
1478 ((u16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4); 1475 ((__le16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4);
1479 ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len); 1476 ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len);
1480 skb_pull(arg->skb, 4); 1477 skb_pull(arg->skb, 4);
1481 return ret; 1478 return ret;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index d96257b79a84..312fa0e42e6f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -3548,6 +3548,7 @@ static int ipw_load(struct ipw_priv *priv)
3548 ipw_rx_queue_reset(priv, priv->rxq); 3548 ipw_rx_queue_reset(priv, priv->rxq);
3549 if (!priv->rxq) { 3549 if (!priv->rxq) {
3550 IPW_ERROR("Unable to initialize Rx queue\n"); 3550 IPW_ERROR("Unable to initialize Rx queue\n");
3551 rc = -ENOMEM;
3551 goto error; 3552 goto error;
3552 } 3553 }
3553 3554
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 95a1ca1e895c..9ffe65931b29 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -1195,7 +1195,7 @@ static int libipw_parse_info_param(struct libipw_info_element
1195#ifdef CONFIG_LIBIPW_DEBUG 1195#ifdef CONFIG_LIBIPW_DEBUG
1196 p += snprintf(p, sizeof(rates_str) - 1196 p += snprintf(p, sizeof(rates_str) -
1197 (p - rates_str), "%02X ", 1197 (p - rates_str), "%02X ",
1198 network->rates[i]); 1198 network->rates_ex[i]);
1199#endif 1199#endif
1200 if (libipw_is_ofdm_rate 1200 if (libipw_is_ofdm_rate
1201 (info_element->data[i])) { 1201 (info_element->data[i])) {
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 56c2040a955b..cbaa5c2c410f 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -128,16 +128,6 @@ config IWLWIFI_DEVICE_TRACING
128 occur. 128 occur.
129endmenu 129endmenu
130 130
131config IWLWIFI_DEVICE_TESTMODE
132 def_bool y
133 depends on IWLWIFI
134 depends on NL80211_TESTMODE
135 help
136 This option enables the testmode support for iwlwifi device through
137 NL80211_TESTMODE. This provide the capabilities of enable user space
138 validation applications to interacts with the device through the
139 generic netlink message via NL80211_TESTMODE channel.
140
141config IWLWIFI_P2P 131config IWLWIFI_P2P
142 def_bool y 132 def_bool y
143 bool "iwlwifi experimental P2P support" 133 bool "iwlwifi experimental P2P support"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index f55a758b87f6..1fa64429bcc2 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -13,7 +13,6 @@ iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o
13iwlwifi-objs += $(iwlwifi-m) 13iwlwifi-objs += $(iwlwifi-m)
14 14
15iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 15iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
16iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
17 16
18ccflags-y += -D__CHECK_ENDIAN__ -I$(src) 17ccflags-y += -D__CHECK_ENDIAN__ -I$(src)
19 18
diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile
index 5ff76b204141..dce7ab2e0c4b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/dvm/Makefile
@@ -8,6 +8,5 @@ iwldvm-objs += scan.o led.o
8iwldvm-objs += rxon.o devices.o 8iwldvm-objs += rxon.o devices.o
9 9
10iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 10iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
11iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o
12 11
13ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ 12ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index de2c9514bef6..18355110deff 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -405,43 +405,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
405 405
406extern int iwl_alive_start(struct iwl_priv *priv); 406extern int iwl_alive_start(struct iwl_priv *priv);
407 407
408/* testmode support */
409#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
410
411extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data,
412 int len);
413extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw,
414 struct sk_buff *skb,
415 struct netlink_callback *cb,
416 void *data, int len);
417extern void iwl_testmode_init(struct iwl_priv *priv);
418extern void iwl_testmode_free(struct iwl_priv *priv);
419
420#else
421
422static inline
423int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
424{
425 return -ENOSYS;
426}
427
428static inline
429int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
430 struct netlink_callback *cb,
431 void *data, int len)
432{
433 return -ENOSYS;
434}
435
436static inline void iwl_testmode_init(struct iwl_priv *priv)
437{
438}
439
440static inline void iwl_testmode_free(struct iwl_priv *priv)
441{
442}
443#endif
444
445#ifdef CONFIG_IWLWIFI_DEBUG 408#ifdef CONFIG_IWLWIFI_DEBUG
446void iwl_print_rx_config_cmd(struct iwl_priv *priv, 409void iwl_print_rx_config_cmd(struct iwl_priv *priv,
447 enum iwl_rxon_context_id ctxid); 410 enum iwl_rxon_context_id ctxid);
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 5cd87f949266..60a4e0d15715 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -52,8 +52,6 @@
52#include "rs.h" 52#include "rs.h"
53#include "tt.h" 53#include "tt.h"
54 54
55#include "iwl-test.h"
56
57/* CT-KILL constants */ 55/* CT-KILL constants */
58#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ 56#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */
59#define CT_KILL_THRESHOLD 114 /* in Celsius */ 57#define CT_KILL_THRESHOLD 114 /* in Celsius */
@@ -691,10 +689,6 @@ struct iwl_priv {
691 struct iwl_spectrum_notification measure_report; 689 struct iwl_spectrum_notification measure_report;
692 u8 measurement_status; 690 u8 measurement_status;
693 691
694#define IWL_OWNERSHIP_DRIVER 0
695#define IWL_OWNERSHIP_TM 1
696 u8 ucode_owner;
697
698 /* ucode beacon time */ 692 /* ucode beacon time */
699 u32 ucode_beacon_time; 693 u32 ucode_beacon_time;
700 int missed_beacon_threshold; 694 int missed_beacon_threshold;
@@ -889,7 +883,7 @@ struct iwl_priv {
889#endif /* CONFIG_IWLWIFI_DEBUGFS */ 883#endif /* CONFIG_IWLWIFI_DEBUGFS */
890 884
891 struct iwl_nvm_data *nvm_data; 885 struct iwl_nvm_data *nvm_data;
892 /* eeprom blob for debugfs/testmode */ 886 /* eeprom blob for debugfs */
893 u8 *eeprom_blob; 887 u8 *eeprom_blob;
894 size_t eeprom_blob_size; 888 size_t eeprom_blob_size;
895 889
@@ -905,11 +899,6 @@ struct iwl_priv {
905 unsigned long blink_on, blink_off; 899 unsigned long blink_on, blink_off;
906 bool led_registered; 900 bool led_registered;
907 901
908#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
909 struct iwl_test tst;
910 u32 tm_fixed_rate;
911#endif
912
913 /* WoWLAN GTK rekey data */ 902 /* WoWLAN GTK rekey data */
914 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; 903 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
915 __le64 replay_ctr; 904 __le64 replay_ctr;
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 9879550a0fea..3d5bdc4217a8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -1288,12 +1288,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1288 if (!(cmd->flags & CMD_ASYNC)) 1288 if (!(cmd->flags & CMD_ASYNC))
1289 lockdep_assert_held(&priv->mutex); 1289 lockdep_assert_held(&priv->mutex);
1290 1290
1291 if (priv->ucode_owner == IWL_OWNERSHIP_TM &&
1292 !(cmd->flags & CMD_ON_DEMAND)) {
1293 IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n");
1294 return -EIO;
1295 }
1296
1297 return iwl_trans_send_cmd(priv->trans, cmd); 1291 return iwl_trans_send_cmd(priv->trans, cmd);
1298} 1292}
1299 1293
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index eef64bb854f7..822f1a00efbb 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1766,8 +1766,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
1766 .remain_on_channel = iwlagn_mac_remain_on_channel, 1766 .remain_on_channel = iwlagn_mac_remain_on_channel,
1767 .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, 1767 .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel,
1768 .rssi_callback = iwlagn_mac_rssi_callback, 1768 .rssi_callback = iwlagn_mac_rssi_callback,
1769 CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd)
1770 CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump)
1771 .set_tim = iwlagn_mac_set_tim, 1769 .set_tim = iwlagn_mac_set_tim,
1772}; 1770};
1773 1771
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7aa9c8dc33ef..3952ddf2ddb2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1105,8 +1105,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
1105 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 1105 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
1106 priv->agg_tids_count = 0; 1106 priv->agg_tids_count = 0;
1107 1107
1108 priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
1109
1110 priv->rx_statistics_jiffies = jiffies; 1108 priv->rx_statistics_jiffies = jiffies;
1111 1109
1112 /* Choose which receivers/antennas to use */ 1110 /* Choose which receivers/antennas to use */
@@ -1172,12 +1170,6 @@ static void iwl_option_config(struct iwl_priv *priv)
1172 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n"); 1170 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n");
1173#endif 1171#endif
1174 1172
1175#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1176 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n");
1177#else
1178 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n");
1179#endif
1180
1181#ifdef CONFIG_IWLWIFI_P2P 1173#ifdef CONFIG_IWLWIFI_P2P
1182 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n"); 1174 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n");
1183#else 1175#else
@@ -1355,8 +1347,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1355 IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? 1347 IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
1356 true : false; 1348 true : false;
1357 1349
1358 /* enable/disable bt channel inhibition */ 1350 /* bt channel inhibition enabled*/
1359 priv->bt_ch_announce = iwlwifi_mod_params.bt_ch_announce; 1351 priv->bt_ch_announce = true;
1360 IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n", 1352 IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
1361 (priv->bt_ch_announce) ? "On" : "Off"); 1353 (priv->bt_ch_announce) ? "On" : "Off");
1362 1354
@@ -1451,7 +1443,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1451 ********************/ 1443 ********************/
1452 iwl_setup_deferred_work(priv); 1444 iwl_setup_deferred_work(priv);
1453 iwl_setup_rx_handlers(priv); 1445 iwl_setup_rx_handlers(priv);
1454 iwl_testmode_init(priv);
1455 1446
1456 iwl_power_initialize(priv); 1447 iwl_power_initialize(priv);
1457 iwl_tt_initialize(priv); 1448 iwl_tt_initialize(priv);
@@ -1488,7 +1479,6 @@ out_mac80211_unregister:
1488 iwlagn_mac_unregister(priv); 1479 iwlagn_mac_unregister(priv);
1489out_destroy_workqueue: 1480out_destroy_workqueue:
1490 iwl_tt_exit(priv); 1481 iwl_tt_exit(priv);
1491 iwl_testmode_free(priv);
1492 iwl_cancel_deferred_work(priv); 1482 iwl_cancel_deferred_work(priv);
1493 destroy_workqueue(priv->workqueue); 1483 destroy_workqueue(priv->workqueue);
1494 priv->workqueue = NULL; 1484 priv->workqueue = NULL;
@@ -1510,7 +1500,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1510 1500
1511 IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); 1501 IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
1512 1502
1513 iwl_testmode_free(priv);
1514 iwlagn_mac_unregister(priv); 1503 iwlagn_mac_unregister(priv);
1515 1504
1516 iwl_tt_exit(priv); 1505 iwl_tt_exit(priv);
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index 8fe76dc4f373..1b693944123b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -351,12 +351,6 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
351 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 351 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
352 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 352 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
353 353
354#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
355 /* testmode has higher priority to overwirte the fixed rate */
356 if (priv->tm_fixed_rate)
357 lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
358#endif
359
360 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", 354 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
361 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); 355 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
362 356
@@ -419,23 +413,18 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
419 413
420 load = rs_tl_get_load(lq_data, tid); 414 load = rs_tl_get_load(lq_data, tid);
421 415
422 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { 416 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
423 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", 417 sta->addr, tid);
424 sta->addr, tid); 418 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
425 ret = ieee80211_start_tx_ba_session(sta, tid, 5000); 419 if (ret == -EAGAIN) {
426 if (ret == -EAGAIN) { 420 /*
427 /* 421 * driver and mac80211 is out of sync
428 * driver and mac80211 is out of sync 422 * this might be cause by reloading firmware
429 * this might be cause by reloading firmware 423 * stop the tx ba session here
430 * stop the tx ba session here 424 */
431 */ 425 IWL_ERR(priv, "Fail start Tx agg on tid: %d\n",
432 IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", 426 tid);
433 tid); 427 ieee80211_stop_tx_ba_session(sta, tid);
434 ieee80211_stop_tx_ba_session(sta, tid);
435 }
436 } else {
437 IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d "
438 "because load = %u\n", tid, load);
439 } 428 }
440 return ret; 429 return ret;
441} 430}
@@ -1083,11 +1072,6 @@ done:
1083 if (sta && sta->supp_rates[sband->band]) 1072 if (sta && sta->supp_rates[sband->band])
1084 rs_rate_scale_perform(priv, skb, sta, lq_sta); 1073 rs_rate_scale_perform(priv, skb, sta, lq_sta);
1085 1074
1086#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_TESTMODE)
1087 if ((priv->tm_fixed_rate) &&
1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
1089 rs_program_fix_rate(priv, lq_sta);
1090#endif
1091 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist) 1075 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist)
1092 rs_bt_update_lq(priv, ctx, lq_sta); 1076 rs_bt_update_lq(priv, ctx, lq_sta);
1093} 1077}
@@ -2913,9 +2897,6 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2913 if (sband->band == IEEE80211_BAND_5GHZ) 2897 if (sband->band == IEEE80211_BAND_5GHZ)
2914 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2898 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2915 lq_sta->is_agg = 0; 2899 lq_sta->is_agg = 0;
2916#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
2917 priv->tm_fixed_rate = 0;
2918#endif
2919#ifdef CONFIG_MAC80211_DEBUGFS 2900#ifdef CONFIG_MAC80211_DEBUGFS
2920 lq_sta->dbg_fixed_rate = 0; 2901 lq_sta->dbg_fixed_rate = 0;
2921#endif 2902#endif
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index 2f3fd160ab44..d71776dd1e6a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -335,8 +335,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
335 if (msecs < 99) 335 if (msecs < 99)
336 return; 336 return;
337 337
338 if (iwlwifi_mod_params.plcp_check && 338 if (!iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
339 !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
340 iwl_force_rf_reset(priv, false); 339 iwl_force_rf_reset(priv, false);
341} 340}
342 341
@@ -1120,32 +1119,17 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
1120 */ 1119 */
1121 iwl_notification_wait_notify(&priv->notif_wait, pkt); 1120 iwl_notification_wait_notify(&priv->notif_wait, pkt);
1122 1121
1123#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 1122 /* Based on type of command response or notification,
1124 /* 1123 * handle those that need handling via function in
1125 * RX data may be forwarded to userspace in one 1124 * rx_handlers table. See iwl_setup_rx_handlers() */
1126 * of two cases: the user owns the fw through testmode or when 1125 if (priv->rx_handlers[pkt->hdr.cmd]) {
1127 * the user requested to monitor the rx w/o affecting the regular flow. 1126 priv->rx_handlers_stats[pkt->hdr.cmd]++;
1128 * In these cases the iwl_test object will handle forwarding the rx 1127 err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
1129 * data to user space. 1128 } else {
1130 * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow 1129 /* No handling needed */
1131 * continues. 1130 IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
1132 */ 1131 iwl_dvm_get_cmd_string(pkt->hdr.cmd),
1133 iwl_test_rx(&priv->tst, rxb); 1132 pkt->hdr.cmd);
1134#endif
1135
1136 if (priv->ucode_owner != IWL_OWNERSHIP_TM) {
1137 /* Based on type of command response or notification,
1138 * handle those that need handling via function in
1139 * rx_handlers table. See iwl_setup_rx_handlers() */
1140 if (priv->rx_handlers[pkt->hdr.cmd]) {
1141 priv->rx_handlers_stats[pkt->hdr.cmd]++;
1142 err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
1143 } else {
1144 /* No handling needed */
1145 IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
1146 iwl_dvm_get_cmd_string(pkt->hdr.cmd),
1147 pkt->hdr.cmd);
1148 }
1149 } 1133 }
1150 return err; 1134 return err;
1151} 1135}
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c
deleted file mode 100644
index b89b9d9b9969..000000000000
--- a/drivers/net/wireless/iwlwifi/dvm/testmode.c
+++ /dev/null
@@ -1,471 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/init.h>
65#include <linux/kernel.h>
66#include <linux/module.h>
67#include <linux/dma-mapping.h>
68#include <net/net_namespace.h>
69#include <linux/netdevice.h>
70#include <net/cfg80211.h>
71#include <net/mac80211.h>
72#include <net/netlink.h>
73
74#include "iwl-debug.h"
75#include "iwl-trans.h"
76#include "dev.h"
77#include "agn.h"
78#include "iwl-test.h"
79#include "iwl-testmode.h"
80
81static int iwl_testmode_send_cmd(struct iwl_op_mode *op_mode,
82 struct iwl_host_cmd *cmd)
83{
84 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
85 return iwl_dvm_send_cmd(priv, cmd);
86}
87
88static bool iwl_testmode_valid_hw_addr(u32 addr)
89{
90 if (iwlagn_hw_valid_rtc_data_addr(addr))
91 return true;
92
93 if (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
94 addr < IWLAGN_RTC_INST_UPPER_BOUND)
95 return true;
96
97 return false;
98}
99
100static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode)
101{
102 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
103 return priv->fw->ucode_ver;
104}
105
106static struct sk_buff*
107iwl_testmode_alloc_reply(struct iwl_op_mode *op_mode, int len)
108{
109 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
110 return cfg80211_testmode_alloc_reply_skb(priv->hw->wiphy, len);
111}
112
113static int iwl_testmode_reply(struct iwl_op_mode *op_mode, struct sk_buff *skb)
114{
115 return cfg80211_testmode_reply(skb);
116}
117
118static struct sk_buff *iwl_testmode_alloc_event(struct iwl_op_mode *op_mode,
119 int len)
120{
121 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
122 return cfg80211_testmode_alloc_event_skb(priv->hw->wiphy, len,
123 GFP_ATOMIC);
124}
125
126static void iwl_testmode_event(struct iwl_op_mode *op_mode, struct sk_buff *skb)
127{
128 return cfg80211_testmode_event(skb, GFP_ATOMIC);
129}
130
131static struct iwl_test_ops tst_ops = {
132 .send_cmd = iwl_testmode_send_cmd,
133 .valid_hw_addr = iwl_testmode_valid_hw_addr,
134 .get_fw_ver = iwl_testmode_get_fw_ver,
135 .alloc_reply = iwl_testmode_alloc_reply,
136 .reply = iwl_testmode_reply,
137 .alloc_event = iwl_testmode_alloc_event,
138 .event = iwl_testmode_event,
139};
140
141void iwl_testmode_init(struct iwl_priv *priv)
142{
143 iwl_test_init(&priv->tst, priv->trans, &tst_ops);
144}
145
146void iwl_testmode_free(struct iwl_priv *priv)
147{
148 iwl_test_free(&priv->tst);
149}
150
151static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
152{
153 struct iwl_notification_wait calib_wait;
154 static const u8 calib_complete[] = {
155 CALIBRATION_COMPLETE_NOTIFICATION
156 };
157 int ret;
158
159 iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
160 calib_complete, ARRAY_SIZE(calib_complete),
161 NULL, NULL);
162 ret = iwl_init_alive_start(priv);
163 if (ret) {
164 IWL_ERR(priv, "Fail init calibration: %d\n", ret);
165 goto cfg_init_calib_error;
166 }
167
168 ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ);
169 if (ret)
170 IWL_ERR(priv, "Error detecting"
171 " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
172 return ret;
173
174cfg_init_calib_error:
175 iwl_remove_notification(&priv->notif_wait, &calib_wait);
176 return ret;
177}
178
179/*
180 * This function handles the user application commands for driver.
181 *
182 * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
183 * handlers respectively.
184 *
185 * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
186 * value of the actual command execution is replied to the user application.
187 *
188 * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
189 * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
190 * IWL_TM_CMD_DEV2APP_SYNC_RSP.
191 *
192 * @hw: ieee80211_hw object that represents the device
193 * @tb: gnl message fields from the user space
194 */
195static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
196{
197 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
198 struct iwl_trans *trans = priv->trans;
199 struct sk_buff *skb;
200 unsigned char *rsp_data_ptr = NULL;
201 int status = 0, rsp_data_len = 0;
202 u32 inst_size = 0, data_size = 0;
203 const struct fw_img *img;
204
205 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
206 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
207 rsp_data_ptr = (unsigned char *)priv->cfg->name;
208 rsp_data_len = strlen(priv->cfg->name);
209 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
210 rsp_data_len + 20);
211 if (!skb) {
212 IWL_ERR(priv, "Memory allocation fail\n");
213 return -ENOMEM;
214 }
215 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
216 IWL_TM_CMD_DEV2APP_SYNC_RSP) ||
217 nla_put(skb, IWL_TM_ATTR_SYNC_RSP,
218 rsp_data_len, rsp_data_ptr))
219 goto nla_put_failure;
220 status = cfg80211_testmode_reply(skb);
221 if (status < 0)
222 IWL_ERR(priv, "Error sending msg : %d\n", status);
223 break;
224
225 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
226 status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
227 if (status)
228 IWL_ERR(priv, "Error loading init ucode: %d\n", status);
229 break;
230
231 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
232 iwl_testmode_cfg_init_calib(priv);
233 priv->ucode_loaded = false;
234 iwl_trans_stop_device(trans);
235 break;
236
237 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
238 status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);
239 if (status) {
240 IWL_ERR(priv,
241 "Error loading runtime ucode: %d\n", status);
242 break;
243 }
244 status = iwl_alive_start(priv);
245 if (status)
246 IWL_ERR(priv,
247 "Error starting the device: %d\n", status);
248 break;
249
250 case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
251 iwl_scan_cancel_timeout(priv, 200);
252 priv->ucode_loaded = false;
253 iwl_trans_stop_device(trans);
254 status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
255 if (status) {
256 IWL_ERR(priv,
257 "Error loading WOWLAN ucode: %d\n", status);
258 break;
259 }
260 status = iwl_alive_start(priv);
261 if (status)
262 IWL_ERR(priv,
263 "Error starting the device: %d\n", status);
264 break;
265
266 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
267 if (priv->eeprom_blob) {
268 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
269 priv->eeprom_blob_size + 20);
270 if (!skb) {
271 IWL_ERR(priv, "Memory allocation fail\n");
272 return -ENOMEM;
273 }
274 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
275 IWL_TM_CMD_DEV2APP_EEPROM_RSP) ||
276 nla_put(skb, IWL_TM_ATTR_EEPROM,
277 priv->eeprom_blob_size,
278 priv->eeprom_blob))
279 goto nla_put_failure;
280 status = cfg80211_testmode_reply(skb);
281 if (status < 0)
282 IWL_ERR(priv, "Error sending msg : %d\n",
283 status);
284 } else
285 return -ENODATA;
286 break;
287
288 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
289 if (!tb[IWL_TM_ATTR_FIXRATE]) {
290 IWL_ERR(priv, "Missing fixrate setting\n");
291 return -ENOMSG;
292 }
293 priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
294 break;
295
296 case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
297 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
298 if (!skb) {
299 IWL_ERR(priv, "Memory allocation fail\n");
300 return -ENOMEM;
301 }
302 if (!priv->ucode_loaded) {
303 IWL_ERR(priv, "No uCode has not been loaded\n");
304 return -EINVAL;
305 } else {
306 img = &priv->fw->img[priv->cur_ucode];
307 inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
308 data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
309 }
310 if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) ||
311 nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) ||
312 nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size))
313 goto nla_put_failure;
314 status = cfg80211_testmode_reply(skb);
315 if (status < 0)
316 IWL_ERR(priv, "Error sending msg : %d\n", status);
317 break;
318
319 default:
320 IWL_ERR(priv, "Unknown testmode driver command ID\n");
321 return -ENOSYS;
322 }
323 return status;
324
325nla_put_failure:
326 kfree_skb(skb);
327 return -EMSGSIZE;
328}
329
330/*
331 * This function handles the user application switch ucode ownership.
332 *
333 * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
334 * decide who the current owner of the uCode
335 *
336 * If the current owner is OWNERSHIP_TM, then the only host command
337 * can deliver to uCode is from testmode, all the other host commands
338 * will dropped.
339 *
340 * default driver is the owner of uCode in normal operational mode
341 *
342 * @hw: ieee80211_hw object that represents the device
343 * @tb: gnl message fields from the user space
344 */
345static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
346{
347 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
348 u8 owner;
349
350 if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
351 IWL_ERR(priv, "Missing ucode owner\n");
352 return -ENOMSG;
353 }
354
355 owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
356 if (owner == IWL_OWNERSHIP_DRIVER) {
357 priv->ucode_owner = owner;
358 iwl_test_enable_notifications(&priv->tst, false);
359 } else if (owner == IWL_OWNERSHIP_TM) {
360 priv->ucode_owner = owner;
361 iwl_test_enable_notifications(&priv->tst, true);
362 } else {
363 IWL_ERR(priv, "Invalid owner\n");
364 return -EINVAL;
365 }
366 return 0;
367}
368
369/* The testmode gnl message handler that takes the gnl message from the
370 * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
371 * invoke the corresponding handlers.
372 *
373 * This function is invoked when there is user space application sending
374 * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
375 * by nl80211.
376 *
377 * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
378 * dispatching it to the corresponding handler.
379 *
380 * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
381 * -ENOSYS is replied to the user application if the command is unknown;
382 * Otherwise, the command is dispatched to the respective handler.
383 *
384 * @hw: ieee80211_hw object that represents the device
385 * @data: pointer to user space message
386 * @len: length in byte of @data
387 */
388int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
389{
390 struct nlattr *tb[IWL_TM_ATTR_MAX];
391 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
392 int result;
393
394 result = iwl_test_parse(&priv->tst, tb, data, len);
395 if (result)
396 return result;
397
398 /* in case multiple accesses to the device happens */
399 mutex_lock(&priv->mutex);
400 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
401 case IWL_TM_CMD_APP2DEV_UCODE:
402 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
403 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
404 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
405 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
406 case IWL_TM_CMD_APP2DEV_END_TRACE:
407 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
408 case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
409 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
410 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
411 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
412 result = iwl_test_handle_cmd(&priv->tst, tb);
413 break;
414
415 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
416 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
417 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
418 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
419 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
420 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
421 case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
422 case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
423 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
424 result = iwl_testmode_driver(hw, tb);
425 break;
426
427 case IWL_TM_CMD_APP2DEV_OWNERSHIP:
428 IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
429 result = iwl_testmode_ownership(hw, tb);
430 break;
431
432 default:
433 IWL_ERR(priv, "Unknown testmode command\n");
434 result = -ENOSYS;
435 break;
436 }
437 mutex_unlock(&priv->mutex);
438
439 if (result)
440 IWL_ERR(priv, "Test cmd failed result=%d\n", result);
441 return result;
442}
443
444int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
445 struct netlink_callback *cb,
446 void *data, int len)
447{
448 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
449 int result;
450 u32 cmd;
451
452 if (cb->args[3]) {
453 /* offset by 1 since commands start at 0 */
454 cmd = cb->args[3] - 1;
455 } else {
456 struct nlattr *tb[IWL_TM_ATTR_MAX];
457
458 result = iwl_test_parse(&priv->tst, tb, data, len);
459 if (result)
460 return result;
461
462 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
463 cb->args[3] = cmd + 1;
464 }
465
466 /* in case multiple accesses to the device happens */
467 mutex_lock(&priv->mutex);
468 result = iwl_test_dump(&priv->tst, cmd, skb, cb);
469 mutex_unlock(&priv->mutex);
470 return result;
471}
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 353a053b4eb1..5ee983faa679 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -162,18 +162,6 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
162 if (ieee80211_is_data(fc)) { 162 if (ieee80211_is_data(fc)) {
163 tx_cmd->initial_rate_index = 0; 163 tx_cmd->initial_rate_index = 0;
164 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; 164 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
165#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
166 if (priv->tm_fixed_rate) {
167 /*
168 * rate overwrite by testmode
169 * we not only send lq command to change rate
170 * we also re-enforce per data pkt base.
171 */
172 tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK;
173 memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate,
174 sizeof(tx_cmd->rate_n_flags));
175 }
176#endif
177 return; 165 return;
178 } else if (ieee80211_is_back_req(fc)) 166 } else if (ieee80211_is_back_req(fc))
179 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; 167 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index d4f3b4864ab1..22b7fa5b971a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -67,16 +67,16 @@
67#include "iwl-agn-hw.h" 67#include "iwl-agn-hw.h"
68 68
69/* Highest firmware API version supported */ 69/* Highest firmware API version supported */
70#define IWL7260_UCODE_API_MAX 6 70#define IWL7260_UCODE_API_MAX 7
71#define IWL3160_UCODE_API_MAX 6 71#define IWL3160_UCODE_API_MAX 7
72 72
73/* Oldest version we won't warn about */ 73/* Oldest version we won't warn about */
74#define IWL7260_UCODE_API_OK 6 74#define IWL7260_UCODE_API_OK 7
75#define IWL3160_UCODE_API_OK 6 75#define IWL3160_UCODE_API_OK 7
76 76
77/* Lowest firmware API version supported */ 77/* Lowest firmware API version supported */
78#define IWL7260_UCODE_API_MIN 6 78#define IWL7260_UCODE_API_MIN 7
79#define IWL3160_UCODE_API_MIN 6 79#define IWL3160_UCODE_API_MIN 7
80 80
81/* NVM versions */ 81/* NVM versions */
82#define IWL7260_NVM_VERSION 0x0a1d 82#define IWL7260_NVM_VERSION 0x0a1d
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 0189b9050f22..83b9ff6ff3ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -222,6 +222,7 @@ struct iwl_cfg {
222 const u32 max_inst_size; 222 const u32 max_inst_size;
223 u8 valid_tx_ant; 223 u8 valid_tx_ant;
224 u8 valid_rx_ant; 224 u8 valid_rx_ant;
225 bool bt_shared_single_ant;
225 u16 nvm_ver; 226 u16 nvm_ver;
226 u16 nvm_calib_ver; 227 u16 nvm_calib_ver;
227 /* params not likely to change within a device family */ 228 /* params not likely to change within a device family */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 2f690e578b5c..d0162d426f88 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1111,11 +1111,8 @@ void iwl_drv_stop(struct iwl_drv *drv)
1111/* shared module parameters */ 1111/* shared module parameters */
1112struct iwl_mod_params iwlwifi_mod_params = { 1112struct iwl_mod_params iwlwifi_mod_params = {
1113 .restart_fw = true, 1113 .restart_fw = true,
1114 .plcp_check = true,
1115 .bt_coex_active = true, 1114 .bt_coex_active = true,
1116 .power_level = IWL_POWER_INDEX_1, 1115 .power_level = IWL_POWER_INDEX_1,
1117 .bt_ch_announce = true,
1118 .auto_agg = true,
1119 .wd_disable = true, 1116 .wd_disable = true,
1120 /* the rest are 0 by default */ 1117 /* the rest are 0 by default */
1121}; 1118};
@@ -1223,14 +1220,6 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
1223MODULE_PARM_DESC(antenna_coupling, 1220MODULE_PARM_DESC(antenna_coupling,
1224 "specify antenna coupling in dB (defualt: 0 dB)"); 1221 "specify antenna coupling in dB (defualt: 0 dB)");
1225 1222
1226module_param_named(bt_ch_inhibition, iwlwifi_mod_params.bt_ch_announce,
1227 bool, S_IRUGO);
1228MODULE_PARM_DESC(bt_ch_inhibition,
1229 "Enable BT channel inhibition (default: enable)");
1230
1231module_param_named(plcp_check, iwlwifi_mod_params.plcp_check, bool, S_IRUGO);
1232MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
1233
1234module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); 1223module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
1235MODULE_PARM_DESC(wd_disable, 1224MODULE_PARM_DESC(wd_disable,
1236 "Disable stuck queue watchdog timer 0=system default, " 1225 "Disable stuck queue watchdog timer 0=system default, "
@@ -1272,8 +1261,3 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
1272 int, S_IRUGO); 1261 int, S_IRUGO);
1273MODULE_PARM_DESC(power_level, 1262MODULE_PARM_DESC(power_level,
1274 "default power save level (range from 1 - 5, default: 1)"); 1263 "default power save level (range from 1 - 5, default: 1)");
1275
1276module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
1277 bool, S_IRUGO);
1278MODULE_PARM_DESC(auto_agg,
1279 "enable agg w/o check traffic load (default: enable)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d4ad505b0a4b..a1f580c0c6c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -93,7 +93,6 @@ enum iwl_power_level {
93 * use IWL_DISABLE_HT_* constants 93 * use IWL_DISABLE_HT_* constants
94 * @amsdu_size_8K: enable 8K amsdu size, default = 0 94 * @amsdu_size_8K: enable 8K amsdu size, default = 0
95 * @restart_fw: restart firmware, default = 1 95 * @restart_fw: restart firmware, default = 1
96 * @plcp_check: enable plcp health check, default = true
97 * @wd_disable: enable stuck queue check, default = 0 96 * @wd_disable: enable stuck queue check, default = 0
98 * @bt_coex_active: enable bt coex, default = true 97 * @bt_coex_active: enable bt coex, default = true
99 * @led_mode: system default, default = 0 98 * @led_mode: system default, default = 0
@@ -101,15 +100,12 @@ enum iwl_power_level {
101 * @power_level: power level, default = 1 100 * @power_level: power level, default = 1
102 * @debug_level: levels are IWL_DL_* 101 * @debug_level: levels are IWL_DL_*
103 * @ant_coupling: antenna coupling in dB, default = 0 102 * @ant_coupling: antenna coupling in dB, default = 0
104 * @bt_ch_announce: BT channel inhibition, default = enable
105 * @auto_agg: enable agg. without check, default = true
106 */ 103 */
107struct iwl_mod_params { 104struct iwl_mod_params {
108 int sw_crypto; 105 int sw_crypto;
109 unsigned int disable_11n; 106 unsigned int disable_11n;
110 int amsdu_size_8K; 107 int amsdu_size_8K;
111 bool restart_fw; 108 bool restart_fw;
112 bool plcp_check;
113 int wd_disable; 109 int wd_disable;
114 bool bt_coex_active; 110 bool bt_coex_active;
115 int led_mode; 111 int led_mode;
@@ -119,8 +115,6 @@ struct iwl_mod_params {
119 u32 debug_level; 115 u32 debug_level;
120#endif 116#endif
121 int ant_coupling; 117 int ant_coupling;
122 bool bt_ch_announce;
123 bool auto_agg;
124 char *nvm_file; 118 char *nvm_file;
125}; 119};
126 120
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c
deleted file mode 100644
index 5cfd55b86ed3..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-test.c
+++ /dev/null
@@ -1,852 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/export.h>
65#include <net/netlink.h>
66
67#include "iwl-drv.h"
68#include "iwl-io.h"
69#include "iwl-fh.h"
70#include "iwl-prph.h"
71#include "iwl-trans.h"
72#include "iwl-test.h"
73#include "iwl-csr.h"
74#include "iwl-testmode.h"
75
76/*
77 * Periphery registers absolute lower bound. This is used in order to
78 * differentiate registery access through HBUS_TARG_PRPH_* and
79 * HBUS_TARG_MEM_* accesses.
80 */
81#define IWL_ABS_PRPH_START (0xA00000)
82
83/*
84 * The TLVs used in the gnl message policy between the kernel module and
85 * user space application. iwl_testmode_gnl_msg_policy is to be carried
86 * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
87 * See iwl-testmode.h
88 */
89static
90struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
91 [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
92
93 [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
94 [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
95
96 [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
97 [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
98 [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
99
100 [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
101 [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
102
103 [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
104
105 [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
106 [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
107 [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
108
109 [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
110
111 [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
112
113 [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
114 [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
115 [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
116
117 [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
118 [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
119 [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
120 [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
121 [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
122
123 [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
124};
125
126static inline void iwl_test_trace_clear(struct iwl_test *tst)
127{
128 memset(&tst->trace, 0, sizeof(struct iwl_test_trace));
129}
130
131static void iwl_test_trace_stop(struct iwl_test *tst)
132{
133 if (!tst->trace.enabled)
134 return;
135
136 if (tst->trace.cpu_addr && tst->trace.dma_addr)
137 dma_free_coherent(tst->trans->dev,
138 tst->trace.tsize,
139 tst->trace.cpu_addr,
140 tst->trace.dma_addr);
141
142 iwl_test_trace_clear(tst);
143}
144
145static inline void iwl_test_mem_clear(struct iwl_test *tst)
146{
147 memset(&tst->mem, 0, sizeof(struct iwl_test_mem));
148}
149
150static inline void iwl_test_mem_stop(struct iwl_test *tst)
151{
152 if (!tst->mem.in_read)
153 return;
154
155 iwl_test_mem_clear(tst);
156}
157
158/*
159 * Initializes the test object
160 * During the lifetime of the test object it is assumed that the transport is
161 * started. The test object should be stopped before the transport is stopped.
162 */
163void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
164 struct iwl_test_ops *ops)
165{
166 tst->trans = trans;
167 tst->ops = ops;
168
169 iwl_test_trace_clear(tst);
170 iwl_test_mem_clear(tst);
171}
172EXPORT_SYMBOL_GPL(iwl_test_init);
173
174/*
175 * Stop the test object
176 */
177void iwl_test_free(struct iwl_test *tst)
178{
179 iwl_test_mem_stop(tst);
180 iwl_test_trace_stop(tst);
181}
182EXPORT_SYMBOL_GPL(iwl_test_free);
183
184static inline int iwl_test_send_cmd(struct iwl_test *tst,
185 struct iwl_host_cmd *cmd)
186{
187 return tst->ops->send_cmd(tst->trans->op_mode, cmd);
188}
189
190static inline bool iwl_test_valid_hw_addr(struct iwl_test *tst, u32 addr)
191{
192 return tst->ops->valid_hw_addr(addr);
193}
194
195static inline u32 iwl_test_fw_ver(struct iwl_test *tst)
196{
197 return tst->ops->get_fw_ver(tst->trans->op_mode);
198}
199
200static inline struct sk_buff*
201iwl_test_alloc_reply(struct iwl_test *tst, int len)
202{
203 return tst->ops->alloc_reply(tst->trans->op_mode, len);
204}
205
206static inline int iwl_test_reply(struct iwl_test *tst, struct sk_buff *skb)
207{
208 return tst->ops->reply(tst->trans->op_mode, skb);
209}
210
211static inline struct sk_buff*
212iwl_test_alloc_event(struct iwl_test *tst, int len)
213{
214 return tst->ops->alloc_event(tst->trans->op_mode, len);
215}
216
217static inline void
218iwl_test_event(struct iwl_test *tst, struct sk_buff *skb)
219{
220 return tst->ops->event(tst->trans->op_mode, skb);
221}
222
223/*
224 * This function handles the user application commands to the fw. The fw
225 * commands are sent in a synchronuous manner. In case that the user requested
226 * to get commands response, it is send to the user.
227 */
228static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
229{
230 struct iwl_host_cmd cmd;
231 struct iwl_rx_packet *pkt;
232 struct sk_buff *skb;
233 void *reply_buf;
234 u32 reply_len;
235 int ret;
236 bool cmd_want_skb;
237
238 memset(&cmd, 0, sizeof(struct iwl_host_cmd));
239
240 if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
241 !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
242 IWL_ERR(tst->trans, "Missing fw command mandatory fields\n");
243 return -ENOMSG;
244 }
245
246 cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
247 cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
248 if (cmd_want_skb)
249 cmd.flags |= CMD_WANT_SKB;
250
251 cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
252 cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
253 cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
254 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
255 IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n",
256 cmd.id, cmd.flags, cmd.len[0]);
257
258 ret = iwl_test_send_cmd(tst, &cmd);
259 if (ret) {
260 IWL_ERR(tst->trans, "Failed to send hcmd\n");
261 return ret;
262 }
263 if (!cmd_want_skb)
264 return ret;
265
266 /* Handling return of SKB to the user */
267 pkt = cmd.resp_pkt;
268 if (!pkt) {
269 IWL_ERR(tst->trans, "HCMD received a null response packet\n");
270 return ret;
271 }
272
273 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
274 skb = iwl_test_alloc_reply(tst, reply_len + 20);
275 reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL);
276 if (!skb || !reply_buf) {
277 kfree_skb(skb);
278 kfree(reply_buf);
279 return -ENOMEM;
280 }
281
282 /* The reply is in a page, that we cannot send to user space. */
283 iwl_free_resp(&cmd);
284
285 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
286 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
287 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf))
288 goto nla_put_failure;
289 return iwl_test_reply(tst, skb);
290
291nla_put_failure:
292 IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n");
293 kfree(reply_buf);
294 kfree_skb(skb);
295 return -ENOMSG;
296}
297
298/*
299 * Handles the user application commands for register access.
300 */
301static int iwl_test_reg(struct iwl_test *tst, struct nlattr **tb)
302{
303 u32 ofs, val32, cmd;
304 u8 val8;
305 struct sk_buff *skb;
306 int status = 0;
307 struct iwl_trans *trans = tst->trans;
308
309 if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
310 IWL_ERR(trans, "Missing reg offset\n");
311 return -ENOMSG;
312 }
313
314 ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
315 IWL_DEBUG_INFO(trans, "test reg access cmd offset=0x%x\n", ofs);
316
317 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
318
319 /*
320 * Allow access only to FH/CSR/HBUS in direct mode.
321 * Since we don't have the upper bounds for the CSR and HBUS segments,
322 * we will use only the upper bound of FH for sanity check.
323 */
324 if (ofs >= FH_MEM_UPPER_BOUND) {
325 IWL_ERR(trans, "offset out of segment (0x0 - 0x%x)\n",
326 FH_MEM_UPPER_BOUND);
327 return -EINVAL;
328 }
329
330 switch (cmd) {
331 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
332 val32 = iwl_read_direct32(tst->trans, ofs);
333 IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32);
334
335 skb = iwl_test_alloc_reply(tst, 20);
336 if (!skb) {
337 IWL_ERR(trans, "Memory allocation fail\n");
338 return -ENOMEM;
339 }
340 if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32))
341 goto nla_put_failure;
342 status = iwl_test_reply(tst, skb);
343 if (status < 0)
344 IWL_ERR(trans, "Error sending msg : %d\n", status);
345 break;
346
347 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
348 if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
349 IWL_ERR(trans, "Missing value to write\n");
350 return -ENOMSG;
351 } else {
352 val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
353 IWL_DEBUG_INFO(trans, "32b write val=0x%x\n", val32);
354 iwl_write_direct32(tst->trans, ofs, val32);
355 }
356 break;
357
358 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
359 if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
360 IWL_ERR(trans, "Missing value to write\n");
361 return -ENOMSG;
362 } else {
363 val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
364 IWL_DEBUG_INFO(trans, "8b write val=0x%x\n", val8);
365 iwl_write8(tst->trans, ofs, val8);
366 }
367 break;
368
369 default:
370 IWL_ERR(trans, "Unknown test register cmd ID\n");
371 return -ENOMSG;
372 }
373
374 return status;
375
376nla_put_failure:
377 kfree_skb(skb);
378 return -EMSGSIZE;
379}
380
381/*
382 * Handles the request to start FW tracing. Allocates of the trace buffer
383 * and sends a reply to user space with the address of the allocated buffer.
384 */
385static int iwl_test_trace_begin(struct iwl_test *tst, struct nlattr **tb)
386{
387 struct sk_buff *skb;
388 int status = 0;
389
390 if (tst->trace.enabled)
391 return -EBUSY;
392
393 if (!tb[IWL_TM_ATTR_TRACE_SIZE])
394 tst->trace.size = TRACE_BUFF_SIZE_DEF;
395 else
396 tst->trace.size =
397 nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
398
399 if (!tst->trace.size)
400 return -EINVAL;
401
402 if (tst->trace.size < TRACE_BUFF_SIZE_MIN ||
403 tst->trace.size > TRACE_BUFF_SIZE_MAX)
404 return -EINVAL;
405
406 tst->trace.tsize = tst->trace.size + TRACE_BUFF_PADD;
407 tst->trace.cpu_addr = dma_alloc_coherent(tst->trans->dev,
408 tst->trace.tsize,
409 &tst->trace.dma_addr,
410 GFP_KERNEL);
411 if (!tst->trace.cpu_addr)
412 return -ENOMEM;
413
414 tst->trace.enabled = true;
415 tst->trace.trace_addr = (u8 *)PTR_ALIGN(tst->trace.cpu_addr, 0x100);
416
417 memset(tst->trace.trace_addr, 0x03B, tst->trace.size);
418
419 skb = iwl_test_alloc_reply(tst, sizeof(tst->trace.dma_addr) + 20);
420 if (!skb) {
421 IWL_ERR(tst->trans, "Memory allocation fail\n");
422 iwl_test_trace_stop(tst);
423 return -ENOMEM;
424 }
425
426 if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR,
427 sizeof(tst->trace.dma_addr),
428 (u64 *)&tst->trace.dma_addr))
429 goto nla_put_failure;
430
431 status = iwl_test_reply(tst, skb);
432 if (status < 0)
433 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
434
435 tst->trace.nchunks = DIV_ROUND_UP(tst->trace.size,
436 DUMP_CHUNK_SIZE);
437
438 return status;
439
440nla_put_failure:
441 kfree_skb(skb);
442 if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
443 IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
444 iwl_test_trace_stop(tst);
445 return -EMSGSIZE;
446}
447
448/*
449 * Handles indirect read from the periphery or the SRAM. The read is performed
450 * to a temporary buffer. The user space application should later issue a dump
451 */
452static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
453{
454 struct iwl_trans *trans = tst->trans;
455 unsigned long flags;
456 int i;
457
458 if (size & 0x3)
459 return -EINVAL;
460
461 tst->mem.size = size;
462 tst->mem.addr = kmalloc(tst->mem.size, GFP_KERNEL);
463 if (tst->mem.addr == NULL)
464 return -ENOMEM;
465
466 /* Hard-coded periphery absolute address */
467 if (IWL_ABS_PRPH_START <= addr &&
468 addr < IWL_ABS_PRPH_START + PRPH_END) {
469 if (!iwl_trans_grab_nic_access(trans, false, &flags)) {
470 return -EIO;
471 }
472 iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
473 addr | (3 << 24));
474 for (i = 0; i < size; i += 4)
475 *(u32 *)(tst->mem.addr + i) =
476 iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
477 iwl_trans_release_nic_access(trans, &flags);
478 } else { /* target memory (SRAM) */
479 iwl_trans_read_mem(trans, addr, tst->mem.addr,
480 tst->mem.size / 4);
481 }
482
483 tst->mem.nchunks =
484 DIV_ROUND_UP(tst->mem.size, DUMP_CHUNK_SIZE);
485 tst->mem.in_read = true;
486 return 0;
487
488}
489
490/*
491 * Handles indirect write to the periphery or SRAM. The is performed to a
492 * temporary buffer.
493 */
494static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
495 u32 size, unsigned char *buf)
496{
497 struct iwl_trans *trans = tst->trans;
498 u32 val, i;
499 unsigned long flags;
500
501 if (IWL_ABS_PRPH_START <= addr &&
502 addr < IWL_ABS_PRPH_START + PRPH_END) {
503 /* Periphery writes can be 1-3 bytes long, or DWORDs */
504 if (size < 4) {
505 memcpy(&val, buf, size);
506 if (!iwl_trans_grab_nic_access(trans, false, &flags))
507 return -EIO;
508 iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
509 (addr & 0x0000FFFF) |
510 ((size - 1) << 24));
511 iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
512 iwl_trans_release_nic_access(trans, &flags);
513 } else {
514 if (size % 4)
515 return -EINVAL;
516 for (i = 0; i < size; i += 4)
517 iwl_write_prph(trans, addr+i,
518 *(u32 *)(buf+i));
519 }
520 } else if (iwl_test_valid_hw_addr(tst, addr)) {
521 iwl_trans_write_mem(trans, addr, buf, size / 4);
522 } else {
523 return -EINVAL;
524 }
525 return 0;
526}
527
528/*
529 * Handles the user application commands for indirect read/write
530 * to/from the periphery or the SRAM.
531 */
532static int iwl_test_indirect_mem(struct iwl_test *tst, struct nlattr **tb)
533{
534 u32 addr, size, cmd;
535 unsigned char *buf;
536
537 /* Both read and write should be blocked, for atomicity */
538 if (tst->mem.in_read)
539 return -EBUSY;
540
541 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
542 if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
543 IWL_ERR(tst->trans, "Error finding memory offset address\n");
544 return -ENOMSG;
545 }
546 addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
547 if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
548 IWL_ERR(tst->trans, "Error finding size for memory reading\n");
549 return -ENOMSG;
550 }
551 size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
552
553 if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) {
554 return iwl_test_indirect_read(tst, addr, size);
555 } else {
556 if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
557 return -EINVAL;
558 buf = (unsigned char *)nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
559 return iwl_test_indirect_write(tst, addr, size, buf);
560 }
561}
562
563/*
564 * Enable notifications to user space
565 */
566static int iwl_test_notifications(struct iwl_test *tst,
567 struct nlattr **tb)
568{
569 tst->notify = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
570 return 0;
571}
572
573/*
574 * Handles the request to get the device id
575 */
576static int iwl_test_get_dev_id(struct iwl_test *tst, struct nlattr **tb)
577{
578 u32 devid = tst->trans->hw_id;
579 struct sk_buff *skb;
580 int status;
581
582 IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid);
583
584 skb = iwl_test_alloc_reply(tst, 20);
585 if (!skb) {
586 IWL_ERR(tst->trans, "Memory allocation fail\n");
587 return -ENOMEM;
588 }
589
590 if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid))
591 goto nla_put_failure;
592 status = iwl_test_reply(tst, skb);
593 if (status < 0)
594 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
595
596 return 0;
597
598nla_put_failure:
599 kfree_skb(skb);
600 return -EMSGSIZE;
601}
602
603/*
604 * Handles the request to get the FW version
605 */
606static int iwl_test_get_fw_ver(struct iwl_test *tst, struct nlattr **tb)
607{
608 struct sk_buff *skb;
609 int status;
610 u32 ver = iwl_test_fw_ver(tst);
611
612 IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver);
613
614 skb = iwl_test_alloc_reply(tst, 20);
615 if (!skb) {
616 IWL_ERR(tst->trans, "Memory allocation fail\n");
617 return -ENOMEM;
618 }
619
620 if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver))
621 goto nla_put_failure;
622
623 status = iwl_test_reply(tst, skb);
624 if (status < 0)
625 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
626
627 return 0;
628
629nla_put_failure:
630 kfree_skb(skb);
631 return -EMSGSIZE;
632}
633
634/*
635 * Parse the netlink message and validate that the IWL_TM_ATTR_CMD exists
636 */
637int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
638 void *data, int len)
639{
640 int result;
641
642 result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
643 iwl_testmode_gnl_msg_policy);
644 if (result) {
645 IWL_ERR(tst->trans, "Fail parse gnl msg: %d\n", result);
646 return result;
647 }
648
649 /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
650 if (!tb[IWL_TM_ATTR_COMMAND]) {
651 IWL_ERR(tst->trans, "Missing testmode command type\n");
652 return -ENOMSG;
653 }
654 return 0;
655}
656IWL_EXPORT_SYMBOL(iwl_test_parse);
657
658/*
659 * Handle test commands.
660 * Returns 1 for unknown commands (not handled by the test object); negative
661 * value in case of error.
662 */
663int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb)
664{
665 int result;
666
667 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
668 case IWL_TM_CMD_APP2DEV_UCODE:
669 IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n");
670 result = iwl_test_fw_cmd(tst, tb);
671 break;
672
673 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
674 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
675 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
676 IWL_DEBUG_INFO(tst->trans, "test cmd to register\n");
677 result = iwl_test_reg(tst, tb);
678 break;
679
680 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
681 IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n");
682 result = iwl_test_trace_begin(tst, tb);
683 break;
684
685 case IWL_TM_CMD_APP2DEV_END_TRACE:
686 iwl_test_trace_stop(tst);
687 result = 0;
688 break;
689
690 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
691 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
692 IWL_DEBUG_INFO(tst->trans, "test indirect memory cmd\n");
693 result = iwl_test_indirect_mem(tst, tb);
694 break;
695
696 case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
697 IWL_DEBUG_INFO(tst->trans, "test notifications cmd\n");
698 result = iwl_test_notifications(tst, tb);
699 break;
700
701 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
702 IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n");
703 result = iwl_test_get_fw_ver(tst, tb);
704 break;
705
706 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
707 IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n");
708 result = iwl_test_get_dev_id(tst, tb);
709 break;
710
711 default:
712 IWL_DEBUG_INFO(tst->trans, "Unknown test command\n");
713 result = 1;
714 break;
715 }
716 return result;
717}
718IWL_EXPORT_SYMBOL(iwl_test_handle_cmd);
719
720static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb,
721 struct netlink_callback *cb)
722{
723 int idx, length;
724
725 if (!tst->trace.enabled || !tst->trace.trace_addr)
726 return -EFAULT;
727
728 idx = cb->args[4];
729 if (idx >= tst->trace.nchunks)
730 return -ENOENT;
731
732 length = DUMP_CHUNK_SIZE;
733 if (((idx + 1) == tst->trace.nchunks) &&
734 (tst->trace.size % DUMP_CHUNK_SIZE))
735 length = tst->trace.size %
736 DUMP_CHUNK_SIZE;
737
738 if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length,
739 tst->trace.trace_addr + (DUMP_CHUNK_SIZE * idx)))
740 goto nla_put_failure;
741
742 cb->args[4] = ++idx;
743 return 0;
744
745 nla_put_failure:
746 return -ENOBUFS;
747}
748
749static int iwl_test_buffer_dump(struct iwl_test *tst, struct sk_buff *skb,
750 struct netlink_callback *cb)
751{
752 int idx, length;
753
754 if (!tst->mem.in_read)
755 return -EFAULT;
756
757 idx = cb->args[4];
758 if (idx >= tst->mem.nchunks) {
759 iwl_test_mem_stop(tst);
760 return -ENOENT;
761 }
762
763 length = DUMP_CHUNK_SIZE;
764 if (((idx + 1) == tst->mem.nchunks) &&
765 (tst->mem.size % DUMP_CHUNK_SIZE))
766 length = tst->mem.size % DUMP_CHUNK_SIZE;
767
768 if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
769 tst->mem.addr + (DUMP_CHUNK_SIZE * idx)))
770 goto nla_put_failure;
771
772 cb->args[4] = ++idx;
773 return 0;
774
775 nla_put_failure:
776 return -ENOBUFS;
777}
778
779/*
780 * Handle dump commands.
781 * Returns 1 for unknown commands (not handled by the test object); negative
782 * value in case of error.
783 */
784int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
785 struct netlink_callback *cb)
786{
787 int result;
788
789 switch (cmd) {
790 case IWL_TM_CMD_APP2DEV_READ_TRACE:
791 IWL_DEBUG_INFO(tst->trans, "uCode trace cmd\n");
792 result = iwl_test_trace_dump(tst, skb, cb);
793 break;
794
795 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
796 IWL_DEBUG_INFO(tst->trans, "testmode sram dump cmd\n");
797 result = iwl_test_buffer_dump(tst, skb, cb);
798 break;
799
800 default:
801 result = 1;
802 break;
803 }
804 return result;
805}
806IWL_EXPORT_SYMBOL(iwl_test_dump);
807
808/*
809 * Multicast a spontaneous messages from the device to the user space.
810 */
811static void iwl_test_send_rx(struct iwl_test *tst,
812 struct iwl_rx_cmd_buffer *rxb)
813{
814 struct sk_buff *skb;
815 struct iwl_rx_packet *data;
816 int length;
817
818 data = rxb_addr(rxb);
819 length = le32_to_cpu(data->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
820
821 /* the length doesn't include len_n_flags field, so add it manually */
822 length += sizeof(__le32);
823
824 skb = iwl_test_alloc_event(tst, length + 20);
825 if (skb == NULL) {
826 IWL_ERR(tst->trans, "Out of memory for message to user\n");
827 return;
828 }
829
830 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
831 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
832 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data))
833 goto nla_put_failure;
834
835 iwl_test_event(tst, skb);
836 return;
837
838nla_put_failure:
839 kfree_skb(skb);
840 IWL_ERR(tst->trans, "Ouch, overran buffer, check allocation!\n");
841}
842
843/*
844 * Called whenever a Rx frames is recevied from the device. If notifications to
845 * the user space are requested, sends the frames to the user.
846 */
847void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb)
848{
849 if (tst->notify)
850 iwl_test_send_rx(tst, rxb);
851}
852IWL_EXPORT_SYMBOL(iwl_test_rx);
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h
deleted file mode 100644
index 8fbd21704840..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-test.h
+++ /dev/null
@@ -1,161 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __IWL_TEST_H__
65#define __IWL_TEST_H__
66
67#include <linux/types.h>
68#include "iwl-trans.h"
69
70struct iwl_test_trace {
71 u32 size;
72 u32 tsize;
73 u32 nchunks;
74 u8 *cpu_addr;
75 u8 *trace_addr;
76 dma_addr_t dma_addr;
77 bool enabled;
78};
79
80struct iwl_test_mem {
81 u32 size;
82 u32 nchunks;
83 u8 *addr;
84 bool in_read;
85};
86
87/*
88 * struct iwl_test_ops: callback to the op mode
89 *
90 * The structure defines the callbacks that the op_mode should handle,
91 * inorder to handle logic that is out of the scope of iwl_test. The
92 * op_mode must set all the callbacks.
93
94 * @send_cmd: handler that is used by the test object to request the
95 * op_mode to send a command to the fw.
96 *
97 * @valid_hw_addr: handler that is used by the test object to request the
98 * op_mode to check if the given address is a valid address.
99 *
100 * @get_fw_ver: handler used to get the FW version.
101 *
102 * @alloc_reply: handler used by the test object to request the op_mode
103 * to allocate an skb for sending a reply to the user, and initialize
104 * the skb. It is assumed that the test object only fills the required
105 * attributes.
106 *
107 * @reply: handler used by the test object to request the op_mode to reply
108 * to a request. The skb is an skb previously allocated by the the
109 * alloc_reply callback.
110 I
111 * @alloc_event: handler used by the test object to request the op_mode
112 * to allocate an skb for sending an event, and initialize
113 * the skb. It is assumed that the test object only fills the required
114 * attributes.
115 *
116 * @reply: handler used by the test object to request the op_mode to send
117 * an event. The skb is an skb previously allocated by the the
118 * alloc_event callback.
119 */
120struct iwl_test_ops {
121 int (*send_cmd)(struct iwl_op_mode *op_modes,
122 struct iwl_host_cmd *cmd);
123 bool (*valid_hw_addr)(u32 addr);
124 u32 (*get_fw_ver)(struct iwl_op_mode *op_mode);
125
126 struct sk_buff *(*alloc_reply)(struct iwl_op_mode *op_mode, int len);
127 int (*reply)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
128 struct sk_buff* (*alloc_event)(struct iwl_op_mode *op_mode, int len);
129 void (*event)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
130};
131
132struct iwl_test {
133 struct iwl_trans *trans;
134 struct iwl_test_ops *ops;
135 struct iwl_test_trace trace;
136 struct iwl_test_mem mem;
137 bool notify;
138};
139
140void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
141 struct iwl_test_ops *ops);
142
143void iwl_test_free(struct iwl_test *tst);
144
145int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
146 void *data, int len);
147
148int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb);
149
150int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
151 struct netlink_callback *cb);
152
153void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb);
154
155static inline void iwl_test_enable_notifications(struct iwl_test *tst,
156 bool enable)
157{
158 tst->notify = enable;
159}
160
161#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
deleted file mode 100644
index 98f48a9afc98..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ /dev/null
@@ -1,309 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#ifndef __IWL_TESTMODE_H__
64#define __IWL_TESTMODE_H__
65
66#include <linux/types.h>
67
68
69/*
70 * Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
71 * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
72 * The command ID is carried with IWL_TM_ATTR_COMMAND.
73 *
74 * @IWL_TM_CMD_APP2DEV_UCODE:
75 * commands from user application to the uCode,
76 * the actual uCode host command ID is carried with
77 * IWL_TM_ATTR_UCODE_CMD_ID
78 *
79 * @IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
80 * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
81 * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
82 * commands from user applicaiton to access register
83 *
84 * @IWL_TM_CMD_APP2DEV_GET_DEVICENAME: retrieve device name
85 * @IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: load initial uCode image
86 * @IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: perform calibration
87 * @IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: load runtime uCode image
88 * @IWL_TM_CMD_APP2DEV_GET_EEPROM: request EEPROM data
89 * @IWL_TM_CMD_APP2DEV_FIXRATE_REQ: set fix MCS
90 * commands fom user space for pure driver level operations
91 *
92 * @IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
93 * @IWL_TM_CMD_APP2DEV_END_TRACE:
94 * @IWL_TM_CMD_APP2DEV_READ_TRACE:
95 * commands fom user space for uCode trace operations
96 *
97 * @IWL_TM_CMD_DEV2APP_SYNC_RSP:
98 * commands from kernel space to carry the synchronous response
99 * to user application
100 * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT:
101 * commands from kernel space to multicast the spontaneous messages
102 * to user application, or reply of host commands
103 * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
104 * commands from kernel space to carry the eeprom response
105 * to user application
106 *
107 * @IWL_TM_CMD_APP2DEV_OWNERSHIP:
108 * commands from user application to own change the ownership of the uCode
109 * if application has the ownership, the only host command from
110 * testmode will deliver to uCode. Default owner is driver
111 *
112 * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image
113 * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
114 * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
115 * @IWL_TM_CMD_APP2DEV_GET_FW_INFO:
116 * retrieve information of existing loaded uCode image
117 *
118 * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
119 * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
120 * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
121 * Commands to read/write data from periphery or SRAM memory ranges.
122 * Fore reading, a READ command is sent from the userspace and the data
123 * is returned when the user calls a DUMP command.
124 * For writing, only a WRITE command is used.
125 * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
126 * Command to enable/disable notifications (currently RX packets) from the
127 * driver to userspace.
128 */
129enum iwl_tm_cmd_t {
130 IWL_TM_CMD_APP2DEV_UCODE = 1,
131 IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 = 2,
132 IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 = 3,
133 IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8 = 4,
134 IWL_TM_CMD_APP2DEV_GET_DEVICENAME = 5,
135 IWL_TM_CMD_APP2DEV_LOAD_INIT_FW = 6,
136 IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB = 7,
137 IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW = 8,
138 IWL_TM_CMD_APP2DEV_GET_EEPROM = 9,
139 IWL_TM_CMD_APP2DEV_FIXRATE_REQ = 10,
140 IWL_TM_CMD_APP2DEV_BEGIN_TRACE = 11,
141 IWL_TM_CMD_APP2DEV_END_TRACE = 12,
142 IWL_TM_CMD_APP2DEV_READ_TRACE = 13,
143 IWL_TM_CMD_DEV2APP_SYNC_RSP = 14,
144 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT = 15,
145 IWL_TM_CMD_DEV2APP_EEPROM_RSP = 16,
146 IWL_TM_CMD_APP2DEV_OWNERSHIP = 17,
147 RESERVED_18 = 18,
148 RESERVED_19 = 19,
149 RESERVED_20 = 20,
150 RESERVED_21 = 21,
151 IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22,
152 IWL_TM_CMD_APP2DEV_GET_FW_VERSION = 23,
153 IWL_TM_CMD_APP2DEV_GET_DEVICE_ID = 24,
154 IWL_TM_CMD_APP2DEV_GET_FW_INFO = 25,
155 IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26,
156 IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27,
157 IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28,
158 IWL_TM_CMD_APP2DEV_NOTIFICATIONS = 29,
159 IWL_TM_CMD_MAX = 30,
160};
161
162/*
163 * Atrribute filed in testmode command
164 * See enum iwl_tm_cmd_t.
165 *
166 * @IWL_TM_ATTR_NOT_APPLICABLE:
167 * The attribute is not applicable or invalid
168 * @IWL_TM_ATTR_COMMAND:
169 * From user space to kernel space:
170 * the command either destines to ucode, driver, or register;
171 * From kernel space to user space:
172 * the command either carries synchronous response,
173 * or the spontaneous message multicast from the device;
174 *
175 * @IWL_TM_ATTR_UCODE_CMD_ID:
176 * @IWL_TM_ATTR_UCODE_CMD_DATA:
177 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
178 * The mandatory fields are :
179 * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
180 * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
181 * to the ucode
182 *
183 * @IWL_TM_ATTR_REG_OFFSET:
184 * @IWL_TM_ATTR_REG_VALUE8:
185 * @IWL_TM_ATTR_REG_VALUE32:
186 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
187 * The mandatory fields are:
188 * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
189 * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value
190 *
191 * @IWL_TM_ATTR_SYNC_RSP:
192 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
193 * The mandatory fields are:
194 * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
195 * application command
196 *
197 * @IWL_TM_ATTR_UCODE_RX_PKT:
198 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
199 * The mandatory fields are:
200 * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
201 * application
202 *
203 * @IWL_TM_ATTR_EEPROM:
204 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM,
205 * The mandatory fields are:
206 * IWL_TM_ATTR_EEPROM for the data content responging to the user
207 * application
208 *
209 * @IWL_TM_ATTR_TRACE_ADDR:
210 * @IWL_TM_ATTR_TRACE_SIZE:
211 * @IWL_TM_ATTR_TRACE_DUMP:
212 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE,
213 * The mandatory fields are:
214 * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
215 * IWL_TM_ATTR_MEM_TRACE_SIZE for the trace buffer size
216 * IWL_TM_ATTR_MEM_TRACE_DUMP for the trace dump
217 *
218 * @IWL_TM_ATTR_FIXRATE:
219 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
220 * The mandatory fields are:
221 * IWL_TM_ATTR_FIXRATE for the fixed rate
222 *
223 * @IWL_TM_ATTR_UCODE_OWNER:
224 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP,
225 * The mandatory fields are:
226 * IWL_TM_ATTR_UCODE_OWNER for the new owner
227 *
228 * @IWL_TM_ATTR_MEM_ADDR:
229 * @IWL_TM_ATTR_BUFFER_SIZE:
230 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
231 * or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE.
232 * The mandatory fields are:
233 * IWL_TM_ATTR_MEM_ADDR for the address in SRAM/periphery to read/write
234 * IWL_TM_ATTR_BUFFER_SIZE for the buffer size of data to read/write.
235 *
236 * @IWL_TM_ATTR_BUFFER_DUMP:
237 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP,
238 * IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read.
239 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE,
240 * this attribute contains the data to write.
241 *
242 * @IWL_TM_ATTR_FW_VERSION:
243 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION,
244 * IWL_TM_ATTR_FW_VERSION for the uCode version
245 *
246 * @IWL_TM_ATTR_DEVICE_ID:
247 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID,
248 * IWL_TM_ATTR_DEVICE_ID for the device ID information
249 *
250 * @IWL_TM_ATTR_FW_TYPE:
251 * @IWL_TM_ATTR_FW_INST_SIZE:
252 * @IWL_TM_ATTR_FW_DATA_SIZE:
253 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO,
254 * The mandatory fields are:
255 * IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...)
256 * IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section
257 * IWL_TM_ATTR_FW_DATA_SIZE for the size of data section
258 *
259 * @IWL_TM_ATTR_UCODE_CMD_SKB:
260 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag
261 * indicates that the user wants to receive the response of the command
262 * in a reply SKB. If it's not present, the response is not returned.
263 * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS:
264 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this
265 * flag enables (if present) or disables (if not) the forwarding
266 * to userspace.
267 */
268enum iwl_tm_attr_t {
269 IWL_TM_ATTR_NOT_APPLICABLE = 0,
270 IWL_TM_ATTR_COMMAND = 1,
271 IWL_TM_ATTR_UCODE_CMD_ID = 2,
272 IWL_TM_ATTR_UCODE_CMD_DATA = 3,
273 IWL_TM_ATTR_REG_OFFSET = 4,
274 IWL_TM_ATTR_REG_VALUE8 = 5,
275 IWL_TM_ATTR_REG_VALUE32 = 6,
276 IWL_TM_ATTR_SYNC_RSP = 7,
277 IWL_TM_ATTR_UCODE_RX_PKT = 8,
278 IWL_TM_ATTR_EEPROM = 9,
279 IWL_TM_ATTR_TRACE_ADDR = 10,
280 IWL_TM_ATTR_TRACE_SIZE = 11,
281 IWL_TM_ATTR_TRACE_DUMP = 12,
282 IWL_TM_ATTR_FIXRATE = 13,
283 IWL_TM_ATTR_UCODE_OWNER = 14,
284 IWL_TM_ATTR_MEM_ADDR = 15,
285 IWL_TM_ATTR_BUFFER_SIZE = 16,
286 IWL_TM_ATTR_BUFFER_DUMP = 17,
287 IWL_TM_ATTR_FW_VERSION = 18,
288 IWL_TM_ATTR_DEVICE_ID = 19,
289 IWL_TM_ATTR_FW_TYPE = 20,
290 IWL_TM_ATTR_FW_INST_SIZE = 21,
291 IWL_TM_ATTR_FW_DATA_SIZE = 22,
292 IWL_TM_ATTR_UCODE_CMD_SKB = 23,
293 IWL_TM_ATTR_ENABLE_NOTIFICATION = 24,
294 IWL_TM_ATTR_MAX = 25,
295};
296
297/* uCode trace buffer */
298#define TRACE_BUFF_SIZE_MAX 0x200000
299#define TRACE_BUFF_SIZE_MIN 0x20000
300#define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN
301#define TRACE_BUFF_PADD 0x2000
302
303/* Maximum data size of each dump it packet */
304#define DUMP_CHUNK_SIZE (PAGE_SIZE - 1024)
305
306/* Address offset of data segment in SRAM */
307#define SRAM_DATA_SEG_OFFSET 0x800000
308
309#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index be4b2ac3dbbf..8d91422c5982 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -183,14 +183,12 @@ struct iwl_rx_packet {
183 * @CMD_ASYNC: Return right away and don't want for the response 183 * @CMD_ASYNC: Return right away and don't want for the response
184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the 184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
185 * response. The caller needs to call iwl_free_resp when done. 185 * response. The caller needs to call iwl_free_resp when done.
186 * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
187 */ 186 */
188enum CMD_MODE { 187enum CMD_MODE {
189 CMD_SYNC = 0, 188 CMD_SYNC = 0,
190 CMD_ASYNC = BIT(0), 189 CMD_ASYNC = BIT(0),
191 CMD_WANT_SKB = BIT(1), 190 CMD_WANT_SKB = BIT(1),
192 CMD_SEND_IN_RFKILL = BIT(2), 191 CMD_SEND_IN_RFKILL = BIT(2),
193 CMD_ON_DEMAND = BIT(3),
194}; 192};
195 193
196#define DEF_CMD_PAYLOAD_SIZE 320 194#define DEF_CMD_PAYLOAD_SIZE 320
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 9a4d94a1f90d..dbd622a3929c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -202,6 +202,22 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {
202 cpu_to_le32(0x00000000), 202 cpu_to_le32(0x00000000),
203}; 203};
204 204
205/* single shared antenna */
206static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = {
207 cpu_to_le32(0x40000000),
208 cpu_to_le32(0x00000000),
209 cpu_to_le32(0x44000000),
210 cpu_to_le32(0x00000000),
211 cpu_to_le32(0x40000000),
212 cpu_to_le32(0x00000000),
213 cpu_to_le32(0x44000000),
214 cpu_to_le32(0x00000000),
215 cpu_to_le32(0xC0004000),
216 cpu_to_le32(0xF0005000),
217 cpu_to_le32(0xC0004000),
218 cpu_to_le32(0xF0005000),
219};
220
205int iwl_send_bt_init_conf(struct iwl_mvm *mvm) 221int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
206{ 222{
207 struct iwl_bt_coex_cmd cmd = { 223 struct iwl_bt_coex_cmd cmd = {
@@ -225,7 +241,10 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
225 BT_VALID_REDUCED_TX_POWER | 241 BT_VALID_REDUCED_TX_POWER |
226 BT_VALID_LUT); 242 BT_VALID_LUT);
227 243
228 if (is_loose_coex()) 244 if (mvm->cfg->bt_shared_single_ant)
245 memcpy(&cmd.decision_lut, iwl_single_shared_ant_lookup,
246 sizeof(iwl_single_shared_ant_lookup));
247 else if (is_loose_coex())
229 memcpy(&cmd.decision_lut, iwl_loose_lookup, 248 memcpy(&cmd.decision_lut, iwl_loose_lookup,
230 sizeof(iwl_tight_lookup)); 249 sizeof(iwl_tight_lookup));
231 else 250 else
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 8c49db02c9c1..7e5e5c2f9f87 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1026,6 +1026,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1026 if (ret) 1026 if (ret)
1027 goto out; 1027 goto out;
1028 1028
1029#ifdef CONFIG_IWLWIFI_DEBUGFS
1030 if (mvm->d3_wake_sysassert)
1031 d3_cfg_cmd_data.wakeup_flags |=
1032 cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR);
1033#endif
1034
1029 /* must be last -- this switches firmware state */ 1035 /* must be last -- this switches firmware state */
1030 ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); 1036 ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
1031 if (ret) 1037 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index b7643c16201f..e56ed2a84888 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -344,6 +344,13 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: 344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); 345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
346 dbgfs_pm->disable_power_off = val; 346 dbgfs_pm->disable_power_off = val;
347 case MVM_DEBUGFS_PM_LPRX_ENA:
348 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
349 dbgfs_pm->lprx_ena = val;
350 break;
351 case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
352 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
353 dbgfs_pm->lprx_rssi_threshold = val;
347 break; 354 break;
348 } 355 }
349} 356}
@@ -387,6 +394,17 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
387 if (sscanf(buf + 18, "%d", &val) != 1) 394 if (sscanf(buf + 18, "%d", &val) != 1)
388 return -EINVAL; 395 return -EINVAL;
389 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; 396 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
397 } else if (!strncmp("lprx=", buf, 5)) {
398 if (sscanf(buf + 5, "%d", &val) != 1)
399 return -EINVAL;
400 param = MVM_DEBUGFS_PM_LPRX_ENA;
401 } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
402 if (sscanf(buf + 20, "%d", &val) != 1)
403 return -EINVAL;
404 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
405 POWER_LPRX_RSSI_THRESHOLD_MIN)
406 return -EINVAL;
407 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
390 } else { 408 } else {
391 return -EINVAL; 409 return -EINVAL;
392 } 410 }
@@ -421,7 +439,7 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
421 le32_to_cpu(cmd.skip_dtim_periods)); 439 le32_to_cpu(cmd.skip_dtim_periods));
422 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", 440 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
423 iwlmvm_mod_params.power_scheme); 441 iwlmvm_mod_params.power_scheme);
424 pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n", 442 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
425 le16_to_cpu(cmd.flags)); 443 le16_to_cpu(cmd.flags));
426 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", 444 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
427 cmd.keep_alive_seconds); 445 cmd.keep_alive_seconds);
@@ -435,6 +453,10 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
435 le32_to_cpu(cmd.rx_data_timeout)); 453 le32_to_cpu(cmd.rx_data_timeout));
436 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", 454 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
437 le32_to_cpu(cmd.tx_data_timeout)); 455 le32_to_cpu(cmd.tx_data_timeout));
456 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
457 pos += scnprintf(buf+pos, bufsz-pos,
458 "lprx_rssi_threshold = %d\n",
459 le32_to_cpu(cmd.lprx_rssi_threshold));
438 } 460 }
439 461
440 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 462 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -939,6 +961,9 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
939#ifdef CONFIG_PM_SLEEP 961#ifdef CONFIG_PM_SLEEP
940 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 962 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
941 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); 963 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR);
964 if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR,
965 mvm->debugfs_dir, &mvm->d3_wake_sysassert))
966 goto err;
942#endif 967#endif
943 968
944 /* 969 /*
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index d8e19290b0f3..a6da359a80c3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -66,6 +66,11 @@
66 66
67/* Power Management Commands, Responses, Notifications */ 67/* Power Management Commands, Responses, Notifications */
68 68
69/* Radio LP RX Energy Threshold measured in dBm */
70#define POWER_LPRX_RSSI_THRESHOLD 75
71#define POWER_LPRX_RSSI_THRESHOLD_MAX 94
72#define POWER_LPRX_RSSI_THRESHOLD_MIN 30
73
69/** 74/**
70 * enum iwl_scan_flags - masks for power table command flags 75 * enum iwl_scan_flags - masks for power table command flags
71 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off 76 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 273b0cc197ab..94aae9c8562c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -865,6 +865,30 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
865 return ret; 865 return ret;
866} 866}
867 867
868struct iwl_mvm_mac_ap_iterator_data {
869 struct iwl_mvm *mvm;
870 struct ieee80211_vif *vif;
871 u32 beacon_device_ts;
872 u16 beacon_int;
873};
874
875/* Find the beacon_device_ts and beacon_int for a managed interface */
876static void iwl_mvm_mac_ap_iterator(void *_data, u8 *mac,
877 struct ieee80211_vif *vif)
878{
879 struct iwl_mvm_mac_ap_iterator_data *data = _data;
880
881 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc)
882 return;
883
884 /* Station client has higher priority over P2P client*/
885 if (vif->p2p && data->beacon_device_ts)
886 return;
887
888 data->beacon_device_ts = vif->bss_conf.sync_device_ts;
889 data->beacon_int = vif->bss_conf.beacon_int;
890}
891
868/* 892/*
869 * Fill the specific data for mac context of type AP of P2P GO 893 * Fill the specific data for mac context of type AP of P2P GO
870 */ 894 */
@@ -874,6 +898,11 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
874 bool add) 898 bool add)
875{ 899{
876 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 900 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
901 struct iwl_mvm_mac_ap_iterator_data data = {
902 .mvm = mvm,
903 .vif = vif,
904 .beacon_device_ts = 0
905 };
877 906
878 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); 907 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
879 ctxt_ap->bi_reciprocal = 908 ctxt_ap->bi_reciprocal =
@@ -887,16 +916,33 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
887 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); 916 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
888 917
889 /* 918 /*
890 * Only read the system time when the MAC is being added, when we 919 * Only set the beacon time when the MAC is being added, when we
891 * just modify the MAC then we should keep the time -- the firmware 920 * just modify the MAC then we should keep the time -- the firmware
892 * can otherwise have a "jumping" TBTT. 921 * can otherwise have a "jumping" TBTT.
893 */ 922 */
894 if (add) 923 if (add) {
895 mvmvif->ap_beacon_time = 924 /*
896 iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); 925 * If there is a station/P2P client interface which is
926 * associated, set the AP's TBTT far enough from the station's
927 * TBTT. Otherwise, set it to the current system time
928 */
929 ieee80211_iterate_active_interfaces_atomic(
930 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
931 iwl_mvm_mac_ap_iterator, &data);
932
933 if (data.beacon_device_ts) {
934 u32 rand = (prandom_u32() % (80 - 20)) + 20;
935 mvmvif->ap_beacon_time = data.beacon_device_ts +
936 ieee80211_tu_to_usec(data.beacon_int * rand /
937 100);
938 } else {
939 mvmvif->ap_beacon_time =
940 iwl_read_prph(mvm->trans,
941 DEVICE_SYSTEM_TIME_REG);
942 }
943 }
897 944
898 ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); 945 ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
899
900 ctxt_ap->beacon_tsf = 0; /* unused */ 946 ctxt_ap->beacon_tsf = 0; /* unused */
901 947
902 /* TODO: Assume that the beacon id == mac context id */ 948 /* TODO: Assume that the beacon id == mac context id */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index c7409f159a36..d40d7db185d6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -73,7 +73,6 @@
73#include "iwl-trans.h" 73#include "iwl-trans.h"
74#include "iwl-notif-wait.h" 74#include "iwl-notif-wait.h"
75#include "iwl-eeprom-parse.h" 75#include "iwl-eeprom-parse.h"
76#include "iwl-test.h"
77#include "iwl-trans.h" 76#include "iwl-trans.h"
78#include "sta.h" 77#include "sta.h"
79#include "fw-api.h" 78#include "fw-api.h"
@@ -159,6 +158,8 @@ enum iwl_dbgfs_pm_mask {
159 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3), 158 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
160 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4), 159 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
161 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5), 160 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
161 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
162 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
162}; 163};
163 164
164struct iwl_dbgfs_pm { 165struct iwl_dbgfs_pm {
@@ -168,6 +169,8 @@ struct iwl_dbgfs_pm {
168 bool skip_over_dtim; 169 bool skip_over_dtim;
169 u8 skip_dtim_periods; 170 u8 skip_dtim_periods;
170 bool disable_power_off; 171 bool disable_power_off;
172 bool lprx_ena;
173 u32 lprx_rssi_threshold;
171 int mask; 174 int mask;
172}; 175};
173 176
@@ -353,12 +356,14 @@ struct iwl_tt_params {
353 * @dynamic_smps: Is thermal throttling enabled dynamic_smps? 356 * @dynamic_smps: Is thermal throttling enabled dynamic_smps?
354 * @tx_backoff: The current thremal throttling tx backoff in uSec. 357 * @tx_backoff: The current thremal throttling tx backoff in uSec.
355 * @params: Parameters to configure the thermal throttling algorithm. 358 * @params: Parameters to configure the thermal throttling algorithm.
359 * @throttle: Is thermal throttling is active?
356 */ 360 */
357struct iwl_mvm_tt_mgmt { 361struct iwl_mvm_tt_mgmt {
358 struct delayed_work ct_kill_exit; 362 struct delayed_work ct_kill_exit;
359 bool dynamic_smps; 363 bool dynamic_smps;
360 u32 tx_backoff; 364 u32 tx_backoff;
361 const struct iwl_tt_params *params; 365 const struct iwl_tt_params *params;
366 bool throttle;
362}; 367};
363 368
364struct iwl_mvm { 369struct iwl_mvm {
@@ -461,6 +466,7 @@ struct iwl_mvm {
461 struct wiphy_wowlan_support wowlan; 466 struct wiphy_wowlan_support wowlan;
462 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 467 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
463#ifdef CONFIG_IWLWIFI_DEBUGFS 468#ifdef CONFIG_IWLWIFI_DEBUGFS
469 u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */
464 bool d3_test_active; 470 bool d3_test_active;
465 bool store_d3_resume_sram; 471 bool store_d3_resume_sram;
466 void *d3_resume_sram; 472 void *d3_resume_sram;
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 3760a33ca3a4..e7ca965a89b8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -137,11 +137,12 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
137 le32_to_cpu(cmd->rx_data_timeout)); 137 le32_to_cpu(cmd->rx_data_timeout));
138 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", 138 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
139 le32_to_cpu(cmd->tx_data_timeout)); 139 le32_to_cpu(cmd->tx_data_timeout));
140 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
141 cmd->lprx_rssi_threshold);
142 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) 140 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
143 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", 141 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
144 le32_to_cpu(cmd->skip_dtim_periods)); 142 le32_to_cpu(cmd->skip_dtim_periods));
143 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
144 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
145 le32_to_cpu(cmd->lprx_rssi_threshold));
145 } 146 }
146} 147}
147 148
@@ -181,6 +182,14 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
181 182
182 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 183 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
183 184
185 if (vif->bss_conf.beacon_rate &&
186 (vif->bss_conf.beacon_rate->bitrate == 10 ||
187 vif->bss_conf.beacon_rate->bitrate == 60)) {
188 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
189 cmd->lprx_rssi_threshold =
190 cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD);
191 }
192
184 dtimper = hw->conf.ps_dtim_period ?: 1; 193 dtimper = hw->conf.ps_dtim_period ?: 1;
185 194
186 /* Check if radar detection is required on current channel */ 195 /* Check if radar detection is required on current channel */
@@ -236,6 +245,15 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
236 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) 245 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
237 cmd->skip_dtim_periods = 246 cmd->skip_dtim_periods =
238 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); 247 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
248 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) {
249 if (mvmvif->dbgfs_pm.lprx_ena)
250 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
251 else
252 cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK);
253 }
254 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
255 cmd->lprx_rssi_threshold =
256 cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold);
239#endif /* CONFIG_IWLWIFI_DEBUGFS */ 257#endif /* CONFIG_IWLWIFI_DEBUGFS */
240} 258}
241 259
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 31587a318f8b..b328a988c130 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -412,24 +412,18 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
412 return ret; 412 return ret;
413 } 413 }
414 414
415 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { 415 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
416 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", 416 sta->addr, tid);
417 sta->addr, tid); 417 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
418 ret = ieee80211_start_tx_ba_session(sta, tid, 5000); 418 if (ret == -EAGAIN) {
419 if (ret == -EAGAIN) { 419 /*
420 /* 420 * driver and mac80211 is out of sync
421 * driver and mac80211 is out of sync 421 * this might be cause by reloading firmware
422 * this might be cause by reloading firmware 422 * stop the tx ba session here
423 * stop the tx ba session here 423 */
424 */ 424 IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n",
425 IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n", 425 tid);
426 tid); 426 ieee80211_stop_tx_ba_session(sta, tid);
427 ieee80211_stop_tx_ba_session(sta, tid);
428 }
429 } else {
430 IWL_DEBUG_HT(mvm,
431 "Aggregation not enabled for tid %d because load = %u\n",
432 tid, load);
433 } 427 }
434 return ret; 428 return ret;
435} 429}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index a7e3b8ddf22b..d6ae7f16ac11 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -427,6 +427,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
427 const struct iwl_tt_params *params = mvm->thermal_throttle.params; 427 const struct iwl_tt_params *params = mvm->thermal_throttle.params;
428 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; 428 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
429 s32 temperature = mvm->temperature; 429 s32 temperature = mvm->temperature;
430 bool throttle_enable = false;
430 int i; 431 int i;
431 u32 tx_backoff; 432 u32 tx_backoff;
432 433
@@ -445,6 +446,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
445 ieee80211_iterate_active_interfaces_atomic( 446 ieee80211_iterate_active_interfaces_atomic(
446 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 447 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
447 iwl_mvm_tt_smps_iterator, mvm); 448 iwl_mvm_tt_smps_iterator, mvm);
449 throttle_enable = true;
448 } else if (tt->dynamic_smps && 450 } else if (tt->dynamic_smps &&
449 temperature <= params->dynamic_smps_exit) { 451 temperature <= params->dynamic_smps_exit) {
450 IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n"); 452 IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n");
@@ -456,10 +458,12 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
456 } 458 }
457 459
458 if (params->support_tx_protection) { 460 if (params->support_tx_protection) {
459 if (temperature >= params->tx_protection_entry) 461 if (temperature >= params->tx_protection_entry) {
460 iwl_mvm_tt_tx_protection(mvm, true); 462 iwl_mvm_tt_tx_protection(mvm, true);
461 else if (temperature <= params->tx_protection_exit) 463 throttle_enable = true;
464 } else if (temperature <= params->tx_protection_exit) {
462 iwl_mvm_tt_tx_protection(mvm, false); 465 iwl_mvm_tt_tx_protection(mvm, false);
466 }
463 } 467 }
464 468
465 if (params->support_tx_backoff) { 469 if (params->support_tx_backoff) {
@@ -469,9 +473,22 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
469 break; 473 break;
470 tx_backoff = params->tx_backoff[i].backoff; 474 tx_backoff = params->tx_backoff[i].backoff;
471 } 475 }
476 if (tx_backoff != 0)
477 throttle_enable = true;
472 if (tt->tx_backoff != tx_backoff) 478 if (tt->tx_backoff != tx_backoff)
473 iwl_mvm_tt_tx_backoff(mvm, tx_backoff); 479 iwl_mvm_tt_tx_backoff(mvm, tx_backoff);
474 } 480 }
481
482 if (!tt->throttle && throttle_enable) {
483 IWL_WARN(mvm,
484 "Due to high temperature thermal throttling initiated\n");
485 tt->throttle = true;
486 } else if (tt->throttle && !tt->dynamic_smps && tt->tx_backoff == 0 &&
487 temperature <= params->tx_protection_exit) {
488 IWL_WARN(mvm,
489 "Temperature is back to normal thermal throttling stopped\n");
490 tt->throttle = false;
491 }
475} 492}
476 493
477static const struct iwl_tt_params iwl7000_tt_params = { 494static const struct iwl_tt_params iwl7000_tt_params = {
@@ -502,6 +519,7 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm)
502 519
503 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n"); 520 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");
504 tt->params = &iwl7000_tt_params; 521 tt->params = &iwl7000_tt_params;
522 tt->throttle = false;
505 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill); 523 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
506} 524}
507 525
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 3688dc5ba1ac..fd848cd1583e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -110,9 +110,10 @@
110/* 110/*
111 * iwl_rxq_space - Return number of free slots available in queue. 111 * iwl_rxq_space - Return number of free slots available in queue.
112 */ 112 */
113static int iwl_rxq_space(const struct iwl_rxq *q) 113static int iwl_rxq_space(const struct iwl_rxq *rxq)
114{ 114{
115 int s = q->read - q->write; 115 int s = rxq->read - rxq->write;
116
116 if (s <= 0) 117 if (s <= 0)
117 s += RX_QUEUE_SIZE; 118 s += RX_QUEUE_SIZE;
118 /* keep some buffer to not confuse full and empty queue */ 119 /* keep some buffer to not confuse full and empty queue */
@@ -143,21 +144,22 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans)
143/* 144/*
144 * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue 145 * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue
145 */ 146 */
146static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) 147static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
148 struct iwl_rxq *rxq)
147{ 149{
148 unsigned long flags; 150 unsigned long flags;
149 u32 reg; 151 u32 reg;
150 152
151 spin_lock_irqsave(&q->lock, flags); 153 spin_lock_irqsave(&rxq->lock, flags);
152 154
153 if (q->need_update == 0) 155 if (rxq->need_update == 0)
154 goto exit_unlock; 156 goto exit_unlock;
155 157
156 if (trans->cfg->base_params->shadow_reg_enable) { 158 if (trans->cfg->base_params->shadow_reg_enable) {
157 /* shadow register enabled */ 159 /* shadow register enabled */
158 /* Device expects a multiple of 8 */ 160 /* Device expects a multiple of 8 */
159 q->write_actual = (q->write & ~0x7); 161 rxq->write_actual = (rxq->write & ~0x7);
160 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); 162 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
161 } else { 163 } else {
162 struct iwl_trans_pcie *trans_pcie = 164 struct iwl_trans_pcie *trans_pcie =
163 IWL_TRANS_GET_PCIE_TRANS(trans); 165 IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -175,22 +177,22 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q)
175 goto exit_unlock; 177 goto exit_unlock;
176 } 178 }
177 179
178 q->write_actual = (q->write & ~0x7); 180 rxq->write_actual = (rxq->write & ~0x7);
179 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, 181 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
180 q->write_actual); 182 rxq->write_actual);
181 183
182 /* Else device is assumed to be awake */ 184 /* Else device is assumed to be awake */
183 } else { 185 } else {
184 /* Device expects a multiple of 8 */ 186 /* Device expects a multiple of 8 */
185 q->write_actual = (q->write & ~0x7); 187 rxq->write_actual = (rxq->write & ~0x7);
186 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, 188 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
187 q->write_actual); 189 rxq->write_actual);
188 } 190 }
189 } 191 }
190 q->need_update = 0; 192 rxq->need_update = 0;
191 193
192 exit_unlock: 194 exit_unlock:
193 spin_unlock_irqrestore(&q->lock, flags); 195 spin_unlock_irqrestore(&rxq->lock, flags);
194} 196}
195 197
196/* 198/*
@@ -355,19 +357,16 @@ static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans)
355 struct iwl_rxq *rxq = &trans_pcie->rxq; 357 struct iwl_rxq *rxq = &trans_pcie->rxq;
356 int i; 358 int i;
357 359
358 /* Fill the rx_used queue with _all_ of the Rx buffers */ 360 lockdep_assert_held(&rxq->lock);
361
359 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { 362 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
360 /* In the reset function, these buffers may have been allocated 363 if (!rxq->pool[i].page)
361 * to an SKB, so we need to unmap and free potential storage */ 364 continue;
362 if (rxq->pool[i].page != NULL) { 365 dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
363 dma_unmap_page(trans->dev, rxq->pool[i].page_dma, 366 PAGE_SIZE << trans_pcie->rx_page_order,
364 PAGE_SIZE << trans_pcie->rx_page_order, 367 DMA_FROM_DEVICE);
365 DMA_FROM_DEVICE); 368 __free_pages(rxq->pool[i].page, trans_pcie->rx_page_order);
366 __free_pages(rxq->pool[i].page, 369 rxq->pool[i].page = NULL;
367 trans_pcie->rx_page_order);
368 rxq->pool[i].page = NULL;
369 }
370 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
371 } 370 }
372} 371}
373 372
@@ -491,6 +490,20 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
491 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); 490 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
492} 491}
493 492
493static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq)
494{
495 int i;
496
497 lockdep_assert_held(&rxq->lock);
498
499 INIT_LIST_HEAD(&rxq->rx_free);
500 INIT_LIST_HEAD(&rxq->rx_used);
501 rxq->free_count = 0;
502
503 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
504 list_add(&rxq->pool[i].list, &rxq->rx_used);
505}
506
494int iwl_pcie_rx_init(struct iwl_trans *trans) 507int iwl_pcie_rx_init(struct iwl_trans *trans)
495{ 508{
496 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 509 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -505,13 +518,12 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
505 } 518 }
506 519
507 spin_lock_irqsave(&rxq->lock, flags); 520 spin_lock_irqsave(&rxq->lock, flags);
508 INIT_LIST_HEAD(&rxq->rx_free);
509 INIT_LIST_HEAD(&rxq->rx_used);
510 521
511 INIT_WORK(&trans_pcie->rx_replenish, 522 INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work);
512 iwl_pcie_rx_replenish_work);
513 523
524 /* free all first - we might be reconfigured for a different size */
514 iwl_pcie_rxq_free_rbs(trans); 525 iwl_pcie_rxq_free_rbs(trans);
526 iwl_pcie_rx_init_rxb_lists(rxq);
515 527
516 for (i = 0; i < RX_QUEUE_SIZE; i++) 528 for (i = 0; i < RX_QUEUE_SIZE; i++)
517 rxq->queue[i] = NULL; 529 rxq->queue[i] = NULL;
@@ -520,7 +532,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
520 * not restocked the Rx queue with fresh buffers */ 532 * not restocked the Rx queue with fresh buffers */
521 rxq->read = rxq->write = 0; 533 rxq->read = rxq->write = 0;
522 rxq->write_actual = 0; 534 rxq->write_actual = 0;
523 rxq->free_count = 0;
524 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); 535 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
525 spin_unlock_irqrestore(&rxq->lock, flags); 536 spin_unlock_irqrestore(&rxq->lock, flags);
526 537
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 197dbe0a868c..826c15602c46 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -838,8 +838,9 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
838 unsigned long *flags) 838 unsigned long *flags)
839{ 839{
840 int ret; 840 int ret;
841 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans); 841 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
842 spin_lock_irqsave(&pcie_trans->reg_lock, *flags); 842
843 spin_lock_irqsave(&trans_pcie->reg_lock, *flags);
843 844
844 /* this bit wakes up the NIC */ 845 /* this bit wakes up the NIC */
845 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, 846 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
@@ -875,7 +876,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
875 WARN_ONCE(1, 876 WARN_ONCE(1,
876 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", 877 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
877 val); 878 val);
878 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags); 879 spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
879 return false; 880 return false;
880 } 881 }
881 } 882 }
@@ -884,22 +885,22 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
884 * Fool sparse by faking we release the lock - sparse will 885 * Fool sparse by faking we release the lock - sparse will
885 * track nic_access anyway. 886 * track nic_access anyway.
886 */ 887 */
887 __release(&pcie_trans->reg_lock); 888 __release(&trans_pcie->reg_lock);
888 return true; 889 return true;
889} 890}
890 891
891static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, 892static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
892 unsigned long *flags) 893 unsigned long *flags)
893{ 894{
894 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans); 895 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
895 896
896 lockdep_assert_held(&pcie_trans->reg_lock); 897 lockdep_assert_held(&trans_pcie->reg_lock);
897 898
898 /* 899 /*
899 * Fool sparse by faking we acquiring the lock - sparse will 900 * Fool sparse by faking we acquiring the lock - sparse will
900 * track nic_access anyway. 901 * track nic_access anyway.
901 */ 902 */
902 __acquire(&pcie_trans->reg_lock); 903 __acquire(&trans_pcie->reg_lock);
903 904
904 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 905 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
905 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 906 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -910,7 +911,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
910 * scheduled on different CPUs (after we drop reg_lock). 911 * scheduled on different CPUs (after we drop reg_lock).
911 */ 912 */
912 mmiowb(); 913 mmiowb();
913 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags); 914 spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
914} 915}
915 916
916static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, 917static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index a7630d5ec892..d78c495a86a0 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -100,7 +100,7 @@
100#define CSR_REG_BASE 0x1000 100#define CSR_REG_BASE 0x1000
101#define CSR_REG_SIZE 0x0800 101#define CSR_REG_SIZE 0x0800
102#define EEPROM_BASE 0x0000 102#define EEPROM_BASE 0x0000
103#define EEPROM_SIZE 0x0110 103#define EEPROM_SIZE 0x0200
104#define BBP_BASE 0x0000 104#define BBP_BASE 0x0000
105#define BBP_SIZE 0x00ff 105#define BBP_SIZE 0x00ff
106#define RF_BASE 0x0004 106#define RF_BASE 0x0004
@@ -2625,11 +2625,13 @@ struct mac_iveiv_entry {
2625/* 2625/*
2626 * DMA descriptor defines. 2626 * DMA descriptor defines.
2627 */ 2627 */
2628#define TXWI_DESC_SIZE (4 * sizeof(__le32))
2629#define RXWI_DESC_SIZE (4 * sizeof(__le32))
2630 2628
2631#define TXWI_DESC_SIZE_5592 (5 * sizeof(__le32)) 2629#define TXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32))
2632#define RXWI_DESC_SIZE_5592 (6 * sizeof(__le32)) 2630#define TXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32))
2631
2632#define RXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32))
2633#define RXWI_DESC_SIZE_6WORDS (6 * sizeof(__le32))
2634
2633/* 2635/*
2634 * TX WI structure 2636 * TX WI structure
2635 */ 2637 */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 3aa30ddcbfea..1f80ea5e29dd 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2392,7 +2392,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
2392 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); 2392 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
2393 2393
2394 rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); 2394 rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
2395 if (info->default_power1 > power_bound) 2395 if (info->default_power2 > power_bound)
2396 rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound); 2396 rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound);
2397 else 2397 else
2398 rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2); 2398 rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2);
@@ -2678,30 +2678,53 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2678 2678
2679 tx_pin = 0; 2679 tx_pin = 0;
2680 2680
2681 /* Turn on unused PA or LNA when not using 1T or 1R */ 2681 switch (rt2x00dev->default_ant.tx_chain_num) {
2682 if (rt2x00dev->default_ant.tx_chain_num == 2) { 2682 case 3:
2683 /* Turn on tertiary PAs */
2684 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN,
2685 rf->channel > 14);
2686 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN,
2687 rf->channel <= 14);
2688 /* fall-through */
2689 case 2:
2690 /* Turn on secondary PAs */
2683 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 2691 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN,
2684 rf->channel > 14); 2692 rf->channel > 14);
2685 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 2693 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN,
2686 rf->channel <= 14); 2694 rf->channel <= 14);
2695 /* fall-through */
2696 case 1:
2697 /* Turn on primary PAs */
2698 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN,
2699 rf->channel > 14);
2700 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
2701 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
2702 else
2703 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
2704 rf->channel <= 14);
2705 break;
2687 } 2706 }
2688 2707
2689 /* Turn on unused PA or LNA when not using 1T or 1R */ 2708 switch (rt2x00dev->default_ant.rx_chain_num) {
2690 if (rt2x00dev->default_ant.rx_chain_num == 2) { 2709 case 3:
2710 /* Turn on tertiary LNAs */
2711 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1);
2712 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1);
2713 /* fall-through */
2714 case 2:
2715 /* Turn on secondary LNAs */
2691 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); 2716 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
2692 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); 2717 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
2718 /* fall-through */
2719 case 1:
2720 /* Turn on primary LNAs */
2721 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
2722 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
2723 break;
2693 } 2724 }
2694 2725
2695 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
2696 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
2697 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); 2726 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
2698 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); 2727 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
2699 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
2700 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
2701 else
2702 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
2703 rf->channel <= 14);
2704 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
2705 2728
2706 rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); 2729 rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
2707 2730
@@ -6254,8 +6277,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6254 default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); 6277 default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
6255 6278
6256 for (i = 14; i < spec->num_channels; i++) { 6279 for (i = 14; i < spec->num_channels; i++) {
6257 info[i].default_power1 = default_power1[i]; 6280 info[i].default_power1 = default_power1[i - 14];
6258 info[i].default_power2 = default_power2[i]; 6281 info[i].default_power2 = default_power2[i - 14];
6259 } 6282 }
6260 } 6283 }
6261 6284
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 7c7478219bbc..00055627eb8d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -637,6 +637,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
637 struct queue_entry_priv_mmio *entry_priv = entry->priv_data; 637 struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
638 __le32 *txd = entry_priv->desc; 638 __le32 *txd = entry_priv->desc;
639 u32 word; 639 u32 word;
640 const unsigned int txwi_size = entry->queue->winfo_size;
640 641
641 /* 642 /*
642 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1 643 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1
@@ -659,14 +660,14 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
659 !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); 660 !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
660 rt2x00_set_field32(&word, TXD_W1_BURST, 661 rt2x00_set_field32(&word, TXD_W1_BURST,
661 test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 662 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
662 rt2x00_set_field32(&word, TXD_W1_SD_LEN0, TXWI_DESC_SIZE); 663 rt2x00_set_field32(&word, TXD_W1_SD_LEN0, txwi_size);
663 rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0); 664 rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
664 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); 665 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
665 rt2x00_desc_write(txd, 1, word); 666 rt2x00_desc_write(txd, 1, word);
666 667
667 word = 0; 668 word = 0;
668 rt2x00_set_field32(&word, TXD_W2_SD_PTR1, 669 rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
669 skbdesc->skb_dma + TXWI_DESC_SIZE); 670 skbdesc->skb_dma + txwi_size);
670 rt2x00_desc_write(txd, 2, word); 671 rt2x00_desc_write(txd, 2, word);
671 672
672 word = 0; 673 word = 0;
@@ -1193,7 +1194,7 @@ static void rt2800pci_queue_init(struct data_queue *queue)
1193 queue->limit = 128; 1194 queue->limit = 128;
1194 queue->data_size = AGGREGATION_SIZE; 1195 queue->data_size = AGGREGATION_SIZE;
1195 queue->desc_size = RXD_DESC_SIZE; 1196 queue->desc_size = RXD_DESC_SIZE;
1196 queue->winfo_size = RXWI_DESC_SIZE; 1197 queue->winfo_size = RXWI_DESC_SIZE_4WORDS;
1197 queue->priv_size = sizeof(struct queue_entry_priv_mmio); 1198 queue->priv_size = sizeof(struct queue_entry_priv_mmio);
1198 break; 1199 break;
1199 1200
@@ -1204,7 +1205,7 @@ static void rt2800pci_queue_init(struct data_queue *queue)
1204 queue->limit = 64; 1205 queue->limit = 64;
1205 queue->data_size = AGGREGATION_SIZE; 1206 queue->data_size = AGGREGATION_SIZE;
1206 queue->desc_size = TXD_DESC_SIZE; 1207 queue->desc_size = TXD_DESC_SIZE;
1207 queue->winfo_size = TXWI_DESC_SIZE; 1208 queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
1208 queue->priv_size = sizeof(struct queue_entry_priv_mmio); 1209 queue->priv_size = sizeof(struct queue_entry_priv_mmio);
1209 break; 1210 break;
1210 1211
@@ -1212,7 +1213,7 @@ static void rt2800pci_queue_init(struct data_queue *queue)
1212 queue->limit = 8; 1213 queue->limit = 8;
1213 queue->data_size = 0; /* No DMA required for beacons */ 1214 queue->data_size = 0; /* No DMA required for beacons */
1214 queue->desc_size = TXD_DESC_SIZE; 1215 queue->desc_size = TXD_DESC_SIZE;
1215 queue->winfo_size = TXWI_DESC_SIZE; 1216 queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
1216 queue->priv_size = sizeof(struct queue_entry_priv_mmio); 1217 queue->priv_size = sizeof(struct queue_entry_priv_mmio);
1217 break; 1218 break;
1218 1219
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 7edd903dd749..840833b26bfa 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -855,11 +855,11 @@ static void rt2800usb_queue_init(struct data_queue *queue)
855 unsigned short txwi_size, rxwi_size; 855 unsigned short txwi_size, rxwi_size;
856 856
857 if (rt2x00_rt(rt2x00dev, RT5592)) { 857 if (rt2x00_rt(rt2x00dev, RT5592)) {
858 txwi_size = TXWI_DESC_SIZE_5592; 858 txwi_size = TXWI_DESC_SIZE_5WORDS;
859 rxwi_size = RXWI_DESC_SIZE_5592; 859 rxwi_size = RXWI_DESC_SIZE_6WORDS;
860 } else { 860 } else {
861 txwi_size = TXWI_DESC_SIZE; 861 txwi_size = TXWI_DESC_SIZE_4WORDS;
862 rxwi_size = RXWI_DESC_SIZE; 862 rxwi_size = RXWI_DESC_SIZE_4WORDS;
863 } 863 }
864 864
865 switch (queue->qid) { 865 switch (queue->qid) {
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 53754bc66d05..54d3ddfc9888 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2825,7 +2825,8 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2825 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); 2825 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
2826 for (i = 14; i < spec->num_channels; i++) { 2826 for (i = 14; i < spec->num_channels; i++) {
2827 info[i].max_power = MAX_TXPOWER; 2827 info[i].max_power = MAX_TXPOWER;
2828 info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); 2828 info[i].default_power1 =
2829 TXPOWER_FROM_DEV(tx_power[i - 14]);
2829 } 2830 }
2830 } 2831 }
2831 2832
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 1616ed484ceb..1d3880e09a13 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2167,7 +2167,8 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2167 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); 2167 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
2168 for (i = 14; i < spec->num_channels; i++) { 2168 for (i = 14; i < spec->num_channels; i++) {
2169 info[i].max_power = MAX_TXPOWER; 2169 info[i].max_power = MAX_TXPOWER;
2170 info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); 2170 info[i].default_power1 =
2171 TXPOWER_FROM_DEV(tx_power[i - 14]);
2171 } 2172 }
2172 } 2173 }
2173 2174
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
index e4c4cdc3eb67..d9ee2efffe5f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -251,7 +251,7 @@ static struct rtl_hal_cfg rtl8723ae_hal_cfg = {
251 .bar_id = 2, 251 .bar_id = 2,
252 .write_readback = true, 252 .write_readback = true,
253 .name = "rtl8723ae_pci", 253 .name = "rtl8723ae_pci",
254 .fw_name = "rtlwifi/rtl8723aefw.bin", 254 .fw_name = "rtlwifi/rtl8723fw.bin",
255 .ops = &rtl8723ae_hal_ops, 255 .ops = &rtl8723ae_hal_ops,
256 .mod_params = &rtl8723ae_mod_params, 256 .mod_params = &rtl8723ae_mod_params,
257 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, 257 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
@@ -353,8 +353,8 @@ MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
353MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); 353MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
354MODULE_LICENSE("GPL"); 354MODULE_LICENSE("GPL");
355MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); 355MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
356MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin"); 356MODULE_FIRMWARE("rtlwifi/rtl8723fw.bin");
357MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin"); 357MODULE_FIRMWARE("rtlwifi/rtl8723fw_B.bin");
358 358
359module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); 359module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444);
360module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); 360module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444);
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 2e34db82a643..622fc505d3e1 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -144,6 +144,7 @@ struct bcma_host_ops {
144 144
145/* Chip IDs of PCIe devices */ 145/* Chip IDs of PCIe devices */
146#define BCMA_CHIP_ID_BCM4313 0x4313 146#define BCMA_CHIP_ID_BCM4313 0x4313
147#define BCMA_CHIP_ID_BCM43142 43142
147#define BCMA_CHIP_ID_BCM43224 43224 148#define BCMA_CHIP_ID_BCM43224 43224
148#define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8 149#define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8
149#define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa 150#define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index b8b09eac60a4..c49e1a159e6e 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -330,6 +330,8 @@
330#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */ 330#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */
331#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */ 331#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */
332#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */ 332#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */
333#define BCMA_CC_PMU_STAT_EXT_LPO_AVAIL 0x00000100
334#define BCMA_CC_PMU_STAT_WDRESET 0x00000080
333#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */ 335#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */
334#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */ 336#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */
335#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */ 337#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */
@@ -355,6 +357,11 @@
355#define BCMA_CC_REGCTL_DATA 0x065C 357#define BCMA_CC_REGCTL_DATA 0x065C
356#define BCMA_CC_PLLCTL_ADDR 0x0660 358#define BCMA_CC_PLLCTL_ADDR 0x0660
357#define BCMA_CC_PLLCTL_DATA 0x0664 359#define BCMA_CC_PLLCTL_DATA 0x0664
360#define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */
361#define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */
362#define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF
363#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK 0x80000000
364#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT 31
358#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ 365#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
359/* NAND flash MLC controller registers (corerev >= 38) */ 366/* NAND flash MLC controller registers (corerev >= 38) */
360#define BCMA_CC_NAND_REVISION 0x0C00 367#define BCMA_CC_NAND_REVISION 0x0C00
@@ -435,6 +442,23 @@
435#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 442#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007
436#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0 443#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0
437 444
445/* PMU rev 15 */
446#define BCMA_CC_PMU15_PLL_PLLCTL0 0
447#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK 0x00000003
448#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT 0
449#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC
450#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT 2
451#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000
452#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT 22
453#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK 0x07000000
454#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT 24
455#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000
456#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT 27
457#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK 0x40000000
458#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT 30
459#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000
460#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT 31
461
438/* ALP clock on pre-PMU chips */ 462/* ALP clock on pre-PMU chips */
439#define BCMA_CC_PMU_ALP_CLOCK 20000000 463#define BCMA_CC_PMU_ALP_CLOCK 20000000
440/* HT clock for systems with PMU-enabled chipcommon */ 464/* HT clock for systems with PMU-enabled chipcommon */
@@ -507,6 +531,37 @@
507#define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18) 531#define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18)
508#define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19) 532#define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19)
509 533
534#define BCMA_RES_4314_LPLDO_PU BIT(0)
535#define BCMA_RES_4314_PMU_SLEEP_DIS BIT(1)
536#define BCMA_RES_4314_PMU_BG_PU BIT(2)
537#define BCMA_RES_4314_CBUCK_LPOM_PU BIT(3)
538#define BCMA_RES_4314_CBUCK_PFM_PU BIT(4)
539#define BCMA_RES_4314_CLDO_PU BIT(5)
540#define BCMA_RES_4314_LPLDO2_LVM BIT(6)
541#define BCMA_RES_4314_WL_PMU_PU BIT(7)
542#define BCMA_RES_4314_LNLDO_PU BIT(8)
543#define BCMA_RES_4314_LDO3P3_PU BIT(9)
544#define BCMA_RES_4314_OTP_PU BIT(10)
545#define BCMA_RES_4314_XTAL_PU BIT(11)
546#define BCMA_RES_4314_WL_PWRSW_PU BIT(12)
547#define BCMA_RES_4314_LQ_AVAIL BIT(13)
548#define BCMA_RES_4314_LOGIC_RET BIT(14)
549#define BCMA_RES_4314_MEM_SLEEP BIT(15)
550#define BCMA_RES_4314_MACPHY_RET BIT(16)
551#define BCMA_RES_4314_WL_CORE_READY BIT(17)
552#define BCMA_RES_4314_ILP_REQ BIT(18)
553#define BCMA_RES_4314_ALP_AVAIL BIT(19)
554#define BCMA_RES_4314_MISC_PWRSW_PU BIT(20)
555#define BCMA_RES_4314_SYNTH_PWRSW_PU BIT(21)
556#define BCMA_RES_4314_RX_PWRSW_PU BIT(22)
557#define BCMA_RES_4314_RADIO_PU BIT(23)
558#define BCMA_RES_4314_VCO_LDO_PU BIT(24)
559#define BCMA_RES_4314_AFE_LDO_PU BIT(25)
560#define BCMA_RES_4314_RX_LDO_PU BIT(26)
561#define BCMA_RES_4314_TX_LDO_PU BIT(27)
562#define BCMA_RES_4314_HT_AVAIL BIT(28)
563#define BCMA_RES_4314_MACPHY_CLK_AVAIL BIT(29)
564
510/* Data for the PMU, if available. 565/* Data for the PMU, if available.
511 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) 566 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
512 */ 567 */
diff --git a/include/linux/platform_data/brcmfmac-sdio.h b/include/linux/platform_data/brcmfmac-sdio.h
index 1ade657d5fc1..b7174998c24a 100644
--- a/include/linux/platform_data/brcmfmac-sdio.h
+++ b/include/linux/platform_data/brcmfmac-sdio.h
@@ -90,6 +90,10 @@ void __init brcmfmac_init_pdata(void)
90 * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are 90 * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are
91 * used for registering the irq using request_irq function. 91 * used for registering the irq using request_irq function.
92 * 92 *
93 * broken_sg_support: flag for broken sg list support of SDIO host controller.
94 * Set this to true if the SDIO host controller has higher align requirement
95 * than 32 bytes for each scatterlist item.
96 *
93 * power_on: This function is called by the brcmfmac when the module gets 97 * power_on: This function is called by the brcmfmac when the module gets
94 * loaded. This can be particularly useful for low power devices. The platform 98 * loaded. This can be particularly useful for low power devices. The platform
95 * spcific routine may for example decide to power up the complete device. 99 * spcific routine may for example decide to power up the complete device.
@@ -116,6 +120,7 @@ struct brcmfmac_sdio_platform_data {
116 bool oob_irq_supported; 120 bool oob_irq_supported;
117 unsigned int oob_irq_nr; 121 unsigned int oob_irq_nr;
118 unsigned long oob_irq_flags; 122 unsigned long oob_irq_flags;
123 bool broken_sg_support;
119 void (*power_on)(void); 124 void (*power_on)(void);
120 void (*power_off)(void); 125 void (*power_off)(void);
121 void (*reset)(void); 126 void (*reset)(void);
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e0512aaef4b8..3c592cf473da 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -107,7 +107,6 @@ enum {
107 HCI_MGMT, 107 HCI_MGMT,
108 HCI_PAIRABLE, 108 HCI_PAIRABLE,
109 HCI_SERVICE_CACHE, 109 HCI_SERVICE_CACHE,
110 HCI_LINK_KEYS,
111 HCI_DEBUG_KEYS, 110 HCI_DEBUG_KEYS,
112 HCI_UNREGISTER, 111 HCI_UNREGISTER,
113 112
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7cb6d360d147..f77885ea78c2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -117,13 +117,6 @@ struct oob_data {
117 u8 randomizer[16]; 117 u8 randomizer[16];
118}; 118};
119 119
120struct le_scan_params {
121 u8 type;
122 u16 interval;
123 u16 window;
124 int timeout;
125};
126
127#define HCI_MAX_SHORT_NAME_LENGTH 10 120#define HCI_MAX_SHORT_NAME_LENGTH 10
128 121
129struct amp_assoc { 122struct amp_assoc {
@@ -283,9 +276,6 @@ struct hci_dev {
283 276
284 struct delayed_work le_scan_disable; 277 struct delayed_work le_scan_disable;
285 278
286 struct work_struct le_scan;
287 struct le_scan_params le_scan_params;
288
289 __s8 adv_tx_power; 279 __s8 adv_tx_power;
290 __u8 adv_data[HCI_MAX_AD_LENGTH]; 280 __u8 adv_data[HCI_MAX_AD_LENGTH];
291 __u8 adv_data_len; 281 __u8 adv_data_len;
@@ -432,6 +422,7 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
432 struct inquiry_entry *ie); 422 struct inquiry_entry *ie);
433bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 423bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
434 bool name_known, bool *ssp); 424 bool name_known, bool *ssp);
425void hci_inquiry_cache_flush(struct hci_dev *hdev);
435 426
436/* ----- HCI Connections ----- */ 427/* ----- HCI Connections ----- */
437enum { 428enum {
@@ -1114,6 +1105,16 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
1114 BIT(BDADDR_LE_PUBLIC) | \ 1105 BIT(BDADDR_LE_PUBLIC) | \
1115 BIT(BDADDR_LE_RANDOM)) 1106 BIT(BDADDR_LE_RANDOM))
1116 1107
1108/* These LE scan and inquiry parameters were chosen according to LE General
1109 * Discovery Procedure specification.
1110 */
1111#define DISCOV_LE_SCAN_WIN 0x12
1112#define DISCOV_LE_SCAN_INT 0x12
1113#define DISCOV_LE_TIMEOUT msecs_to_jiffies(10240)
1114#define DISCOV_INTERLEAVED_TIMEOUT msecs_to_jiffies(5120)
1115#define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04
1116#define DISCOV_BREDR_INQUIRY_LEN 0x08
1117
1117int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); 1118int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
1118int mgmt_index_added(struct hci_dev *hdev); 1119int mgmt_index_added(struct hci_dev *hdev);
1119int mgmt_index_removed(struct hci_dev *hdev); 1120int mgmt_index_removed(struct hci_dev *hdev);
@@ -1169,10 +1170,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1169 u8 ssp, u8 *eir, u16 eir_len); 1170 u8 ssp, u8 *eir, u16 eir_len);
1170int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1171int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1171 u8 addr_type, s8 rssi, u8 *name, u8 name_len); 1172 u8 addr_type, s8 rssi, u8 *name, u8 name_len);
1172int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
1173int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
1174int mgmt_discovering(struct hci_dev *hdev, u8 discovering); 1173int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
1175int mgmt_interleaved_discovery(struct hci_dev *hdev);
1176int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 1174int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1177int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 1175int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
1178bool mgmt_valid_hdev(struct hci_dev *hdev); 1176bool mgmt_valid_hdev(struct hci_dev *hdev);
@@ -1212,11 +1210,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
1212 u16 latency, u16 to_multiplier); 1210 u16 latency, u16 to_multiplier);
1213void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], 1211void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
1214 __u8 ltk[16]); 1212 __u8 ltk[16]);
1215int hci_do_inquiry(struct hci_dev *hdev, u8 length);
1216int hci_cancel_inquiry(struct hci_dev *hdev);
1217int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
1218 int timeout);
1219int hci_cancel_le_scan(struct hci_dev *hdev);
1220 1213
1221u8 bdaddr_to_le(u8 bdaddr_type); 1214u8 bdaddr_to_le(u8 bdaddr_type);
1222 1215
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index fb94cf13c777..1a966afbbfa8 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -242,7 +242,7 @@ struct l2cap_conn_rsp {
242#define L2CAP_CID_SIGNALING 0x0001 242#define L2CAP_CID_SIGNALING 0x0001
243#define L2CAP_CID_CONN_LESS 0x0002 243#define L2CAP_CID_CONN_LESS 0x0002
244#define L2CAP_CID_A2MP 0x0003 244#define L2CAP_CID_A2MP 0x0003
245#define L2CAP_CID_LE_DATA 0x0004 245#define L2CAP_CID_ATT 0x0004
246#define L2CAP_CID_LE_SIGNALING 0x0005 246#define L2CAP_CID_LE_SIGNALING 0x0005
247#define L2CAP_CID_SMP 0x0006 247#define L2CAP_CID_SMP 0x0006
248#define L2CAP_CID_DYN_START 0x0040 248#define L2CAP_CID_DYN_START 0x0040
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6a43c34ce96f..7b0730aeb892 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -188,6 +188,8 @@ struct ieee80211_channel {
188 * when used with 802.11g (on the 2.4 GHz band); filled by the 188 * when used with 802.11g (on the 2.4 GHz band); filled by the
189 * core code when registering the wiphy. 189 * core code when registering the wiphy.
190 * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. 190 * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode.
191 * @IEEE80211_RATE_SUPPORTS_5MHZ: Rate can be used in 5 MHz mode
192 * @IEEE80211_RATE_SUPPORTS_10MHZ: Rate can be used in 10 MHz mode
191 */ 193 */
192enum ieee80211_rate_flags { 194enum ieee80211_rate_flags {
193 IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, 195 IEEE80211_RATE_SHORT_PREAMBLE = 1<<0,
@@ -195,6 +197,8 @@ enum ieee80211_rate_flags {
195 IEEE80211_RATE_MANDATORY_B = 1<<2, 197 IEEE80211_RATE_MANDATORY_B = 1<<2,
196 IEEE80211_RATE_MANDATORY_G = 1<<3, 198 IEEE80211_RATE_MANDATORY_G = 1<<3,
197 IEEE80211_RATE_ERP_G = 1<<4, 199 IEEE80211_RATE_ERP_G = 1<<4,
200 IEEE80211_RATE_SUPPORTS_5MHZ = 1<<5,
201 IEEE80211_RATE_SUPPORTS_10MHZ = 1<<6,
198}; 202};
199 203
200/** 204/**
@@ -433,6 +437,30 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
433 u32 prohibited_flags); 437 u32 prohibited_flags);
434 438
435/** 439/**
440 * ieee80211_chandef_rate_flags - returns rate flags for a channel
441 *
442 * In some channel types, not all rates may be used - for example CCK
443 * rates may not be used in 5/10 MHz channels.
444 *
445 * @chandef: channel definition for the channel
446 *
447 * Returns: rate flags which apply for this channel
448 */
449static inline enum ieee80211_rate_flags
450ieee80211_chandef_rate_flags(struct cfg80211_chan_def *chandef)
451{
452 switch (chandef->width) {
453 case NL80211_CHAN_WIDTH_5:
454 return IEEE80211_RATE_SUPPORTS_5MHZ;
455 case NL80211_CHAN_WIDTH_10:
456 return IEEE80211_RATE_SUPPORTS_10MHZ;
457 default:
458 break;
459 }
460 return 0;
461}
462
463/**
436 * enum survey_info_flags - survey information flags 464 * enum survey_info_flags - survey information flags
437 * 465 *
438 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 466 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
@@ -1431,7 +1459,8 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
1431 * This structure provides information needed to complete IEEE 802.11 1459 * This structure provides information needed to complete IEEE 802.11
1432 * authentication. 1460 * authentication.
1433 * 1461 *
1434 * @bss: The BSS to authenticate with. 1462 * @bss: The BSS to authenticate with, the callee must obtain a reference
1463 * to it if it needs to keep it.
1435 * @auth_type: Authentication type (algorithm) 1464 * @auth_type: Authentication type (algorithm)
1436 * @ie: Extra IEs to add to Authentication frame or %NULL 1465 * @ie: Extra IEs to add to Authentication frame or %NULL
1437 * @ie_len: Length of ie buffer in octets 1466 * @ie_len: Length of ie buffer in octets
@@ -1469,11 +1498,10 @@ enum cfg80211_assoc_req_flags {
1469 * 1498 *
1470 * This structure provides information needed to complete IEEE 802.11 1499 * This structure provides information needed to complete IEEE 802.11
1471 * (re)association. 1500 * (re)association.
1472 * @bss: The BSS to associate with. If the call is successful the driver 1501 * @bss: The BSS to associate with. If the call is successful the driver is
1473 * is given a reference that it must release, normally via a call to 1502 * given a reference that it must give back to cfg80211_send_rx_assoc()
1474 * cfg80211_send_rx_assoc(), or, if association timed out, with a 1503 * or to cfg80211_assoc_timeout(). To ensure proper refcounting, new
1475 * call to cfg80211_put_bss() (in addition to calling 1504 * association requests while already associating must be rejected.
1476 * cfg80211_send_assoc_timeout())
1477 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL 1505 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
1478 * @ie_len: Length of ie buffer in octets 1506 * @ie_len: Length of ie buffer in octets
1479 * @use_mfp: Use management frame protection (IEEE 802.11w) in this association 1507 * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
@@ -2342,6 +2370,7 @@ struct cfg80211_ops {
2342 * responds to probe-requests in hardware. 2370 * responds to probe-requests in hardware.
2343 * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. 2371 * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX.
2344 * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. 2372 * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call.
2373 * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels.
2345 */ 2374 */
2346enum wiphy_flags { 2375enum wiphy_flags {
2347 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 2376 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -2365,6 +2394,7 @@ enum wiphy_flags {
2365 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), 2394 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19),
2366 WIPHY_FLAG_OFFCHAN_TX = BIT(20), 2395 WIPHY_FLAG_OFFCHAN_TX = BIT(20),
2367 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), 2396 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
2397 WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
2368}; 2398};
2369 2399
2370/** 2400/**
@@ -3492,11 +3522,11 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
3492/** 3522/**
3493 * cfg80211_assoc_timeout - notification of timed out association 3523 * cfg80211_assoc_timeout - notification of timed out association
3494 * @dev: network device 3524 * @dev: network device
3495 * @addr: The MAC address of the device with which the association timed out 3525 * @bss: The BSS entry with which association timed out.
3496 * 3526 *
3497 * This function may sleep. The caller must hold the corresponding wdev's mutex. 3527 * This function may sleep. The caller must hold the corresponding wdev's mutex.
3498 */ 3528 */
3499void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr); 3529void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss);
3500 3530
3501/** 3531/**
3502 * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame 3532 * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a405a7a9775c..5b7a3dadadde 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -305,6 +305,7 @@ enum ieee80211_rssi_event {
305 * @basic_rates: bitmap of basic rates, each bit stands for an 305 * @basic_rates: bitmap of basic rates, each bit stands for an
306 * index into the rate table configured by the driver in 306 * index into the rate table configured by the driver in
307 * the current band. 307 * the current band.
308 * @beacon_rate: associated AP's beacon TX rate
308 * @mcast_rate: per-band multicast rate index + 1 (0: disabled) 309 * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
309 * @bssid: The BSSID for this BSS 310 * @bssid: The BSSID for this BSS
310 * @enable_beacon: whether beaconing should be enabled or not 311 * @enable_beacon: whether beaconing should be enabled or not
@@ -352,6 +353,7 @@ struct ieee80211_bss_conf {
352 u32 sync_device_ts; 353 u32 sync_device_ts;
353 u8 sync_dtim_count; 354 u8 sync_dtim_count;
354 u32 basic_rates; 355 u32 basic_rates;
356 struct ieee80211_rate *beacon_rate;
355 int mcast_rate[IEEE80211_NUM_BANDS]; 357 int mcast_rate[IEEE80211_NUM_BANDS];
356 u16 ht_operation_mode; 358 u16 ht_operation_mode;
357 s32 cqm_rssi_thold; 359 s32 cqm_rssi_thold;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ca6facf4df0c..861e5eba3953 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2758,6 +2758,8 @@ enum nl80211_channel_type {
2758 * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well 2758 * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well
2759 * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 2759 * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2760 * attribute must be provided as well 2760 * attribute must be provided as well
2761 * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel
2762 * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel
2761 */ 2763 */
2762enum nl80211_chan_width { 2764enum nl80211_chan_width {
2763 NL80211_CHAN_WIDTH_20_NOHT, 2765 NL80211_CHAN_WIDTH_20_NOHT,
@@ -2766,6 +2768,8 @@ enum nl80211_chan_width {
2766 NL80211_CHAN_WIDTH_80, 2768 NL80211_CHAN_WIDTH_80,
2767 NL80211_CHAN_WIDTH_80P80, 2769 NL80211_CHAN_WIDTH_80P80,
2768 NL80211_CHAN_WIDTH_160, 2770 NL80211_CHAN_WIDTH_160,
2771 NL80211_CHAN_WIDTH_5,
2772 NL80211_CHAN_WIDTH_10,
2769}; 2773};
2770 2774
2771/** 2775/**
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ace5e55fe5a3..061523eb52a1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -597,7 +597,15 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
597 struct hci_dev *hdev = req->hdev; 597 struct hci_dev *hdev = req->hdev;
598 u8 p; 598 u8 p;
599 599
600 /* Only send HCI_Delete_Stored_Link_Key if it is supported */ 600 /* Some Broadcom based Bluetooth controllers do not support the
601 * Delete Stored Link Key command. They are clearly indicating its
602 * absence in the bit mask of supported commands.
603 *
604 * Check the supported commands and only if the the command is marked
605 * as supported send it. If not supported assume that the controller
606 * does not have actual support for stored link keys which makes this
607 * command redundant anyway.
608 */
601 if (hdev->commands[6] & 0x80) { 609 if (hdev->commands[6] & 0x80) {
602 struct hci_cp_delete_stored_link_key cp; 610 struct hci_cp_delete_stored_link_key cp;
603 611
@@ -751,7 +759,7 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
751 hdev->discovery.state = state; 759 hdev->discovery.state = state;
752} 760}
753 761
754static void inquiry_cache_flush(struct hci_dev *hdev) 762void hci_inquiry_cache_flush(struct hci_dev *hdev)
755{ 763{
756 struct discovery_state *cache = &hdev->discovery; 764 struct discovery_state *cache = &hdev->discovery;
757 struct inquiry_entry *p, *n; 765 struct inquiry_entry *p, *n;
@@ -964,7 +972,7 @@ int hci_inquiry(void __user *arg)
964 hci_dev_lock(hdev); 972 hci_dev_lock(hdev);
965 if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || 973 if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
966 inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { 974 inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
967 inquiry_cache_flush(hdev); 975 hci_inquiry_cache_flush(hdev);
968 do_inquiry = 1; 976 do_inquiry = 1;
969 } 977 }
970 hci_dev_unlock(hdev); 978 hci_dev_unlock(hdev);
@@ -1201,8 +1209,6 @@ static int hci_dev_do_close(struct hci_dev *hdev)
1201{ 1209{
1202 BT_DBG("%s %p", hdev->name, hdev); 1210 BT_DBG("%s %p", hdev->name, hdev);
1203 1211
1204 cancel_work_sync(&hdev->le_scan);
1205
1206 cancel_delayed_work(&hdev->power_off); 1212 cancel_delayed_work(&hdev->power_off);
1207 1213
1208 hci_req_cancel(hdev, ENODEV); 1214 hci_req_cancel(hdev, ENODEV);
@@ -1230,7 +1236,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
1230 cancel_delayed_work_sync(&hdev->le_scan_disable); 1236 cancel_delayed_work_sync(&hdev->le_scan_disable);
1231 1237
1232 hci_dev_lock(hdev); 1238 hci_dev_lock(hdev);
1233 inquiry_cache_flush(hdev); 1239 hci_inquiry_cache_flush(hdev);
1234 hci_conn_hash_flush(hdev); 1240 hci_conn_hash_flush(hdev);
1235 hci_dev_unlock(hdev); 1241 hci_dev_unlock(hdev);
1236 1242
@@ -1331,7 +1337,7 @@ int hci_dev_reset(__u16 dev)
1331 skb_queue_purge(&hdev->cmd_q); 1337 skb_queue_purge(&hdev->cmd_q);
1332 1338
1333 hci_dev_lock(hdev); 1339 hci_dev_lock(hdev);
1334 inquiry_cache_flush(hdev); 1340 hci_inquiry_cache_flush(hdev);
1335 hci_conn_hash_flush(hdev); 1341 hci_conn_hash_flush(hdev);
1336 hci_dev_unlock(hdev); 1342 hci_dev_unlock(hdev);
1337 1343
@@ -1991,80 +1997,59 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1991 return mgmt_device_unblocked(hdev, bdaddr, type); 1997 return mgmt_device_unblocked(hdev, bdaddr, type);
1992} 1998}
1993 1999
1994static void le_scan_param_req(struct hci_request *req, unsigned long opt) 2000static void inquiry_complete(struct hci_dev *hdev, u8 status)
1995{ 2001{
1996 struct le_scan_params *param = (struct le_scan_params *) opt; 2002 if (status) {
1997 struct hci_cp_le_set_scan_param cp; 2003 BT_ERR("Failed to start inquiry: status %d", status);
1998
1999 memset(&cp, 0, sizeof(cp));
2000 cp.type = param->type;
2001 cp.interval = cpu_to_le16(param->interval);
2002 cp.window = cpu_to_le16(param->window);
2003 2004
2004 hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); 2005 hci_dev_lock(hdev);
2005} 2006 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2006 2007 hci_dev_unlock(hdev);
2007static void le_scan_enable_req(struct hci_request *req, unsigned long opt) 2008 return;
2008{ 2009 }
2009 struct hci_cp_le_set_scan_enable cp;
2010
2011 memset(&cp, 0, sizeof(cp));
2012 cp.enable = LE_SCAN_ENABLE;
2013 cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
2014
2015 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
2016} 2010}
2017 2011
2018static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, 2012static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
2019 u16 window, int timeout)
2020{ 2013{
2021 long timeo = msecs_to_jiffies(3000); 2014 /* General inquiry access code (GIAC) */
2022 struct le_scan_params param; 2015 u8 lap[3] = { 0x33, 0x8b, 0x9e };
2016 struct hci_request req;
2017 struct hci_cp_inquiry cp;
2023 int err; 2018 int err;
2024 2019
2025 BT_DBG("%s", hdev->name); 2020 if (status) {
2026 2021 BT_ERR("Failed to disable LE scanning: status %d", status);
2027 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 2022 return;
2028 return -EINPROGRESS; 2023 }
2029
2030 param.type = type;
2031 param.interval = interval;
2032 param.window = window;
2033
2034 hci_req_lock(hdev);
2035
2036 err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) &param,
2037 timeo);
2038 if (!err)
2039 err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo);
2040
2041 hci_req_unlock(hdev);
2042 2024
2043 if (err < 0) 2025 switch (hdev->discovery.type) {
2044 return err; 2026 case DISCOV_TYPE_LE:
2027 hci_dev_lock(hdev);
2028 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2029 hci_dev_unlock(hdev);
2030 break;
2045 2031
2046 queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, 2032 case DISCOV_TYPE_INTERLEAVED:
2047 timeout); 2033 hci_req_init(&req, hdev);
2048 2034
2049 return 0; 2035 memset(&cp, 0, sizeof(cp));
2050} 2036 memcpy(&cp.lap, lap, sizeof(cp.lap));
2037 cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
2038 hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
2051 2039
2052int hci_cancel_le_scan(struct hci_dev *hdev) 2040 hci_dev_lock(hdev);
2053{
2054 BT_DBG("%s", hdev->name);
2055 2041
2056 if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) 2042 hci_inquiry_cache_flush(hdev);
2057 return -EALREADY;
2058 2043
2059 if (cancel_delayed_work(&hdev->le_scan_disable)) { 2044 err = hci_req_run(&req, inquiry_complete);
2060 struct hci_cp_le_set_scan_enable cp; 2045 if (err) {
2046 BT_ERR("Inquiry request failed: err %d", err);
2047 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2048 }
2061 2049
2062 /* Send HCI command to disable LE Scan */ 2050 hci_dev_unlock(hdev);
2063 memset(&cp, 0, sizeof(cp)); 2051 break;
2064 hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
2065 } 2052 }
2066
2067 return 0;
2068} 2053}
2069 2054
2070static void le_scan_disable_work(struct work_struct *work) 2055static void le_scan_disable_work(struct work_struct *work)
@@ -2072,46 +2057,20 @@ static void le_scan_disable_work(struct work_struct *work)
2072 struct hci_dev *hdev = container_of(work, struct hci_dev, 2057 struct hci_dev *hdev = container_of(work, struct hci_dev,
2073 le_scan_disable.work); 2058 le_scan_disable.work);
2074 struct hci_cp_le_set_scan_enable cp; 2059 struct hci_cp_le_set_scan_enable cp;
2060 struct hci_request req;
2061 int err;
2075 2062
2076 BT_DBG("%s", hdev->name); 2063 BT_DBG("%s", hdev->name);
2077 2064
2078 memset(&cp, 0, sizeof(cp)); 2065 hci_req_init(&req, hdev);
2079
2080 hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
2081}
2082
2083static void le_scan_work(struct work_struct *work)
2084{
2085 struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
2086 struct le_scan_params *param = &hdev->le_scan_params;
2087 2066
2088 BT_DBG("%s", hdev->name); 2067 memset(&cp, 0, sizeof(cp));
2068 cp.enable = LE_SCAN_DISABLE;
2069 hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
2089 2070
2090 hci_do_le_scan(hdev, param->type, param->interval, param->window, 2071 err = hci_req_run(&req, le_scan_disable_work_complete);
2091 param->timeout); 2072 if (err)
2092} 2073 BT_ERR("Disable LE scanning request failed: err %d", err);
2093
2094int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
2095 int timeout)
2096{
2097 struct le_scan_params *param = &hdev->le_scan_params;
2098
2099 BT_DBG("%s", hdev->name);
2100
2101 if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
2102 return -ENOTSUPP;
2103
2104 if (work_busy(&hdev->le_scan))
2105 return -EINPROGRESS;
2106
2107 param->type = type;
2108 param->interval = interval;
2109 param->window = window;
2110 param->timeout = timeout;
2111
2112 queue_work(system_long_wq, &hdev->le_scan);
2113
2114 return 0;
2115} 2074}
2116 2075
2117/* Alloc HCI device */ 2076/* Alloc HCI device */
@@ -2148,7 +2107,6 @@ struct hci_dev *hci_alloc_dev(void)
2148 INIT_WORK(&hdev->cmd_work, hci_cmd_work); 2107 INIT_WORK(&hdev->cmd_work, hci_cmd_work);
2149 INIT_WORK(&hdev->tx_work, hci_tx_work); 2108 INIT_WORK(&hdev->tx_work, hci_tx_work);
2150 INIT_WORK(&hdev->power_on, hci_power_on); 2109 INIT_WORK(&hdev->power_on, hci_power_on);
2151 INIT_WORK(&hdev->le_scan, le_scan_work);
2152 2110
2153 INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); 2111 INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
2154 INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); 2112 INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
@@ -3551,36 +3509,6 @@ static void hci_cmd_work(struct work_struct *work)
3551 } 3509 }
3552} 3510}
3553 3511
3554int hci_do_inquiry(struct hci_dev *hdev, u8 length)
3555{
3556 /* General inquiry access code (GIAC) */
3557 u8 lap[3] = { 0x33, 0x8b, 0x9e };
3558 struct hci_cp_inquiry cp;
3559
3560 BT_DBG("%s", hdev->name);
3561
3562 if (test_bit(HCI_INQUIRY, &hdev->flags))
3563 return -EINPROGRESS;
3564
3565 inquiry_cache_flush(hdev);
3566
3567 memset(&cp, 0, sizeof(cp));
3568 memcpy(&cp.lap, lap, sizeof(cp.lap));
3569 cp.length = length;
3570
3571 return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
3572}
3573
3574int hci_cancel_inquiry(struct hci_dev *hdev)
3575{
3576 BT_DBG("%s", hdev->name);
3577
3578 if (!test_bit(HCI_INQUIRY, &hdev->flags))
3579 return -EALREADY;
3580
3581 return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
3582}
3583
3584u8 bdaddr_to_le(u8 bdaddr_type) 3512u8 bdaddr_to_le(u8 bdaddr_type)
3585{ 3513{
3586 switch (bdaddr_type) { 3514 switch (bdaddr_type) {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b93cd2eb5d58..0437200d92f4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -40,21 +40,13 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
40 40
41 BT_DBG("%s status 0x%2.2x", hdev->name, status); 41 BT_DBG("%s status 0x%2.2x", hdev->name, status);
42 42
43 if (status) { 43 if (status)
44 hci_dev_lock(hdev);
45 mgmt_stop_discovery_failed(hdev, status);
46 hci_dev_unlock(hdev);
47 return; 44 return;
48 }
49 45
50 clear_bit(HCI_INQUIRY, &hdev->flags); 46 clear_bit(HCI_INQUIRY, &hdev->flags);
51 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ 47 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
52 wake_up_bit(&hdev->flags, HCI_INQUIRY); 48 wake_up_bit(&hdev->flags, HCI_INQUIRY);
53 49
54 hci_dev_lock(hdev);
55 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
56 hci_dev_unlock(hdev);
57
58 hci_conn_check_pending(hdev); 50 hci_conn_check_pending(hdev);
59} 51}
60 52
@@ -937,20 +929,6 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
937 hci_dev_unlock(hdev); 929 hci_dev_unlock(hdev);
938} 930}
939 931
940static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
941{
942 __u8 status = *((__u8 *) skb->data);
943
944 BT_DBG("%s status 0x%2.2x", hdev->name, status);
945
946 if (status) {
947 hci_dev_lock(hdev);
948 mgmt_start_discovery_failed(hdev, status);
949 hci_dev_unlock(hdev);
950 return;
951 }
952}
953
954static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 932static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
955 struct sk_buff *skb) 933 struct sk_buff *skb)
956{ 934{
@@ -963,41 +941,16 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
963 if (!cp) 941 if (!cp)
964 return; 942 return;
965 943
944 if (status)
945 return;
946
966 switch (cp->enable) { 947 switch (cp->enable) {
967 case LE_SCAN_ENABLE: 948 case LE_SCAN_ENABLE:
968 if (status) {
969 hci_dev_lock(hdev);
970 mgmt_start_discovery_failed(hdev, status);
971 hci_dev_unlock(hdev);
972 return;
973 }
974
975 set_bit(HCI_LE_SCAN, &hdev->dev_flags); 949 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
976
977 hci_dev_lock(hdev);
978 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
979 hci_dev_unlock(hdev);
980 break; 950 break;
981 951
982 case LE_SCAN_DISABLE: 952 case LE_SCAN_DISABLE:
983 if (status) {
984 hci_dev_lock(hdev);
985 mgmt_stop_discovery_failed(hdev, status);
986 hci_dev_unlock(hdev);
987 return;
988 }
989
990 clear_bit(HCI_LE_SCAN, &hdev->dev_flags); 953 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
991
992 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
993 hdev->discovery.state == DISCOVERY_FINDING) {
994 mgmt_interleaved_discovery(hdev);
995 } else {
996 hci_dev_lock(hdev);
997 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
998 hci_dev_unlock(hdev);
999 }
1000
1001 break; 954 break;
1002 955
1003 default: 956 default:
@@ -1077,18 +1030,10 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1077 1030
1078 if (status) { 1031 if (status) {
1079 hci_conn_check_pending(hdev); 1032 hci_conn_check_pending(hdev);
1080 hci_dev_lock(hdev);
1081 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1082 mgmt_start_discovery_failed(hdev, status);
1083 hci_dev_unlock(hdev);
1084 return; 1033 return;
1085 } 1034 }
1086 1035
1087 set_bit(HCI_INQUIRY, &hdev->flags); 1036 set_bit(HCI_INQUIRY, &hdev->flags);
1088
1089 hci_dev_lock(hdev);
1090 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
1091 hci_dev_unlock(hdev);
1092} 1037}
1093 1038
1094static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 1039static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
@@ -2298,10 +2243,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2298 hci_cc_user_passkey_neg_reply(hdev, skb); 2243 hci_cc_user_passkey_neg_reply(hdev, skb);
2299 break; 2244 break;
2300 2245
2301 case HCI_OP_LE_SET_SCAN_PARAM:
2302 hci_cc_le_set_scan_param(hdev, skb);
2303 break;
2304
2305 case HCI_OP_LE_SET_ADV_ENABLE: 2246 case HCI_OP_LE_SET_ADV_ENABLE:
2306 hci_cc_le_set_adv_enable(hdev, skb); 2247 hci_cc_le_set_adv_enable(hdev, skb);
2307 break; 2248 break;
@@ -2670,7 +2611,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2670 2611
2671 BT_DBG("%s", hdev->name); 2612 BT_DBG("%s", hdev->name);
2672 2613
2673 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) 2614 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2674 return; 2615 return;
2675 2616
2676 hci_dev_lock(hdev); 2617 hci_dev_lock(hdev);
@@ -2746,7 +2687,7 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2746 hci_conn_drop(conn); 2687 hci_conn_drop(conn);
2747 } 2688 }
2748 2689
2749 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) 2690 if (test_bit(HCI_MGMT, &hdev->dev_flags))
2750 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, 2691 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
2751 ev->key_type, pin_len); 2692 ev->key_type, pin_len);
2752 2693
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 940f5acb6694..f13a8da441a8 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -76,25 +76,19 @@ static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo
76 ci->flags = session->flags; 76 ci->flags = session->flags;
77 ci->state = BT_CONNECTED; 77 ci->state = BT_CONNECTED;
78 78
79 ci->vendor = 0x0000;
80 ci->product = 0x0000;
81 ci->version = 0x0000;
82
83 if (session->input) { 79 if (session->input) {
84 ci->vendor = session->input->id.vendor; 80 ci->vendor = session->input->id.vendor;
85 ci->product = session->input->id.product; 81 ci->product = session->input->id.product;
86 ci->version = session->input->id.version; 82 ci->version = session->input->id.version;
87 if (session->input->name) 83 if (session->input->name)
88 strncpy(ci->name, session->input->name, 128); 84 strlcpy(ci->name, session->input->name, 128);
89 else 85 else
90 strncpy(ci->name, "HID Boot Device", 128); 86 strlcpy(ci->name, "HID Boot Device", 128);
91 } 87 } else if (session->hid) {
92
93 if (session->hid) {
94 ci->vendor = session->hid->vendor; 88 ci->vendor = session->hid->vendor;
95 ci->product = session->hid->product; 89 ci->product = session->hid->product;
96 ci->version = session->hid->version; 90 ci->version = session->hid->version;
97 strncpy(ci->name, session->hid->name, 128); 91 strlcpy(ci->name, session->hid->name, 128);
98 } 92 }
99} 93}
100 94
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4be6a264b475..8c3499bec893 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -504,8 +504,10 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
504 if (conn->hcon->type == LE_LINK) { 504 if (conn->hcon->type == LE_LINK) {
505 /* LE connection */ 505 /* LE connection */
506 chan->omtu = L2CAP_DEFAULT_MTU; 506 chan->omtu = L2CAP_DEFAULT_MTU;
507 chan->scid = L2CAP_CID_LE_DATA; 507 if (chan->dcid == L2CAP_CID_ATT)
508 chan->dcid = L2CAP_CID_LE_DATA; 508 chan->scid = L2CAP_CID_ATT;
509 else
510 chan->scid = l2cap_alloc_cid(conn);
509 } else { 511 } else {
510 /* Alloc CID for connection-oriented socket */ 512 /* Alloc CID for connection-oriented socket */
511 chan->scid = l2cap_alloc_cid(conn); 513 chan->scid = l2cap_alloc_cid(conn);
@@ -543,6 +545,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
543 545
544 l2cap_chan_hold(chan); 546 l2cap_chan_hold(chan);
545 547
548 hci_conn_hold(conn->hcon);
549
546 list_add(&chan->list, &conn->chan_l); 550 list_add(&chan->list, &conn->chan_l);
547} 551}
548 552
@@ -1338,17 +1342,21 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
1338 1342
1339static void l2cap_le_conn_ready(struct l2cap_conn *conn) 1343static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1340{ 1344{
1341 struct sock *parent, *sk; 1345 struct sock *parent;
1342 struct l2cap_chan *chan, *pchan; 1346 struct l2cap_chan *chan, *pchan;
1343 1347
1344 BT_DBG(""); 1348 BT_DBG("");
1345 1349
1346 /* Check if we have socket listening on cid */ 1350 /* Check if we have socket listening on cid */
1347 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, 1351 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
1348 conn->src, conn->dst); 1352 conn->src, conn->dst);
1349 if (!pchan) 1353 if (!pchan)
1350 return; 1354 return;
1351 1355
1356 /* Client ATT sockets should override the server one */
1357 if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
1358 return;
1359
1352 parent = pchan->sk; 1360 parent = pchan->sk;
1353 1361
1354 lock_sock(parent); 1362 lock_sock(parent);
@@ -1357,17 +1365,12 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1357 if (!chan) 1365 if (!chan)
1358 goto clean; 1366 goto clean;
1359 1367
1360 sk = chan->sk; 1368 chan->dcid = L2CAP_CID_ATT;
1361 1369
1362 hci_conn_hold(conn->hcon); 1370 bacpy(&bt_sk(chan->sk)->src, conn->src);
1363 conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT; 1371 bacpy(&bt_sk(chan->sk)->dst, conn->dst);
1364 1372
1365 bacpy(&bt_sk(sk)->src, conn->src); 1373 __l2cap_chan_add(conn, chan);
1366 bacpy(&bt_sk(sk)->dst, conn->dst);
1367
1368 l2cap_chan_add(conn, chan);
1369
1370 l2cap_chan_ready(chan);
1371 1374
1372clean: 1375clean:
1373 release_sock(parent); 1376 release_sock(parent);
@@ -1380,14 +1383,17 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
1380 1383
1381 BT_DBG("conn %p", conn); 1384 BT_DBG("conn %p", conn);
1382 1385
1383 if (!hcon->out && hcon->type == LE_LINK) 1386 /* For outgoing pairing which doesn't necessarily have an
1384 l2cap_le_conn_ready(conn); 1387 * associated socket (e.g. mgmt_pair_device).
1385 1388 */
1386 if (hcon->out && hcon->type == LE_LINK) 1389 if (hcon->out && hcon->type == LE_LINK)
1387 smp_conn_security(hcon, hcon->pending_sec_level); 1390 smp_conn_security(hcon, hcon->pending_sec_level);
1388 1391
1389 mutex_lock(&conn->chan_lock); 1392 mutex_lock(&conn->chan_lock);
1390 1393
1394 if (hcon->type == LE_LINK)
1395 l2cap_le_conn_ready(conn);
1396
1391 list_for_each_entry(chan, &conn->chan_l, list) { 1397 list_for_each_entry(chan, &conn->chan_l, list) {
1392 1398
1393 l2cap_chan_lock(chan); 1399 l2cap_chan_lock(chan);
@@ -1792,7 +1798,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1792 1798
1793 auth_type = l2cap_get_auth_type(chan); 1799 auth_type = l2cap_get_auth_type(chan);
1794 1800
1795 if (chan->dcid == L2CAP_CID_LE_DATA) 1801 if (bdaddr_type_is_le(dst_type))
1796 hcon = hci_connect(hdev, LE_LINK, dst, dst_type, 1802 hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
1797 chan->sec_level, auth_type); 1803 chan->sec_level, auth_type);
1798 else 1804 else
@@ -1811,16 +1817,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1811 goto done; 1817 goto done;
1812 } 1818 }
1813 1819
1814 if (hcon->type == LE_LINK) { 1820 if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
1815 err = 0; 1821 hci_conn_drop(hcon);
1816 1822 err = -EBUSY;
1817 if (!list_empty(&conn->chan_l)) { 1823 goto done;
1818 err = -EBUSY;
1819 hci_conn_drop(hcon);
1820 }
1821
1822 if (err)
1823 goto done;
1824 } 1824 }
1825 1825
1826 /* Update source addr of the socket */ 1826 /* Update source addr of the socket */
@@ -1830,6 +1830,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1830 l2cap_chan_add(conn, chan); 1830 l2cap_chan_add(conn, chan);
1831 l2cap_chan_lock(chan); 1831 l2cap_chan_lock(chan);
1832 1832
1833 /* l2cap_chan_add takes its own ref so we can drop this one */
1834 hci_conn_drop(hcon);
1835
1833 l2cap_state_change(chan, BT_CONNECT); 1836 l2cap_state_change(chan, BT_CONNECT);
1834 __set_chan_timer(chan, sk->sk_sndtimeo); 1837 __set_chan_timer(chan, sk->sk_sndtimeo);
1835 1838
@@ -3751,8 +3754,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3751 3754
3752 sk = chan->sk; 3755 sk = chan->sk;
3753 3756
3754 hci_conn_hold(conn->hcon);
3755
3756 bacpy(&bt_sk(sk)->src, conn->src); 3757 bacpy(&bt_sk(sk)->src, conn->src);
3757 bacpy(&bt_sk(sk)->dst, conn->dst); 3758 bacpy(&bt_sk(sk)->dst, conn->dst);
3758 chan->psm = psm; 3759 chan->psm = psm;
@@ -4333,7 +4334,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4333 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; 4334 struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
4334 u16 type, result; 4335 u16 type, result;
4335 4336
4336 if (cmd_len != sizeof(*rsp)) 4337 if (cmd_len < sizeof(*rsp))
4337 return -EPROTO; 4338 return -EPROTO;
4338 4339
4339 type = __le16_to_cpu(rsp->type); 4340 type = __le16_to_cpu(rsp->type);
@@ -5292,6 +5293,51 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
5292 } 5293 }
5293} 5294}
5294 5295
5296static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5297 struct sk_buff *skb)
5298{
5299 u8 *data = skb->data;
5300 int len = skb->len;
5301 struct l2cap_cmd_hdr cmd;
5302 int err;
5303
5304 l2cap_raw_recv(conn, skb);
5305
5306 while (len >= L2CAP_CMD_HDR_SIZE) {
5307 u16 cmd_len;
5308 memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
5309 data += L2CAP_CMD_HDR_SIZE;
5310 len -= L2CAP_CMD_HDR_SIZE;
5311
5312 cmd_len = le16_to_cpu(cmd.len);
5313
5314 BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len,
5315 cmd.ident);
5316
5317 if (cmd_len > len || !cmd.ident) {
5318 BT_DBG("corrupted command");
5319 break;
5320 }
5321
5322 err = l2cap_le_sig_cmd(conn, &cmd, data);
5323 if (err) {
5324 struct l2cap_cmd_rej_unk rej;
5325
5326 BT_ERR("Wrong link type (%d)", err);
5327
5328 /* FIXME: Map err to a valid reason */
5329 rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
5330 l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
5331 sizeof(rej), &rej);
5332 }
5333
5334 data += cmd_len;
5335 len -= cmd_len;
5336 }
5337
5338 kfree_skb(skb);
5339}
5340
5295static inline void l2cap_sig_channel(struct l2cap_conn *conn, 5341static inline void l2cap_sig_channel(struct l2cap_conn *conn,
5296 struct sk_buff *skb) 5342 struct sk_buff *skb)
5297{ 5343{
@@ -5318,11 +5364,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
5318 break; 5364 break;
5319 } 5365 }
5320 5366
5321 if (conn->hcon->type == LE_LINK) 5367 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
5322 err = l2cap_le_sig_cmd(conn, &cmd, data);
5323 else
5324 err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data);
5325
5326 if (err) { 5368 if (err) {
5327 struct l2cap_cmd_rej_unk rej; 5369 struct l2cap_cmd_rej_unk rej;
5328 5370
@@ -6356,16 +6398,13 @@ static void l2cap_att_channel(struct l2cap_conn *conn,
6356{ 6398{
6357 struct l2cap_chan *chan; 6399 struct l2cap_chan *chan;
6358 6400
6359 chan = l2cap_global_chan_by_scid(0, L2CAP_CID_LE_DATA, 6401 chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
6360 conn->src, conn->dst); 6402 conn->src, conn->dst);
6361 if (!chan) 6403 if (!chan)
6362 goto drop; 6404 goto drop;
6363 6405
6364 BT_DBG("chan %p, len %d", chan, skb->len); 6406 BT_DBG("chan %p, len %d", chan, skb->len);
6365 6407
6366 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
6367 goto drop;
6368
6369 if (chan->imtu < skb->len) 6408 if (chan->imtu < skb->len)
6370 goto drop; 6409 goto drop;
6371 6410
@@ -6395,6 +6434,8 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6395 6434
6396 switch (cid) { 6435 switch (cid) {
6397 case L2CAP_CID_LE_SIGNALING: 6436 case L2CAP_CID_LE_SIGNALING:
6437 l2cap_le_sig_channel(conn, skb);
6438 break;
6398 case L2CAP_CID_SIGNALING: 6439 case L2CAP_CID_SIGNALING:
6399 l2cap_sig_channel(conn, skb); 6440 l2cap_sig_channel(conn, skb);
6400 break; 6441 break;
@@ -6405,7 +6446,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
6405 l2cap_conless_channel(conn, psm, skb); 6446 l2cap_conless_channel(conn, psm, skb);
6406 break; 6447 break;
6407 6448
6408 case L2CAP_CID_LE_DATA: 6449 case L2CAP_CID_ATT:
6409 l2cap_att_channel(conn, skb); 6450 l2cap_att_channel(conn, skb);
6410 break; 6451 break;
6411 6452
@@ -6531,7 +6572,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
6531 continue; 6572 continue;
6532 } 6573 }
6533 6574
6534 if (chan->scid == L2CAP_CID_LE_DATA) { 6575 if (chan->scid == L2CAP_CID_ATT) {
6535 if (!status && encrypt) { 6576 if (!status && encrypt) {
6536 chan->sec_level = hcon->sec_level; 6577 chan->sec_level = hcon->sec_level;
6537 l2cap_chan_ready(chan); 6578 l2cap_chan_ready(chan);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 36fed40c162c..0098af80b213 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -466,7 +466,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
466static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) 466static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu)
467{ 467{
468 switch (chan->scid) { 468 switch (chan->scid) {
469 case L2CAP_CID_LE_DATA: 469 case L2CAP_CID_ATT:
470 if (mtu < L2CAP_LE_MIN_MTU) 470 if (mtu < L2CAP_LE_MIN_MTU)
471 return false; 471 return false;
472 break; 472 break;
@@ -630,7 +630,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
630 conn = chan->conn; 630 conn = chan->conn;
631 631
632 /*change security for LE channels */ 632 /*change security for LE channels */
633 if (chan->scid == L2CAP_CID_LE_DATA) { 633 if (chan->scid == L2CAP_CID_ATT) {
634 if (!conn->hcon->out) { 634 if (!conn->hcon->out) {
635 err = -EINVAL; 635 err = -EINVAL;
636 break; 636 break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f8ecbc70293d..fedc5399d465 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -102,18 +102,6 @@ static const u16 mgmt_events[] = {
102 MGMT_EV_PASSKEY_NOTIFY, 102 MGMT_EV_PASSKEY_NOTIFY,
103}; 103};
104 104
105/*
106 * These LE scan and inquiry parameters were chosen according to LE General
107 * Discovery Procedure specification.
108 */
109#define LE_SCAN_WIN 0x12
110#define LE_SCAN_INT 0x12
111#define LE_SCAN_TIMEOUT_LE_ONLY msecs_to_jiffies(10240)
112#define LE_SCAN_TIMEOUT_BREDR_LE msecs_to_jiffies(5120)
113
114#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */
115#define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */
116
117#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) 105#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
118 106
119#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ 107#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \
@@ -1748,8 +1736,6 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
1748 1736
1749 hci_link_keys_clear(hdev); 1737 hci_link_keys_clear(hdev);
1750 1738
1751 set_bit(HCI_LINK_KEYS, &hdev->dev_flags);
1752
1753 if (cp->debug_keys) 1739 if (cp->debug_keys)
1754 set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); 1740 set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
1755 else 1741 else
@@ -2633,28 +2619,72 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
2633 return err; 2619 return err;
2634} 2620}
2635 2621
2636int mgmt_interleaved_discovery(struct hci_dev *hdev) 2622static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
2637{ 2623{
2624 struct pending_cmd *cmd;
2625 u8 type;
2638 int err; 2626 int err;
2639 2627
2640 BT_DBG("%s", hdev->name); 2628 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2641 2629
2642 hci_dev_lock(hdev); 2630 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
2631 if (!cmd)
2632 return -ENOENT;
2643 2633
2644 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR_LE); 2634 type = hdev->discovery.type;
2645 if (err < 0)
2646 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2647 2635
2648 hci_dev_unlock(hdev); 2636 err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
2637 &type, sizeof(type));
2638 mgmt_pending_remove(cmd);
2649 2639
2650 return err; 2640 return err;
2651} 2641}
2652 2642
2643static void start_discovery_complete(struct hci_dev *hdev, u8 status)
2644{
2645 BT_DBG("status %d", status);
2646
2647 if (status) {
2648 hci_dev_lock(hdev);
2649 mgmt_start_discovery_failed(hdev, status);
2650 hci_dev_unlock(hdev);
2651 return;
2652 }
2653
2654 hci_dev_lock(hdev);
2655 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
2656 hci_dev_unlock(hdev);
2657
2658 switch (hdev->discovery.type) {
2659 case DISCOV_TYPE_LE:
2660 queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
2661 DISCOV_LE_TIMEOUT);
2662 break;
2663
2664 case DISCOV_TYPE_INTERLEAVED:
2665 queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
2666 DISCOV_INTERLEAVED_TIMEOUT);
2667 break;
2668
2669 case DISCOV_TYPE_BREDR:
2670 break;
2671
2672 default:
2673 BT_ERR("Invalid discovery type %d", hdev->discovery.type);
2674 }
2675}
2676
2653static int start_discovery(struct sock *sk, struct hci_dev *hdev, 2677static int start_discovery(struct sock *sk, struct hci_dev *hdev,
2654 void *data, u16 len) 2678 void *data, u16 len)
2655{ 2679{
2656 struct mgmt_cp_start_discovery *cp = data; 2680 struct mgmt_cp_start_discovery *cp = data;
2657 struct pending_cmd *cmd; 2681 struct pending_cmd *cmd;
2682 struct hci_cp_le_set_scan_param param_cp;
2683 struct hci_cp_le_set_scan_enable enable_cp;
2684 struct hci_cp_inquiry inq_cp;
2685 struct hci_request req;
2686 /* General inquiry access code (GIAC) */
2687 u8 lap[3] = { 0x33, 0x8b, 0x9e };
2658 int err; 2688 int err;
2659 2689
2660 BT_DBG("%s", hdev->name); 2690 BT_DBG("%s", hdev->name);
@@ -2687,6 +2717,8 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
2687 2717
2688 hdev->discovery.type = cp->type; 2718 hdev->discovery.type = cp->type;
2689 2719
2720 hci_req_init(&req, hdev);
2721
2690 switch (hdev->discovery.type) { 2722 switch (hdev->discovery.type) {
2691 case DISCOV_TYPE_BREDR: 2723 case DISCOV_TYPE_BREDR:
2692 if (!lmp_bredr_capable(hdev)) { 2724 if (!lmp_bredr_capable(hdev)) {
@@ -2696,10 +2728,23 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
2696 goto failed; 2728 goto failed;
2697 } 2729 }
2698 2730
2699 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); 2731 if (test_bit(HCI_INQUIRY, &hdev->flags)) {
2732 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2733 MGMT_STATUS_BUSY);
2734 mgmt_pending_remove(cmd);
2735 goto failed;
2736 }
2737
2738 hci_inquiry_cache_flush(hdev);
2739
2740 memset(&inq_cp, 0, sizeof(inq_cp));
2741 memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap));
2742 inq_cp.length = DISCOV_BREDR_INQUIRY_LEN;
2743 hci_req_add(&req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp);
2700 break; 2744 break;
2701 2745
2702 case DISCOV_TYPE_LE: 2746 case DISCOV_TYPE_LE:
2747 case DISCOV_TYPE_INTERLEAVED:
2703 if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 2748 if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
2704 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 2749 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2705 MGMT_STATUS_NOT_SUPPORTED); 2750 MGMT_STATUS_NOT_SUPPORTED);
@@ -2707,20 +2752,40 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
2707 goto failed; 2752 goto failed;
2708 } 2753 }
2709 2754
2710 err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, 2755 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
2711 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY); 2756 !lmp_bredr_capable(hdev)) {
2712 break;
2713
2714 case DISCOV_TYPE_INTERLEAVED:
2715 if (!lmp_host_le_capable(hdev) || !lmp_bredr_capable(hdev)) {
2716 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, 2757 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2717 MGMT_STATUS_NOT_SUPPORTED); 2758 MGMT_STATUS_NOT_SUPPORTED);
2718 mgmt_pending_remove(cmd); 2759 mgmt_pending_remove(cmd);
2719 goto failed; 2760 goto failed;
2720 } 2761 }
2721 2762
2722 err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, 2763 if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) {
2723 LE_SCAN_WIN, LE_SCAN_TIMEOUT_BREDR_LE); 2764 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2765 MGMT_STATUS_REJECTED);
2766 mgmt_pending_remove(cmd);
2767 goto failed;
2768 }
2769
2770 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
2771 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2772 MGMT_STATUS_BUSY);
2773 mgmt_pending_remove(cmd);
2774 goto failed;
2775 }
2776
2777 memset(&param_cp, 0, sizeof(param_cp));
2778 param_cp.type = LE_SCAN_ACTIVE;
2779 param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
2780 param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
2781 hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
2782 &param_cp);
2783
2784 memset(&enable_cp, 0, sizeof(enable_cp));
2785 enable_cp.enable = LE_SCAN_ENABLE;
2786 enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
2787 hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
2788 &enable_cp);
2724 break; 2789 break;
2725 2790
2726 default: 2791 default:
@@ -2730,6 +2795,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
2730 goto failed; 2795 goto failed;
2731 } 2796 }
2732 2797
2798 err = hci_req_run(&req, start_discovery_complete);
2733 if (err < 0) 2799 if (err < 0)
2734 mgmt_pending_remove(cmd); 2800 mgmt_pending_remove(cmd);
2735 else 2801 else
@@ -2740,6 +2806,39 @@ failed:
2740 return err; 2806 return err;
2741} 2807}
2742 2808
2809static int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
2810{
2811 struct pending_cmd *cmd;
2812 int err;
2813
2814 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
2815 if (!cmd)
2816 return -ENOENT;
2817
2818 err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
2819 &hdev->discovery.type, sizeof(hdev->discovery.type));
2820 mgmt_pending_remove(cmd);
2821
2822 return err;
2823}
2824
2825static void stop_discovery_complete(struct hci_dev *hdev, u8 status)
2826{
2827 BT_DBG("status %d", status);
2828
2829 hci_dev_lock(hdev);
2830
2831 if (status) {
2832 mgmt_stop_discovery_failed(hdev, status);
2833 goto unlock;
2834 }
2835
2836 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2837
2838unlock:
2839 hci_dev_unlock(hdev);
2840}
2841
2743static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, 2842static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
2744 u16 len) 2843 u16 len)
2745{ 2844{
@@ -2747,6 +2846,8 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
2747 struct pending_cmd *cmd; 2846 struct pending_cmd *cmd;
2748 struct hci_cp_remote_name_req_cancel cp; 2847 struct hci_cp_remote_name_req_cancel cp;
2749 struct inquiry_entry *e; 2848 struct inquiry_entry *e;
2849 struct hci_request req;
2850 struct hci_cp_le_set_scan_enable enable_cp;
2750 int err; 2851 int err;
2751 2852
2752 BT_DBG("%s", hdev->name); 2853 BT_DBG("%s", hdev->name);
@@ -2773,12 +2874,20 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
2773 goto unlock; 2874 goto unlock;
2774 } 2875 }
2775 2876
2877 hci_req_init(&req, hdev);
2878
2776 switch (hdev->discovery.state) { 2879 switch (hdev->discovery.state) {
2777 case DISCOVERY_FINDING: 2880 case DISCOVERY_FINDING:
2778 if (test_bit(HCI_INQUIRY, &hdev->flags)) 2881 if (test_bit(HCI_INQUIRY, &hdev->flags)) {
2779 err = hci_cancel_inquiry(hdev); 2882 hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2780 else 2883 } else {
2781 err = hci_cancel_le_scan(hdev); 2884 cancel_delayed_work(&hdev->le_scan_disable);
2885
2886 memset(&enable_cp, 0, sizeof(enable_cp));
2887 enable_cp.enable = LE_SCAN_DISABLE;
2888 hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE,
2889 sizeof(enable_cp), &enable_cp);
2890 }
2782 2891
2783 break; 2892 break;
2784 2893
@@ -2796,16 +2905,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
2796 } 2905 }
2797 2906
2798 bacpy(&cp.bdaddr, &e->data.bdaddr); 2907 bacpy(&cp.bdaddr, &e->data.bdaddr);
2799 err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL, 2908 hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
2800 sizeof(cp), &cp); 2909 &cp);
2801 2910
2802 break; 2911 break;
2803 2912
2804 default: 2913 default:
2805 BT_DBG("unknown discovery state %u", hdev->discovery.state); 2914 BT_DBG("unknown discovery state %u", hdev->discovery.state);
2806 err = -EFAULT; 2915
2916 mgmt_pending_remove(cmd);
2917 err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
2918 MGMT_STATUS_FAILED, &mgmt_cp->type,
2919 sizeof(mgmt_cp->type));
2920 goto unlock;
2807 } 2921 }
2808 2922
2923 err = hci_req_run(&req, stop_discovery_complete);
2809 if (err < 0) 2924 if (err < 0)
2810 mgmt_pending_remove(cmd); 2925 mgmt_pending_remove(cmd);
2811 else 2926 else
@@ -4063,6 +4178,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
4063 struct mgmt_ev_device_found *ev = (void *) buf; 4178 struct mgmt_ev_device_found *ev = (void *) buf;
4064 size_t ev_size; 4179 size_t ev_size;
4065 4180
4181 if (!hci_discovery_active(hdev))
4182 return -EPERM;
4183
4066 /* Leave 5 bytes for a potential CoD field */ 4184 /* Leave 5 bytes for a potential CoD field */
4067 if (sizeof(*ev) + eir_len + 5 > sizeof(buf)) 4185 if (sizeof(*ev) + eir_len + 5 > sizeof(buf))
4068 return -EINVAL; 4186 return -EINVAL;
@@ -4114,43 +4232,6 @@ int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
4114 sizeof(*ev) + eir_len, NULL); 4232 sizeof(*ev) + eir_len, NULL);
4115} 4233}
4116 4234
4117int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
4118{
4119 struct pending_cmd *cmd;
4120 u8 type;
4121 int err;
4122
4123 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
4124
4125 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
4126 if (!cmd)
4127 return -ENOENT;
4128
4129 type = hdev->discovery.type;
4130
4131 err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
4132 &type, sizeof(type));
4133 mgmt_pending_remove(cmd);
4134
4135 return err;
4136}
4137
4138int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
4139{
4140 struct pending_cmd *cmd;
4141 int err;
4142
4143 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
4144 if (!cmd)
4145 return -ENOENT;
4146
4147 err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
4148 &hdev->discovery.type, sizeof(hdev->discovery.type));
4149 mgmt_pending_remove(cmd);
4150
4151 return err;
4152}
4153
4154int mgmt_discovering(struct hci_dev *hdev, u8 discovering) 4235int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
4155{ 4236{
4156 struct mgmt_ev_discovering ev; 4237 struct mgmt_ev_discovering ev;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 082f270b5912..8184d121ff09 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2827,7 +2827,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2827 !rcu_access_pointer(sdata->bss->beacon)) 2827 !rcu_access_pointer(sdata->bss->beacon))
2828 need_offchan = true; 2828 need_offchan = true;
2829 if (!ieee80211_is_action(mgmt->frame_control) || 2829 if (!ieee80211_is_action(mgmt->frame_control) ||
2830 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 2830 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC ||
2831 mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED)
2831 break; 2832 break;
2832 rcu_read_lock(); 2833 rcu_read_lock();
2833 sta = sta_info_get(sdata, mgmt->da); 2834 sta = sta_info_get(sdata, mgmt->da);
@@ -2930,19 +2931,8 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
2930 u16 frame_type, bool reg) 2931 u16 frame_type, bool reg)
2931{ 2932{
2932 struct ieee80211_local *local = wiphy_priv(wiphy); 2933 struct ieee80211_local *local = wiphy_priv(wiphy);
2933 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2934 2934
2935 switch (frame_type) { 2935 switch (frame_type) {
2936 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
2937 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2938 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2939
2940 if (reg)
2941 ifibss->auth_frame_registrations++;
2942 else
2943 ifibss->auth_frame_registrations--;
2944 }
2945 break;
2946 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: 2936 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
2947 if (reg) 2937 if (reg)
2948 local->probe_req_reg++; 2938 local->probe_req_reg++;
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 75dff338f581..f83534f6a2ee 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -281,13 +281,14 @@ void ieee80211_ba_session_work(struct work_struct *work)
281 sta, tid, WLAN_BACK_RECIPIENT, 281 sta, tid, WLAN_BACK_RECIPIENT,
282 WLAN_REASON_UNSPECIFIED, true); 282 WLAN_REASON_UNSPECIFIED, true);
283 283
284 spin_lock_bh(&sta->lock);
285
284 tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; 286 tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
285 if (tid_tx) { 287 if (tid_tx) {
286 /* 288 /*
287 * Assign it over to the normal tid_tx array 289 * Assign it over to the normal tid_tx array
288 * where it "goes live". 290 * where it "goes live".
289 */ 291 */
290 spin_lock_bh(&sta->lock);
291 292
292 sta->ampdu_mlme.tid_start_tx[tid] = NULL; 293 sta->ampdu_mlme.tid_start_tx[tid] = NULL;
293 /* could there be a race? */ 294 /* could there be a race? */
@@ -300,6 +301,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
300 ieee80211_tx_ba_session_handle_start(sta, tid); 301 ieee80211_tx_ba_session_handle_start(sta, tid);
301 continue; 302 continue;
302 } 303 }
304 spin_unlock_bh(&sta->lock);
303 305
304 tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 306 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
305 if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, 307 if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index caa4b4f7f6e4..ea7b9c2c7e66 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -81,7 +81,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
81 81
82 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 82 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
83 83
84 cfg80211_chandef_create(&chandef, chan, ifibss->channel_type); 84 chandef = ifibss->chandef;
85 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { 85 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
86 chandef.width = NL80211_CHAN_WIDTH_20; 86 chandef.width = NL80211_CHAN_WIDTH_20;
87 chandef.center_freq1 = chan->center_freq; 87 chandef.center_freq1 = chan->center_freq;
@@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
176 176
177 /* add HT capability and information IEs */ 177 /* add HT capability and information IEs */
178 if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && 178 if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
179 chandef.width != NL80211_CHAN_WIDTH_5 &&
180 chandef.width != NL80211_CHAN_WIDTH_10 &&
179 sband->ht_cap.ht_supported) { 181 sband->ht_cap.ht_supported) {
180 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, 182 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
181 sband->ht_cap.cap); 183 sband->ht_cap.cap);
@@ -298,8 +300,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
298 tsf, false); 300 tsf, false);
299} 301}
300 302
301static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, 303static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
302 bool auth)
303 __acquires(RCU) 304 __acquires(RCU)
304{ 305{
305 struct ieee80211_sub_if_data *sdata = sta->sdata; 306 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -321,20 +322,12 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
321 /* If it fails, maybe we raced another insertion? */ 322 /* If it fails, maybe we raced another insertion? */
322 if (sta_info_insert_rcu(sta)) 323 if (sta_info_insert_rcu(sta))
323 return sta_info_get(sdata, addr); 324 return sta_info_get(sdata, addr);
324 if (auth && !sdata->u.ibss.auth_frame_registrations) {
325 ibss_dbg(sdata,
326 "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
327 sdata->vif.addr, addr, sdata->u.ibss.bssid);
328 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0,
329 addr, sdata->u.ibss.bssid, NULL, 0, 0, 0);
330 }
331 return sta; 325 return sta;
332} 326}
333 327
334static struct sta_info * 328static struct sta_info *
335ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 329ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
336 const u8 *bssid, const u8 *addr, 330 const u8 *addr, u32 supp_rates)
337 u32 supp_rates, bool auth)
338 __acquires(RCU) 331 __acquires(RCU)
339{ 332{
340 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 333 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -385,7 +378,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
385 sta->sta.supp_rates[band] = supp_rates | 378 sta->sta.supp_rates[band] = supp_rates |
386 ieee80211_mandatory_rates(sband); 379 ieee80211_mandatory_rates(sband);
387 380
388 return ieee80211_ibss_finish_sta(sta, auth); 381 return ieee80211_ibss_finish_sta(sta);
389} 382}
390 383
391static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, 384static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
@@ -407,8 +400,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
407 size_t len) 400 size_t len)
408{ 401{
409 u16 auth_alg, auth_transaction; 402 u16 auth_alg, auth_transaction;
410 struct sta_info *sta;
411 u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
412 403
413 sdata_assert_lock(sdata); 404 sdata_assert_lock(sdata);
414 405
@@ -425,22 +416,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
425 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) 416 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
426 return; 417 return;
427 418
428 sta_info_destroy_addr(sdata, mgmt->sa);
429 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
430 rcu_read_unlock();
431
432 /*
433 * if we have any problem in allocating the new station, we reply with a
434 * DEAUTH frame to tell the other end that we had a problem
435 */
436 if (!sta) {
437 ieee80211_send_deauth_disassoc(sdata, sdata->u.ibss.bssid,
438 IEEE80211_STYPE_DEAUTH,
439 WLAN_REASON_UNSPECIFIED, true,
440 deauth_frame_buf);
441 return;
442 }
443
444 /* 419 /*
445 * IEEE 802.11 standard does not require authentication in IBSS 420 * IEEE 802.11 standard does not require authentication in IBSS
446 * networks and most implementations do not seem to use it. 421 * networks and most implementations do not seem to use it.
@@ -506,7 +481,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
506 } else { 481 } else {
507 rcu_read_unlock(); 482 rcu_read_unlock();
508 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, 483 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
509 mgmt->sa, supp_rates, true); 484 mgmt->sa, supp_rates);
510 } 485 }
511 } 486 }
512 487
@@ -514,7 +489,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
514 set_sta_flag(sta, WLAN_STA_WME); 489 set_sta_flag(sta, WLAN_STA_WME);
515 490
516 if (sta && elems->ht_operation && elems->ht_cap_elem && 491 if (sta && elems->ht_operation && elems->ht_cap_elem &&
517 sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { 492 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
493 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 &&
494 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
518 /* we both use HT */ 495 /* we both use HT */
519 struct ieee80211_ht_cap htcap_ie; 496 struct ieee80211_ht_cap htcap_ie;
520 struct cfg80211_chan_def chandef; 497 struct cfg80211_chan_def chandef;
@@ -529,8 +506,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
529 * fall back to HT20 if we don't use or use 506 * fall back to HT20 if we don't use or use
530 * the other extension channel 507 * the other extension channel
531 */ 508 */
532 if (cfg80211_get_chandef_type(&chandef) != 509 if (chandef.center_freq1 !=
533 sdata->u.ibss.channel_type) 510 sdata->u.ibss.chandef.center_freq1)
534 htcap_ie.cap_info &= 511 htcap_ie.cap_info &=
535 cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40); 512 cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
536 513
@@ -569,7 +546,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
569 546
570 /* different channel */ 547 /* different channel */
571 if (sdata->u.ibss.fixed_channel && 548 if (sdata->u.ibss.fixed_channel &&
572 sdata->u.ibss.channel != cbss->channel) 549 sdata->u.ibss.chandef.chan != cbss->channel)
573 goto put_bss; 550 goto put_bss;
574 551
575 /* different SSID */ 552 /* different SSID */
@@ -610,7 +587,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
610 ieee80211_sta_join_ibss(sdata, bss); 587 ieee80211_sta_join_ibss(sdata, bss);
611 supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); 588 supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL);
612 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 589 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
613 supp_rates, true); 590 supp_rates);
614 rcu_read_unlock(); 591 rcu_read_unlock();
615 } 592 }
616 593
@@ -759,7 +736,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
759 sdata->drop_unencrypted = 0; 736 sdata->drop_unencrypted = 0;
760 737
761 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, 738 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
762 ifibss->channel, ifibss->basic_rates, 739 ifibss->chandef.chan, ifibss->basic_rates,
763 capability, 0, true); 740 capability, 0, true);
764} 741}
765 742
@@ -791,7 +768,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
791 if (ifibss->fixed_bssid) 768 if (ifibss->fixed_bssid)
792 bssid = ifibss->bssid; 769 bssid = ifibss->bssid;
793 if (ifibss->fixed_channel) 770 if (ifibss->fixed_channel)
794 chan = ifibss->channel; 771 chan = ifibss->chandef.chan;
795 if (!is_zero_ether_addr(ifibss->bssid)) 772 if (!is_zero_ether_addr(ifibss->bssid))
796 bssid = ifibss->bssid; 773 bssid = ifibss->bssid;
797 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, 774 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
@@ -982,7 +959,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
982 list_del(&sta->list); 959 list_del(&sta->list);
983 spin_unlock_bh(&ifibss->incomplete_lock); 960 spin_unlock_bh(&ifibss->incomplete_lock);
984 961
985 ieee80211_ibss_finish_sta(sta, true); 962 ieee80211_ibss_finish_sta(sta);
986 rcu_read_unlock(); 963 rcu_read_unlock();
987 spin_lock_bh(&ifibss->incomplete_lock); 964 spin_lock_bh(&ifibss->incomplete_lock);
988 } 965 }
@@ -1058,9 +1035,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1058 1035
1059 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 1036 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
1060 1037
1061 sdata->u.ibss.channel = params->chandef.chan; 1038 sdata->u.ibss.chandef = params->chandef;
1062 sdata->u.ibss.channel_type =
1063 cfg80211_get_chandef_type(&params->chandef);
1064 sdata->u.ibss.fixed_channel = params->channel_fixed; 1039 sdata->u.ibss.fixed_channel = params->channel_fixed;
1065 1040
1066 if (params->ie) { 1041 if (params->ie) {
@@ -1119,7 +1094,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1119 if (ifibss->privacy) 1094 if (ifibss->privacy)
1120 capability |= WLAN_CAPABILITY_PRIVACY; 1095 capability |= WLAN_CAPABILITY_PRIVACY;
1121 1096
1122 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->channel, 1097 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,
1123 ifibss->bssid, ifibss->ssid, 1098 ifibss->bssid, ifibss->ssid,
1124 ifibss->ssid_len, WLAN_CAPABILITY_IBSS | 1099 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
1125 WLAN_CAPABILITY_PRIVACY, 1100 WLAN_CAPABILITY_PRIVACY,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f97cd9d9105f..8412a303993a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -94,6 +94,7 @@ struct ieee80211_bss {
94#define IEEE80211_MAX_SUPP_RATES 32 94#define IEEE80211_MAX_SUPP_RATES 32
95 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 95 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
96 size_t supp_rates_len; 96 size_t supp_rates_len;
97 struct ieee80211_rate *beacon_rate;
97 98
98 /* 99 /*
99 * During association, we save an ERP value from a probe response so 100 * During association, we save an ERP value from a probe response so
@@ -497,14 +498,12 @@ struct ieee80211_if_ibss {
497 bool privacy; 498 bool privacy;
498 499
499 bool control_port; 500 bool control_port;
500 unsigned int auth_frame_registrations;
501 501
502 u8 bssid[ETH_ALEN] __aligned(2); 502 u8 bssid[ETH_ALEN] __aligned(2);
503 u8 ssid[IEEE80211_MAX_SSID_LEN]; 503 u8 ssid[IEEE80211_MAX_SSID_LEN];
504 u8 ssid_len, ie_len; 504 u8 ssid_len, ie_len;
505 u8 *ie; 505 u8 *ie;
506 struct ieee80211_channel *channel; 506 struct cfg80211_chan_def chandef;
507 enum nl80211_channel_type channel_type;
508 507
509 unsigned long ibss_join_req; 508 unsigned long ibss_join_req;
510 /* probe response/beacon for IBSS */ 509 /* probe response/beacon for IBSS */
@@ -543,6 +542,7 @@ struct ieee80211_if_mesh {
543 struct timer_list mesh_path_root_timer; 542 struct timer_list mesh_path_root_timer;
544 543
545 unsigned long wrkq_flags; 544 unsigned long wrkq_flags;
545 unsigned long mbss_changed;
546 546
547 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; 547 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
548 size_t mesh_id_len; 548 size_t mesh_id_len;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6c33af482df4..447f41bbe744 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -161,11 +161,8 @@ void mesh_sta_cleanup(struct sta_info *sta)
161 del_timer_sync(&sta->plink_timer); 161 del_timer_sync(&sta->plink_timer);
162 } 162 }
163 163
164 if (changed) { 164 if (changed)
165 sdata_lock(sdata);
166 ieee80211_mbss_info_change_notify(sdata, changed); 165 ieee80211_mbss_info_change_notify(sdata, changed);
167 sdata_unlock(sdata);
168 }
169} 166}
170 167
171int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 168int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -419,7 +416,9 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
419 416
420 sband = local->hw.wiphy->bands[band]; 417 sband = local->hw.wiphy->bands[band];
421 if (!sband->ht_cap.ht_supported || 418 if (!sband->ht_cap.ht_supported ||
422 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) 419 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
420 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
421 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
423 return 0; 422 return 0;
424 423
425 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) 424 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
@@ -719,14 +718,18 @@ ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
719void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, 718void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
720 u32 changed) 719 u32 changed)
721{ 720{
722 if (sdata->vif.bss_conf.enable_beacon && 721 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
723 (changed & (BSS_CHANGED_BEACON | 722 unsigned long bits = changed;
724 BSS_CHANGED_HT | 723 u32 bit;
725 BSS_CHANGED_BASIC_RATES | 724
726 BSS_CHANGED_BEACON_INT))) 725 if (!bits)
727 if (ieee80211_mesh_rebuild_beacon(sdata)) 726 return;
728 return; 727
729 ieee80211_bss_info_change_notify(sdata, changed); 728 /* if we race with running work, worst case this work becomes a noop */
729 for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
730 set_bit(bit, &ifmsh->mbss_changed);
731 set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags);
732 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
730} 733}
731 734
732int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) 735int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
@@ -799,6 +802,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
799 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); 802 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
800 del_timer_sync(&sdata->u.mesh.mesh_path_timer); 803 del_timer_sync(&sdata->u.mesh.mesh_path_timer);
801 804
805 /* clear any mesh work (for next join) we may have accrued */
806 ifmsh->wrkq_flags = 0;
807 ifmsh->mbss_changed = 0;
808
802 local->fif_other_bss--; 809 local->fif_other_bss--;
803 atomic_dec(&local->iff_allmultis); 810 atomic_dec(&local->iff_allmultis);
804 ieee80211_configure_filter(local); 811 ieee80211_configure_filter(local);
@@ -965,6 +972,28 @@ out:
965 sdata_unlock(sdata); 972 sdata_unlock(sdata);
966} 973}
967 974
975static void mesh_bss_info_changed(struct ieee80211_sub_if_data *sdata)
976{
977 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
978 u32 bit, changed = 0;
979
980 for_each_set_bit(bit, &ifmsh->mbss_changed,
981 sizeof(changed) * BITS_PER_BYTE) {
982 clear_bit(bit, &ifmsh->mbss_changed);
983 changed |= BIT(bit);
984 }
985
986 if (sdata->vif.bss_conf.enable_beacon &&
987 (changed & (BSS_CHANGED_BEACON |
988 BSS_CHANGED_HT |
989 BSS_CHANGED_BASIC_RATES |
990 BSS_CHANGED_BEACON_INT)))
991 if (ieee80211_mesh_rebuild_beacon(sdata))
992 return;
993
994 ieee80211_bss_info_change_notify(sdata, changed);
995}
996
968void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) 997void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
969{ 998{
970 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 999 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -995,6 +1024,8 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
995 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) 1024 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags))
996 mesh_sync_adjust_tbtt(sdata); 1025 mesh_sync_adjust_tbtt(sdata);
997 1026
1027 if (test_and_clear_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags))
1028 mesh_bss_info_changed(sdata);
998out: 1029out:
999 sdata_unlock(sdata); 1030 sdata_unlock(sdata);
1000} 1031}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 01a28bca6e9b..2bc7fd2f787d 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -58,6 +58,7 @@ enum mesh_path_flags {
58 * @MESH_WORK_ROOT: the mesh root station needs to send a frame 58 * @MESH_WORK_ROOT: the mesh root station needs to send a frame
59 * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other 59 * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other
60 * mesh nodes 60 * mesh nodes
61 * @MESH_WORK_MBSS_CHANGED: rebuild beacon and notify driver of BSS changes
61 */ 62 */
62enum mesh_deferred_task_flags { 63enum mesh_deferred_task_flags {
63 MESH_WORK_HOUSEKEEPING, 64 MESH_WORK_HOUSEKEEPING,
@@ -65,6 +66,7 @@ enum mesh_deferred_task_flags {
65 MESH_WORK_GROW_MPP_TABLE, 66 MESH_WORK_GROW_MPP_TABLE,
66 MESH_WORK_ROOT, 67 MESH_WORK_ROOT,
67 MESH_WORK_DRIFT_ADJUST, 68 MESH_WORK_DRIFT_ADJUST,
69 MESH_WORK_MBSS_CHANGED,
68}; 70};
69 71
70/** 72/**
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 09bebed99416..02c05fa15c20 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -154,8 +154,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
154 u16 ht_opmode; 154 u16 ht_opmode;
155 bool non_ht_sta = false, ht20_sta = false; 155 bool non_ht_sta = false, ht20_sta = false;
156 156
157 if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) 157 switch (sdata->vif.bss_conf.chandef.width) {
158 case NL80211_CHAN_WIDTH_20_NOHT:
159 case NL80211_CHAN_WIDTH_5:
160 case NL80211_CHAN_WIDTH_10:
158 return 0; 161 return 0;
162 default:
163 break;
164 }
159 165
160 rcu_read_lock(); 166 rcu_read_lock();
161 list_for_each_entry_rcu(sta, &local->sta_list, list) { 167 list_for_each_entry_rcu(sta, &local->sta_list, list) {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9e49f557fa5c..ae31968d42d3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -190,6 +190,12 @@ static u32 chandef_downgrade(struct cfg80211_chan_def *c)
190 c->width = NL80211_CHAN_WIDTH_20_NOHT; 190 c->width = NL80211_CHAN_WIDTH_20_NOHT;
191 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; 191 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
192 break; 192 break;
193 case NL80211_CHAN_WIDTH_5:
194 case NL80211_CHAN_WIDTH_10:
195 WARN_ON_ONCE(1);
196 /* keep c->width */
197 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
198 break;
193 } 199 }
194 200
195 WARN_ON_ONCE(!cfg80211_chandef_valid(c)); 201 WARN_ON_ONCE(!cfg80211_chandef_valid(c));
@@ -1779,8 +1785,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1779 * probably just won't work at all. 1785 * probably just won't work at all.
1780 */ 1786 */
1781 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; 1787 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1;
1788 bss_conf->beacon_rate = bss->beacon_rate;
1782 bss_info_changed |= BSS_CHANGED_BEACON_INFO; 1789 bss_info_changed |= BSS_CHANGED_BEACON_INFO;
1783 } else { 1790 } else {
1791 bss_conf->beacon_rate = NULL;
1784 bss_conf->dtim_period = 0; 1792 bss_conf->dtim_period = 0;
1785 } 1793 }
1786 1794
@@ -1903,6 +1911,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1903 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1911 del_timer_sync(&sdata->u.mgd.chswitch_timer);
1904 1912
1905 sdata->vif.bss_conf.dtim_period = 0; 1913 sdata->vif.bss_conf.dtim_period = 0;
1914 sdata->vif.bss_conf.beacon_rate = NULL;
1915
1906 ifmgd->have_beacon = false; 1916 ifmgd->have_beacon = false;
1907 1917
1908 ifmgd->flags = 0; 1918 ifmgd->flags = 0;
@@ -2785,8 +2795,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2785 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { 2795 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
2786 /* oops -- internal error -- send timeout for now */ 2796 /* oops -- internal error -- send timeout for now */
2787 ieee80211_destroy_assoc_data(sdata, false); 2797 ieee80211_destroy_assoc_data(sdata, false);
2788 cfg80211_put_bss(sdata->local->hw.wiphy, bss); 2798 cfg80211_assoc_timeout(sdata->dev, bss);
2789 cfg80211_assoc_timeout(sdata->dev, mgmt->bssid);
2790 return; 2799 return;
2791 } 2800 }
2792 sdata_info(sdata, "associated\n"); 2801 sdata_info(sdata, "associated\n");
@@ -2827,8 +2836,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2827 2836
2828 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 2837 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
2829 channel); 2838 channel);
2830 if (bss) 2839 if (bss) {
2831 ieee80211_rx_bss_put(local, bss); 2840 ieee80211_rx_bss_put(local, bss);
2841 sdata->vif.bss_conf.beacon_rate = bss->beacon_rate;
2842 }
2832 2843
2833 if (!sdata->u.mgd.associated || 2844 if (!sdata->u.mgd.associated ||
2834 !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) 2845 !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid))
@@ -3501,13 +3512,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3501 time_after(jiffies, ifmgd->assoc_data->timeout)) { 3512 time_after(jiffies, ifmgd->assoc_data->timeout)) {
3502 if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || 3513 if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
3503 ieee80211_do_assoc(sdata)) { 3514 ieee80211_do_assoc(sdata)) {
3504 u8 bssid[ETH_ALEN]; 3515 struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
3505
3506 memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
3507 3516
3508 ieee80211_destroy_assoc_data(sdata, false); 3517 ieee80211_destroy_assoc_data(sdata, false);
3509 3518 cfg80211_assoc_timeout(sdata->dev, bss);
3510 cfg80211_assoc_timeout(sdata->dev, bssid);
3511 } 3519 }
3512 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3520 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
3513 run_again(sdata, ifmgd->assoc_data->timeout); 3521 run_again(sdata, ifmgd->assoc_data->timeout);
@@ -3838,6 +3846,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3838 */ 3846 */
3839 ret = ieee80211_vif_use_channel(sdata, &chandef, 3847 ret = ieee80211_vif_use_channel(sdata, &chandef,
3840 IEEE80211_CHANCTX_SHARED); 3848 IEEE80211_CHANCTX_SHARED);
3849
3850 /* don't downgrade for 5 and 10 MHz channels, though. */
3851 if (chandef.width == NL80211_CHAN_WIDTH_5 ||
3852 chandef.width == NL80211_CHAN_WIDTH_10)
3853 return ret;
3854
3841 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { 3855 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
3842 ifmgd->flags |= chandef_downgrade(&chandef); 3856 ifmgd->flags |= chandef_downgrade(&chandef);
3843 ret = ieee80211_vif_use_channel(sdata, &chandef, 3857 ret = ieee80211_vif_use_channel(sdata, &chandef,
@@ -4427,8 +4441,11 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
4427 cancel_work_sync(&ifmgd->chswitch_work); 4441 cancel_work_sync(&ifmgd->chswitch_work);
4428 4442
4429 sdata_lock(sdata); 4443 sdata_lock(sdata);
4430 if (ifmgd->assoc_data) 4444 if (ifmgd->assoc_data) {
4445 struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
4431 ieee80211_destroy_assoc_data(sdata, false); 4446 ieee80211_destroy_assoc_data(sdata, false);
4447 cfg80211_assoc_timeout(sdata->dev, bss);
4448 }
4432 if (ifmgd->auth_data) 4449 if (ifmgd->auth_data)
4433 ieee80211_destroy_auth_data(sdata, false); 4450 ieee80211_destroy_auth_data(sdata, false);
4434 del_timer_sync(&ifmgd->timer); 4451 del_timer_sync(&ifmgd->timer);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index a02bef35b134..30d58d2d13e2 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -397,8 +397,14 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
397 return; 397 return;
398 398
399 /* if HT BSS, and we handle a data frame, also try HT rates */ 399 /* if HT BSS, and we handle a data frame, also try HT rates */
400 if (chan_width == NL80211_CHAN_WIDTH_20_NOHT) 400 switch (chan_width) {
401 case NL80211_CHAN_WIDTH_20_NOHT:
402 case NL80211_CHAN_WIDTH_5:
403 case NL80211_CHAN_WIDTH_10:
401 return; 404 return;
405 default:
406 break;
407 }
402 408
403 alt_rate.idx = 0; 409 alt_rate.idx = 0;
404 /* keep protection flags */ 410 /* keep protection flags */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 99b103921a4b..1b122a79b0d8 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -140,6 +140,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
140 bss->valid_data |= IEEE80211_BSS_VALID_WMM; 140 bss->valid_data |= IEEE80211_BSS_VALID_WMM;
141 } 141 }
142 142
143 if (beacon) {
144 struct ieee80211_supported_band *sband =
145 local->hw.wiphy->bands[rx_status->band];
146 if (!(rx_status->flag & RX_FLAG_HT) &&
147 !(rx_status->flag & RX_FLAG_VHT))
148 bss->beacon_rate =
149 &sband->bitrates[rx_status->rate_idx];
150 }
151
143 return bss; 152 return bss;
144} 153}
145 154
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index b4297982d34a..aeb967a0aeed 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -149,6 +149,7 @@ static void cleanup_single_sta(struct sta_info *sta)
149 * directly by station destruction. 149 * directly by station destruction.
150 */ 150 */
151 for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 151 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
152 kfree(sta->ampdu_mlme.tid_start_tx[i]);
152 tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); 153 tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
153 if (!tid_tx) 154 if (!tid_tx)
154 continue; 155 continue;
@@ -346,6 +347,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
346 if (ieee80211_vif_is_mesh(&sdata->vif) && 347 if (ieee80211_vif_is_mesh(&sdata->vif) &&
347 !sdata->u.mesh.user_mpm) 348 !sdata->u.mesh.user_mpm)
348 init_timer(&sta->plink_timer); 349 init_timer(&sta->plink_timer);
350 sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
349#endif 351#endif
350 352
351 memcpy(sta->sta.addr, addr, ETH_ALEN); 353 memcpy(sta->sta.addr, addr, ETH_ALEN);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index bd12fc54266c..4208dbd5861f 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -203,6 +203,7 @@ struct tid_ampdu_rx {
203 * driver requested to close until the work for it runs 203 * driver requested to close until the work for it runs
204 * @mtx: mutex to protect all TX data (except non-NULL assignments 204 * @mtx: mutex to protect all TX data (except non-NULL assignments
205 * to tid_tx[idx], which are protected by the sta spinlock) 205 * to tid_tx[idx], which are protected by the sta spinlock)
206 * tid_start_tx is also protected by sta->lock.
206 */ 207 */
207struct sta_ampdu_mlme { 208struct sta_ampdu_mlme {
208 struct mutex mtx; 209 struct mutex mtx;
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index 171344d4eb7c..97c289414e32 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -396,7 +396,7 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
396 new_bw = ieee80211_sta_cur_vht_bw(sta); 396 new_bw = ieee80211_sta_cur_vht_bw(sta);
397 if (new_bw != sta->sta.bandwidth) { 397 if (new_bw != sta->sta.bandwidth) {
398 sta->sta.bandwidth = new_bw; 398 sta->sta.bandwidth = new_bw;
399 changed |= IEEE80211_RC_NSS_CHANGED; 399 changed |= IEEE80211_RC_BW_CHANGED;
400 } 400 }
401 401
402 change: 402 change:
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index fd556ac05fdb..50f6195c8b70 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -54,6 +54,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
54 control_freq = chandef->chan->center_freq; 54 control_freq = chandef->chan->center_freq;
55 55
56 switch (chandef->width) { 56 switch (chandef->width) {
57 case NL80211_CHAN_WIDTH_5:
58 case NL80211_CHAN_WIDTH_10:
57 case NL80211_CHAN_WIDTH_20: 59 case NL80211_CHAN_WIDTH_20:
58 case NL80211_CHAN_WIDTH_20_NOHT: 60 case NL80211_CHAN_WIDTH_20_NOHT:
59 if (chandef->center_freq1 != control_freq) 61 if (chandef->center_freq1 != control_freq)
@@ -152,6 +154,12 @@ static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
152 int width; 154 int width;
153 155
154 switch (c->width) { 156 switch (c->width) {
157 case NL80211_CHAN_WIDTH_5:
158 width = 5;
159 break;
160 case NL80211_CHAN_WIDTH_10:
161 width = 10;
162 break;
155 case NL80211_CHAN_WIDTH_20: 163 case NL80211_CHAN_WIDTH_20:
156 case NL80211_CHAN_WIDTH_20_NOHT: 164 case NL80211_CHAN_WIDTH_20_NOHT:
157 width = 20; 165 width = 20;
@@ -194,6 +202,16 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
194 if (c1->width == c2->width) 202 if (c1->width == c2->width)
195 return NULL; 203 return NULL;
196 204
205 /*
206 * can't be compatible if one of them is 5 or 10 MHz,
207 * but they don't have the same width.
208 */
209 if (c1->width == NL80211_CHAN_WIDTH_5 ||
210 c1->width == NL80211_CHAN_WIDTH_10 ||
211 c2->width == NL80211_CHAN_WIDTH_5 ||
212 c2->width == NL80211_CHAN_WIDTH_10)
213 return NULL;
214
197 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT || 215 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
198 c1->width == NL80211_CHAN_WIDTH_20) 216 c1->width == NL80211_CHAN_WIDTH_20)
199 return c2; 217 return c2;
@@ -264,11 +282,17 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
264 u32 bandwidth) 282 u32 bandwidth)
265{ 283{
266 struct ieee80211_channel *c; 284 struct ieee80211_channel *c;
267 u32 freq; 285 u32 freq, start_freq, end_freq;
286
287 if (bandwidth <= 20) {
288 start_freq = center_freq;
289 end_freq = center_freq;
290 } else {
291 start_freq = center_freq - bandwidth/2 + 10;
292 end_freq = center_freq + bandwidth/2 - 10;
293 }
268 294
269 for (freq = center_freq - bandwidth/2 + 10; 295 for (freq = start_freq; freq <= end_freq; freq += 20) {
270 freq <= center_freq + bandwidth/2 - 10;
271 freq += 20) {
272 c = ieee80211_get_channel(wiphy, freq); 296 c = ieee80211_get_channel(wiphy, freq);
273 if (!c) 297 if (!c)
274 return -EINVAL; 298 return -EINVAL;
@@ -310,11 +334,17 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
310 u32 prohibited_flags) 334 u32 prohibited_flags)
311{ 335{
312 struct ieee80211_channel *c; 336 struct ieee80211_channel *c;
313 u32 freq; 337 u32 freq, start_freq, end_freq;
338
339 if (bandwidth <= 20) {
340 start_freq = center_freq;
341 end_freq = center_freq;
342 } else {
343 start_freq = center_freq - bandwidth/2 + 10;
344 end_freq = center_freq + bandwidth/2 - 10;
345 }
314 346
315 for (freq = center_freq - bandwidth/2 + 10; 347 for (freq = start_freq; freq <= end_freq; freq += 20) {
316 freq <= center_freq + bandwidth/2 - 10;
317 freq += 20) {
318 c = ieee80211_get_channel(wiphy, freq); 348 c = ieee80211_get_channel(wiphy, freq);
319 if (!c) 349 if (!c)
320 return false; 350 return false;
@@ -349,6 +379,12 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
349 control_freq = chandef->chan->center_freq; 379 control_freq = chandef->chan->center_freq;
350 380
351 switch (chandef->width) { 381 switch (chandef->width) {
382 case NL80211_CHAN_WIDTH_5:
383 width = 5;
384 break;
385 case NL80211_CHAN_WIDTH_10:
386 width = 10;
387 break;
352 case NL80211_CHAN_WIDTH_20: 388 case NL80211_CHAN_WIDTH_20:
353 if (!ht_cap->ht_supported) 389 if (!ht_cap->ht_supported)
354 return false; 390 return false;
@@ -405,6 +441,11 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
405 if (width > 20) 441 if (width > 20)
406 prohibited_flags |= IEEE80211_CHAN_NO_OFDM; 442 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
407 443
444 /* 5 and 10 MHz are only defined for the OFDM PHY */
445 if (width < 20)
446 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
447
448
408 if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, 449 if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1,
409 width, prohibited_flags)) 450 width, prohibited_flags))
410 return false; 451 return false;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f277246080b5..4f9f216665e9 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -933,6 +933,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
933 * freed. 933 * freed.
934 */ 934 */
935 cfg80211_process_wdev_events(wdev); 935 cfg80211_process_wdev_events(wdev);
936
937 if (WARN_ON(wdev->current_bss)) {
938 cfg80211_unhold_bss(wdev->current_bss);
939 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
940 wdev->current_bss = NULL;
941 }
936 break; 942 break;
937 case NETDEV_PRE_UP: 943 case NETDEV_PRE_UP:
938 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 944 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index a61a44bc6cf0..bfac5e186f57 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -38,6 +38,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
38 * frame instead of reassoc. 38 * frame instead of reassoc.
39 */ 39 */
40 if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { 40 if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {
41 cfg80211_unhold_bss(bss_from_pub(bss));
41 cfg80211_put_bss(wiphy, bss); 42 cfg80211_put_bss(wiphy, bss);
42 return; 43 return;
43 } 44 }
@@ -131,16 +132,19 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
131} 132}
132EXPORT_SYMBOL(cfg80211_auth_timeout); 133EXPORT_SYMBOL(cfg80211_auth_timeout);
133 134
134void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr) 135void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
135{ 136{
136 struct wireless_dev *wdev = dev->ieee80211_ptr; 137 struct wireless_dev *wdev = dev->ieee80211_ptr;
137 struct wiphy *wiphy = wdev->wiphy; 138 struct wiphy *wiphy = wdev->wiphy;
138 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 139 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
139 140
140 trace_cfg80211_send_assoc_timeout(dev, addr); 141 trace_cfg80211_send_assoc_timeout(dev, bss->bssid);
141 142
142 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 143 nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL);
143 cfg80211_sme_assoc_timeout(wdev); 144 cfg80211_sme_assoc_timeout(wdev);
145
146 cfg80211_unhold_bss(bss_from_pub(bss));
147 cfg80211_put_bss(wiphy, bss);
144} 148}
145EXPORT_SYMBOL(cfg80211_assoc_timeout); 149EXPORT_SYMBOL(cfg80211_assoc_timeout);
146 150
@@ -307,6 +311,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
307 goto out; 311 goto out;
308 312
309 err = rdev_assoc(rdev, dev, req); 313 err = rdev_assoc(rdev, dev, req);
314 if (!err)
315 cfg80211_hold_bss(bss_from_pub(req->bss));
310 316
311out: 317out:
312 if (err) 318 if (err)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e545023e2871..1cc47aca7f05 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1111,10 +1111,16 @@ nl80211_send_mgmt_stypes(struct sk_buff *msg,
1111 return 0; 1111 return 0;
1112} 1112}
1113 1113
1114struct nl80211_dump_wiphy_state {
1115 s64 filter_wiphy;
1116 long start;
1117 long split_start, band_start, chan_start;
1118 bool split;
1119};
1120
1114static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, 1121static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1115 struct sk_buff *msg, u32 portid, u32 seq, 1122 struct sk_buff *msg, u32 portid, u32 seq,
1116 int flags, bool split, long *split_start, 1123 int flags, struct nl80211_dump_wiphy_state *state)
1117 long *band_start, long *chan_start)
1118{ 1124{
1119 void *hdr; 1125 void *hdr;
1120 struct nlattr *nl_bands, *nl_band; 1126 struct nlattr *nl_bands, *nl_band;
@@ -1125,19 +1131,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1125 int i; 1131 int i;
1126 const struct ieee80211_txrx_stypes *mgmt_stypes = 1132 const struct ieee80211_txrx_stypes *mgmt_stypes =
1127 dev->wiphy.mgmt_stypes; 1133 dev->wiphy.mgmt_stypes;
1128 long start = 0, start_chan = 0, start_band = 0;
1129 u32 features; 1134 u32 features;
1130 1135
1131 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); 1136 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY);
1132 if (!hdr) 1137 if (!hdr)
1133 return -ENOBUFS; 1138 return -ENOBUFS;
1134 1139
1135 /* allow always using the variables */ 1140 if (WARN_ON(!state))
1136 if (!split) { 1141 return -EINVAL;
1137 split_start = &start;
1138 band_start = &start_band;
1139 chan_start = &start_chan;
1140 }
1141 1142
1142 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || 1143 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) ||
1143 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, 1144 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
@@ -1146,7 +1147,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1146 cfg80211_rdev_list_generation)) 1147 cfg80211_rdev_list_generation))
1147 goto nla_put_failure; 1148 goto nla_put_failure;
1148 1149
1149 switch (*split_start) { 1150 switch (state->split_start) {
1150 case 0: 1151 case 0:
1151 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, 1152 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1152 dev->wiphy.retry_short) || 1153 dev->wiphy.retry_short) ||
@@ -1188,9 +1189,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1188 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && 1189 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
1189 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) 1190 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
1190 goto nla_put_failure; 1191 goto nla_put_failure;
1192 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
1193 nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ))
1194 goto nla_put_failure;
1191 1195
1192 (*split_start)++; 1196 state->split_start++;
1193 if (split) 1197 if (state->split)
1194 break; 1198 break;
1195 case 1: 1199 case 1:
1196 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, 1200 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
@@ -1234,22 +1238,23 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1234 } 1238 }
1235 } 1239 }
1236 1240
1237 (*split_start)++; 1241 state->split_start++;
1238 if (split) 1242 if (state->split)
1239 break; 1243 break;
1240 case 2: 1244 case 2:
1241 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, 1245 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1242 dev->wiphy.interface_modes)) 1246 dev->wiphy.interface_modes))
1243 goto nla_put_failure; 1247 goto nla_put_failure;
1244 (*split_start)++; 1248 state->split_start++;
1245 if (split) 1249 if (state->split)
1246 break; 1250 break;
1247 case 3: 1251 case 3:
1248 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 1252 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1249 if (!nl_bands) 1253 if (!nl_bands)
1250 goto nla_put_failure; 1254 goto nla_put_failure;
1251 1255
1252 for (band = *band_start; band < IEEE80211_NUM_BANDS; band++) { 1256 for (band = state->band_start;
1257 band < IEEE80211_NUM_BANDS; band++) {
1253 struct ieee80211_supported_band *sband; 1258 struct ieee80211_supported_band *sband;
1254 1259
1255 sband = dev->wiphy.bands[band]; 1260 sband = dev->wiphy.bands[band];
@@ -1261,12 +1266,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1261 if (!nl_band) 1266 if (!nl_band)
1262 goto nla_put_failure; 1267 goto nla_put_failure;
1263 1268
1264 switch (*chan_start) { 1269 switch (state->chan_start) {
1265 case 0: 1270 case 0:
1266 if (nl80211_send_band_rateinfo(msg, sband)) 1271 if (nl80211_send_band_rateinfo(msg, sband))
1267 goto nla_put_failure; 1272 goto nla_put_failure;
1268 (*chan_start)++; 1273 state->chan_start++;
1269 if (split) 1274 if (state->split)
1270 break; 1275 break;
1271 default: 1276 default:
1272 /* add frequencies */ 1277 /* add frequencies */
@@ -1275,7 +1280,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1275 if (!nl_freqs) 1280 if (!nl_freqs)
1276 goto nla_put_failure; 1281 goto nla_put_failure;
1277 1282
1278 for (i = *chan_start - 1; 1283 for (i = state->chan_start - 1;
1279 i < sband->n_channels; 1284 i < sband->n_channels;
1280 i++) { 1285 i++) {
1281 nl_freq = nla_nest_start(msg, i); 1286 nl_freq = nla_nest_start(msg, i);
@@ -1284,26 +1289,27 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1284 1289
1285 chan = &sband->channels[i]; 1290 chan = &sband->channels[i];
1286 1291
1287 if (nl80211_msg_put_channel(msg, chan, 1292 if (nl80211_msg_put_channel(
1288 split)) 1293 msg, chan,
1294 state->split))
1289 goto nla_put_failure; 1295 goto nla_put_failure;
1290 1296
1291 nla_nest_end(msg, nl_freq); 1297 nla_nest_end(msg, nl_freq);
1292 if (split) 1298 if (state->split)
1293 break; 1299 break;
1294 } 1300 }
1295 if (i < sband->n_channels) 1301 if (i < sband->n_channels)
1296 *chan_start = i + 2; 1302 state->chan_start = i + 2;
1297 else 1303 else
1298 *chan_start = 0; 1304 state->chan_start = 0;
1299 nla_nest_end(msg, nl_freqs); 1305 nla_nest_end(msg, nl_freqs);
1300 } 1306 }
1301 1307
1302 nla_nest_end(msg, nl_band); 1308 nla_nest_end(msg, nl_band);
1303 1309
1304 if (split) { 1310 if (state->split) {
1305 /* start again here */ 1311 /* start again here */
1306 if (*chan_start) 1312 if (state->chan_start)
1307 band--; 1313 band--;
1308 break; 1314 break;
1309 } 1315 }
@@ -1311,14 +1317,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1311 nla_nest_end(msg, nl_bands); 1317 nla_nest_end(msg, nl_bands);
1312 1318
1313 if (band < IEEE80211_NUM_BANDS) 1319 if (band < IEEE80211_NUM_BANDS)
1314 *band_start = band + 1; 1320 state->band_start = band + 1;
1315 else 1321 else
1316 *band_start = 0; 1322 state->band_start = 0;
1317 1323
1318 /* if bands & channels are done, continue outside */ 1324 /* if bands & channels are done, continue outside */
1319 if (*band_start == 0 && *chan_start == 0) 1325 if (state->band_start == 0 && state->chan_start == 0)
1320 (*split_start)++; 1326 state->split_start++;
1321 if (split) 1327 if (state->split)
1322 break; 1328 break;
1323 case 4: 1329 case 4:
1324 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); 1330 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
@@ -1384,7 +1390,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1384 } 1390 }
1385 CMD(start_p2p_device, START_P2P_DEVICE); 1391 CMD(start_p2p_device, START_P2P_DEVICE);
1386 CMD(set_mcast_rate, SET_MCAST_RATE); 1392 CMD(set_mcast_rate, SET_MCAST_RATE);
1387 if (split) { 1393 if (state->split) {
1388 CMD(crit_proto_start, CRIT_PROTOCOL_START); 1394 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1389 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); 1395 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1390 } 1396 }
@@ -1408,8 +1414,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1408 } 1414 }
1409 1415
1410 nla_nest_end(msg, nl_cmds); 1416 nla_nest_end(msg, nl_cmds);
1411 (*split_start)++; 1417 state->split_start++;
1412 if (split) 1418 if (state->split)
1413 break; 1419 break;
1414 case 5: 1420 case 5:
1415 if (dev->ops->remain_on_channel && 1421 if (dev->ops->remain_on_channel &&
@@ -1425,29 +1431,30 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1425 1431
1426 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes)) 1432 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1427 goto nla_put_failure; 1433 goto nla_put_failure;
1428 (*split_start)++; 1434 state->split_start++;
1429 if (split) 1435 if (state->split)
1430 break; 1436 break;
1431 case 6: 1437 case 6:
1432#ifdef CONFIG_PM 1438#ifdef CONFIG_PM
1433 if (nl80211_send_wowlan(msg, dev, split)) 1439 if (nl80211_send_wowlan(msg, dev, state->split))
1434 goto nla_put_failure; 1440 goto nla_put_failure;
1435 (*split_start)++; 1441 state->split_start++;
1436 if (split) 1442 if (state->split)
1437 break; 1443 break;
1438#else 1444#else
1439 (*split_start)++; 1445 state->split_start++;
1440#endif 1446#endif
1441 case 7: 1447 case 7:
1442 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, 1448 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1443 dev->wiphy.software_iftypes)) 1449 dev->wiphy.software_iftypes))
1444 goto nla_put_failure; 1450 goto nla_put_failure;
1445 1451
1446 if (nl80211_put_iface_combinations(&dev->wiphy, msg, split)) 1452 if (nl80211_put_iface_combinations(&dev->wiphy, msg,
1453 state->split))
1447 goto nla_put_failure; 1454 goto nla_put_failure;
1448 1455
1449 (*split_start)++; 1456 state->split_start++;
1450 if (split) 1457 if (state->split)
1451 break; 1458 break;
1452 case 8: 1459 case 8:
1453 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && 1460 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
@@ -1461,7 +1468,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1461 * dump is split, otherwise it makes it too big. Therefore 1468 * dump is split, otherwise it makes it too big. Therefore
1462 * only advertise it in that case. 1469 * only advertise it in that case.
1463 */ 1470 */
1464 if (split) 1471 if (state->split)
1465 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS; 1472 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1466 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features)) 1473 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
1467 goto nla_put_failure; 1474 goto nla_put_failure;
@@ -1488,7 +1495,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1488 * case we'll continue with more data in the next round, 1495 * case we'll continue with more data in the next round,
1489 * but break unconditionally so unsplit data stops here. 1496 * but break unconditionally so unsplit data stops here.
1490 */ 1497 */
1491 (*split_start)++; 1498 state->split_start++;
1492 break; 1499 break;
1493 case 9: 1500 case 9:
1494 if (dev->wiphy.extended_capabilities && 1501 if (dev->wiphy.extended_capabilities &&
@@ -1507,7 +1514,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1507 goto nla_put_failure; 1514 goto nla_put_failure;
1508 1515
1509 /* done */ 1516 /* done */
1510 *split_start = 0; 1517 state->split_start = 0;
1511 break; 1518 break;
1512 } 1519 }
1513 return genlmsg_end(msg, hdr); 1520 return genlmsg_end(msg, hdr);
@@ -1517,67 +1524,78 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1517 return -EMSGSIZE; 1524 return -EMSGSIZE;
1518} 1525}
1519 1526
1527static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
1528 struct netlink_callback *cb,
1529 struct nl80211_dump_wiphy_state *state)
1530{
1531 struct nlattr **tb = nl80211_fam.attrbuf;
1532 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1533 tb, nl80211_fam.maxattr, nl80211_policy);
1534 /* ignore parse errors for backward compatibility */
1535 if (ret)
1536 return 0;
1537
1538 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1539 if (tb[NL80211_ATTR_WIPHY])
1540 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1541 if (tb[NL80211_ATTR_WDEV])
1542 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1543 if (tb[NL80211_ATTR_IFINDEX]) {
1544 struct net_device *netdev;
1545 struct cfg80211_registered_device *rdev;
1546 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1547
1548 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1549 if (!netdev)
1550 return -ENODEV;
1551 if (netdev->ieee80211_ptr) {
1552 rdev = wiphy_to_dev(
1553 netdev->ieee80211_ptr->wiphy);
1554 state->filter_wiphy = rdev->wiphy_idx;
1555 }
1556 dev_put(netdev);
1557 }
1558
1559 return 0;
1560}
1561
1520static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) 1562static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1521{ 1563{
1522 int idx = 0, ret; 1564 int idx = 0, ret;
1523 int start = cb->args[0]; 1565 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1524 struct cfg80211_registered_device *dev; 1566 struct cfg80211_registered_device *dev;
1525 s64 filter_wiphy = -1;
1526 bool split = false;
1527 struct nlattr **tb;
1528 int res;
1529
1530 /* will be zeroed in nlmsg_parse() */
1531 tb = kmalloc(sizeof(*tb) * (NL80211_ATTR_MAX + 1), GFP_KERNEL);
1532 if (!tb)
1533 return -ENOMEM;
1534 1567
1535 rtnl_lock(); 1568 rtnl_lock();
1536 1569 if (!state) {
1537 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1570 state = kzalloc(sizeof(*state), GFP_KERNEL);
1538 tb, NL80211_ATTR_MAX, nl80211_policy); 1571 if (!state) {
1539 if (res == 0) { 1572 rtnl_unlock();
1540 split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; 1573 return -ENOMEM;
1541 if (tb[NL80211_ATTR_WIPHY])
1542 filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1543 if (tb[NL80211_ATTR_WDEV])
1544 filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1545 if (tb[NL80211_ATTR_IFINDEX]) {
1546 struct net_device *netdev;
1547 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1548
1549 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1550 if (!netdev) {
1551 rtnl_unlock();
1552 kfree(tb);
1553 return -ENODEV;
1554 }
1555 if (netdev->ieee80211_ptr) {
1556 dev = wiphy_to_dev(
1557 netdev->ieee80211_ptr->wiphy);
1558 filter_wiphy = dev->wiphy_idx;
1559 }
1560 dev_put(netdev);
1561 } 1574 }
1575 state->filter_wiphy = -1;
1576 ret = nl80211_dump_wiphy_parse(skb, cb, state);
1577 if (ret) {
1578 kfree(state);
1579 rtnl_unlock();
1580 return ret;
1581 }
1582 cb->args[0] = (long)state;
1562 } 1583 }
1563 kfree(tb);
1564 1584
1565 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 1585 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
1566 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) 1586 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
1567 continue; 1587 continue;
1568 if (++idx <= start) 1588 if (++idx <= state->start)
1569 continue; 1589 continue;
1570 if (filter_wiphy != -1 && dev->wiphy_idx != filter_wiphy) 1590 if (state->filter_wiphy != -1 &&
1591 state->filter_wiphy != dev->wiphy_idx)
1571 continue; 1592 continue;
1572 /* attempt to fit multiple wiphy data chunks into the skb */ 1593 /* attempt to fit multiple wiphy data chunks into the skb */
1573 do { 1594 do {
1574 ret = nl80211_send_wiphy(dev, skb, 1595 ret = nl80211_send_wiphy(dev, skb,
1575 NETLINK_CB(cb->skb).portid, 1596 NETLINK_CB(cb->skb).portid,
1576 cb->nlh->nlmsg_seq, 1597 cb->nlh->nlmsg_seq,
1577 NLM_F_MULTI, 1598 NLM_F_MULTI, state);
1578 split, &cb->args[1],
1579 &cb->args[2],
1580 &cb->args[3]);
1581 if (ret < 0) { 1599 if (ret < 0) {
1582 /* 1600 /*
1583 * If sending the wiphy data didn't fit (ENOBUFS 1601 * If sending the wiphy data didn't fit (ENOBUFS
@@ -1602,27 +1620,34 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1602 idx--; 1620 idx--;
1603 break; 1621 break;
1604 } 1622 }
1605 } while (cb->args[1] > 0); 1623 } while (state->split_start > 0);
1606 break; 1624 break;
1607 } 1625 }
1608 rtnl_unlock(); 1626 rtnl_unlock();
1609 1627
1610 cb->args[0] = idx; 1628 state->start = idx;
1611 1629
1612 return skb->len; 1630 return skb->len;
1613} 1631}
1614 1632
1633static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
1634{
1635 kfree((void *)cb->args[0]);
1636 return 0;
1637}
1638
1615static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) 1639static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
1616{ 1640{
1617 struct sk_buff *msg; 1641 struct sk_buff *msg;
1618 struct cfg80211_registered_device *dev = info->user_ptr[0]; 1642 struct cfg80211_registered_device *dev = info->user_ptr[0];
1643 struct nl80211_dump_wiphy_state state = {};
1619 1644
1620 msg = nlmsg_new(4096, GFP_KERNEL); 1645 msg = nlmsg_new(4096, GFP_KERNEL);
1621 if (!msg) 1646 if (!msg)
1622 return -ENOMEM; 1647 return -ENOMEM;
1623 1648
1624 if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0, 1649 if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0,
1625 false, NULL, NULL, NULL) < 0) { 1650 &state) < 0) {
1626 nlmsg_free(msg); 1651 nlmsg_free(msg);
1627 return -ENOBUFS; 1652 return -ENOBUFS;
1628 } 1653 }
@@ -1739,6 +1764,11 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1739 IEEE80211_CHAN_DISABLED)) 1764 IEEE80211_CHAN_DISABLED))
1740 return -EINVAL; 1765 return -EINVAL;
1741 1766
1767 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
1768 chandef->width == NL80211_CHAN_WIDTH_10) &&
1769 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ))
1770 return -EINVAL;
1771
1742 return 0; 1772 return 0;
1743} 1773}
1744 1774
@@ -2890,61 +2920,58 @@ static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
2890 return err; 2920 return err;
2891} 2921}
2892 2922
2893static int nl80211_parse_beacon(struct genl_info *info, 2923static int nl80211_parse_beacon(struct nlattr *attrs[],
2894 struct cfg80211_beacon_data *bcn) 2924 struct cfg80211_beacon_data *bcn)
2895{ 2925{
2896 bool haveinfo = false; 2926 bool haveinfo = false;
2897 2927
2898 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) || 2928 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
2899 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) || 2929 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
2900 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) || 2930 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
2901 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP])) 2931 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
2902 return -EINVAL; 2932 return -EINVAL;
2903 2933
2904 memset(bcn, 0, sizeof(*bcn)); 2934 memset(bcn, 0, sizeof(*bcn));
2905 2935
2906 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { 2936 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
2907 bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); 2937 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
2908 bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); 2938 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
2909 if (!bcn->head_len) 2939 if (!bcn->head_len)
2910 return -EINVAL; 2940 return -EINVAL;
2911 haveinfo = true; 2941 haveinfo = true;
2912 } 2942 }
2913 2943
2914 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { 2944 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
2915 bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); 2945 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
2916 bcn->tail_len = 2946 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
2917 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
2918 haveinfo = true; 2947 haveinfo = true;
2919 } 2948 }
2920 2949
2921 if (!haveinfo) 2950 if (!haveinfo)
2922 return -EINVAL; 2951 return -EINVAL;
2923 2952
2924 if (info->attrs[NL80211_ATTR_IE]) { 2953 if (attrs[NL80211_ATTR_IE]) {
2925 bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]); 2954 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
2926 bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2955 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
2927 } 2956 }
2928 2957
2929 if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) { 2958 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
2930 bcn->proberesp_ies = 2959 bcn->proberesp_ies =
2931 nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); 2960 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
2932 bcn->proberesp_ies_len = 2961 bcn->proberesp_ies_len =
2933 nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); 2962 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
2934 } 2963 }
2935 2964
2936 if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) { 2965 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
2937 bcn->assocresp_ies = 2966 bcn->assocresp_ies =
2938 nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); 2967 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2939 bcn->assocresp_ies_len = 2968 bcn->assocresp_ies_len =
2940 nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); 2969 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2941 } 2970 }
2942 2971
2943 if (info->attrs[NL80211_ATTR_PROBE_RESP]) { 2972 if (attrs[NL80211_ATTR_PROBE_RESP]) {
2944 bcn->probe_resp = 2973 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
2945 nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]); 2974 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
2946 bcn->probe_resp_len =
2947 nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]);
2948 } 2975 }
2949 2976
2950 return 0; 2977 return 0;
@@ -3023,7 +3050,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3023 !info->attrs[NL80211_ATTR_BEACON_HEAD]) 3050 !info->attrs[NL80211_ATTR_BEACON_HEAD])
3024 return -EINVAL; 3051 return -EINVAL;
3025 3052
3026 err = nl80211_parse_beacon(info, &params.beacon); 3053 err = nl80211_parse_beacon(info->attrs, &params.beacon);
3027 if (err) 3054 if (err)
3028 return err; 3055 return err;
3029 3056
@@ -3175,7 +3202,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3175 if (!wdev->beacon_interval) 3202 if (!wdev->beacon_interval)
3176 return -EINVAL; 3203 return -EINVAL;
3177 3204
3178 err = nl80211_parse_beacon(info, &params); 3205 err = nl80211_parse_beacon(info->attrs, &params);
3179 if (err) 3206 if (err)
3180 return err; 3207 return err;
3181 3208
@@ -6291,11 +6318,16 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
6291 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) 6318 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
6292 return -EINVAL; 6319 return -EINVAL;
6293 6320
6294 if (ibss.chandef.width > NL80211_CHAN_WIDTH_40) 6321 switch (ibss.chandef.width) {
6295 return -EINVAL; 6322 case NL80211_CHAN_WIDTH_20_NOHT:
6296 if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && 6323 break;
6297 !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) 6324 case NL80211_CHAN_WIDTH_20:
6325 case NL80211_CHAN_WIDTH_40:
6326 if (rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)
6327 break;
6328 default:
6298 return -EINVAL; 6329 return -EINVAL;
6330 }
6299 6331
6300 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 6332 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
6301 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 6333 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
@@ -8409,6 +8441,7 @@ static struct genl_ops nl80211_ops[] = {
8409 .cmd = NL80211_CMD_GET_WIPHY, 8441 .cmd = NL80211_CMD_GET_WIPHY,
8410 .doit = nl80211_get_wiphy, 8442 .doit = nl80211_get_wiphy,
8411 .dumpit = nl80211_dump_wiphy, 8443 .dumpit = nl80211_dump_wiphy,
8444 .done = nl80211_dump_wiphy_done,
8412 .policy = nl80211_policy, 8445 .policy = nl80211_policy,
8413 /* can be retrieved by unprivileged users */ 8446 /* can be retrieved by unprivileged users */
8414 .internal_flags = NL80211_FLAG_NEED_WIPHY | 8447 .internal_flags = NL80211_FLAG_NEED_WIPHY |
@@ -9029,13 +9062,13 @@ static struct genl_multicast_group nl80211_regulatory_mcgrp = {
9029void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) 9062void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
9030{ 9063{
9031 struct sk_buff *msg; 9064 struct sk_buff *msg;
9065 struct nl80211_dump_wiphy_state state = {};
9032 9066
9033 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9067 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9034 if (!msg) 9068 if (!msg)
9035 return; 9069 return;
9036 9070
9037 if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, 9071 if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, &state) < 0) {
9038 false, NULL, NULL, NULL) < 0) {
9039 nlmsg_free(msg); 9072 nlmsg_free(msg);
9040 return; 9073 return;
9041 } 9074 }
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index dd01b58fa78c..ae8c186b50d6 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -523,6 +523,7 @@ static int cmp_bss(struct cfg80211_bss *a,
523 } 523 }
524} 524}
525 525
526/* Returned bss is reference counted and must be cleaned up appropriately. */
526struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, 527struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
527 struct ieee80211_channel *channel, 528 struct ieee80211_channel *channel,
528 const u8 *bssid, 529 const u8 *bssid,
@@ -678,6 +679,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
678 return true; 679 return true;
679} 680}
680 681
682/* Returned bss is reference counted and must be cleaned up appropriately. */
681static struct cfg80211_internal_bss * 683static struct cfg80211_internal_bss *
682cfg80211_bss_update(struct cfg80211_registered_device *dev, 684cfg80211_bss_update(struct cfg80211_registered_device *dev,
683 struct cfg80211_internal_bss *tmp) 685 struct cfg80211_internal_bss *tmp)
@@ -866,6 +868,7 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
866 return channel; 868 return channel;
867} 869}
868 870
871/* Returned bss is reference counted and must be cleaned up appropriately. */
869struct cfg80211_bss* 872struct cfg80211_bss*
870cfg80211_inform_bss(struct wiphy *wiphy, 873cfg80211_inform_bss(struct wiphy *wiphy,
871 struct ieee80211_channel *channel, 874 struct ieee80211_channel *channel,
@@ -923,6 +926,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
923} 926}
924EXPORT_SYMBOL(cfg80211_inform_bss); 927EXPORT_SYMBOL(cfg80211_inform_bss);
925 928
929/* Returned bss is reference counted and must be cleaned up appropriately. */
926struct cfg80211_bss * 930struct cfg80211_bss *
927cfg80211_inform_bss_frame(struct wiphy *wiphy, 931cfg80211_inform_bss_frame(struct wiphy *wiphy,
928 struct ieee80211_channel *channel, 932 struct ieee80211_channel *channel,
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index ae7e2cbf45cb..1d3cfb1a3f28 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -239,6 +239,7 @@ void cfg80211_conn_work(struct work_struct *work)
239 rtnl_unlock(); 239 rtnl_unlock();
240} 240}
241 241
242/* Returned bss is reference counted and must be cleaned up appropriately. */
242static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) 243static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
243{ 244{
244 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 245 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -557,6 +558,7 @@ static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
557 * SME event handling 558 * SME event handling
558 */ 559 */
559 560
561/* This method must consume bss one way or another */
560void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 562void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
561 const u8 *req_ie, size_t req_ie_len, 563 const u8 *req_ie, size_t req_ie_len,
562 const u8 *resp_ie, size_t resp_ie_len, 564 const u8 *resp_ie, size_t resp_ie_len,
@@ -572,8 +574,10 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
572 ASSERT_WDEV_LOCK(wdev); 574 ASSERT_WDEV_LOCK(wdev);
573 575
574 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && 576 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
575 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 577 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) {
578 cfg80211_put_bss(wdev->wiphy, bss);
576 return; 579 return;
580 }
577 581
578 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, 582 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
579 bssid, req_ie, req_ie_len, 583 bssid, req_ie, req_ie_len,
@@ -615,19 +619,24 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
615 kfree(wdev->connect_keys); 619 kfree(wdev->connect_keys);
616 wdev->connect_keys = NULL; 620 wdev->connect_keys = NULL;
617 wdev->ssid_len = 0; 621 wdev->ssid_len = 0;
618 cfg80211_put_bss(wdev->wiphy, bss); 622 if (bss) {
623 cfg80211_unhold_bss(bss_from_pub(bss));
624 cfg80211_put_bss(wdev->wiphy, bss);
625 }
619 return; 626 return;
620 } 627 }
621 628
622 if (!bss) 629 if (!bss) {
630 WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect);
623 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 631 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
624 wdev->ssid, wdev->ssid_len, 632 wdev->ssid, wdev->ssid_len,
625 WLAN_CAPABILITY_ESS, 633 WLAN_CAPABILITY_ESS,
626 WLAN_CAPABILITY_ESS); 634 WLAN_CAPABILITY_ESS);
627 if (WARN_ON(!bss)) 635 if (WARN_ON(!bss))
628 return; 636 return;
637 cfg80211_hold_bss(bss_from_pub(bss));
638 }
629 639
630 cfg80211_hold_bss(bss_from_pub(bss));
631 wdev->current_bss = bss_from_pub(bss); 640 wdev->current_bss = bss_from_pub(bss);
632 641
633 cfg80211_upload_connect_keys(wdev); 642 cfg80211_upload_connect_keys(wdev);
@@ -691,6 +700,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
691} 700}
692EXPORT_SYMBOL(cfg80211_connect_result); 701EXPORT_SYMBOL(cfg80211_connect_result);
693 702
703/* Consumes bss object one way or another */
694void __cfg80211_roamed(struct wireless_dev *wdev, 704void __cfg80211_roamed(struct wireless_dev *wdev,
695 struct cfg80211_bss *bss, 705 struct cfg80211_bss *bss,
696 const u8 *req_ie, size_t req_ie_len, 706 const u8 *req_ie, size_t req_ie_len,
@@ -767,6 +777,7 @@ void cfg80211_roamed(struct net_device *dev,
767} 777}
768EXPORT_SYMBOL(cfg80211_roamed); 778EXPORT_SYMBOL(cfg80211_roamed);
769 779
780/* Consumes bss object one way or another */
770void cfg80211_roamed_bss(struct net_device *dev, 781void cfg80211_roamed_bss(struct net_device *dev,
771 struct cfg80211_bss *bss, const u8 *req_ie, 782 struct cfg80211_bss *bss, const u8 *req_ie,
772 size_t req_ie_len, const u8 *resp_ie, 783 size_t req_ie_len, const u8 *resp_ie,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 360a42c6f694..a23253e06358 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -83,6 +83,7 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
83 return 0; 83 return 0;
84} 84}
85 85
86#ifdef CONFIG_PM
86static void cfg80211_leave_all(struct cfg80211_registered_device *rdev) 87static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
87{ 88{
88 struct wireless_dev *wdev; 89 struct wireless_dev *wdev;
@@ -91,7 +92,6 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
91 cfg80211_leave(rdev, wdev); 92 cfg80211_leave(rdev, wdev);
92} 93}
93 94
94#ifdef CONFIG_PM
95static int wiphy_suspend(struct device *dev, pm_message_t state) 95static int wiphy_suspend(struct device *dev, pm_message_t state)
96{ 96{
97 struct cfg80211_registered_device *rdev = dev_to_rdev(dev); 97 struct cfg80211_registered_device *rdev = dev_to_rdev(dev);