aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS25
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c20
-rw-r--r--drivers/bcma/scan.c2
-rw-r--r--drivers/bcma/sprom.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c89
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c32
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h1673
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c55
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c27
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c54
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c48
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c44
-rw-r--r--drivers/net/wireless/ath/carl9170/Kconfig14
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h24
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.c34
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h1
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c3
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h11
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c229
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c16
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h4
-rw-r--r--drivers/net/wireless/b43/Kconfig10
-rw-r--r--drivers/net/wireless/b43/b43.h23
-rw-r--r--drivers/net/wireless/b43/dma.c126
-rw-r--r--drivers/net/wireless/b43/dma.h13
-rw-r--r--drivers/net/wireless/b43/main.c66
-rw-r--r--drivers/net/wireless/b43/phy_common.c32
-rw-r--r--drivers/net/wireless/b43/phy_common.h2
-rw-r--r--drivers/net/wireless/b43/phy_ht.c203
-rw-r--r--drivers/net/wireless/b43/phy_ht.h19
-rw-r--r--drivers/net/wireless/b43/phy_lcn.c211
-rw-r--r--drivers/net/wireless/b43/phy_lcn.h16
-rw-r--r--drivers/net/wireless/b43/phy_n.c40
-rw-r--r--drivers/net/wireless/b43/pio.c12
-rw-r--r--drivers/net/wireless/b43/tables_phy_ht.c84
-rw-r--r--drivers/net/wireless/b43/tables_phy_ht.h4
-rw-r--r--drivers/net/wireless/b43/tables_phy_lcn.c432
-rw-r--r--drivers/net/wireless/b43/tables_phy_lcn.h16
-rw-r--r--drivers/net/wireless/b43/xmit.c120
-rw-r--r--drivers/net/wireless/b43/xmit.h62
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h4
-rw-r--r--drivers/net/wireless/b43legacy/main.c4
-rw-r--r--drivers/net/wireless/libertas/README25
-rw-r--r--drivers/net/wireless/libertas/dev.h4
-rw-r--r--drivers/net/wireless/mwifiex/scan.c4
-rw-r--r--drivers/net/wireless/mwl8k.c3
-rw-r--r--drivers/net/wireless/p54/eeprom.c26
-rw-r--r--drivers/net/wireless/p54/fwio.c2
-rw-r--r--drivers/net/wireless/p54/main.c113
-rw-r--r--drivers/net/wireless/p54/p54.h18
-rw-r--r--drivers/net/wireless/p54/txrx.c66
-rw-r--r--drivers/net/wireless/rtlwifi/base.c161
-rw-r--r--drivers/net/wireless/rtlwifi/base.h2
-rw-r--r--drivers/net/wireless/rtlwifi/debug.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h139
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c30
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c116
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.h8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.h8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c28
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c23
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/def.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c30
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.c121
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.h8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c30
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c124
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h35
-rw-r--r--drivers/nfc/pn533.c17
-rw-r--r--drivers/ssb/main.c24
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h18
-rw-r--r--include/linux/ieee80211.h59
-rw-r--r--include/linux/nfc.h2
-rw-r--r--include/linux/nl80211.h32
-rw-r--r--include/net/cfg80211.h12
-rw-r--r--include/net/mac80211.h2
-rw-r--r--include/net/nfc.h7
-rw-r--r--include/net/regulatory.h16
-rw-r--r--net/mac80211/Kconfig13
-rw-r--r--net/mac80211/agg-tx.c2
-rw-r--r--net/mac80211/cfg.c19
-rw-r--r--net/mac80211/debugfs_netdev.c8
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mesh.c259
-rw-r--r--net/mac80211/mesh.h36
-rw-r--r--net/mac80211/mesh_hwmp.c130
-rw-r--r--net/mac80211/mesh_pathtbl.c305
-rw-r--r--net/mac80211/mesh_plink.c241
-rw-r--r--net/mac80211/mlme.c59
-rw-r--r--net/mac80211/rx.c48
-rw-r--r--net/mac80211/sta_info.c330
-rw-r--r--net/mac80211/sta_info.h30
-rw-r--r--net/mac80211/status.c18
-rw-r--r--net/mac80211/tx.c14
-rw-r--r--net/nfc/core.c6
-rw-r--r--net/nfc/rawsock.c13
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/nl80211.c42
-rw-r--r--net/wireless/util.c6
121 files changed, 5613 insertions, 1490 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 194095ac07ec..579713ef7cfb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1230,7 +1230,7 @@ F: Documentation/aoe/
1230F: drivers/block/aoe/ 1230F: drivers/block/aoe/
1231 1231
1232ATHEROS ATH GENERIC UTILITIES 1232ATHEROS ATH GENERIC UTILITIES
1233M: "Luis R. Rodriguez" <lrodriguez@atheros.com> 1233M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
1234L: linux-wireless@vger.kernel.org 1234L: linux-wireless@vger.kernel.org
1235S: Supported 1235S: Supported
1236F: drivers/net/wireless/ath/* 1236F: drivers/net/wireless/ath/*
@@ -1238,7 +1238,7 @@ F: drivers/net/wireless/ath/*
1238ATHEROS ATH5K WIRELESS DRIVER 1238ATHEROS ATH5K WIRELESS DRIVER
1239M: Jiri Slaby <jirislaby@gmail.com> 1239M: Jiri Slaby <jirislaby@gmail.com>
1240M: Nick Kossifidis <mickflemm@gmail.com> 1240M: Nick Kossifidis <mickflemm@gmail.com>
1241M: "Luis R. Rodriguez" <lrodriguez@atheros.com> 1241M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
1242M: Bob Copeland <me@bobcopeland.com> 1242M: Bob Copeland <me@bobcopeland.com>
1243L: linux-wireless@vger.kernel.org 1243L: linux-wireless@vger.kernel.org
1244L: ath5k-devel@lists.ath5k.org 1244L: ath5k-devel@lists.ath5k.org
@@ -1247,10 +1247,10 @@ S: Maintained
1247F: drivers/net/wireless/ath/ath5k/ 1247F: drivers/net/wireless/ath/ath5k/
1248 1248
1249ATHEROS ATH9K WIRELESS DRIVER 1249ATHEROS ATH9K WIRELESS DRIVER
1250M: "Luis R. Rodriguez" <lrodriguez@atheros.com> 1250M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
1251M: Jouni Malinen <jmalinen@atheros.com> 1251M: Jouni Malinen <jouni@qca.qualcomm.com>
1252M: Vasanthakumar Thiagarajan <vasanth@atheros.com> 1252M: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
1253M: Senthil Balasubramanian <senthilkumar@atheros.com> 1253M: Senthil Balasubramanian <senthilb@qca.qualcomm.com>
1254L: linux-wireless@vger.kernel.org 1254L: linux-wireless@vger.kernel.org
1255L: ath9k-devel@lists.ath9k.org 1255L: ath9k-devel@lists.ath9k.org
1256W: http://wireless.kernel.org/en/users/Drivers/ath9k 1256W: http://wireless.kernel.org/en/users/Drivers/ath9k
@@ -1278,7 +1278,7 @@ F: drivers/input/misc/ati_remote2.c
1278ATLX ETHERNET DRIVERS 1278ATLX ETHERNET DRIVERS
1279M: Jay Cliburn <jcliburn@gmail.com> 1279M: Jay Cliburn <jcliburn@gmail.com>
1280M: Chris Snook <chris.snook@gmail.com> 1280M: Chris Snook <chris.snook@gmail.com>
1281M: Jie Yang <jie.yang@atheros.com> 1281M: Jie Yang <yangjie@qca.qualcomm.com>
1282L: netdev@vger.kernel.org 1282L: netdev@vger.kernel.org
1283W: http://sourceforge.net/projects/atl1 1283W: http://sourceforge.net/projects/atl1
1284W: http://atl1.sourceforge.net 1284W: http://atl1.sourceforge.net
@@ -4503,6 +4503,17 @@ W: http://www.qlogic.com
4503S: Supported 4503S: Supported
4504F: drivers/net/ethernet/qlogic/netxen/ 4504F: drivers/net/ethernet/qlogic/netxen/
4505 4505
4506NFC SUBSYSTEM
4507M: Lauro Ramos Venancio <lauro.venancio@openbossa.org>
4508M: Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
4509M: Samuel Ortiz <sameo@linux.intel.com>
4510L: linux-wireless@vger.kernel.org
4511S: Maintained
4512F: net/nfc/
4513F: include/linux/nfc.h
4514F: include/net/nfc.h
4515F: drivers/nfc/
4516
4506NFS, SUNRPC, AND LOCKD CLIENTS 4517NFS, SUNRPC, AND LOCKD CLIENTS
4507M: Trond Myklebust <Trond.Myklebust@netapp.com> 4518M: Trond Myklebust <Trond.Myklebust@netapp.com>
4508L: linux-nfs@vger.kernel.org 4519L: linux-nfs@vger.kernel.org
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index 5940c81e7e12..4bc10aa57bd4 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -90,6 +90,24 @@ void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
90 } 90 }
91} 91}
92 92
93/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
94void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
95{
96 struct bcma_bus *bus = cc->core->bus;
97 u32 val;
98
99 val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
100 if (enable) {
101 val |= BCMA_CHIPCTL_4331_EXTPA_EN;
102 if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
103 val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
104 } else {
105 val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
106 val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
107 }
108 bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
109}
110
93void bcma_pmu_workarounds(struct bcma_drv_cc *cc) 111void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
94{ 112{
95 struct bcma_bus *bus = cc->core->bus; 113 struct bcma_bus *bus = cc->core->bus;
@@ -99,7 +117,7 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
99 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); 117 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
100 break; 118 break;
101 case 0x4331: 119 case 0x4331:
102 pr_err("Enabling Ext PA lines not implemented\n"); 120 /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
103 break; 121 break;
104 case 43224: 122 case 43224:
105 if (bus->chipinfo.rev == 0) { 123 if (bus->chipinfo.rev == 0) {
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 0ea390f9aa9e..cad994857683 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -281,7 +281,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
281 281
282 /* get & parse master ports */ 282 /* get & parse master ports */
283 for (i = 0; i < ports[0]; i++) { 283 for (i = 0; i < ports[0]; i++) {
284 u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr); 284 s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
285 if (mst_port_d < 0) 285 if (mst_port_d < 0)
286 return -EILSEQ; 286 return -EILSEQ;
287 } 287 }
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 8b5b7856abe3..166ed13ec066 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -152,6 +152,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
152 if (!sprom) 152 if (!sprom)
153 return -ENOMEM; 153 return -ENOMEM;
154 154
155 if (bus->chipinfo.id == 0x4331)
156 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
157
155 /* Most cards have SPROM moved by additional offset 0x30 (48 dwords). 158 /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
156 * According to brcm80211 this applies to cards with PCIe rev >= 6 159 * According to brcm80211 this applies to cards with PCIe rev >= 6
157 * TODO: understand this condition and use it */ 160 * TODO: understand this condition and use it */
@@ -159,6 +162,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
159 BCMA_CC_SPROM_PCIE6; 162 BCMA_CC_SPROM_PCIE6;
160 bcma_sprom_read(bus, offset, sprom); 163 bcma_sprom_read(bus, offset, sprom);
161 164
165 if (bus->chipinfo.id == 0x4331)
166 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
167
162 err = bcma_sprom_valid(sprom); 168 err = bcma_sprom_valid(sprom);
163 if (err) 169 if (err)
164 goto out; 170 goto out;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 44d9d8d56490..b54ab78fb092 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -303,17 +303,13 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
303 * register as the other analog registers. Hence the 9 writes. 303 * register as the other analog registers. Hence the 9 writes.
304 */ 304 */
305static void ar9002_hw_configpcipowersave(struct ath_hw *ah, 305static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
306 int restore, 306 bool power_off)
307 int power_off)
308{ 307{
309 u8 i; 308 u8 i;
310 u32 val; 309 u32 val;
311 310
312 if (ah->is_pciexpress != true || ah->aspm_enabled != true)
313 return;
314
315 /* Nothing to do on restore for 11N */ 311 /* Nothing to do on restore for 11N */
316 if (!restore) { 312 if (!power_off /* !restore */) {
317 if (AR_SREV_9280_20_OR_LATER(ah)) { 313 if (AR_SREV_9280_20_OR_LATER(ah)) {
318 /* 314 /*
319 * AR9280 2.0 or later chips use SerDes values from the 315 * AR9280 2.0 or later chips use SerDes values from the
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index a0aadaddd071..f2c6f2316a3b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -636,7 +636,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
636 {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, 636 {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
637 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, 637 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
638 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, 638 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
639 {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0}, 639 {0x0000a204, 0x000036c0, 0x000036c4, 0x000036c4, 0x000036c0},
640 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, 640 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
641 {0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f}, 641 {0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f},
642 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, 642 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index f48051c50092..fa35a0235f44 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -839,20 +839,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
839 struct ath9k_channel *chan) 839 struct ath9k_channel *chan)
840{ 840{
841 struct ath_common *common = ath9k_hw_common(ah); 841 struct ath_common *common = ath9k_hw_common(ah);
842 struct ath9k_hw_capabilities *pCap = &ah->caps;
843 int val;
844 bool txiqcal_done = false; 842 bool txiqcal_done = false;
845 843
846 val = REG_READ(ah, AR_ENT_OTP);
847 ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
848
849 /* Configure rx/tx chains before running AGC/TxiQ cals */
850 if (val & AR_ENT_OTP_CHAIN2_DISABLE)
851 ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
852 else
853 ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
854 pCap->tx_chainmask);
855
856 /* Do Tx IQ Calibration */ 844 /* Do Tx IQ Calibration */
857 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, 845 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
858 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, 846 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
@@ -887,9 +875,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
887 if (txiqcal_done) 875 if (txiqcal_done)
888 ar9003_hw_tx_iq_cal_post_proc(ah); 876 ar9003_hw_tx_iq_cal_post_proc(ah);
889 877
890 /* Revert chainmasks to their original values before NF cal */
891 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
892
893 ath9k_hw_start_nfcal(ah, true); 878 ath9k_hw_start_nfcal(ah, true);
894 879
895 /* Initialize list pointers */ 880 /* Initialize list pointers */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index ad2bb2bf4e8a..b6839e695270 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -21,6 +21,7 @@
21#include "ar9340_initvals.h" 21#include "ar9340_initvals.h"
22#include "ar9330_1p1_initvals.h" 22#include "ar9330_1p1_initvals.h"
23#include "ar9330_1p2_initvals.h" 23#include "ar9330_1p2_initvals.h"
24#include "ar9580_1p0_initvals.h"
24 25
25/* General hardware code for the AR9003 hadware family */ 26/* General hardware code for the AR9003 hadware family */
26 27
@@ -253,6 +254,56 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
253 ar9485_1_1_pcie_phy_clkreq_disable_L1, 254 ar9485_1_1_pcie_phy_clkreq_disable_L1,
254 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 255 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
255 2); 256 2);
257 } else if (AR_SREV_9580(ah)) {
258 /* mac */
259 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
260 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
261 ar9580_1p0_mac_core,
262 ARRAY_SIZE(ar9580_1p0_mac_core), 2);
263 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
264 ar9580_1p0_mac_postamble,
265 ARRAY_SIZE(ar9580_1p0_mac_postamble), 5);
266
267 /* bb */
268 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
269 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
270 ar9580_1p0_baseband_core,
271 ARRAY_SIZE(ar9580_1p0_baseband_core), 2);
272 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
273 ar9580_1p0_baseband_postamble,
274 ARRAY_SIZE(ar9580_1p0_baseband_postamble), 5);
275
276 /* radio */
277 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
278 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
279 ar9580_1p0_radio_core,
280 ARRAY_SIZE(ar9580_1p0_radio_core), 2);
281 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
282 ar9580_1p0_radio_postamble,
283 ARRAY_SIZE(ar9580_1p0_radio_postamble), 5);
284
285 /* soc */
286 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
287 ar9580_1p0_soc_preamble,
288 ARRAY_SIZE(ar9580_1p0_soc_preamble), 2);
289 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
290 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
291 ar9580_1p0_soc_postamble,
292 ARRAY_SIZE(ar9580_1p0_soc_postamble), 5);
293
294 /* rx/tx gain */
295 INIT_INI_ARRAY(&ah->iniModesRxGain,
296 ar9580_1p0_rx_gain_table,
297 ARRAY_SIZE(ar9580_1p0_rx_gain_table), 2);
298 INIT_INI_ARRAY(&ah->iniModesTxGain,
299 ar9580_1p0_low_ob_db_tx_gain_table,
300 ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
301 5);
302
303 INIT_INI_ARRAY(&ah->iniModesAdditional,
304 ar9580_1p0_modes_fast_clock,
305 ARRAY_SIZE(ar9580_1p0_modes_fast_clock),
306 3);
256 } else { 307 } else {
257 /* mac */ 308 /* mac */
258 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 309 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -348,6 +399,11 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
348 ar9485_modes_lowest_ob_db_tx_gain_1_1, 399 ar9485_modes_lowest_ob_db_tx_gain_1_1,
349 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), 400 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
350 5); 401 5);
402 else if (AR_SREV_9580(ah))
403 INIT_INI_ARRAY(&ah->iniModesTxGain,
404 ar9580_1p0_lowest_ob_db_tx_gain_table,
405 ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
406 5);
351 else 407 else
352 INIT_INI_ARRAY(&ah->iniModesTxGain, 408 INIT_INI_ARRAY(&ah->iniModesTxGain,
353 ar9300Modes_lowest_ob_db_tx_gain_table_2p2, 409 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
@@ -375,6 +431,11 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
375 ar9485Modes_high_ob_db_tx_gain_1_1, 431 ar9485Modes_high_ob_db_tx_gain_1_1,
376 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), 432 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
377 5); 433 5);
434 else if (AR_SREV_9580(ah))
435 INIT_INI_ARRAY(&ah->iniModesTxGain,
436 ar9580_1p0_high_ob_db_tx_gain_table,
437 ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
438 5);
378 else 439 else
379 INIT_INI_ARRAY(&ah->iniModesTxGain, 440 INIT_INI_ARRAY(&ah->iniModesTxGain,
380 ar9300Modes_high_ob_db_tx_gain_table_2p2, 441 ar9300Modes_high_ob_db_tx_gain_table_2p2,
@@ -402,6 +463,11 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
402 ar9485Modes_low_ob_db_tx_gain_1_1, 463 ar9485Modes_low_ob_db_tx_gain_1_1,
403 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), 464 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
404 5); 465 5);
466 else if (AR_SREV_9580(ah))
467 INIT_INI_ARRAY(&ah->iniModesTxGain,
468 ar9580_1p0_low_ob_db_tx_gain_table,
469 ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
470 5);
405 else 471 else
406 INIT_INI_ARRAY(&ah->iniModesTxGain, 472 INIT_INI_ARRAY(&ah->iniModesTxGain,
407 ar9300Modes_low_ob_db_tx_gain_table_2p2, 473 ar9300Modes_low_ob_db_tx_gain_table_2p2,
@@ -429,6 +495,11 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
429 ar9485Modes_high_power_tx_gain_1_1, 495 ar9485Modes_high_power_tx_gain_1_1,
430 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), 496 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
431 5); 497 5);
498 else if (AR_SREV_9580(ah))
499 INIT_INI_ARRAY(&ah->iniModesTxGain,
500 ar9580_1p0_high_power_tx_gain_table,
501 ARRAY_SIZE(ar9580_1p0_high_power_tx_gain_table),
502 5);
432 else 503 else
433 INIT_INI_ARRAY(&ah->iniModesTxGain, 504 INIT_INI_ARRAY(&ah->iniModesTxGain,
434 ar9300Modes_high_power_tx_gain_table_2p2, 505 ar9300Modes_high_power_tx_gain_table_2p2,
@@ -463,6 +534,11 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
463 ar9485Common_wo_xlna_rx_gain_1_1, 534 ar9485Common_wo_xlna_rx_gain_1_1,
464 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 535 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
465 2); 536 2);
537 else if (AR_SREV_9580(ah))
538 INIT_INI_ARRAY(&ah->iniModesRxGain,
539 ar9580_1p0_rx_gain_table,
540 ARRAY_SIZE(ar9580_1p0_rx_gain_table),
541 2);
466 else 542 else
467 INIT_INI_ARRAY(&ah->iniModesRxGain, 543 INIT_INI_ARRAY(&ah->iniModesRxGain,
468 ar9300Common_rx_gain_table_2p2, 544 ar9300Common_rx_gain_table_2p2,
@@ -490,6 +566,11 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
490 ar9485Common_wo_xlna_rx_gain_1_1, 566 ar9485Common_wo_xlna_rx_gain_1_1,
491 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 567 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
492 2); 568 2);
569 else if (AR_SREV_9580(ah))
570 INIT_INI_ARRAY(&ah->iniModesRxGain,
571 ar9580_1p0_wo_xlna_rx_gain_table,
572 ARRAY_SIZE(ar9580_1p0_wo_xlna_rx_gain_table),
573 2);
493 else 574 else
494 INIT_INI_ARRAY(&ah->iniModesRxGain, 575 INIT_INI_ARRAY(&ah->iniModesRxGain,
495 ar9300Common_wo_xlna_rx_gain_table_2p2, 576 ar9300Common_wo_xlna_rx_gain_table_2p2,
@@ -516,14 +597,10 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
516 * register as the other analog registers. Hence the 9 writes. 597 * register as the other analog registers. Hence the 9 writes.
517 */ 598 */
518static void ar9003_hw_configpcipowersave(struct ath_hw *ah, 599static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
519 int restore, 600 bool power_off)
520 int power_off)
521{ 601{
522 if (ah->is_pciexpress != true || ah->aspm_enabled != true)
523 return;
524
525 /* Nothing to do on restore for 11N */ 602 /* Nothing to do on restore for 11N */
526 if (!restore) { 603 if (!power_off /* !restore */) {
527 /* set bit 19 to allow forcing of pcie core into L1 state */ 604 /* set bit 19 to allow forcing of pcie core into L1 state */
528 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 605 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
529 606
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 1aadc4757e67..8ace36e77399 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -253,8 +253,6 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
253 return -EIO; 253 return -EIO;
254 } 254 }
255 255
256 if (status & AR_TxOpExceeded)
257 ts->ts_status |= ATH9K_TXERR_XTXOP;
258 ts->ts_rateindex = MS(status, AR_FinalTxIdx); 256 ts->ts_rateindex = MS(status, AR_FinalTxIdx);
259 ts->ts_seqnum = MS(status, AR_SeqNum); 257 ts->ts_seqnum = MS(status, AR_SeqNum);
260 ts->tid = MS(status, AR_TxTid); 258 ts->tid = MS(status, AR_TxTid);
@@ -264,6 +262,8 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
264 ts->ts_status = 0; 262 ts->ts_status = 0;
265 ts->ts_flags = 0; 263 ts->ts_flags = 0;
266 264
265 if (status & AR_TxOpExceeded)
266 ts->ts_status |= ATH9K_TXERR_XTXOP;
267 status = ACCESS_ONCE(ads->status2); 267 status = ACCESS_ONCE(ads->status2);
268 ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00); 268 ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
269 ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01); 269 ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
@@ -415,36 +415,12 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
415static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, 415static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
416 u32 aggrLen) 416 u32 aggrLen)
417{ 417{
418#define FIRST_DESC_NDELIMS 60
419 struct ar9003_txc *ads = (struct ar9003_txc *) ds; 418 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
420 419
421 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); 420 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
422 421
423 if (ah->ent_mode & AR_ENT_OTP_MPSD) { 422 ads->ctl17 &= ~AR_AggrLen;
424 u32 ctl17, ndelim; 423 ads->ctl17 |= SM(aggrLen, AR_AggrLen);
425 /*
426 * Add delimiter when using RTS/CTS with aggregation
427 * and non enterprise AR9003 card
428 */
429 ctl17 = ads->ctl17;
430 ndelim = MS(ctl17, AR_PadDelim);
431
432 if (ndelim < FIRST_DESC_NDELIMS) {
433 aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
434 ndelim = FIRST_DESC_NDELIMS;
435 }
436
437 ctl17 &= ~AR_AggrLen;
438 ctl17 |= SM(aggrLen, AR_AggrLen);
439
440 ctl17 &= ~AR_PadDelim;
441 ctl17 |= SM(ndelim, AR_PadDelim);
442
443 ads->ctl17 = ctl17;
444 } else {
445 ads->ctl17 &= ~AR_AggrLen;
446 ads->ctl17 |= SM(aggrLen, AR_AggrLen);
447 }
448} 424}
449 425
450static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, 426static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index a0aaa6855486..33edb5653ca6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -482,7 +482,7 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
482 (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO); 482 (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO);
483 483
484 /* Enable 11n HT, 20 MHz */ 484 /* Enable 11n HT, 20 MHz */
485 phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH | 485 phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 |
486 AR_PHY_GC_SHORT_GI_40 | enableDacFifo; 486 AR_PHY_GC_SHORT_GI_40 | enableDacFifo;
487 487
488 /* Configure baseband for dynamic 20/40 operation */ 488 /* Configure baseband for dynamic 20/40 operation */
@@ -540,7 +540,7 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
540 udelay(synthDelay + BASE_ACTIVATE_DELAY); 540 udelay(synthDelay + BASE_ACTIVATE_DELAY);
541} 541}
542 542
543void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) 543static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
544{ 544{
545 switch (rx) { 545 switch (rx) {
546 case 0x5: 546 case 0x5:
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 5c590429f120..80397de11e0d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -1124,6 +1124,4 @@
1124#define AR_PHY_CL_TAB_CL_GAIN_MOD 0x1f 1124#define AR_PHY_CL_TAB_CL_GAIN_MOD 0x1f
1125#define AR_PHY_CL_TAB_CL_GAIN_MOD_S 0 1125#define AR_PHY_CL_TAB_CL_GAIN_MOD_S 0
1126 1126
1127void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
1128
1129#endif /* AR9003_PHY_H */ 1127#endif /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
new file mode 100644
index 000000000000..06b3f0df9fad
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
@@ -0,0 +1,1673 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef INITVALS_9580_1P0_H
18#define INITVALS_9580_1P0_H
19
20/* AR9580 1.0 */
21
22static const u32 ar9580_1p0_modes_fast_clock[][3] = {
23 /* Addr 5G_HT20 5G_HT40 */
24 {0x00001030, 0x00000268, 0x000004d0},
25 {0x00001070, 0x0000018c, 0x00000318},
26 {0x000010b0, 0x00000fd0, 0x00001fa0},
27 {0x00008014, 0x044c044c, 0x08980898},
28 {0x0000801c, 0x148ec02b, 0x148ec057},
29 {0x00008318, 0x000044c0, 0x00008980},
30 {0x00009e00, 0x0372131c, 0x0372131c},
31 {0x0000a230, 0x0000000b, 0x00000016},
32 {0x0000a254, 0x00000898, 0x00001130},
33};
34
35static const u32 ar9580_1p0_radio_postamble[][5] = {
36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
37 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
38 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
39 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
40 {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
41 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
42 {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
43 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
44 {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
45 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
46};
47
48static const u32 ar9580_1p0_baseband_core[][2] = {
49 /* Addr allmodes */
50 {0x00009800, 0xafe68e30},
51 {0x00009804, 0xfd14e000},
52 {0x00009808, 0x9c0a9f6b},
53 {0x0000980c, 0x04900000},
54 {0x00009814, 0x3280c00a},
55 {0x00009818, 0x00000000},
56 {0x0000981c, 0x00020028},
57 {0x00009834, 0x6400a290},
58 {0x00009838, 0x0108ecff},
59 {0x0000983c, 0x0d000600},
60 {0x00009880, 0x201fff00},
61 {0x00009884, 0x00001042},
62 {0x000098a4, 0x00200400},
63 {0x000098b0, 0x32840bbe},
64 {0x000098d0, 0x004b6a8e},
65 {0x000098d4, 0x00000820},
66 {0x000098dc, 0x00000000},
67 {0x000098f0, 0x00000000},
68 {0x000098f4, 0x00000000},
69 {0x00009c04, 0xff55ff55},
70 {0x00009c08, 0x0320ff55},
71 {0x00009c0c, 0x00000000},
72 {0x00009c10, 0x00000000},
73 {0x00009c14, 0x00046384},
74 {0x00009c18, 0x05b6b440},
75 {0x00009c1c, 0x00b6b440},
76 {0x00009d00, 0xc080a333},
77 {0x00009d04, 0x40206c10},
78 {0x00009d08, 0x009c4060},
79 {0x00009d0c, 0x9883800a},
80 {0x00009d10, 0x01834061},
81 {0x00009d14, 0x00c0040b},
82 {0x00009d18, 0x00000000},
83 {0x00009e08, 0x0038230c},
84 {0x00009e24, 0x990bb515},
85 {0x00009e28, 0x0c6f0000},
86 {0x00009e30, 0x06336f77},
87 {0x00009e34, 0x6af6532f},
88 {0x00009e38, 0x0cc80c00},
89 {0x00009e40, 0x0d261820},
90 {0x00009e4c, 0x00001004},
91 {0x00009e50, 0x00ff03f1},
92 {0x00009e54, 0x00000000},
93 {0x00009fc0, 0x803e4788},
94 {0x00009fc4, 0x0001efb5},
95 {0x00009fcc, 0x40000014},
96 {0x00009fd0, 0x01193b93},
97 {0x0000a20c, 0x00000000},
98 {0x0000a220, 0x00000000},
99 {0x0000a224, 0x00000000},
100 {0x0000a228, 0x10002310},
101 {0x0000a23c, 0x00000000},
102 {0x0000a244, 0x0c000000},
103 {0x0000a2a0, 0x00000001},
104 {0x0000a2c0, 0x00000001},
105 {0x0000a2c8, 0x00000000},
106 {0x0000a2cc, 0x18c43433},
107 {0x0000a2d4, 0x00000000},
108 {0x0000a2ec, 0x00000000},
109 {0x0000a2f0, 0x00000000},
110 {0x0000a2f4, 0x00000000},
111 {0x0000a2f8, 0x00000000},
112 {0x0000a344, 0x00000000},
113 {0x0000a34c, 0x00000000},
114 {0x0000a350, 0x0000a000},
115 {0x0000a364, 0x00000000},
116 {0x0000a370, 0x00000000},
117 {0x0000a390, 0x00000001},
118 {0x0000a394, 0x00000444},
119 {0x0000a398, 0x001f0e0f},
120 {0x0000a39c, 0x0075393f},
121 {0x0000a3a0, 0xb79f6427},
122 {0x0000a3a4, 0x00000000},
123 {0x0000a3a8, 0xaaaaaaaa},
124 {0x0000a3ac, 0x3c466478},
125 {0x0000a3c0, 0x20202020},
126 {0x0000a3c4, 0x22222220},
127 {0x0000a3c8, 0x20200020},
128 {0x0000a3cc, 0x20202020},
129 {0x0000a3d0, 0x20202020},
130 {0x0000a3d4, 0x20202020},
131 {0x0000a3d8, 0x20202020},
132 {0x0000a3dc, 0x20202020},
133 {0x0000a3e0, 0x20202020},
134 {0x0000a3e4, 0x20202020},
135 {0x0000a3e8, 0x20202020},
136 {0x0000a3ec, 0x20202020},
137 {0x0000a3f0, 0x00000000},
138 {0x0000a3f4, 0x00000000},
139 {0x0000a3f8, 0x0c9bd380},
140 {0x0000a3fc, 0x000f0f01},
141 {0x0000a400, 0x8fa91f01},
142 {0x0000a404, 0x00000000},
143 {0x0000a408, 0x0e79e5c6},
144 {0x0000a40c, 0x00820820},
145 {0x0000a414, 0x1ce739ce},
146 {0x0000a418, 0x2d001dce},
147 {0x0000a41c, 0x1ce739ce},
148 {0x0000a420, 0x000001ce},
149 {0x0000a424, 0x1ce739ce},
150 {0x0000a428, 0x000001ce},
151 {0x0000a42c, 0x1ce739ce},
152 {0x0000a430, 0x1ce739ce},
153 {0x0000a434, 0x00000000},
154 {0x0000a438, 0x00001801},
155 {0x0000a43c, 0x00100000},
156 {0x0000a440, 0x00000000},
157 {0x0000a444, 0x00000000},
158 {0x0000a448, 0x05000080},
159 {0x0000a44c, 0x00000001},
160 {0x0000a450, 0x00010000},
161 {0x0000a458, 0x00000000},
162 {0x0000a640, 0x00000000},
163 {0x0000a644, 0x3fad9d74},
164 {0x0000a648, 0x0048060a},
165 {0x0000a64c, 0x00003c37},
166 {0x0000a670, 0x03020100},
167 {0x0000a674, 0x09080504},
168 {0x0000a678, 0x0d0c0b0a},
169 {0x0000a67c, 0x13121110},
170 {0x0000a680, 0x31301514},
171 {0x0000a684, 0x35343332},
172 {0x0000a688, 0x00000036},
173 {0x0000a690, 0x00000838},
174 {0x0000a7c0, 0x00000000},
175 {0x0000a7c4, 0xfffffffc},
176 {0x0000a7c8, 0x00000000},
177 {0x0000a7cc, 0x00000000},
178 {0x0000a7d0, 0x00000000},
179 {0x0000a7d4, 0x00000004},
180 {0x0000a7dc, 0x00000000},
181 {0x0000a8d0, 0x004b6a8e},
182 {0x0000a8d4, 0x00000820},
183 {0x0000a8dc, 0x00000000},
184 {0x0000a8f0, 0x00000000},
185 {0x0000a8f4, 0x00000000},
186 {0x0000b2d0, 0x00000080},
187 {0x0000b2d4, 0x00000000},
188 {0x0000b2ec, 0x00000000},
189 {0x0000b2f0, 0x00000000},
190 {0x0000b2f4, 0x00000000},
191 {0x0000b2f8, 0x00000000},
192 {0x0000b408, 0x0e79e5c0},
193 {0x0000b40c, 0x00820820},
194 {0x0000b420, 0x00000000},
195 {0x0000b8d0, 0x004b6a8e},
196 {0x0000b8d4, 0x00000820},
197 {0x0000b8dc, 0x00000000},
198 {0x0000b8f0, 0x00000000},
199 {0x0000b8f4, 0x00000000},
200 {0x0000c2d0, 0x00000080},
201 {0x0000c2d4, 0x00000000},
202 {0x0000c2ec, 0x00000000},
203 {0x0000c2f0, 0x00000000},
204 {0x0000c2f4, 0x00000000},
205 {0x0000c2f8, 0x00000000},
206 {0x0000c408, 0x0e79e5c0},
207 {0x0000c40c, 0x00820820},
208 {0x0000c420, 0x00000000},
209};
210
211static const u32 ar9580_1p0_mac_postamble[][5] = {
212 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
213 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
214 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
215 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
216 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
217 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
218 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
219 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
220 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
221};
222
223static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
224 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
225 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
226 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
227 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
228 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
229 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
230 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
231 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
232 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
233 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
234 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
235 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
236 {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
237 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
238 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
239 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
240 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
241 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
242 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
243 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
244 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
245 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
246 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
247 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
248 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
249 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
250 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
251 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
252 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
253 {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
254 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
255 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
256 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
257 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
258 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
259 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
260 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
261 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
262 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
263 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
264 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
265 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
266 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
267 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
268 {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
269 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
270 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
271 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
272 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
273 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
274 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
275 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
276 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
277 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
278 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
279 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
280 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
281 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
282 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
283 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
284 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
285 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
286 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
287 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
288 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
289 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
290 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
291 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
292 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
293 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
294 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
295 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
296 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
297 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
298 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
299 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
300 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
301 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
302 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
303 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
304 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
305 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
306 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
307 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
308 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
309 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
310 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
311 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
312 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
313 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
314 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
315 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
316 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
317 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
318 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
319 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
320 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
321 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
322 {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
323 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
324 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
325 {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
326 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
327};
328
329static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = {
330 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
331 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
332 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
333 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
334 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
335 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
336 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
337 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
338 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
339 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
340 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
341 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
342 {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
343 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
344 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
345 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
346 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
347 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
348 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
349 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
350 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
351 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
352 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
353 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
354 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
355 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
356 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
357 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
358 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
359 {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
360 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
361 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
362 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
363 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
364 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
365 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
366 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
367 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
368 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
369 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
370 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
371 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
372 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
373 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
374 {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
375 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
376 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
377 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
378 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
379 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
380 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
381 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
382 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
383 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
384 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
385 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
386 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
387 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
388 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
389 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
390 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
391 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
392 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
393 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
394 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
395 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
396 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
397 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
398 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
399 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
400 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
401 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
402 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
403 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
404 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
405 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
406 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
407 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
408 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
409 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
410 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
411 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
412 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
413 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
414 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
415 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
416 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
417 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
418 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
419 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
420 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
421 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
422 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
423 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
424 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
425 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
426 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
427 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
428 {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
429 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
430 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
431 {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
432 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
433};
434
435static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
436 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
437 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
438 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
439 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
440 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
441 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
442 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
443 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
444 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
445 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
446 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
447 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
448 {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
449 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
450 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
451 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
452 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
453 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
454 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
455 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
456 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
457 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
458 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
459 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
460 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
461 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
462 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
463 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
464 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
465 {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
466 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
467 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
468 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
469 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
470 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
471 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
472 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
473 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
474 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
475 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
476 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
477 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
478 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
479 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
480 {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
481 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
482 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
483 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
484 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
485 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
486 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
487 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
488 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
489 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
490 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
491 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
492 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
493 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
494 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
495 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
496 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
497 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
498 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
499 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
500 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
501 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
502 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
503 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
504 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
505 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
506 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
507 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
508 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
509 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
510 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
511 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
512 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
513 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
514 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
515 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
516 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
517 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
518 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
519 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
520 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
521 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
522 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
523 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
524 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
525 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
526 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
527 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
528 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
529 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
530 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
531 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
532 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
533 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
534 {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
535 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
536 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
537 {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
538 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
539};
540
541static const u32 ar9580_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
542 /* Addr allmodes */
543 {0x0000a398, 0x00000000},
544 {0x0000a39c, 0x6f7f0301},
545 {0x0000a3a0, 0xca9228ee},
546};
547
548static const u32 ar9580_1p0_mac_core[][2] = {
549 /* Addr allmodes */
550 {0x00000008, 0x00000000},
551 {0x00000030, 0x00020085},
552 {0x00000034, 0x00000005},
553 {0x00000040, 0x00000000},
554 {0x00000044, 0x00000000},
555 {0x00000048, 0x00000008},
556 {0x0000004c, 0x00000010},
557 {0x00000050, 0x00000000},
558 {0x00001040, 0x002ffc0f},
559 {0x00001044, 0x002ffc0f},
560 {0x00001048, 0x002ffc0f},
561 {0x0000104c, 0x002ffc0f},
562 {0x00001050, 0x002ffc0f},
563 {0x00001054, 0x002ffc0f},
564 {0x00001058, 0x002ffc0f},
565 {0x0000105c, 0x002ffc0f},
566 {0x00001060, 0x002ffc0f},
567 {0x00001064, 0x002ffc0f},
568 {0x000010f0, 0x00000100},
569 {0x00001270, 0x00000000},
570 {0x000012b0, 0x00000000},
571 {0x000012f0, 0x00000000},
572 {0x0000143c, 0x00000000},
573 {0x0000147c, 0x00000000},
574 {0x00008000, 0x00000000},
575 {0x00008004, 0x00000000},
576 {0x00008008, 0x00000000},
577 {0x0000800c, 0x00000000},
578 {0x00008018, 0x00000000},
579 {0x00008020, 0x00000000},
580 {0x00008038, 0x00000000},
581 {0x0000803c, 0x00000000},
582 {0x00008040, 0x00000000},
583 {0x00008044, 0x00000000},
584 {0x00008048, 0x00000000},
585 {0x0000804c, 0xffffffff},
586 {0x00008054, 0x00000000},
587 {0x00008058, 0x00000000},
588 {0x0000805c, 0x000fc78f},
589 {0x00008060, 0x0000000f},
590 {0x00008064, 0x00000000},
591 {0x00008070, 0x00000310},
592 {0x00008074, 0x00000020},
593 {0x00008078, 0x00000000},
594 {0x0000809c, 0x0000000f},
595 {0x000080a0, 0x00000000},
596 {0x000080a4, 0x02ff0000},
597 {0x000080a8, 0x0e070605},
598 {0x000080ac, 0x0000000d},
599 {0x000080b0, 0x00000000},
600 {0x000080b4, 0x00000000},
601 {0x000080b8, 0x00000000},
602 {0x000080bc, 0x00000000},
603 {0x000080c0, 0x2a800000},
604 {0x000080c4, 0x06900168},
605 {0x000080c8, 0x13881c22},
606 {0x000080cc, 0x01f40000},
607 {0x000080d0, 0x00252500},
608 {0x000080d4, 0x00a00000},
609 {0x000080d8, 0x00400000},
610 {0x000080dc, 0x00000000},
611 {0x000080e0, 0xffffffff},
612 {0x000080e4, 0x0000ffff},
613 {0x000080e8, 0x3f3f3f3f},
614 {0x000080ec, 0x00000000},
615 {0x000080f0, 0x00000000},
616 {0x000080f4, 0x00000000},
617 {0x000080fc, 0x00020000},
618 {0x00008100, 0x00000000},
619 {0x00008108, 0x00000052},
620 {0x0000810c, 0x00000000},
621 {0x00008110, 0x00000000},
622 {0x00008114, 0x000007ff},
623 {0x00008118, 0x000000aa},
624 {0x0000811c, 0x00003210},
625 {0x00008124, 0x00000000},
626 {0x00008128, 0x00000000},
627 {0x0000812c, 0x00000000},
628 {0x00008130, 0x00000000},
629 {0x00008134, 0x00000000},
630 {0x00008138, 0x00000000},
631 {0x0000813c, 0x0000ffff},
632 {0x00008144, 0xffffffff},
633 {0x00008168, 0x00000000},
634 {0x0000816c, 0x00000000},
635 {0x000081c0, 0x00000000},
636 {0x000081c4, 0x33332210},
637 {0x000081ec, 0x00000000},
638 {0x000081f0, 0x00000000},
639 {0x000081f4, 0x00000000},
640 {0x000081f8, 0x00000000},
641 {0x000081fc, 0x00000000},
642 {0x00008240, 0x00100000},
643 {0x00008244, 0x0010f400},
644 {0x00008248, 0x00000800},
645 {0x0000824c, 0x0001e800},
646 {0x00008250, 0x00000000},
647 {0x00008254, 0x00000000},
648 {0x00008258, 0x00000000},
649 {0x0000825c, 0x40000000},
650 {0x00008260, 0x00080922},
651 {0x00008264, 0x9bc00010},
652 {0x00008268, 0xffffffff},
653 {0x0000826c, 0x0000ffff},
654 {0x00008270, 0x00000000},
655 {0x00008274, 0x40000000},
656 {0x00008278, 0x003e4180},
657 {0x0000827c, 0x00000004},
658 {0x00008284, 0x0000002c},
659 {0x00008288, 0x0000002c},
660 {0x0000828c, 0x000000ff},
661 {0x00008294, 0x00000000},
662 {0x00008298, 0x00000000},
663 {0x0000829c, 0x00000000},
664 {0x00008300, 0x00000140},
665 {0x00008314, 0x00000000},
666 {0x0000831c, 0x0000010d},
667 {0x00008328, 0x00000000},
668 {0x0000832c, 0x00000007},
669 {0x00008330, 0x00000302},
670 {0x00008334, 0x00000700},
671 {0x00008338, 0x00ff0000},
672 {0x0000833c, 0x02400000},
673 {0x00008340, 0x000107ff},
674 {0x00008344, 0xaa48105b},
675 {0x00008348, 0x008f0000},
676 {0x0000835c, 0x00000000},
677 {0x00008360, 0xffffffff},
678 {0x00008364, 0xffffffff},
679 {0x00008368, 0x00000000},
680 {0x00008370, 0x00000000},
681 {0x00008374, 0x000000ff},
682 {0x00008378, 0x00000000},
683 {0x0000837c, 0x00000000},
684 {0x00008380, 0xffffffff},
685 {0x00008384, 0xffffffff},
686 {0x00008390, 0xffffffff},
687 {0x00008394, 0xffffffff},
688 {0x00008398, 0x00000000},
689 {0x0000839c, 0x00000000},
690 {0x000083a0, 0x00000000},
691 {0x000083a4, 0x0000fa14},
692 {0x000083a8, 0x000f0c00},
693 {0x000083ac, 0x33332210},
694 {0x000083b0, 0x33332210},
695 {0x000083b4, 0x33332210},
696 {0x000083b8, 0x33332210},
697 {0x000083bc, 0x00000000},
698 {0x000083c0, 0x00000000},
699 {0x000083c4, 0x00000000},
700 {0x000083c8, 0x00000000},
701 {0x000083cc, 0x00000200},
702 {0x000083d0, 0x000301ff},
703};
704
705static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = {
706 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
707 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
708 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
709 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
710 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
711 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
712 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
713 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
714 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
715 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
716 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
717 {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
718 {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
719 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
720 {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
721 {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
722 {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
723 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
724 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
725 {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
726 {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
727 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
728 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
729 {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
730 {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
731 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83},
732 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84},
733 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3},
734 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5},
735 {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9},
736 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb},
737 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
738 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
739 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
740 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
741 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
742 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
743 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
744 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
745 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
746 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
747 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
748 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
749 {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
750 {0x0000a598, 0x21802220, 0x21802220, 0x15800402, 0x15800402},
751 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
752 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
753 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
754 {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
755 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
756 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
757 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
758 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
759 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
760 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
761 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
762 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
763 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x42801a83, 0x42801a83},
764 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x44801c84, 0x44801c84},
765 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x48801ce3, 0x48801ce3},
766 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x4c801ce5, 0x4c801ce5},
767 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x50801ce9, 0x50801ce9},
768 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x54801ceb, 0x54801ceb},
769 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x56801eec, 0x56801eec},
770 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x56801eec, 0x56801eec},
771 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x56801eec, 0x56801eec},
772 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x56801eec, 0x56801eec},
773 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x56801eec, 0x56801eec},
774 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x56801eec, 0x56801eec},
775 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x56801eec, 0x56801eec},
776 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
777 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
778 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
779 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
780 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
781 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
782 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
783 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
784 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
785 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
786 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
787 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
788 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
789 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
790 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
791 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
792 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
793 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
794 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
795 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
796 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
797 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
798 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
799 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
800 {0x00016044, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
801 {0x00016048, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
802 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
803 {0x00016444, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
804 {0x00016448, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
805 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
806 {0x00016844, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
807 {0x00016848, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
808 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
809};
810
811static const u32 ar9580_1p0_wo_xlna_rx_gain_table[][2] = {
812 /* Addr allmodes */
813 {0x0000a000, 0x00010000},
814 {0x0000a004, 0x00030002},
815 {0x0000a008, 0x00050004},
816 {0x0000a00c, 0x00810080},
817 {0x0000a010, 0x00830082},
818 {0x0000a014, 0x01810180},
819 {0x0000a018, 0x01830182},
820 {0x0000a01c, 0x01850184},
821 {0x0000a020, 0x01890188},
822 {0x0000a024, 0x018b018a},
823 {0x0000a028, 0x018d018c},
824 {0x0000a02c, 0x03820190},
825 {0x0000a030, 0x03840383},
826 {0x0000a034, 0x03880385},
827 {0x0000a038, 0x038a0389},
828 {0x0000a03c, 0x038c038b},
829 {0x0000a040, 0x0390038d},
830 {0x0000a044, 0x03920391},
831 {0x0000a048, 0x03940393},
832 {0x0000a04c, 0x03960395},
833 {0x0000a050, 0x00000000},
834 {0x0000a054, 0x00000000},
835 {0x0000a058, 0x00000000},
836 {0x0000a05c, 0x00000000},
837 {0x0000a060, 0x00000000},
838 {0x0000a064, 0x00000000},
839 {0x0000a068, 0x00000000},
840 {0x0000a06c, 0x00000000},
841 {0x0000a070, 0x00000000},
842 {0x0000a074, 0x00000000},
843 {0x0000a078, 0x00000000},
844 {0x0000a07c, 0x00000000},
845 {0x0000a080, 0x29292929},
846 {0x0000a084, 0x29292929},
847 {0x0000a088, 0x29292929},
848 {0x0000a08c, 0x29292929},
849 {0x0000a090, 0x22292929},
850 {0x0000a094, 0x1d1d2222},
851 {0x0000a098, 0x0c111117},
852 {0x0000a09c, 0x00030303},
853 {0x0000a0a0, 0x00000000},
854 {0x0000a0a4, 0x00000000},
855 {0x0000a0a8, 0x00000000},
856 {0x0000a0ac, 0x00000000},
857 {0x0000a0b0, 0x00000000},
858 {0x0000a0b4, 0x00000000},
859 {0x0000a0b8, 0x00000000},
860 {0x0000a0bc, 0x00000000},
861 {0x0000a0c0, 0x001f0000},
862 {0x0000a0c4, 0x01000101},
863 {0x0000a0c8, 0x011e011f},
864 {0x0000a0cc, 0x011c011d},
865 {0x0000a0d0, 0x02030204},
866 {0x0000a0d4, 0x02010202},
867 {0x0000a0d8, 0x021f0200},
868 {0x0000a0dc, 0x0302021e},
869 {0x0000a0e0, 0x03000301},
870 {0x0000a0e4, 0x031e031f},
871 {0x0000a0e8, 0x0402031d},
872 {0x0000a0ec, 0x04000401},
873 {0x0000a0f0, 0x041e041f},
874 {0x0000a0f4, 0x0502041d},
875 {0x0000a0f8, 0x05000501},
876 {0x0000a0fc, 0x051e051f},
877 {0x0000a100, 0x06010602},
878 {0x0000a104, 0x061f0600},
879 {0x0000a108, 0x061d061e},
880 {0x0000a10c, 0x07020703},
881 {0x0000a110, 0x07000701},
882 {0x0000a114, 0x00000000},
883 {0x0000a118, 0x00000000},
884 {0x0000a11c, 0x00000000},
885 {0x0000a120, 0x00000000},
886 {0x0000a124, 0x00000000},
887 {0x0000a128, 0x00000000},
888 {0x0000a12c, 0x00000000},
889 {0x0000a130, 0x00000000},
890 {0x0000a134, 0x00000000},
891 {0x0000a138, 0x00000000},
892 {0x0000a13c, 0x00000000},
893 {0x0000a140, 0x001f0000},
894 {0x0000a144, 0x01000101},
895 {0x0000a148, 0x011e011f},
896 {0x0000a14c, 0x011c011d},
897 {0x0000a150, 0x02030204},
898 {0x0000a154, 0x02010202},
899 {0x0000a158, 0x021f0200},
900 {0x0000a15c, 0x0302021e},
901 {0x0000a160, 0x03000301},
902 {0x0000a164, 0x031e031f},
903 {0x0000a168, 0x0402031d},
904 {0x0000a16c, 0x04000401},
905 {0x0000a170, 0x041e041f},
906 {0x0000a174, 0x0502041d},
907 {0x0000a178, 0x05000501},
908 {0x0000a17c, 0x051e051f},
909 {0x0000a180, 0x06010602},
910 {0x0000a184, 0x061f0600},
911 {0x0000a188, 0x061d061e},
912 {0x0000a18c, 0x07020703},
913 {0x0000a190, 0x07000701},
914 {0x0000a194, 0x00000000},
915 {0x0000a198, 0x00000000},
916 {0x0000a19c, 0x00000000},
917 {0x0000a1a0, 0x00000000},
918 {0x0000a1a4, 0x00000000},
919 {0x0000a1a8, 0x00000000},
920 {0x0000a1ac, 0x00000000},
921 {0x0000a1b0, 0x00000000},
922 {0x0000a1b4, 0x00000000},
923 {0x0000a1b8, 0x00000000},
924 {0x0000a1bc, 0x00000000},
925 {0x0000a1c0, 0x00000000},
926 {0x0000a1c4, 0x00000000},
927 {0x0000a1c8, 0x00000000},
928 {0x0000a1cc, 0x00000000},
929 {0x0000a1d0, 0x00000000},
930 {0x0000a1d4, 0x00000000},
931 {0x0000a1d8, 0x00000000},
932 {0x0000a1dc, 0x00000000},
933 {0x0000a1e0, 0x00000000},
934 {0x0000a1e4, 0x00000000},
935 {0x0000a1e8, 0x00000000},
936 {0x0000a1ec, 0x00000000},
937 {0x0000a1f0, 0x00000396},
938 {0x0000a1f4, 0x00000396},
939 {0x0000a1f8, 0x00000396},
940 {0x0000a1fc, 0x00000196},
941 {0x0000b000, 0x00010000},
942 {0x0000b004, 0x00030002},
943 {0x0000b008, 0x00050004},
944 {0x0000b00c, 0x00810080},
945 {0x0000b010, 0x00830082},
946 {0x0000b014, 0x01810180},
947 {0x0000b018, 0x01830182},
948 {0x0000b01c, 0x01850184},
949 {0x0000b020, 0x02810280},
950 {0x0000b024, 0x02830282},
951 {0x0000b028, 0x02850284},
952 {0x0000b02c, 0x02890288},
953 {0x0000b030, 0x028b028a},
954 {0x0000b034, 0x0388028c},
955 {0x0000b038, 0x038a0389},
956 {0x0000b03c, 0x038c038b},
957 {0x0000b040, 0x0390038d},
958 {0x0000b044, 0x03920391},
959 {0x0000b048, 0x03940393},
960 {0x0000b04c, 0x03960395},
961 {0x0000b050, 0x00000000},
962 {0x0000b054, 0x00000000},
963 {0x0000b058, 0x00000000},
964 {0x0000b05c, 0x00000000},
965 {0x0000b060, 0x00000000},
966 {0x0000b064, 0x00000000},
967 {0x0000b068, 0x00000000},
968 {0x0000b06c, 0x00000000},
969 {0x0000b070, 0x00000000},
970 {0x0000b074, 0x00000000},
971 {0x0000b078, 0x00000000},
972 {0x0000b07c, 0x00000000},
973 {0x0000b080, 0x32323232},
974 {0x0000b084, 0x2f2f3232},
975 {0x0000b088, 0x23282a2d},
976 {0x0000b08c, 0x1c1e2123},
977 {0x0000b090, 0x14171919},
978 {0x0000b094, 0x0e0e1214},
979 {0x0000b098, 0x03050707},
980 {0x0000b09c, 0x00030303},
981 {0x0000b0a0, 0x00000000},
982 {0x0000b0a4, 0x00000000},
983 {0x0000b0a8, 0x00000000},
984 {0x0000b0ac, 0x00000000},
985 {0x0000b0b0, 0x00000000},
986 {0x0000b0b4, 0x00000000},
987 {0x0000b0b8, 0x00000000},
988 {0x0000b0bc, 0x00000000},
989 {0x0000b0c0, 0x003f0020},
990 {0x0000b0c4, 0x00400041},
991 {0x0000b0c8, 0x0140005f},
992 {0x0000b0cc, 0x0160015f},
993 {0x0000b0d0, 0x017e017f},
994 {0x0000b0d4, 0x02410242},
995 {0x0000b0d8, 0x025f0240},
996 {0x0000b0dc, 0x027f0260},
997 {0x0000b0e0, 0x0341027e},
998 {0x0000b0e4, 0x035f0340},
999 {0x0000b0e8, 0x037f0360},
1000 {0x0000b0ec, 0x04400441},
1001 {0x0000b0f0, 0x0460045f},
1002 {0x0000b0f4, 0x0541047f},
1003 {0x0000b0f8, 0x055f0540},
1004 {0x0000b0fc, 0x057f0560},
1005 {0x0000b100, 0x06400641},
1006 {0x0000b104, 0x0660065f},
1007 {0x0000b108, 0x067e067f},
1008 {0x0000b10c, 0x07410742},
1009 {0x0000b110, 0x075f0740},
1010 {0x0000b114, 0x077f0760},
1011 {0x0000b118, 0x07800781},
1012 {0x0000b11c, 0x07a0079f},
1013 {0x0000b120, 0x07c107bf},
1014 {0x0000b124, 0x000007c0},
1015 {0x0000b128, 0x00000000},
1016 {0x0000b12c, 0x00000000},
1017 {0x0000b130, 0x00000000},
1018 {0x0000b134, 0x00000000},
1019 {0x0000b138, 0x00000000},
1020 {0x0000b13c, 0x00000000},
1021 {0x0000b140, 0x003f0020},
1022 {0x0000b144, 0x00400041},
1023 {0x0000b148, 0x0140005f},
1024 {0x0000b14c, 0x0160015f},
1025 {0x0000b150, 0x017e017f},
1026 {0x0000b154, 0x02410242},
1027 {0x0000b158, 0x025f0240},
1028 {0x0000b15c, 0x027f0260},
1029 {0x0000b160, 0x0341027e},
1030 {0x0000b164, 0x035f0340},
1031 {0x0000b168, 0x037f0360},
1032 {0x0000b16c, 0x04400441},
1033 {0x0000b170, 0x0460045f},
1034 {0x0000b174, 0x0541047f},
1035 {0x0000b178, 0x055f0540},
1036 {0x0000b17c, 0x057f0560},
1037 {0x0000b180, 0x06400641},
1038 {0x0000b184, 0x0660065f},
1039 {0x0000b188, 0x067e067f},
1040 {0x0000b18c, 0x07410742},
1041 {0x0000b190, 0x075f0740},
1042 {0x0000b194, 0x077f0760},
1043 {0x0000b198, 0x07800781},
1044 {0x0000b19c, 0x07a0079f},
1045 {0x0000b1a0, 0x07c107bf},
1046 {0x0000b1a4, 0x000007c0},
1047 {0x0000b1a8, 0x00000000},
1048 {0x0000b1ac, 0x00000000},
1049 {0x0000b1b0, 0x00000000},
1050 {0x0000b1b4, 0x00000000},
1051 {0x0000b1b8, 0x00000000},
1052 {0x0000b1bc, 0x00000000},
1053 {0x0000b1c0, 0x00000000},
1054 {0x0000b1c4, 0x00000000},
1055 {0x0000b1c8, 0x00000000},
1056 {0x0000b1cc, 0x00000000},
1057 {0x0000b1d0, 0x00000000},
1058 {0x0000b1d4, 0x00000000},
1059 {0x0000b1d8, 0x00000000},
1060 {0x0000b1dc, 0x00000000},
1061 {0x0000b1e0, 0x00000000},
1062 {0x0000b1e4, 0x00000000},
1063 {0x0000b1e8, 0x00000000},
1064 {0x0000b1ec, 0x00000000},
1065 {0x0000b1f0, 0x00000396},
1066 {0x0000b1f4, 0x00000396},
1067 {0x0000b1f8, 0x00000396},
1068 {0x0000b1fc, 0x00000196},
1069};
1070
1071static const u32 ar9580_1p0_soc_postamble[][5] = {
1072 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1073 {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
1074};
1075
1076static const u32 ar9580_1p0_high_ob_db_tx_gain_table[][5] = {
1077 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1078 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1079 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1080 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1081 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1082 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
1083 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1084 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
1085 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
1086 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
1087 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
1088 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
1089 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
1090 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
1091 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
1092 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
1093 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
1094 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
1095 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
1096 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
1097 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
1098 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
1099 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
1100 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
1101 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
1102 {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
1103 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
1104 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
1105 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
1106 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
1107 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
1108 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
1109 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
1110 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
1111 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
1112 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
1113 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
1114 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
1115 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
1116 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
1117 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
1118 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
1119 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
1120 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
1121 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
1122 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
1123 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
1124 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
1125 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
1126 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
1127 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
1128 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
1129 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
1130 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
1131 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
1132 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
1133 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
1134 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
1135 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
1136 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
1137 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
1138 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
1139 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
1140 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
1141 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
1142 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
1143 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
1144 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
1145 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
1146 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
1147 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1148 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1149 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1150 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1151 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1152 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1153 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1154 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1155 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1156 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1157 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1158 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1159 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1160 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1161 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1162 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1163 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1164 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1165 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1166 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1167 {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1168 {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1169 {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1170 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1171 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
1172 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
1173 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1174 {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
1175 {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
1176 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1177 {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
1178 {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
1179 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1180};
1181
1182static const u32 ar9580_1p0_soc_preamble[][2] = {
1183 /* Addr allmodes */
1184 {0x000040a4, 0x00a0c1c9},
1185 {0x00007008, 0x00000000},
1186 {0x00007020, 0x00000000},
1187 {0x00007034, 0x00000002},
1188 {0x00007038, 0x000004c2},
1189 {0x00007048, 0x00000008},
1190};
1191
1192static const u32 ar9580_1p0_rx_gain_table[][2] = {
1193 /* Addr allmodes */
1194 {0x0000a000, 0x00010000},
1195 {0x0000a004, 0x00030002},
1196 {0x0000a008, 0x00050004},
1197 {0x0000a00c, 0x00810080},
1198 {0x0000a010, 0x00830082},
1199 {0x0000a014, 0x01810180},
1200 {0x0000a018, 0x01830182},
1201 {0x0000a01c, 0x01850184},
1202 {0x0000a020, 0x01890188},
1203 {0x0000a024, 0x018b018a},
1204 {0x0000a028, 0x018d018c},
1205 {0x0000a02c, 0x01910190},
1206 {0x0000a030, 0x01930192},
1207 {0x0000a034, 0x01950194},
1208 {0x0000a038, 0x038a0196},
1209 {0x0000a03c, 0x038c038b},
1210 {0x0000a040, 0x0390038d},
1211 {0x0000a044, 0x03920391},
1212 {0x0000a048, 0x03940393},
1213 {0x0000a04c, 0x03960395},
1214 {0x0000a050, 0x00000000},
1215 {0x0000a054, 0x00000000},
1216 {0x0000a058, 0x00000000},
1217 {0x0000a05c, 0x00000000},
1218 {0x0000a060, 0x00000000},
1219 {0x0000a064, 0x00000000},
1220 {0x0000a068, 0x00000000},
1221 {0x0000a06c, 0x00000000},
1222 {0x0000a070, 0x00000000},
1223 {0x0000a074, 0x00000000},
1224 {0x0000a078, 0x00000000},
1225 {0x0000a07c, 0x00000000},
1226 {0x0000a080, 0x22222229},
1227 {0x0000a084, 0x1d1d1d1d},
1228 {0x0000a088, 0x1d1d1d1d},
1229 {0x0000a08c, 0x1d1d1d1d},
1230 {0x0000a090, 0x171d1d1d},
1231 {0x0000a094, 0x11111717},
1232 {0x0000a098, 0x00030311},
1233 {0x0000a09c, 0x00000000},
1234 {0x0000a0a0, 0x00000000},
1235 {0x0000a0a4, 0x00000000},
1236 {0x0000a0a8, 0x00000000},
1237 {0x0000a0ac, 0x00000000},
1238 {0x0000a0b0, 0x00000000},
1239 {0x0000a0b4, 0x00000000},
1240 {0x0000a0b8, 0x00000000},
1241 {0x0000a0bc, 0x00000000},
1242 {0x0000a0c0, 0x001f0000},
1243 {0x0000a0c4, 0x01000101},
1244 {0x0000a0c8, 0x011e011f},
1245 {0x0000a0cc, 0x011c011d},
1246 {0x0000a0d0, 0x02030204},
1247 {0x0000a0d4, 0x02010202},
1248 {0x0000a0d8, 0x021f0200},
1249 {0x0000a0dc, 0x0302021e},
1250 {0x0000a0e0, 0x03000301},
1251 {0x0000a0e4, 0x031e031f},
1252 {0x0000a0e8, 0x0402031d},
1253 {0x0000a0ec, 0x04000401},
1254 {0x0000a0f0, 0x041e041f},
1255 {0x0000a0f4, 0x0502041d},
1256 {0x0000a0f8, 0x05000501},
1257 {0x0000a0fc, 0x051e051f},
1258 {0x0000a100, 0x06010602},
1259 {0x0000a104, 0x061f0600},
1260 {0x0000a108, 0x061d061e},
1261 {0x0000a10c, 0x07020703},
1262 {0x0000a110, 0x07000701},
1263 {0x0000a114, 0x00000000},
1264 {0x0000a118, 0x00000000},
1265 {0x0000a11c, 0x00000000},
1266 {0x0000a120, 0x00000000},
1267 {0x0000a124, 0x00000000},
1268 {0x0000a128, 0x00000000},
1269 {0x0000a12c, 0x00000000},
1270 {0x0000a130, 0x00000000},
1271 {0x0000a134, 0x00000000},
1272 {0x0000a138, 0x00000000},
1273 {0x0000a13c, 0x00000000},
1274 {0x0000a140, 0x001f0000},
1275 {0x0000a144, 0x01000101},
1276 {0x0000a148, 0x011e011f},
1277 {0x0000a14c, 0x011c011d},
1278 {0x0000a150, 0x02030204},
1279 {0x0000a154, 0x02010202},
1280 {0x0000a158, 0x021f0200},
1281 {0x0000a15c, 0x0302021e},
1282 {0x0000a160, 0x03000301},
1283 {0x0000a164, 0x031e031f},
1284 {0x0000a168, 0x0402031d},
1285 {0x0000a16c, 0x04000401},
1286 {0x0000a170, 0x041e041f},
1287 {0x0000a174, 0x0502041d},
1288 {0x0000a178, 0x05000501},
1289 {0x0000a17c, 0x051e051f},
1290 {0x0000a180, 0x06010602},
1291 {0x0000a184, 0x061f0600},
1292 {0x0000a188, 0x061d061e},
1293 {0x0000a18c, 0x07020703},
1294 {0x0000a190, 0x07000701},
1295 {0x0000a194, 0x00000000},
1296 {0x0000a198, 0x00000000},
1297 {0x0000a19c, 0x00000000},
1298 {0x0000a1a0, 0x00000000},
1299 {0x0000a1a4, 0x00000000},
1300 {0x0000a1a8, 0x00000000},
1301 {0x0000a1ac, 0x00000000},
1302 {0x0000a1b0, 0x00000000},
1303 {0x0000a1b4, 0x00000000},
1304 {0x0000a1b8, 0x00000000},
1305 {0x0000a1bc, 0x00000000},
1306 {0x0000a1c0, 0x00000000},
1307 {0x0000a1c4, 0x00000000},
1308 {0x0000a1c8, 0x00000000},
1309 {0x0000a1cc, 0x00000000},
1310 {0x0000a1d0, 0x00000000},
1311 {0x0000a1d4, 0x00000000},
1312 {0x0000a1d8, 0x00000000},
1313 {0x0000a1dc, 0x00000000},
1314 {0x0000a1e0, 0x00000000},
1315 {0x0000a1e4, 0x00000000},
1316 {0x0000a1e8, 0x00000000},
1317 {0x0000a1ec, 0x00000000},
1318 {0x0000a1f0, 0x00000396},
1319 {0x0000a1f4, 0x00000396},
1320 {0x0000a1f8, 0x00000396},
1321 {0x0000a1fc, 0x00000196},
1322 {0x0000b000, 0x00010000},
1323 {0x0000b004, 0x00030002},
1324 {0x0000b008, 0x00050004},
1325 {0x0000b00c, 0x00810080},
1326 {0x0000b010, 0x00830082},
1327 {0x0000b014, 0x01810180},
1328 {0x0000b018, 0x01830182},
1329 {0x0000b01c, 0x01850184},
1330 {0x0000b020, 0x02810280},
1331 {0x0000b024, 0x02830282},
1332 {0x0000b028, 0x02850284},
1333 {0x0000b02c, 0x02890288},
1334 {0x0000b030, 0x028b028a},
1335 {0x0000b034, 0x0388028c},
1336 {0x0000b038, 0x038a0389},
1337 {0x0000b03c, 0x038c038b},
1338 {0x0000b040, 0x0390038d},
1339 {0x0000b044, 0x03920391},
1340 {0x0000b048, 0x03940393},
1341 {0x0000b04c, 0x03960395},
1342 {0x0000b050, 0x00000000},
1343 {0x0000b054, 0x00000000},
1344 {0x0000b058, 0x00000000},
1345 {0x0000b05c, 0x00000000},
1346 {0x0000b060, 0x00000000},
1347 {0x0000b064, 0x00000000},
1348 {0x0000b068, 0x00000000},
1349 {0x0000b06c, 0x00000000},
1350 {0x0000b070, 0x00000000},
1351 {0x0000b074, 0x00000000},
1352 {0x0000b078, 0x00000000},
1353 {0x0000b07c, 0x00000000},
1354 {0x0000b080, 0x2a2d2f32},
1355 {0x0000b084, 0x21232328},
1356 {0x0000b088, 0x19191c1e},
1357 {0x0000b08c, 0x12141417},
1358 {0x0000b090, 0x07070e0e},
1359 {0x0000b094, 0x03030305},
1360 {0x0000b098, 0x00000003},
1361 {0x0000b09c, 0x00000000},
1362 {0x0000b0a0, 0x00000000},
1363 {0x0000b0a4, 0x00000000},
1364 {0x0000b0a8, 0x00000000},
1365 {0x0000b0ac, 0x00000000},
1366 {0x0000b0b0, 0x00000000},
1367 {0x0000b0b4, 0x00000000},
1368 {0x0000b0b8, 0x00000000},
1369 {0x0000b0bc, 0x00000000},
1370 {0x0000b0c0, 0x003f0020},
1371 {0x0000b0c4, 0x00400041},
1372 {0x0000b0c8, 0x0140005f},
1373 {0x0000b0cc, 0x0160015f},
1374 {0x0000b0d0, 0x017e017f},
1375 {0x0000b0d4, 0x02410242},
1376 {0x0000b0d8, 0x025f0240},
1377 {0x0000b0dc, 0x027f0260},
1378 {0x0000b0e0, 0x0341027e},
1379 {0x0000b0e4, 0x035f0340},
1380 {0x0000b0e8, 0x037f0360},
1381 {0x0000b0ec, 0x04400441},
1382 {0x0000b0f0, 0x0460045f},
1383 {0x0000b0f4, 0x0541047f},
1384 {0x0000b0f8, 0x055f0540},
1385 {0x0000b0fc, 0x057f0560},
1386 {0x0000b100, 0x06400641},
1387 {0x0000b104, 0x0660065f},
1388 {0x0000b108, 0x067e067f},
1389 {0x0000b10c, 0x07410742},
1390 {0x0000b110, 0x075f0740},
1391 {0x0000b114, 0x077f0760},
1392 {0x0000b118, 0x07800781},
1393 {0x0000b11c, 0x07a0079f},
1394 {0x0000b120, 0x07c107bf},
1395 {0x0000b124, 0x000007c0},
1396 {0x0000b128, 0x00000000},
1397 {0x0000b12c, 0x00000000},
1398 {0x0000b130, 0x00000000},
1399 {0x0000b134, 0x00000000},
1400 {0x0000b138, 0x00000000},
1401 {0x0000b13c, 0x00000000},
1402 {0x0000b140, 0x003f0020},
1403 {0x0000b144, 0x00400041},
1404 {0x0000b148, 0x0140005f},
1405 {0x0000b14c, 0x0160015f},
1406 {0x0000b150, 0x017e017f},
1407 {0x0000b154, 0x02410242},
1408 {0x0000b158, 0x025f0240},
1409 {0x0000b15c, 0x027f0260},
1410 {0x0000b160, 0x0341027e},
1411 {0x0000b164, 0x035f0340},
1412 {0x0000b168, 0x037f0360},
1413 {0x0000b16c, 0x04400441},
1414 {0x0000b170, 0x0460045f},
1415 {0x0000b174, 0x0541047f},
1416 {0x0000b178, 0x055f0540},
1417 {0x0000b17c, 0x057f0560},
1418 {0x0000b180, 0x06400641},
1419 {0x0000b184, 0x0660065f},
1420 {0x0000b188, 0x067e067f},
1421 {0x0000b18c, 0x07410742},
1422 {0x0000b190, 0x075f0740},
1423 {0x0000b194, 0x077f0760},
1424 {0x0000b198, 0x07800781},
1425 {0x0000b19c, 0x07a0079f},
1426 {0x0000b1a0, 0x07c107bf},
1427 {0x0000b1a4, 0x000007c0},
1428 {0x0000b1a8, 0x00000000},
1429 {0x0000b1ac, 0x00000000},
1430 {0x0000b1b0, 0x00000000},
1431 {0x0000b1b4, 0x00000000},
1432 {0x0000b1b8, 0x00000000},
1433 {0x0000b1bc, 0x00000000},
1434 {0x0000b1c0, 0x00000000},
1435 {0x0000b1c4, 0x00000000},
1436 {0x0000b1c8, 0x00000000},
1437 {0x0000b1cc, 0x00000000},
1438 {0x0000b1d0, 0x00000000},
1439 {0x0000b1d4, 0x00000000},
1440 {0x0000b1d8, 0x00000000},
1441 {0x0000b1dc, 0x00000000},
1442 {0x0000b1e0, 0x00000000},
1443 {0x0000b1e4, 0x00000000},
1444 {0x0000b1e8, 0x00000000},
1445 {0x0000b1ec, 0x00000000},
1446 {0x0000b1f0, 0x00000396},
1447 {0x0000b1f4, 0x00000396},
1448 {0x0000b1f8, 0x00000396},
1449 {0x0000b1fc, 0x00000196},
1450};
1451
1452static const u32 ar9580_1p0_radio_core[][2] = {
1453 /* Addr allmodes */
1454 {0x00016000, 0x36db6db6},
1455 {0x00016004, 0x6db6db40},
1456 {0x00016008, 0x73f00000},
1457 {0x0001600c, 0x00000000},
1458 {0x00016040, 0x7f80fff8},
1459 {0x0001604c, 0x76d005b5},
1460 {0x00016050, 0x556cf031},
1461 {0x00016054, 0x13449440},
1462 {0x00016058, 0x0c51c92c},
1463 {0x0001605c, 0x3db7fffc},
1464 {0x00016060, 0xfffffffc},
1465 {0x00016064, 0x000f0278},
1466 {0x0001606c, 0x6db60000},
1467 {0x00016080, 0x00000000},
1468 {0x00016084, 0x0e48048c},
1469 {0x00016088, 0x54214514},
1470 {0x0001608c, 0x119f481e},
1471 {0x00016090, 0x24926490},
1472 {0x00016098, 0xd2888888},
1473 {0x000160a0, 0x0a108ffe},
1474 {0x000160a4, 0x812fc370},
1475 {0x000160a8, 0x423c8000},
1476 {0x000160b4, 0x92480080},
1477 {0x000160c0, 0x00adb6d0},
1478 {0x000160c4, 0x6db6db60},
1479 {0x000160c8, 0x6db6db6c},
1480 {0x000160cc, 0x01e6c000},
1481 {0x00016100, 0x3fffbe01},
1482 {0x00016104, 0xfff80000},
1483 {0x00016108, 0x00080010},
1484 {0x00016144, 0x02084080},
1485 {0x00016148, 0x00000000},
1486 {0x00016280, 0x058a0001},
1487 {0x00016284, 0x3d840208},
1488 {0x00016288, 0x05a20408},
1489 {0x0001628c, 0x00038c07},
1490 {0x00016290, 0x00000004},
1491 {0x00016294, 0x458aa14f},
1492 {0x00016380, 0x00000000},
1493 {0x00016384, 0x00000000},
1494 {0x00016388, 0x00800700},
1495 {0x0001638c, 0x00800700},
1496 {0x00016390, 0x00800700},
1497 {0x00016394, 0x00000000},
1498 {0x00016398, 0x00000000},
1499 {0x0001639c, 0x00000000},
1500 {0x000163a0, 0x00000001},
1501 {0x000163a4, 0x00000001},
1502 {0x000163a8, 0x00000000},
1503 {0x000163ac, 0x00000000},
1504 {0x000163b0, 0x00000000},
1505 {0x000163b4, 0x00000000},
1506 {0x000163b8, 0x00000000},
1507 {0x000163bc, 0x00000000},
1508 {0x000163c0, 0x000000a0},
1509 {0x000163c4, 0x000c0000},
1510 {0x000163c8, 0x14021402},
1511 {0x000163cc, 0x00001402},
1512 {0x000163d0, 0x00000000},
1513 {0x000163d4, 0x00000000},
1514 {0x00016400, 0x36db6db6},
1515 {0x00016404, 0x6db6db40},
1516 {0x00016408, 0x73f00000},
1517 {0x0001640c, 0x00000000},
1518 {0x00016440, 0x7f80fff8},
1519 {0x0001644c, 0x76d005b5},
1520 {0x00016450, 0x556cf031},
1521 {0x00016454, 0x13449440},
1522 {0x00016458, 0x0c51c92c},
1523 {0x0001645c, 0x3db7fffc},
1524 {0x00016460, 0xfffffffc},
1525 {0x00016464, 0x000f0278},
1526 {0x0001646c, 0x6db60000},
1527 {0x00016500, 0x3fffbe01},
1528 {0x00016504, 0xfff80000},
1529 {0x00016508, 0x00080010},
1530 {0x00016544, 0x02084080},
1531 {0x00016548, 0x00000000},
1532 {0x00016780, 0x00000000},
1533 {0x00016784, 0x00000000},
1534 {0x00016788, 0x00800700},
1535 {0x0001678c, 0x00800700},
1536 {0x00016790, 0x00800700},
1537 {0x00016794, 0x00000000},
1538 {0x00016798, 0x00000000},
1539 {0x0001679c, 0x00000000},
1540 {0x000167a0, 0x00000001},
1541 {0x000167a4, 0x00000001},
1542 {0x000167a8, 0x00000000},
1543 {0x000167ac, 0x00000000},
1544 {0x000167b0, 0x00000000},
1545 {0x000167b4, 0x00000000},
1546 {0x000167b8, 0x00000000},
1547 {0x000167bc, 0x00000000},
1548 {0x000167c0, 0x000000a0},
1549 {0x000167c4, 0x000c0000},
1550 {0x000167c8, 0x14021402},
1551 {0x000167cc, 0x00001402},
1552 {0x000167d0, 0x00000000},
1553 {0x000167d4, 0x00000000},
1554 {0x00016800, 0x36db6db6},
1555 {0x00016804, 0x6db6db40},
1556 {0x00016808, 0x73f00000},
1557 {0x0001680c, 0x00000000},
1558 {0x00016840, 0x7f80fff8},
1559 {0x0001684c, 0x76d005b5},
1560 {0x00016850, 0x556cf031},
1561 {0x00016854, 0x13449440},
1562 {0x00016858, 0x0c51c92c},
1563 {0x0001685c, 0x3db7fffc},
1564 {0x00016860, 0xfffffffc},
1565 {0x00016864, 0x000f0278},
1566 {0x0001686c, 0x6db60000},
1567 {0x00016900, 0x3fffbe01},
1568 {0x00016904, 0xfff80000},
1569 {0x00016908, 0x00080010},
1570 {0x00016944, 0x02084080},
1571 {0x00016948, 0x00000000},
1572 {0x00016b80, 0x00000000},
1573 {0x00016b84, 0x00000000},
1574 {0x00016b88, 0x00800700},
1575 {0x00016b8c, 0x00800700},
1576 {0x00016b90, 0x00800700},
1577 {0x00016b94, 0x00000000},
1578 {0x00016b98, 0x00000000},
1579 {0x00016b9c, 0x00000000},
1580 {0x00016ba0, 0x00000001},
1581 {0x00016ba4, 0x00000001},
1582 {0x00016ba8, 0x00000000},
1583 {0x00016bac, 0x00000000},
1584 {0x00016bb0, 0x00000000},
1585 {0x00016bb4, 0x00000000},
1586 {0x00016bb8, 0x00000000},
1587 {0x00016bbc, 0x00000000},
1588 {0x00016bc0, 0x000000a0},
1589 {0x00016bc4, 0x000c0000},
1590 {0x00016bc8, 0x14021402},
1591 {0x00016bcc, 0x00001402},
1592 {0x00016bd0, 0x00000000},
1593 {0x00016bd4, 0x00000000},
1594};
1595
1596static const u32 ar9580_1p0_baseband_postamble[][5] = {
1597 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1598 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
1599 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
1600 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
1601 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
1602 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
1603 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
1604 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
1605 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
1606 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
1607 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
1608 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
1609 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
1610 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1611 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
1612 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
1613 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
1614 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
1615 {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
1616 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
1617 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
1618 {0x0000a204, 0x000036c0, 0x000036c4, 0x000036c4, 0x000036c0},
1619 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
1620 {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f},
1621 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
1622 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
1623 {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018},
1624 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
1625 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
1626 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
1627 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
1628 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
1629 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
1630 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
1631 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
1632 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
1633 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
1634 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
1635 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
1636 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
1637 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1638 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
1639 {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
1640 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1641 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
1642 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
1643 {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
1644 {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
1645 {0x0000be04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
1646 {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1647 {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
1648 {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
1649 {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
1650};
1651
1652static const u32 ar9580_1p0_pcie_phy_clkreq_enable_L1[][2] = {
1653 /* Addr allmodes */
1654 {0x00004040, 0x0835365e},
1655 {0x00004040, 0x0008003b},
1656 {0x00004044, 0x00000000},
1657};
1658
1659static const u32 ar9580_1p0_pcie_phy_clkreq_disable_L1[][2] = {
1660 /* Addr allmodes */
1661 {0x00004040, 0x0831365e},
1662 {0x00004040, 0x0008003b},
1663 {0x00004044, 0x00000000},
1664};
1665
1666static const u32 ar9580_1p0_pcie_phy_pll_on_clkreq[][2] = {
1667 /* Addr allmodes */
1668 {0x00004040, 0x0831265e},
1669 {0x00004040, 0x0008003b},
1670 {0x00004044, 0x00000000},
1671};
1672
1673#endif /* INITVALS_9580_1P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index c03949eb37c8..3a893e19d6c3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -558,8 +558,7 @@ struct ath_ant_comb {
558#define SC_OP_BT_PRIORITY_DETECTED BIT(12) 558#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
559#define SC_OP_BT_SCAN BIT(13) 559#define SC_OP_BT_SCAN BIT(13)
560#define SC_OP_ANI_RUN BIT(14) 560#define SC_OP_ANI_RUN BIT(14)
561#define SC_OP_ENABLE_APM BIT(15) 561#define SC_OP_PRIM_STA_VIF BIT(15)
562#define SC_OP_PRIM_STA_VIF BIT(16)
563 562
564/* Powersave flags */ 563/* Powersave flags */
565#define PS_WAIT_FOR_BEACON BIT(0) 564#define PS_WAIT_FOR_BEACON BIT(0)
@@ -664,7 +663,6 @@ extern int led_blink;
664extern bool is_ath9k_unloaded; 663extern bool is_ath9k_unloaded;
665 664
666irqreturn_t ath_isr(int irq, void *dev); 665irqreturn_t ath_isr(int irq, void *dev);
667void ath9k_init_crypto(struct ath_softc *sc);
668int ath9k_init_device(u16 devid, struct ath_softc *sc, 666int ath9k_init_device(u16 devid, struct ath_softc *sc,
669 const struct ath_bus_ops *bus_ops); 667 const struct ath_bus_ops *bus_ops);
670void ath9k_deinit_device(struct ath_softc *sc); 668void ath9k_deinit_device(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index ac2da3cce788..ebaf304f464b 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -82,7 +82,6 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
82 int16_t *nfarray) 82 int16_t *nfarray)
83{ 83{
84 struct ath_common *common = ath9k_hw_common(ah); 84 struct ath_common *common = ath9k_hw_common(ah);
85 struct ieee80211_conf *conf = &common->hw->conf;
86 struct ath_nf_limits *limit; 85 struct ath_nf_limits *limit;
87 struct ath9k_nfcal_hist *h; 86 struct ath9k_nfcal_hist *h;
88 bool high_nf_mid = false; 87 bool high_nf_mid = false;
@@ -94,7 +93,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
94 93
95 for (i = 0; i < NUM_NF_READINGS; i++) { 94 for (i = 0; i < NUM_NF_READINGS; i++) {
96 if (!(chainmask & (1 << i)) || 95 if (!(chainmask & (1 << i)) ||
97 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) 96 ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(ah->curchan)))
98 continue; 97 continue;
99 98
100 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; 99 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index fa6bd2d189e5..dc705a224952 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -169,6 +169,32 @@ void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
169} 169}
170EXPORT_SYMBOL(ath9k_cmn_update_txpow); 170EXPORT_SYMBOL(ath9k_cmn_update_txpow);
171 171
172void ath9k_cmn_init_crypto(struct ath_hw *ah)
173{
174 struct ath_common *common = ath9k_hw_common(ah);
175 int i = 0;
176
177 /* Get the hardware key cache size. */
178 common->keymax = AR_KEYTABLE_SIZE;
179
180 /*
181 * Check whether the separate key cache entries
182 * are required to handle both tx+rx MIC keys.
183 * With split mic keys the number of stations is limited
184 * to 27 otherwise 59.
185 */
186 if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
187 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
188
189 /*
190 * Reset the key cache since some parts do not
191 * reset the contents on initial power up.
192 */
193 for (i = 0; i < common->keymax; i++)
194 ath_hw_keyreset(common, (u16) i);
195}
196EXPORT_SYMBOL(ath9k_cmn_init_crypto);
197
172static int __init ath9k_cmn_init(void) 198static int __init ath9k_cmn_init(void)
173{ 199{
174 return 0; 200 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 77ec288b5a70..ad14fecc76c6 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -62,3 +62,4 @@ void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
62 enum ath_stomp_type stomp_type); 62 enum ath_stomp_type stomp_type);
63void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, 63void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
64 u16 new_txpow, u16 *txpower); 64 u16 new_txpow, u16 *txpower);
65void ath9k_cmn_init_crypto(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9bec3b89fb68..da45f325be7d 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1163,6 +1163,59 @@ static const struct file_operations fops_regdump = {
1163 .llseek = default_llseek,/* read accesses f_pos */ 1163 .llseek = default_llseek,/* read accesses f_pos */
1164}; 1164};
1165 1165
1166static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf,
1167 size_t count, loff_t *ppos)
1168{
1169 struct ath_softc *sc = file->private_data;
1170 struct ath_hw *ah = sc->sc_ah;
1171 struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist;
1172 struct ath_common *common = ath9k_hw_common(ah);
1173 struct ieee80211_conf *conf = &common->hw->conf;
1174 u32 len = 0, size = 1500;
1175 u32 i, j;
1176 ssize_t retval = 0;
1177 char *buf;
1178 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
1179 u8 nread;
1180
1181 buf = kzalloc(size, GFP_KERNEL);
1182 if (!buf)
1183 return -ENOMEM;
1184
1185 len += snprintf(buf + len, size - len,
1186 "Channel Noise Floor : %d\n", ah->noise);
1187 len += snprintf(buf + len, size - len,
1188 "Chain | privNF | # Readings | NF Readings\n");
1189 for (i = 0; i < NUM_NF_READINGS; i++) {
1190 if (!(chainmask & (1 << i)) ||
1191 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
1192 continue;
1193
1194 nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount;
1195 len += snprintf(buf + len, size - len, " %d\t %d\t %d\t\t",
1196 i, h[i].privNF, nread);
1197 for (j = 0; j < nread; j++)
1198 len += snprintf(buf + len, size - len,
1199 " %d", h[i].nfCalBuffer[j]);
1200 len += snprintf(buf + len, size - len, "\n");
1201 }
1202
1203 if (len > size)
1204 len = size;
1205
1206 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1207 kfree(buf);
1208
1209 return retval;
1210}
1211
1212static const struct file_operations fops_dump_nfcal = {
1213 .read = read_file_dump_nfcal,
1214 .open = ath9k_debugfs_open,
1215 .owner = THIS_MODULE,
1216 .llseek = default_llseek,
1217};
1218
1166static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, 1219static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
1167 size_t count, loff_t *ppos) 1220 size_t count, loff_t *ppos)
1168{ 1221{
@@ -1262,6 +1315,8 @@ int ath9k_init_debug(struct ath_hw *ah)
1262 &ah->config.cwm_ignore_extcca); 1315 &ah->config.cwm_ignore_extcca);
1263 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, 1316 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
1264 &fops_regdump); 1317 &fops_regdump);
1318 debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc,
1319 &fops_dump_nfcal);
1265 debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, 1320 debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
1266 &fops_base_eeprom); 1321 &fops_base_eeprom);
1267 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, 1322 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 19aa5b724887..9cf42f6973aa 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -572,25 +572,6 @@ err:
572 return -EINVAL; 572 return -EINVAL;
573} 573}
574 574
575static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
576{
577 struct ath_common *common = ath9k_hw_common(priv->ah);
578 int i = 0;
579
580 /* Get the hardware key cache size. */
581 common->keymax = AR_KEYTABLE_SIZE;
582
583 if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
584 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
585
586 /*
587 * Reset the key cache since some parts do not
588 * reset the contents on initial power up.
589 */
590 for (i = 0; i < common->keymax; i++)
591 ath_hw_keyreset(common, (u16) i);
592}
593
594static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) 575static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
595{ 576{
596 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { 577 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
@@ -720,7 +701,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
720 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) 701 for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
721 priv->cur_beacon_conf.bslot[i] = NULL; 702 priv->cur_beacon_conf.bslot[i] = NULL;
722 703
723 ath9k_init_crypto(priv); 704 ath9k_cmn_init_crypto(ah);
724 ath9k_init_channels_rates(priv); 705 ath9k_init_channels_rates(priv);
725 ath9k_init_misc(priv); 706 ath9k_init_misc(priv);
726 707
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 7212acb2bd6c..0248024da56a 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1736,6 +1736,22 @@ out:
1736 return ret; 1736 return ret;
1737} 1737}
1738 1738
1739
1740static int ath9k_htc_get_stats(struct ieee80211_hw *hw,
1741 struct ieee80211_low_level_stats *stats)
1742{
1743 struct ath9k_htc_priv *priv = hw->priv;
1744 struct ath_hw *ah = priv->ah;
1745 struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;
1746
1747 stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
1748 stats->dot11RTSFailureCount = mib_stats->rts_bad;
1749 stats->dot11FCSErrorCount = mib_stats->fcs_bad;
1750 stats->dot11RTSSuccessCount = mib_stats->rts_good;
1751
1752 return 0;
1753}
1754
1739struct ieee80211_ops ath9k_htc_ops = { 1755struct ieee80211_ops ath9k_htc_ops = {
1740 .tx = ath9k_htc_tx, 1756 .tx = ath9k_htc_tx,
1741 .start = ath9k_htc_start, 1757 .start = ath9k_htc_start,
@@ -1759,4 +1775,5 @@ struct ieee80211_ops ath9k_htc_ops = {
1759 .rfkill_poll = ath9k_htc_rfkill_poll_state, 1775 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1760 .set_coverage_class = ath9k_htc_set_coverage_class, 1776 .set_coverage_class = ath9k_htc_set_coverage_class,
1761 .set_bitrate_mask = ath9k_htc_set_bitrate_mask, 1777 .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
1778 .get_stats = ath9k_htc_get_stats,
1762}; 1779};
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index cb29e8875386..dd9003ee123b 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -22,10 +22,12 @@
22/* Hardware core and driver accessible callbacks */ 22/* Hardware core and driver accessible callbacks */
23 23
24static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah, 24static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
25 int restore, 25 bool power_off)
26 int power_off)
27{ 26{
28 ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off); 27 if (ah->aspm_enabled != true)
28 return;
29
30 ath9k_hw_ops(ah)->config_pci_powersave(ah, power_off);
29} 31}
30 32
31static inline void ath9k_hw_rxena(struct ath_hw *ah) 33static inline void ath9k_hw_rxena(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index db44e5b0c98b..a0d1147844fb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -603,10 +603,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
603 603
604 ath9k_hw_init_mode_regs(ah); 604 ath9k_hw_init_mode_regs(ah);
605 605
606 606 if (!ah->is_pciexpress)
607 if (ah->is_pciexpress)
608 ath9k_hw_aspm_init(ah);
609 else
610 ath9k_hw_disablepcie(ah); 607 ath9k_hw_disablepcie(ah);
611 608
612 if (!AR_SREV_9300_20_OR_LATER(ah)) 609 if (!AR_SREV_9300_20_OR_LATER(ah))
@@ -621,6 +618,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
621 if (r) 618 if (r)
622 return r; 619 return r;
623 620
621 if (ah->is_pciexpress)
622 ath9k_hw_aspm_init(ah);
623
624 r = ath9k_hw_init_macaddr(ah); 624 r = ath9k_hw_init_macaddr(ah);
625 if (r) { 625 if (r) {
626 ath_err(common, "Failed to initialize MAC address\n"); 626 ath_err(common, "Failed to initialize MAC address\n");
@@ -663,6 +663,7 @@ int ath9k_hw_init(struct ath_hw *ah)
663 case AR9300_DEVID_AR9485_PCIE: 663 case AR9300_DEVID_AR9485_PCIE:
664 case AR9300_DEVID_AR9330: 664 case AR9300_DEVID_AR9330:
665 case AR9300_DEVID_AR9340: 665 case AR9300_DEVID_AR9340:
666 case AR9300_DEVID_AR9580:
666 break; 667 break;
667 default: 668 default:
668 if (common->bus_ops->ath_bus_type == ATH_USB) 669 if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -996,7 +997,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
996 slottime = 21; 997 slottime = 21;
997 sifstime = 64; 998 sifstime = 64;
998 } else { 999 } else {
999 eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS); 1000 eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS)/common->clockrate;
1000 reg = REG_READ(ah, AR_USEC); 1001 reg = REG_READ(ah, AR_USEC);
1001 rx_lat = MS(reg, AR_USEC_RX_LAT); 1002 rx_lat = MS(reg, AR_USEC_RX_LAT);
1002 tx_lat = MS(reg, AR_USEC_TX_LAT); 1003 tx_lat = MS(reg, AR_USEC_TX_LAT);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 4fbcced2828c..3aa3fb191775 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -45,6 +45,7 @@
45#define AR9300_DEVID_PCIE 0x0030 45#define AR9300_DEVID_PCIE 0x0030
46#define AR9300_DEVID_AR9340 0x0031 46#define AR9300_DEVID_AR9340 0x0031
47#define AR9300_DEVID_AR9485_PCIE 0x0032 47#define AR9300_DEVID_AR9485_PCIE 0x0032
48#define AR9300_DEVID_AR9580 0x0033
48#define AR9300_DEVID_AR9330 0x0035 49#define AR9300_DEVID_AR9330 0x0035
49 50
50#define AR5416_AR9100_DEVID 0x000b 51#define AR5416_AR9100_DEVID 0x000b
@@ -606,8 +607,7 @@ struct ath_hw_private_ops {
606 */ 607 */
607struct ath_hw_ops { 608struct ath_hw_ops {
608 void (*config_pci_powersave)(struct ath_hw *ah, 609 void (*config_pci_powersave)(struct ath_hw *ah,
609 int restore, 610 bool power_off);
610 int power_off);
611 void (*rx_enable)(struct ath_hw *ah); 611 void (*rx_enable)(struct ath_hw *ah);
612 void (*set_desc_link)(void *ds, u32 link); 612 void (*set_desc_link)(void *ds, u32 link);
613 bool (*calibrate)(struct ath_hw *ah, 613 bool (*calibrate)(struct ath_hw *ah,
@@ -1037,10 +1037,6 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
1037void ath9k_hw_proc_mib_event(struct ath_hw *ah); 1037void ath9k_hw_proc_mib_event(struct ath_hw *ah);
1038void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); 1038void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
1039 1039
1040#define ATH_PCIE_CAP_LINK_CTRL 0x70
1041#define ATH_PCIE_CAP_LINK_L0S 1
1042#define ATH_PCIE_CAP_LINK_L1 2
1043
1044#define ATH9K_CLOCK_RATE_CCK 22 1040#define ATH9K_CLOCK_RATE_CCK 22
1045#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 1041#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
1046#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 1042#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index db38a58e752d..d7761d1fc5ba 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -404,31 +404,6 @@ fail:
404 return error; 404 return error;
405} 405}
406 406
407void ath9k_init_crypto(struct ath_softc *sc)
408{
409 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
410 int i = 0;
411
412 /* Get the hardware key cache size. */
413 common->keymax = AR_KEYTABLE_SIZE;
414
415 /*
416 * Reset the key cache since some parts do not
417 * reset the contents on initial power up.
418 */
419 for (i = 0; i < common->keymax; i++)
420 ath_hw_keyreset(common, (u16) i);
421
422 /*
423 * Check whether the separate key cache entries
424 * are required to handle both tx+rx MIC keys.
425 * With split mic keys the number of stations is limited
426 * to 27 otherwise 59.
427 */
428 if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
429 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
430}
431
432static int ath9k_init_btcoex(struct ath_softc *sc) 407static int ath9k_init_btcoex(struct ath_softc *sc)
433{ 408{
434 struct ath_txq *txq; 409 struct ath_txq *txq;
@@ -630,7 +605,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
630 if (ret) 605 if (ret)
631 goto err_btcoex; 606 goto err_btcoex;
632 607
633 ath9k_init_crypto(sc); 608 ath9k_cmn_init_crypto(sc->sc_ah);
634 ath9k_init_misc(sc); 609 ath9k_init_misc(sc);
635 610
636 return 0; 611 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 0f90e1521ffe..7ce9b320f0d9 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -345,21 +345,8 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
345 } 345 }
346 memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); 346 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
347 qi->tqi_type = type; 347 qi->tqi_type = type;
348 if (qinfo == NULL) { 348 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
349 qi->tqi_qflags = 349 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
350 TXQ_FLAG_TXOKINT_ENABLE
351 | TXQ_FLAG_TXERRINT_ENABLE
352 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
353 qi->tqi_aifs = INIT_AIFS;
354 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
355 qi->tqi_cwmax = INIT_CWMAX;
356 qi->tqi_shretry = INIT_SH_RETRY;
357 qi->tqi_lgretry = INIT_LG_RETRY;
358 qi->tqi_physCompBuf = 0;
359 } else {
360 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
361 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
362 }
363 350
364 return q; 351 return q;
365} 352}
@@ -564,7 +551,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
564EXPORT_SYMBOL(ath9k_hw_resettxqueue); 551EXPORT_SYMBOL(ath9k_hw_resettxqueue);
565 552
566int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 553int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
567 struct ath_rx_status *rs, u64 tsf) 554 struct ath_rx_status *rs)
568{ 555{
569 struct ar5416_desc ads; 556 struct ar5416_desc ads;
570 struct ar5416_desc *adsp = AR5416DESC(ds); 557 struct ar5416_desc *adsp = AR5416DESC(ds);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 8e848c4d16ba..153859ccc2a1 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -687,7 +687,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
687bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); 687bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
688bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); 688bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
689int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 689int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
690 struct ath_rx_status *rs, u64 tsf); 690 struct ath_rx_status *rs);
691void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 691void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
692 u32 size, u32 flags); 692 u32 size, u32 flags);
693bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); 693bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1e7fe8c0e119..5ac4f3f2ad60 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -565,7 +565,6 @@ set_timer:
565static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) 565static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
566{ 566{
567 struct ath_node *an; 567 struct ath_node *an;
568 struct ath_hw *ah = sc->sc_ah;
569 an = (struct ath_node *)sta->drv_priv; 568 an = (struct ath_node *)sta->drv_priv;
570 569
571#ifdef CONFIG_ATH9K_DEBUGFS 570#ifdef CONFIG_ATH9K_DEBUGFS
@@ -574,9 +573,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
574 spin_unlock(&sc->nodes_lock); 573 spin_unlock(&sc->nodes_lock);
575 an->sta = sta; 574 an->sta = sta;
576#endif 575#endif
577 if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM)
578 sc->sc_flags |= SC_OP_ENABLE_APM;
579
580 if (sc->sc_flags & SC_OP_TXAGGR) { 576 if (sc->sc_flags & SC_OP_TXAGGR) {
581 ath_tx_node_init(sc, an); 577 ath_tx_node_init(sc, an);
582 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + 578 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
@@ -826,11 +822,9 @@ irqreturn_t ath_isr(int irq, void *dev)
826 if (status & ATH9K_INT_TXURN) 822 if (status & ATH9K_INT_TXURN)
827 ath9k_hw_updatetxtriglevel(ah, true); 823 ath9k_hw_updatetxtriglevel(ah, true);
828 824
829 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 825 if (status & ATH9K_INT_RXEOL) {
830 if (status & ATH9K_INT_RXEOL) { 826 ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
831 ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN); 827 ath9k_hw_set_interrupts(ah, ah->imask);
832 ath9k_hw_set_interrupts(ah, ah->imask);
833 }
834 } 828 }
835 829
836 if (status & ATH9K_INT_MIB) { 830 if (status & ATH9K_INT_MIB) {
@@ -888,7 +882,7 @@ static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
888 spin_lock_bh(&sc->sc_pcu_lock); 882 spin_lock_bh(&sc->sc_pcu_lock);
889 atomic_set(&ah->intr_ref_cnt, -1); 883 atomic_set(&ah->intr_ref_cnt, -1);
890 884
891 ath9k_hw_configpcipowersave(ah, 0, 0); 885 ath9k_hw_configpcipowersave(ah, false);
892 886
893 if (!ah->curchan) 887 if (!ah->curchan)
894 ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah); 888 ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah);
@@ -969,7 +963,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
969 963
970 ath9k_hw_phy_disable(ah); 964 ath9k_hw_phy_disable(ah);
971 965
972 ath9k_hw_configpcipowersave(ah, 1, 1); 966 ath9k_hw_configpcipowersave(ah, true);
973 967
974 spin_unlock_bh(&sc->sc_pcu_lock); 968 spin_unlock_bh(&sc->sc_pcu_lock);
975 ath9k_ps_restore(sc); 969 ath9k_ps_restore(sc);
@@ -1069,7 +1063,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1069 init_channel = ath9k_cmn_get_curchannel(hw, ah); 1063 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1070 1064
1071 /* Reset SERDES registers */ 1065 /* Reset SERDES registers */
1072 ath9k_hw_configpcipowersave(ah, 0, 0); 1066 ath9k_hw_configpcipowersave(ah, false);
1073 1067
1074 /* 1068 /*
1075 * The basic interface to setting the hardware in a good 1069 * The basic interface to setting the hardware in a good
@@ -1145,8 +1139,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
1145 AR_STOMP_LOW_WLAN_WGHT); 1139 AR_STOMP_LOW_WLAN_WGHT);
1146 ath9k_hw_btcoex_enable(ah); 1140 ath9k_hw_btcoex_enable(ah);
1147 1141
1148 if (common->bus_ops->bt_coex_prep)
1149 common->bus_ops->bt_coex_prep(common);
1150 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 1142 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1151 ath9k_btcoex_timer_resume(sc); 1143 ath9k_btcoex_timer_resume(sc);
1152 } 1144 }
@@ -1680,6 +1672,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1680 1672
1681 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1673 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1682 struct ieee80211_channel *curchan = hw->conf.channel; 1674 struct ieee80211_channel *curchan = hw->conf.channel;
1675 struct ath9k_channel old_chan;
1683 int pos = curchan->hw_value; 1676 int pos = curchan->hw_value;
1684 int old_pos = -1; 1677 int old_pos = -1;
1685 unsigned long flags; 1678 unsigned long flags;
@@ -1696,15 +1689,25 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1696 "Set channel: %d MHz type: %d\n", 1689 "Set channel: %d MHz type: %d\n",
1697 curchan->center_freq, conf->channel_type); 1690 curchan->center_freq, conf->channel_type);
1698 1691
1699 ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
1700 curchan, conf->channel_type);
1701
1702 /* update survey stats for the old channel before switching */ 1692 /* update survey stats for the old channel before switching */
1703 spin_lock_irqsave(&common->cc_lock, flags); 1693 spin_lock_irqsave(&common->cc_lock, flags);
1704 ath_update_survey_stats(sc); 1694 ath_update_survey_stats(sc);
1705 spin_unlock_irqrestore(&common->cc_lock, flags); 1695 spin_unlock_irqrestore(&common->cc_lock, flags);
1706 1696
1707 /* 1697 /*
1698 * Preserve the current channel values, before updating
1699 * the same channel
1700 */
1701 if (old_pos == pos) {
1702 memcpy(&old_chan, &sc->sc_ah->channels[pos],
1703 sizeof(struct ath9k_channel));
1704 ah->curchan = &old_chan;
1705 }
1706
1707 ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
1708 curchan, conf->channel_type);
1709
1710 /*
1708 * If the operating channel changes, change the survey in-use flags 1711 * If the operating channel changes, change the survey in-use flags
1709 * along with it. 1712 * along with it.
1710 * Reset the survey data for the new channel, unless we're switching 1713 * Reset the survey data for the new channel, unless we're switching
@@ -2400,6 +2403,20 @@ skip:
2400 return sc->beacon.tx_last; 2403 return sc->beacon.tx_last;
2401} 2404}
2402 2405
2406static int ath9k_get_stats(struct ieee80211_hw *hw,
2407 struct ieee80211_low_level_stats *stats)
2408{
2409 struct ath_softc *sc = hw->priv;
2410 struct ath_hw *ah = sc->sc_ah;
2411 struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;
2412
2413 stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
2414 stats->dot11RTSFailureCount = mib_stats->rts_bad;
2415 stats->dot11FCSErrorCount = mib_stats->fcs_bad;
2416 stats->dot11RTSSuccessCount = mib_stats->rts_good;
2417 return 0;
2418}
2419
2403struct ieee80211_ops ath9k_ops = { 2420struct ieee80211_ops ath9k_ops = {
2404 .tx = ath9k_tx, 2421 .tx = ath9k_tx,
2405 .start = ath9k_start, 2422 .start = ath9k_start,
@@ -2424,5 +2441,6 @@ struct ieee80211_ops ath9k_ops = {
2424 .set_coverage_class = ath9k_set_coverage_class, 2441 .set_coverage_class = ath9k_set_coverage_class,
2425 .flush = ath9k_flush, 2442 .flush = ath9k_flush,
2426 .tx_frames_pending = ath9k_tx_frames_pending, 2443 .tx_frames_pending = ath9k_tx_frames_pending,
2427 .tx_last_beacon = ath9k_tx_last_beacon, 2444 .tx_last_beacon = ath9k_tx_last_beacon,
2445 .get_stats = ath9k_get_stats,
2428}; 2446};
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 5685cf11cfe3..891661a61513 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -32,9 +32,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
32 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 32 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
33 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ 33 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
34 { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ 34 { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
35 { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
35 { 0 } 36 { 0 }
36}; 37};
37 38
39
38/* return bus cachesize in 4B word units */ 40/* return bus cachesize in 4B word units */
39static void ath_pci_read_cachesize(struct ath_common *common, int *csz) 41static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
40{ 42{
@@ -88,23 +90,6 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
88 return true; 90 return true;
89} 91}
90 92
91/*
92 * Bluetooth coexistance requires disabling ASPM.
93 */
94static void ath_pci_bt_coex_prep(struct ath_common *common)
95{
96 struct ath_softc *sc = (struct ath_softc *) common->priv;
97 struct pci_dev *pdev = to_pci_dev(sc->dev);
98 u8 aspm;
99
100 if (!pci_is_pcie(pdev))
101 return;
102
103 pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
104 aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
105 pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
106}
107
108static void ath_pci_extn_synch_enable(struct ath_common *common) 93static void ath_pci_extn_synch_enable(struct ath_common *common)
109{ 94{
110 struct ath_softc *sc = (struct ath_softc *) common->priv; 95 struct ath_softc *sc = (struct ath_softc *) common->priv;
@@ -116,6 +101,7 @@ static void ath_pci_extn_synch_enable(struct ath_common *common)
116 pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); 101 pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
117} 102}
118 103
104/* Need to be called after we discover btcoex capabilities */
119static void ath_pci_aspm_init(struct ath_common *common) 105static void ath_pci_aspm_init(struct ath_common *common)
120{ 106{
121 struct ath_softc *sc = (struct ath_softc *) common->priv; 107 struct ath_softc *sc = (struct ath_softc *) common->priv;
@@ -125,19 +111,38 @@ static void ath_pci_aspm_init(struct ath_common *common)
125 int pos; 111 int pos;
126 u8 aspm; 112 u8 aspm;
127 113
128 if (!pci_is_pcie(pdev)) 114 pos = pci_pcie_cap(pdev);
115 if (!pos)
129 return; 116 return;
130 117
131 parent = pdev->bus->self; 118 parent = pdev->bus->self;
132 if (WARN_ON(!parent)) 119 if (!parent)
133 return; 120 return;
134 121
122 if (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) {
123 /* Bluetooth coexistance requires disabling ASPM. */
124 pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm);
125 aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
126 pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm);
127
128 /*
129 * Both upstream and downstream PCIe components should
130 * have the same ASPM settings.
131 */
132 pos = pci_pcie_cap(parent);
133 pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
134 aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
135 pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm);
136
137 return;
138 }
139
135 pos = pci_pcie_cap(parent); 140 pos = pci_pcie_cap(parent);
136 pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); 141 pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
137 if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { 142 if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
138 ah->aspm_enabled = true; 143 ah->aspm_enabled = true;
139 /* Initialize PCIe PM and SERDES registers. */ 144 /* Initialize PCIe PM and SERDES registers. */
140 ath9k_hw_configpcipowersave(ah, 0, 0); 145 ath9k_hw_configpcipowersave(ah, false);
141 } 146 }
142} 147}
143 148
@@ -145,7 +150,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = {
145 .ath_bus_type = ATH_PCI, 150 .ath_bus_type = ATH_PCI,
146 .read_cachesize = ath_pci_read_cachesize, 151 .read_cachesize = ath_pci_read_cachesize,
147 .eeprom_read = ath_pci_eeprom_read, 152 .eeprom_read = ath_pci_eeprom_read,
148 .bt_coex_prep = ath_pci_bt_coex_prep,
149 .extn_synch_en = ath_pci_extn_synch_enable, 153 .extn_synch_en = ath_pci_extn_synch_enable,
150 .aspm_init = ath_pci_aspm_init, 154 .aspm_init = ath_pci_aspm_init,
151}; 155};
@@ -338,7 +342,7 @@ static int ath_pci_resume(struct device *device)
338 * semi-random values after suspend/resume. 342 * semi-random values after suspend/resume.
339 */ 343 */
340 ath9k_ps_wakeup(sc); 344 ath9k_ps_wakeup(sc);
341 ath9k_init_crypto(sc); 345 ath9k_cmn_init_crypto(sc->sc_ah);
342 ath9k_ps_restore(sc); 346 ath9k_ps_restore(sc);
343 347
344 sc->ps_idle = true; 348 sc->ps_idle = true;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 9e3649a3d5ca..4f1301881137 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -603,7 +603,8 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
603static u8 ath_rc_get_highest_rix(struct ath_softc *sc, 603static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
604 struct ath_rate_priv *ath_rc_priv, 604 struct ath_rate_priv *ath_rc_priv,
605 const struct ath_rate_table *rate_table, 605 const struct ath_rate_table *rate_table,
606 int *is_probing) 606 int *is_probing,
607 bool legacy)
607{ 608{
608 u32 best_thruput, this_thruput, now_msec; 609 u32 best_thruput, this_thruput, now_msec;
609 u8 rate, next_rate, best_rate, maxindex, minindex; 610 u8 rate, next_rate, best_rate, maxindex, minindex;
@@ -624,6 +625,8 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
624 u8 per_thres; 625 u8 per_thres;
625 626
626 rate = ath_rc_priv->valid_rate_index[index]; 627 rate = ath_rc_priv->valid_rate_index[index];
628 if (legacy && !(rate_table->info[rate].rate_flags & RC_LEGACY))
629 continue;
627 if (rate > ath_rc_priv->rate_max_phy) 630 if (rate > ath_rc_priv->rate_max_phy)
628 continue; 631 continue;
629 632
@@ -767,7 +770,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
767 struct ieee80211_tx_rate *rates = tx_info->control.rates; 770 struct ieee80211_tx_rate *rates = tx_info->control.rates;
768 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 771 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
769 __le16 fc = hdr->frame_control; 772 __le16 fc = hdr->frame_control;
770 u8 try_per_rate, i = 0, rix; 773 u8 try_per_rate, i = 0, rix, high_rix;
771 int is_probe = 0; 774 int is_probe = 0;
772 775
773 if (rate_control_send_low(sta, priv_sta, txrc)) 776 if (rate_control_send_low(sta, priv_sta, txrc))
@@ -786,7 +789,9 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
786 try_per_rate = 4; 789 try_per_rate = 4;
787 790
788 rate_table = ath_rc_priv->rate_table; 791 rate_table = ath_rc_priv->rate_table;
789 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); 792 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table,
793 &is_probe, false);
794 high_rix = rix;
790 795
791 /* 796 /*
792 * If we're in HT mode and both us and our peer supports LDPC. 797 * If we're in HT mode and both us and our peer supports LDPC.
@@ -822,10 +827,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
822 } 827 }
823 828
824 /* Fill in the other rates for multirate retry */ 829 /* Fill in the other rates for multirate retry */
825 for ( ; i < 4; i++) { 830 for ( ; i < 3; i++) {
826 /* Use twice the number of tries for the last MRR segment. */
827 if (i + 1 == 4)
828 try_per_rate = 8;
829 831
830 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); 832 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
831 /* All other rates in the series have RTS enabled */ 833 /* All other rates in the series have RTS enabled */
@@ -833,6 +835,24 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
833 try_per_rate, rix, 1); 835 try_per_rate, rix, 1);
834 } 836 }
835 837
838 /* Use twice the number of tries for the last MRR segment. */
839 try_per_rate = 8;
840
841 /*
842 * Use a legacy rate as last retry to ensure that the frame
843 * is tried in both MCS and legacy rates.
844 */
845 if ((rates[2].flags & IEEE80211_TX_RC_MCS) &&
846 (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) ||
847 (ath_rc_priv->per[high_rix] > 45)))
848 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table,
849 &is_probe, true);
850 else
851 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
852
853 /* All other rates in the series have RTS enabled */
854 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
855 try_per_rate, rix, 1);
836 /* 856 /*
837 * NB:Change rate series to enable aggregation when operating 857 * NB:Change rate series to enable aggregation when operating
838 * at lower MCS rates. When first rate in series is MCS2 858 * at lower MCS rates. When first rate in series is MCS2
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 74094022b654..ad5f9bd2f0b9 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -761,7 +761,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
761 * on. All this is necessary because of our use of 761 * on. All this is necessary because of our use of
762 * a self-linked list to avoid rx overruns. 762 * a self-linked list to avoid rx overruns.
763 */ 763 */
764 ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0); 764 ret = ath9k_hw_rxprocdesc(ah, ds, rs);
765 if (ret == -EINPROGRESS) { 765 if (ret == -EINPROGRESS) {
766 struct ath_rx_status trs; 766 struct ath_rx_status trs;
767 struct ath_buf *tbf; 767 struct ath_buf *tbf;
@@ -787,7 +787,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
787 */ 787 */
788 788
789 tds = tbf->bf_desc; 789 tds = tbf->bf_desc;
790 ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0); 790 ret = ath9k_hw_rxprocdesc(ah, tds, &trs);
791 if (ret == -EINPROGRESS) 791 if (ret == -EINPROGRESS)
792 return NULL; 792 return NULL;
793 } 793 }
@@ -824,7 +824,8 @@ static bool ath9k_rx_accept(struct ath_common *common,
824 is_mc = !!is_multicast_ether_addr(hdr->addr1); 824 is_mc = !!is_multicast_ether_addr(hdr->addr1);
825 is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && 825 is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&
826 test_bit(rx_stats->rs_keyix, common->tkip_keymap); 826 test_bit(rx_stats->rs_keyix, common->tkip_keymap);
827 strip_mic = is_valid_tkip && !(rx_stats->rs_status & 827 strip_mic = is_valid_tkip && ieee80211_is_data(fc) &&
828 !(rx_stats->rs_status &
828 (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC)); 829 (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC));
829 830
830 if (!rx_stats->rs_datalen) 831 if (!rx_stats->rs_datalen)
@@ -1978,5 +1979,10 @@ requeue:
1978 1979
1979 spin_unlock_bh(&sc->rx.rxbuflock); 1980 spin_unlock_bh(&sc->rx.rxbuflock);
1980 1981
1982 if (!(ah->imask & ATH9K_INT_RXEOL)) {
1983 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
1984 ath9k_hw_set_interrupts(ah, ah->imask);
1985 }
1986
1981 return 0; 1987 return 0;
1982} 1988}
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index fa4c0bbce6b9..a3b8bbc6c063 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -793,6 +793,8 @@
793#define AR_SREV_REVISION_9485_10 0 793#define AR_SREV_REVISION_9485_10 0
794#define AR_SREV_REVISION_9485_11 1 794#define AR_SREV_REVISION_9485_11 1
795#define AR_SREV_VERSION_9340 0x300 795#define AR_SREV_VERSION_9340 0x300
796#define AR_SREV_VERSION_9580 0x1C0
797#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
796 798
797#define AR_SREV_5416(_ah) \ 799#define AR_SREV_5416(_ah) \
798 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 800 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -893,6 +895,18 @@
893 (AR_SREV_9285_12_OR_LATER(_ah) && \ 895 (AR_SREV_9285_12_OR_LATER(_ah) && \
894 ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) 896 ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
895 897
898#define AR_SREV_9580(_ah) \
899 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \
900 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9580_10))
901
902#define AR_SREV_9580_10(_ah) \
903 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \
904 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9580_10))
905
906/* NOTE: When adding chips newer than Peacock, add chip check here */
907#define AR_SREV_9580_10_OR_LATER(_ah) \
908 (AR_SREV_9580(_ah))
909
896enum ath_usb_dev { 910enum ath_usb_dev {
897 AR9280_USB = 1, /* AR7010 + AR9280, UB94 */ 911 AR9280_USB = 1, /* AR7010 + AR9280, UB94 */
898 AR9287_USB = 2, /* AR7010 + AR9287, UB95 */ 912 AR9287_USB = 2, /* AR7010 + AR9287, UB95 */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index e1d1e903229b..5e2982938ffc 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -571,6 +571,25 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
571 ath_reset(sc, false); 571 ath_reset(sc, false);
572} 572}
573 573
574static bool ath_lookup_legacy(struct ath_buf *bf)
575{
576 struct sk_buff *skb;
577 struct ieee80211_tx_info *tx_info;
578 struct ieee80211_tx_rate *rates;
579 int i;
580
581 skb = bf->bf_mpdu;
582 tx_info = IEEE80211_SKB_CB(skb);
583 rates = tx_info->control.rates;
584
585 for (i = 3; i >= 0; i--) {
586 if (!(rates[i].flags & IEEE80211_TX_RC_MCS))
587 return true;
588 }
589
590 return false;
591}
592
574static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, 593static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
575 struct ath_atx_tid *tid) 594 struct ath_atx_tid *tid)
576{ 595{
@@ -644,8 +663,10 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
644 * meet the minimum required mpdudensity. 663 * meet the minimum required mpdudensity.
645 */ 664 */
646static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, 665static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
647 struct ath_buf *bf, u16 frmlen) 666 struct ath_buf *bf, u16 frmlen,
667 bool first_subfrm)
648{ 668{
669#define FIRST_DESC_NDELIMS 60
649 struct sk_buff *skb = bf->bf_mpdu; 670 struct sk_buff *skb = bf->bf_mpdu;
650 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 671 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
651 u32 nsymbits, nsymbols; 672 u32 nsymbits, nsymbols;
@@ -668,6 +689,13 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
668 ndelim += ATH_AGGR_ENCRYPTDELIM; 689 ndelim += ATH_AGGR_ENCRYPTDELIM;
669 690
670 /* 691 /*
692 * Add delimiter when using RTS/CTS with aggregation
693 * and non enterprise AR9003 card
694 */
695 if (first_subfrm)
696 ndelim = max(ndelim, FIRST_DESC_NDELIMS);
697
698 /*
671 * Convert desired mpdu density from microeconds to bytes based 699 * Convert desired mpdu density from microeconds to bytes based
672 * on highest rate in rate series (i.e. first rate) to determine 700 * on highest rate in rate series (i.e. first rate) to determine
673 * required minimum length for subframe. Take into account 701 * required minimum length for subframe. Take into account
@@ -741,7 +769,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
741 al_delta = ATH_AGGR_DELIM_SZ + fi->framelen; 769 al_delta = ATH_AGGR_DELIM_SZ + fi->framelen;
742 770
743 if (nframes && 771 if (nframes &&
744 (aggr_limit < (al + bpad + al_delta + prev_al))) { 772 ((aggr_limit < (al + bpad + al_delta + prev_al)) ||
773 ath_lookup_legacy(bf))) {
745 status = ATH_AGGR_LIMITED; 774 status = ATH_AGGR_LIMITED;
746 break; 775 break;
747 } 776 }
@@ -756,7 +785,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
756 status = ATH_AGGR_LIMITED; 785 status = ATH_AGGR_LIMITED;
757 break; 786 break;
758 } 787 }
759 nframes++;
760 788
761 /* add padding for previous frame to aggregation length */ 789 /* add padding for previous frame to aggregation length */
762 al += bpad + al_delta; 790 al += bpad + al_delta;
@@ -765,9 +793,11 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
765 * Get the delimiters needed to meet the MPDU 793 * Get the delimiters needed to meet the MPDU
766 * density for this node. 794 * density for this node.
767 */ 795 */
768 ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen); 796 ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen,
797 !nframes);
769 bpad = PADBYTES(al_delta) + (ndelim << 2); 798 bpad = PADBYTES(al_delta) + (ndelim << 2);
770 799
800 nframes++;
771 bf->bf_next = NULL; 801 bf->bf_next = NULL;
772 ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); 802 ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
773 803
@@ -1574,9 +1604,9 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
1574{ 1604{
1575 struct ath_hw *ah = sc->sc_ah; 1605 struct ath_hw *ah = sc->sc_ah;
1576 struct ath9k_channel *curchan = ah->curchan; 1606 struct ath9k_channel *curchan = ah->curchan;
1577 if ((sc->sc_flags & SC_OP_ENABLE_APM) && 1607 if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) &&
1578 (curchan->channelFlags & CHANNEL_5GHZ) && 1608 (curchan->channelFlags & CHANNEL_5GHZ) &&
1579 (chainmask == 0x7) && (rate < 0x90)) 1609 (chainmask == 0x7) && (rate < 0x90))
1580 return 0x3; 1610 return 0x3;
1581 else 1611 else
1582 return chainmask; 1612 return chainmask;
diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig
index 2d1b821b440d..267d5dcf82dc 100644
--- a/drivers/net/wireless/ath/carl9170/Kconfig
+++ b/drivers/net/wireless/ath/carl9170/Kconfig
@@ -39,3 +39,17 @@ config CARL9170_WPC
39 bool 39 bool
40 depends on CARL9170 && (INPUT = y || INPUT = CARL9170) 40 depends on CARL9170 && (INPUT = y || INPUT = CARL9170)
41 default y 41 default y
42
43config CARL9170_HWRNG
44 bool "Random number generator"
45 depends on CARL9170 && (HW_RANDOM = y || HW_RANDOM = CARL9170)
46 default n
47 help
48 Provides a hardware random number generator to the kernel.
49
50 SECURITY WARNING: It's relatively easy to eavesdrop all
51 generated random numbers from the transport stream with
52 usbmon [software] or special usb sniffer hardware.
53
54 Say N, unless your setup[i.e.: embedded system] has no
55 other rng source and you can afford to take the risk.
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index c5427a72a1e2..6cfbb419e2f6 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -43,6 +43,7 @@
43#include <linux/firmware.h> 43#include <linux/firmware.h>
44#include <linux/completion.h> 44#include <linux/completion.h>
45#include <linux/spinlock.h> 45#include <linux/spinlock.h>
46#include <linux/hw_random.h>
46#include <net/cfg80211.h> 47#include <net/cfg80211.h>
47#include <net/mac80211.h> 48#include <net/mac80211.h>
48#include <linux/usb.h> 49#include <linux/usb.h>
@@ -151,6 +152,7 @@ struct carl9170_sta_tid {
151#define CARL9170_TX_TIMEOUT 2500 152#define CARL9170_TX_TIMEOUT 2500
152#define CARL9170_JANITOR_DELAY 128 153#define CARL9170_JANITOR_DELAY 128
153#define CARL9170_QUEUE_STUCK_TIMEOUT 5500 154#define CARL9170_QUEUE_STUCK_TIMEOUT 5500
155#define CARL9170_STAT_WORK 30000
154 156
155#define CARL9170_NUM_TX_AGG_MAX 30 157#define CARL9170_NUM_TX_AGG_MAX 30
156 158
@@ -282,6 +284,7 @@ struct ar9170 {
282 bool rx_stream; 284 bool rx_stream;
283 bool tx_stream; 285 bool tx_stream;
284 bool rx_filter; 286 bool rx_filter;
287 bool hw_counters;
285 unsigned int mem_blocks; 288 unsigned int mem_blocks;
286 unsigned int mem_block_size; 289 unsigned int mem_block_size;
287 unsigned int rx_size; 290 unsigned int rx_size;
@@ -331,11 +334,21 @@ struct ar9170 {
331 334
332 /* PHY */ 335 /* PHY */
333 struct ieee80211_channel *channel; 336 struct ieee80211_channel *channel;
337 unsigned int num_channels;
334 int noise[4]; 338 int noise[4];
335 unsigned int chan_fail; 339 unsigned int chan_fail;
336 unsigned int total_chan_fail; 340 unsigned int total_chan_fail;
337 u8 heavy_clip; 341 u8 heavy_clip;
338 u8 ht_settings; 342 u8 ht_settings;
343 struct {
344 u64 active; /* usec */
345 u64 cca; /* usec */
346 u64 tx_time; /* usec */
347 u64 rx_total;
348 u64 rx_overrun;
349 } tally;
350 struct delayed_work stat_work;
351 struct survey_info *survey;
339 352
340 /* power calibration data */ 353 /* power calibration data */
341 u8 power_5G_leg[4]; 354 u8 power_5G_leg[4];
@@ -437,6 +450,17 @@ struct ar9170 {
437 unsigned int off_override; 450 unsigned int off_override;
438 bool state; 451 bool state;
439 } ps; 452 } ps;
453
454#ifdef CONFIG_CARL9170_HWRNG
455# define CARL9170_HWRNG_CACHE_SIZE CARL9170_MAX_CMD_PAYLOAD_LEN
456 struct {
457 struct hwrng rng;
458 bool initialized;
459 char name[30 + 1];
460 u16 cache[CARL9170_HWRNG_CACHE_SIZE / sizeof(u16)];
461 unsigned int cache_idx;
462 } rng;
463#endif /* CONFIG_CARL9170_HWRNG */
440}; 464};
441 465
442enum carl9170_ps_off_override_reasons { 466enum carl9170_ps_off_override_reasons {
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c
index cdfc94c371b4..195dc6538110 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.c
+++ b/drivers/net/wireless/ath/carl9170/cmd.c
@@ -36,6 +36,7 @@
36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 36 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 */ 37 */
38 38
39#include <asm/div64.h>
39#include "carl9170.h" 40#include "carl9170.h"
40#include "cmd.h" 41#include "cmd.h"
41 42
@@ -165,6 +166,39 @@ int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
165 return __carl9170_exec_cmd(ar, cmd, true); 166 return __carl9170_exec_cmd(ar, cmd, true);
166} 167}
167 168
169int carl9170_collect_tally(struct ar9170 *ar)
170{
171 struct carl9170_tally_rsp tally;
172 struct survey_info *info;
173 unsigned int tick;
174 int err;
175
176 err = carl9170_exec_cmd(ar, CARL9170_CMD_TALLY, 0, NULL,
177 sizeof(tally), (u8 *)&tally);
178 if (err)
179 return err;
180
181 tick = le32_to_cpu(tally.tick);
182 if (tick) {
183 ar->tally.active += le32_to_cpu(tally.active) / tick;
184 ar->tally.cca += le32_to_cpu(tally.cca) / tick;
185 ar->tally.tx_time += le32_to_cpu(tally.tx_time) / tick;
186 ar->tally.rx_total += le32_to_cpu(tally.rx_total);
187 ar->tally.rx_overrun += le32_to_cpu(tally.rx_overrun);
188
189 if (ar->channel) {
190 info = &ar->survey[ar->channel->hw_value];
191 info->channel_time = ar->tally.active;
192 info->channel_time_busy = ar->tally.cca;
193 info->channel_time_tx = ar->tally.tx_time;
194 do_div(info->channel_time, 1000);
195 do_div(info->channel_time_busy, 1000);
196 do_div(info->channel_time_tx, 1000);
197 }
198 }
199 return 0;
200}
201
168int carl9170_powersave(struct ar9170 *ar, const bool ps) 202int carl9170_powersave(struct ar9170 *ar, const bool ps)
169{ 203{
170 struct carl9170_cmd *cmd; 204 struct carl9170_cmd *cmd;
diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h
index d5f95bdc75c1..885c42778b8b 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.h
+++ b/drivers/net/wireless/ath/carl9170/cmd.h
@@ -50,6 +50,7 @@ int carl9170_echo_test(struct ar9170 *ar, u32 v);
50int carl9170_reboot(struct ar9170 *ar); 50int carl9170_reboot(struct ar9170 *ar);
51int carl9170_mac_reset(struct ar9170 *ar); 51int carl9170_mac_reset(struct ar9170 *ar);
52int carl9170_powersave(struct ar9170 *ar, const bool power_on); 52int carl9170_powersave(struct ar9170 *ar, const bool power_on);
53int carl9170_collect_tally(struct ar9170 *ar);
53int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, 54int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id,
54 const u32 mode, const u32 addr, const u32 len); 55 const u32 mode, const u32 addr, const u32 len);
55 56
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index 39ddea5794f7..f4cae1cccbff 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -266,6 +266,9 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
266 FIF_PROMISC_IN_BSS; 266 FIF_PROMISC_IN_BSS;
267 } 267 }
268 268
269 if (SUPP(CARL9170FW_HW_COUNTERS))
270 ar->fw.hw_counters = true;
271
269 if (SUPP(CARL9170FW_WOL)) 272 if (SUPP(CARL9170FW_WOL))
270 device_set_wakeup_enable(&ar->udev->dev, true); 273 device_set_wakeup_enable(&ar->udev->dev, true);
271 274
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index 0a6dec529b59..9443c802b25b 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -55,6 +55,7 @@ enum carl9170_cmd_oids {
55 CARL9170_CMD_READ_TSF = 0x06, 55 CARL9170_CMD_READ_TSF = 0x06,
56 CARL9170_CMD_RX_FILTER = 0x07, 56 CARL9170_CMD_RX_FILTER = 0x07,
57 CARL9170_CMD_WOL = 0x08, 57 CARL9170_CMD_WOL = 0x08,
58 CARL9170_CMD_TALLY = 0x09,
58 59
59 /* CAM */ 60 /* CAM */
60 CARL9170_CMD_EKEY = 0x10, 61 CARL9170_CMD_EKEY = 0x10,
@@ -286,6 +287,15 @@ struct carl9170_tsf_rsp {
286} __packed; 287} __packed;
287#define CARL9170_TSF_RSP_SIZE 8 288#define CARL9170_TSF_RSP_SIZE 8
288 289
290struct carl9170_tally_rsp {
291 __le32 active;
292 __le32 cca;
293 __le32 tx_time;
294 __le32 rx_total;
295 __le32 rx_overrun;
296 __le32 tick;
297} __packed;
298
289struct carl9170_rsp { 299struct carl9170_rsp {
290 struct carl9170_cmd_head hdr; 300 struct carl9170_cmd_head hdr;
291 301
@@ -300,6 +310,7 @@ struct carl9170_rsp {
300 struct carl9170_gpio gpio; 310 struct carl9170_gpio gpio;
301 struct carl9170_tsf_rsp tsf; 311 struct carl9170_tsf_rsp tsf;
302 struct carl9170_psm psm; 312 struct carl9170_psm psm;
313 struct carl9170_tally_rsp tally;
303 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; 314 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
304 } __packed; 315 } __packed;
305} __packed __aligned(4); 316} __packed __aligned(4);
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 0122930b14c7..782b8f3ae58f 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -413,6 +413,9 @@ static int carl9170_op_start(struct ieee80211_hw *hw)
413 413
414 carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STARTED); 414 carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STARTED);
415 415
416 ieee80211_queue_delayed_work(ar->hw, &ar->stat_work,
417 round_jiffies(msecs_to_jiffies(CARL9170_STAT_WORK)));
418
416 ieee80211_wake_queues(ar->hw); 419 ieee80211_wake_queues(ar->hw);
417 err = 0; 420 err = 0;
418 421
@@ -423,6 +426,7 @@ out:
423 426
424static void carl9170_cancel_worker(struct ar9170 *ar) 427static void carl9170_cancel_worker(struct ar9170 *ar)
425{ 428{
429 cancel_delayed_work_sync(&ar->stat_work);
426 cancel_delayed_work_sync(&ar->tx_janitor); 430 cancel_delayed_work_sync(&ar->tx_janitor);
427#ifdef CONFIG_CARL9170_LEDS 431#ifdef CONFIG_CARL9170_LEDS
428 cancel_delayed_work_sync(&ar->led_work); 432 cancel_delayed_work_sync(&ar->led_work);
@@ -794,6 +798,43 @@ static void carl9170_ps_work(struct work_struct *work)
794 mutex_unlock(&ar->mutex); 798 mutex_unlock(&ar->mutex);
795} 799}
796 800
801static int carl9170_update_survey(struct ar9170 *ar, bool flush, bool noise)
802{
803 int err;
804
805 if (noise) {
806 err = carl9170_get_noisefloor(ar);
807 if (err)
808 return err;
809 }
810
811 if (ar->fw.hw_counters) {
812 err = carl9170_collect_tally(ar);
813 if (err)
814 return err;
815 }
816
817 if (flush)
818 memset(&ar->tally, 0, sizeof(ar->tally));
819
820 return 0;
821}
822
823static void carl9170_stat_work(struct work_struct *work)
824{
825 struct ar9170 *ar = container_of(work, struct ar9170, stat_work.work);
826 int err;
827
828 mutex_lock(&ar->mutex);
829 err = carl9170_update_survey(ar, false, true);
830 mutex_unlock(&ar->mutex);
831
832 if (err)
833 return;
834
835 ieee80211_queue_delayed_work(ar->hw, &ar->stat_work,
836 round_jiffies(msecs_to_jiffies(CARL9170_STAT_WORK)));
837}
797 838
798static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) 839static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
799{ 840{
@@ -828,11 +869,19 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
828 if (err) 869 if (err)
829 goto out; 870 goto out;
830 871
872 err = carl9170_update_survey(ar, true, false);
873 if (err)
874 goto out;
875
831 err = carl9170_set_channel(ar, hw->conf.channel, 876 err = carl9170_set_channel(ar, hw->conf.channel,
832 hw->conf.channel_type, CARL9170_RFI_NONE); 877 hw->conf.channel_type, CARL9170_RFI_NONE);
833 if (err) 878 if (err)
834 goto out; 879 goto out;
835 880
881 err = carl9170_update_survey(ar, false, true);
882 if (err)
883 goto out;
884
836 err = carl9170_set_dyn_sifs_ack(ar); 885 err = carl9170_set_dyn_sifs_ack(ar);
837 if (err) 886 if (err)
838 goto out; 887 goto out;
@@ -1419,24 +1468,159 @@ static int carl9170_register_wps_button(struct ar9170 *ar)
1419} 1468}
1420#endif /* CONFIG_CARL9170_WPC */ 1469#endif /* CONFIG_CARL9170_WPC */
1421 1470
1422static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx, 1471#ifdef CONFIG_CARL9170_HWRNG
1423 struct survey_info *survey) 1472static int carl9170_rng_get(struct ar9170 *ar)
1424{ 1473{
1425 struct ar9170 *ar = hw->priv; 1474
1475#define RW (CARL9170_MAX_CMD_PAYLOAD_LEN / sizeof(u32))
1476#define RB (CARL9170_MAX_CMD_PAYLOAD_LEN)
1477
1478 static const __le32 rng_load[RW] = {
1479 [0 ... (RW - 1)] = cpu_to_le32(AR9170_RAND_REG_NUM)};
1480
1481 u32 buf[RW];
1482
1483 unsigned int i, off = 0, transfer, count;
1426 int err; 1484 int err;
1427 1485
1428 if (idx != 0) 1486 BUILD_BUG_ON(RB > CARL9170_MAX_CMD_PAYLOAD_LEN);
1429 return -ENOENT; 1487
1488 if (!IS_ACCEPTING_CMD(ar) || !ar->rng.initialized)
1489 return -EAGAIN;
1490
1491 count = ARRAY_SIZE(ar->rng.cache);
1492 while (count) {
1493 err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
1494 RB, (u8 *) rng_load,
1495 RB, (u8 *) buf);
1496 if (err)
1497 return err;
1498
1499 transfer = min_t(unsigned int, count, RW);
1500 for (i = 0; i < transfer; i++)
1501 ar->rng.cache[off + i] = buf[i];
1502
1503 off += transfer;
1504 count -= transfer;
1505 }
1506
1507 ar->rng.cache_idx = 0;
1508
1509#undef RW
1510#undef RB
1511 return 0;
1512}
1513
1514static int carl9170_rng_read(struct hwrng *rng, u32 *data)
1515{
1516 struct ar9170 *ar = (struct ar9170 *)rng->priv;
1517 int ret = -EIO;
1430 1518
1431 mutex_lock(&ar->mutex); 1519 mutex_lock(&ar->mutex);
1432 err = carl9170_get_noisefloor(ar); 1520 if (ar->rng.cache_idx >= ARRAY_SIZE(ar->rng.cache)) {
1521 ret = carl9170_rng_get(ar);
1522 if (ret) {
1523 mutex_unlock(&ar->mutex);
1524 return ret;
1525 }
1526 }
1527
1528 *data = ar->rng.cache[ar->rng.cache_idx++];
1433 mutex_unlock(&ar->mutex); 1529 mutex_unlock(&ar->mutex);
1434 if (err) 1530
1531 return sizeof(u16);
1532}
1533
1534static void carl9170_unregister_hwrng(struct ar9170 *ar)
1535{
1536 if (ar->rng.initialized) {
1537 hwrng_unregister(&ar->rng.rng);
1538 ar->rng.initialized = false;
1539 }
1540}
1541
1542static int carl9170_register_hwrng(struct ar9170 *ar)
1543{
1544 int err;
1545
1546 snprintf(ar->rng.name, ARRAY_SIZE(ar->rng.name),
1547 "%s_%s", KBUILD_MODNAME, wiphy_name(ar->hw->wiphy));
1548 ar->rng.rng.name = ar->rng.name;
1549 ar->rng.rng.data_read = carl9170_rng_read;
1550 ar->rng.rng.priv = (unsigned long)ar;
1551
1552 if (WARN_ON(ar->rng.initialized))
1553 return -EALREADY;
1554
1555 err = hwrng_register(&ar->rng.rng);
1556 if (err) {
1557 dev_err(&ar->udev->dev, "Failed to register the random "
1558 "number generator (%d)\n", err);
1435 return err; 1559 return err;
1560 }
1561
1562 ar->rng.initialized = true;
1563
1564 err = carl9170_rng_get(ar);
1565 if (err) {
1566 carl9170_unregister_hwrng(ar);
1567 return err;
1568 }
1569
1570 return 0;
1571}
1572#endif /* CONFIG_CARL9170_HWRNG */
1573
1574static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx,
1575 struct survey_info *survey)
1576{
1577 struct ar9170 *ar = hw->priv;
1578 struct ieee80211_channel *chan;
1579 struct ieee80211_supported_band *band;
1580 int err, b, i;
1581
1582 chan = ar->channel;
1583 if (!chan)
1584 return -ENODEV;
1585
1586 if (idx == chan->hw_value) {
1587 mutex_lock(&ar->mutex);
1588 err = carl9170_update_survey(ar, false, true);
1589 mutex_unlock(&ar->mutex);
1590 if (err)
1591 return err;
1592 }
1593
1594 for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
1595 band = ar->hw->wiphy->bands[b];
1596
1597 if (!band)
1598 continue;
1599
1600 for (i = 0; i < band->n_channels; i++) {
1601 if (band->channels[i].hw_value == idx) {
1602 chan = &band->channels[i];
1603 goto found;
1604 }
1605 }
1606 }
1607 return -ENOENT;
1608
1609found:
1610 memcpy(survey, &ar->survey[idx], sizeof(*survey));
1436 1611
1437 survey->channel = ar->channel; 1612 survey->channel = chan;
1438 survey->filled = SURVEY_INFO_NOISE_DBM; 1613 survey->filled = SURVEY_INFO_NOISE_DBM;
1439 survey->noise = ar->noise[0]; 1614
1615 if (ar->channel == chan)
1616 survey->filled |= SURVEY_INFO_IN_USE;
1617
1618 if (ar->fw.hw_counters) {
1619 survey->filled |= SURVEY_INFO_CHANNEL_TIME |
1620 SURVEY_INFO_CHANNEL_TIME_BUSY |
1621 SURVEY_INFO_CHANNEL_TIME_TX;
1622 }
1623
1440 return 0; 1624 return 0;
1441} 1625}
1442 1626
@@ -1569,6 +1753,7 @@ void *carl9170_alloc(size_t priv_size)
1569 INIT_WORK(&ar->ping_work, carl9170_ping_work); 1753 INIT_WORK(&ar->ping_work, carl9170_ping_work);
1570 INIT_WORK(&ar->restart_work, carl9170_restart_work); 1754 INIT_WORK(&ar->restart_work, carl9170_restart_work);
1571 INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work); 1755 INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
1756 INIT_DELAYED_WORK(&ar->stat_work, carl9170_stat_work);
1572 INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor); 1757 INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
1573 INIT_LIST_HEAD(&ar->tx_ampdu_list); 1758 INIT_LIST_HEAD(&ar->tx_ampdu_list);
1574 rcu_assign_pointer(ar->tx_ampdu_iter, 1759 rcu_assign_pointer(ar->tx_ampdu_iter,
@@ -1652,6 +1837,7 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
1652 struct ath_regulatory *regulatory = &ar->common.regulatory; 1837 struct ath_regulatory *regulatory = &ar->common.regulatory;
1653 unsigned int rx_streams, tx_streams, tx_params = 0; 1838 unsigned int rx_streams, tx_streams, tx_params = 0;
1654 int bands = 0; 1839 int bands = 0;
1840 int chans = 0;
1655 1841
1656 if (ar->eeprom.length == cpu_to_le16(0xffff)) 1842 if (ar->eeprom.length == cpu_to_le16(0xffff))
1657 return -ENODATA; 1843 return -ENODATA;
@@ -1675,14 +1861,24 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
1675 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) { 1861 if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
1676 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 1862 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1677 &carl9170_band_2GHz; 1863 &carl9170_band_2GHz;
1864 chans += carl9170_band_2GHz.n_channels;
1678 bands++; 1865 bands++;
1679 } 1866 }
1680 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) { 1867 if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
1681 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 1868 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1682 &carl9170_band_5GHz; 1869 &carl9170_band_5GHz;
1870 chans += carl9170_band_5GHz.n_channels;
1683 bands++; 1871 bands++;
1684 } 1872 }
1685 1873
1874 if (!bands)
1875 return -EINVAL;
1876
1877 ar->survey = kzalloc(sizeof(struct survey_info) * chans, GFP_KERNEL);
1878 if (!ar->survey)
1879 return -ENOMEM;
1880 ar->num_channels = chans;
1881
1686 /* 1882 /*
1687 * I measured this, a bandswitch takes roughly 1883 * I measured this, a bandswitch takes roughly
1688 * 135 ms and a frequency switch about 80. 1884 * 135 ms and a frequency switch about 80.
@@ -1701,7 +1897,7 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
1701 /* second part of wiphy init */ 1897 /* second part of wiphy init */
1702 SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address); 1898 SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address);
1703 1899
1704 return bands ? 0 : -EINVAL; 1900 return 0;
1705} 1901}
1706 1902
1707static int carl9170_reg_notifier(struct wiphy *wiphy, 1903static int carl9170_reg_notifier(struct wiphy *wiphy,
@@ -1785,6 +1981,12 @@ int carl9170_register(struct ar9170 *ar)
1785 goto err_unreg; 1981 goto err_unreg;
1786#endif /* CONFIG_CARL9170_WPC */ 1982#endif /* CONFIG_CARL9170_WPC */
1787 1983
1984#ifdef CONFIG_CARL9170_HWRNG
1985 err = carl9170_register_hwrng(ar);
1986 if (err)
1987 goto err_unreg;
1988#endif /* CONFIG_CARL9170_HWRNG */
1989
1788 dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n", 1990 dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n",
1789 wiphy_name(ar->hw->wiphy)); 1991 wiphy_name(ar->hw->wiphy));
1790 1992
@@ -1817,6 +2019,10 @@ void carl9170_unregister(struct ar9170 *ar)
1817 } 2019 }
1818#endif /* CONFIG_CARL9170_WPC */ 2020#endif /* CONFIG_CARL9170_WPC */
1819 2021
2022#ifdef CONFIG_CARL9170_HWRNG
2023 carl9170_unregister_hwrng(ar);
2024#endif /* CONFIG_CARL9170_HWRNG */
2025
1820 carl9170_cancel_worker(ar); 2026 carl9170_cancel_worker(ar);
1821 cancel_work_sync(&ar->restart_work); 2027 cancel_work_sync(&ar->restart_work);
1822 2028
@@ -1834,6 +2040,9 @@ void carl9170_free(struct ar9170 *ar)
1834 kfree(ar->mem_bitmap); 2040 kfree(ar->mem_bitmap);
1835 ar->mem_bitmap = NULL; 2041 ar->mem_bitmap = NULL;
1836 2042
2043 kfree(ar->survey);
2044 ar->survey = NULL;
2045
1837 mutex_destroy(&ar->mutex); 2046 mutex_destroy(&ar->mutex);
1838 2047
1839 ieee80211_free_hw(ar->hw); 2048 ieee80211_free_hw(ar->hw);
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index aa147a9120b6..472efc7e3402 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -578,11 +578,10 @@ static int carl9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
578 if (err) 578 if (err)
579 return err; 579 return err;
580 580
581 /* XXX: remove magic! */ 581 if (!ar->fw.hw_counters) {
582 if (is_2ghz) 582 err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC,
583 err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5163); 583 is_2ghz ? 0x5163 : 0x5143);
584 else 584 }
585 err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5143);
586 585
587 return err; 586 return err;
588} 587}
@@ -1574,6 +1573,9 @@ int carl9170_get_noisefloor(struct ar9170 *ar)
1574 AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8); 1573 AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8);
1575 } 1574 }
1576 1575
1576 if (ar->channel)
1577 ar->survey[ar->channel->hw_value].noise = ar->noise[0];
1578
1577 return 0; 1579 return 0;
1578} 1580}
1579 1581
@@ -1766,10 +1768,6 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1766 ar->chan_fail = 0; 1768 ar->chan_fail = 0;
1767 } 1769 }
1768 1770
1769 err = carl9170_get_noisefloor(ar);
1770 if (err)
1771 return err;
1772
1773 if (ar->heavy_clip) { 1771 if (ar->heavy_clip) {
1774 err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, 1772 err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
1775 0x200 | ar->heavy_clip); 1773 0x200 | ar->heavy_clip);
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index 64703778cfea..e651db856344 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
1#ifndef __CARL9170_SHARED_VERSION_H 1#ifndef __CARL9170_SHARED_VERSION_H
2#define __CARL9170_SHARED_VERSION_H 2#define __CARL9170_SHARED_VERSION_H
3#define CARL9170FW_VERSION_YEAR 11 3#define CARL9170FW_VERSION_YEAR 11
4#define CARL9170FW_VERSION_MONTH 6 4#define CARL9170FW_VERSION_MONTH 8
5#define CARL9170FW_VERSION_DAY 30 5#define CARL9170FW_VERSION_DAY 15
6#define CARL9170FW_VERSION_GIT "1.9.4" 6#define CARL9170FW_VERSION_GIT "1.9.4"
7#endif /* __CARL9170_SHARED_VERSION_H */ 7#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index b81a2a1c2618..df2b7c0856ed 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -169,13 +169,3 @@ config B43_DEBUG
169 Say N, if you are a distributor or user building a release kernel 169 Say N, if you are a distributor or user building a release kernel
170 for production use. 170 for production use.
171 Only say Y, if you are debugging a problem in the b43 driver sourcecode. 171 Only say Y, if you are debugging a problem in the b43 driver sourcecode.
172
173config B43_FORCE_PIO
174 bool "Force usage of PIO instead of DMA"
175 depends on B43 && B43_DEBUG
176 ---help---
177 This will disable DMA and always enable PIO instead.
178
179 Say N!
180 This is only for debugging the PIO engine code. You do
181 _NOT_ want to enable this.
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index c818b0bc88ec..8ff706289b5d 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -17,11 +17,6 @@
17#include "phy_common.h" 17#include "phy_common.h"
18 18
19 19
20/* The unique identifier of the firmware that's officially supported by
21 * this driver version. */
22#define B43_SUPPORTED_FIRMWARE_ID "FW13"
23
24
25#ifdef CONFIG_B43_DEBUG 20#ifdef CONFIG_B43_DEBUG
26# define B43_DEBUG 1 21# define B43_DEBUG 1
27#else 22#else
@@ -594,6 +589,7 @@ struct b43_dma {
594 struct b43_dmaring *rx_ring; 589 struct b43_dmaring *rx_ring;
595 590
596 u32 translation; /* Routing bits */ 591 u32 translation; /* Routing bits */
592 bool translation_in_low; /* Should translation bit go into low addr? */
597 bool parity; /* Check for parity */ 593 bool parity; /* Check for parity */
598}; 594};
599 595
@@ -694,6 +690,12 @@ struct b43_firmware_file {
694 enum b43_firmware_file_type type; 690 enum b43_firmware_file_type type;
695}; 691};
696 692
693enum b43_firmware_hdr_format {
694 B43_FW_HDR_598,
695 B43_FW_HDR_410,
696 B43_FW_HDR_351,
697};
698
697/* Pointers to the firmware data and meta information about it. */ 699/* Pointers to the firmware data and meta information about it. */
698struct b43_firmware { 700struct b43_firmware {
699 /* Microcode */ 701 /* Microcode */
@@ -710,6 +712,9 @@ struct b43_firmware {
710 /* Firmware patchlevel */ 712 /* Firmware patchlevel */
711 u16 patch; 713 u16 patch;
712 714
715 /* Format of header used by firmware */
716 enum b43_firmware_hdr_format hdr_format;
717
713 /* Set to true, if we are using an opensource firmware. 718 /* Set to true, if we are using an opensource firmware.
714 * Use this to check for proprietary vs opensource. */ 719 * Use this to check for proprietary vs opensource. */
715 bool opensource; 720 bool opensource;
@@ -875,7 +880,7 @@ struct b43_wl {
875 struct b43_leds leds; 880 struct b43_leds leds;
876 881
877 /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */ 882 /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
878 u8 pio_scratchspace[110] __attribute__((__aligned__(8))); 883 u8 pio_scratchspace[118] __attribute__((__aligned__(8)));
879 u8 pio_tailspace[4] __attribute__((__aligned__(8))); 884 u8 pio_tailspace[4] __attribute__((__aligned__(8)));
880}; 885};
881 886
@@ -965,12 +970,6 @@ static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
965 return dev->__using_pio_transfers; 970 return dev->__using_pio_transfers;
966} 971}
967 972
968#ifdef CONFIG_B43_FORCE_PIO
969# define B43_PIO_DEFAULT 1
970#else
971# define B43_PIO_DEFAULT 0
972#endif
973
974/* Message printing */ 973/* Message printing */
975void b43info(struct b43_wl *wl, const char *fmt, ...) 974void b43info(struct b43_wl *wl, const char *fmt, ...)
976 __attribute__ ((format(printf, 2, 3))); 975 __attribute__ ((format(printf, 2, 3)));
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 481e534534eb..c5d890e74a1e 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -47,6 +47,38 @@
47 * into separate slots. */ 47 * into separate slots. */
48#define TX_SLOTS_PER_FRAME 2 48#define TX_SLOTS_PER_FRAME 2
49 49
50static u32 b43_dma_address(struct b43_dma *dma, dma_addr_t dmaaddr,
51 enum b43_addrtype addrtype)
52{
53 u32 uninitialized_var(addr);
54
55 switch (addrtype) {
56 case B43_DMA_ADDR_LOW:
57 addr = lower_32_bits(dmaaddr);
58 if (dma->translation_in_low) {
59 addr &= ~SSB_DMA_TRANSLATION_MASK;
60 addr |= dma->translation;
61 }
62 break;
63 case B43_DMA_ADDR_HIGH:
64 addr = upper_32_bits(dmaaddr);
65 if (!dma->translation_in_low) {
66 addr &= ~SSB_DMA_TRANSLATION_MASK;
67 addr |= dma->translation;
68 }
69 break;
70 case B43_DMA_ADDR_EXT:
71 if (dma->translation_in_low)
72 addr = lower_32_bits(dmaaddr);
73 else
74 addr = upper_32_bits(dmaaddr);
75 addr &= SSB_DMA_TRANSLATION_MASK;
76 addr >>= SSB_DMA_TRANSLATION_SHIFT;
77 break;
78 }
79
80 return addr;
81}
50 82
51/* 32bit DMA ops. */ 83/* 32bit DMA ops. */
52static 84static
@@ -77,10 +109,9 @@ static void op32_fill_descriptor(struct b43_dmaring *ring,
77 slot = (int)(&(desc->dma32) - descbase); 109 slot = (int)(&(desc->dma32) - descbase);
78 B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); 110 B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
79 111
80 addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK); 112 addr = b43_dma_address(&ring->dev->dma, dmaaddr, B43_DMA_ADDR_LOW);
81 addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK) 113 addrext = b43_dma_address(&ring->dev->dma, dmaaddr, B43_DMA_ADDR_EXT);
82 >> SSB_DMA_TRANSLATION_SHIFT; 114
83 addr |= ring->dev->dma.translation;
84 ctl = bufsize & B43_DMA32_DCTL_BYTECNT; 115 ctl = bufsize & B43_DMA32_DCTL_BYTECNT;
85 if (slot == ring->nr_slots - 1) 116 if (slot == ring->nr_slots - 1)
86 ctl |= B43_DMA32_DCTL_DTABLEEND; 117 ctl |= B43_DMA32_DCTL_DTABLEEND;
@@ -170,11 +201,10 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
170 slot = (int)(&(desc->dma64) - descbase); 201 slot = (int)(&(desc->dma64) - descbase);
171 B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); 202 B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
172 203
173 addrlo = (u32) (dmaaddr & 0xFFFFFFFF); 204 addrlo = b43_dma_address(&ring->dev->dma, dmaaddr, B43_DMA_ADDR_LOW);
174 addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); 205 addrhi = b43_dma_address(&ring->dev->dma, dmaaddr, B43_DMA_ADDR_HIGH);
175 addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) 206 addrext = b43_dma_address(&ring->dev->dma, dmaaddr, B43_DMA_ADDR_EXT);
176 >> SSB_DMA_TRANSLATION_SHIFT; 207
177 addrhi |= ring->dev->dma.translation;
178 if (slot == ring->nr_slots - 1) 208 if (slot == ring->nr_slots - 1)
179 ctl0 |= B43_DMA64_DCTL0_DTABLEEND; 209 ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
180 if (start) 210 if (start)
@@ -658,41 +688,37 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
658 int err = 0; 688 int err = 0;
659 u32 value; 689 u32 value;
660 u32 addrext; 690 u32 addrext;
661 u32 trans = ring->dev->dma.translation;
662 bool parity = ring->dev->dma.parity; 691 bool parity = ring->dev->dma.parity;
692 u32 addrlo;
693 u32 addrhi;
663 694
664 if (ring->tx) { 695 if (ring->tx) {
665 if (ring->type == B43_DMA_64BIT) { 696 if (ring->type == B43_DMA_64BIT) {
666 u64 ringbase = (u64) (ring->dmabase); 697 u64 ringbase = (u64) (ring->dmabase);
698 addrext = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_EXT);
699 addrlo = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_LOW);
700 addrhi = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_HIGH);
667 701
668 addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
669 >> SSB_DMA_TRANSLATION_SHIFT;
670 value = B43_DMA64_TXENABLE; 702 value = B43_DMA64_TXENABLE;
671 value |= (addrext << B43_DMA64_TXADDREXT_SHIFT) 703 value |= (addrext << B43_DMA64_TXADDREXT_SHIFT)
672 & B43_DMA64_TXADDREXT_MASK; 704 & B43_DMA64_TXADDREXT_MASK;
673 if (!parity) 705 if (!parity)
674 value |= B43_DMA64_TXPARITYDISABLE; 706 value |= B43_DMA64_TXPARITYDISABLE;
675 b43_dma_write(ring, B43_DMA64_TXCTL, value); 707 b43_dma_write(ring, B43_DMA64_TXCTL, value);
676 b43_dma_write(ring, B43_DMA64_TXRINGLO, 708 b43_dma_write(ring, B43_DMA64_TXRINGLO, addrlo);
677 (ringbase & 0xFFFFFFFF)); 709 b43_dma_write(ring, B43_DMA64_TXRINGHI, addrhi);
678 b43_dma_write(ring, B43_DMA64_TXRINGHI,
679 ((ringbase >> 32) &
680 ~SSB_DMA_TRANSLATION_MASK)
681 | trans);
682 } else { 710 } else {
683 u32 ringbase = (u32) (ring->dmabase); 711 u32 ringbase = (u32) (ring->dmabase);
712 addrext = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_EXT);
713 addrlo = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_LOW);
684 714
685 addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
686 >> SSB_DMA_TRANSLATION_SHIFT;
687 value = B43_DMA32_TXENABLE; 715 value = B43_DMA32_TXENABLE;
688 value |= (addrext << B43_DMA32_TXADDREXT_SHIFT) 716 value |= (addrext << B43_DMA32_TXADDREXT_SHIFT)
689 & B43_DMA32_TXADDREXT_MASK; 717 & B43_DMA32_TXADDREXT_MASK;
690 if (!parity) 718 if (!parity)
691 value |= B43_DMA32_TXPARITYDISABLE; 719 value |= B43_DMA32_TXPARITYDISABLE;
692 b43_dma_write(ring, B43_DMA32_TXCTL, value); 720 b43_dma_write(ring, B43_DMA32_TXCTL, value);
693 b43_dma_write(ring, B43_DMA32_TXRING, 721 b43_dma_write(ring, B43_DMA32_TXRING, addrlo);
694 (ringbase & ~SSB_DMA_TRANSLATION_MASK)
695 | trans);
696 } 722 }
697 } else { 723 } else {
698 err = alloc_initial_descbuffers(ring); 724 err = alloc_initial_descbuffers(ring);
@@ -700,9 +726,10 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
700 goto out; 726 goto out;
701 if (ring->type == B43_DMA_64BIT) { 727 if (ring->type == B43_DMA_64BIT) {
702 u64 ringbase = (u64) (ring->dmabase); 728 u64 ringbase = (u64) (ring->dmabase);
729 addrext = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_EXT);
730 addrlo = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_LOW);
731 addrhi = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_HIGH);
703 732
704 addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK)
705 >> SSB_DMA_TRANSLATION_SHIFT;
706 value = (ring->frameoffset << B43_DMA64_RXFROFF_SHIFT); 733 value = (ring->frameoffset << B43_DMA64_RXFROFF_SHIFT);
707 value |= B43_DMA64_RXENABLE; 734 value |= B43_DMA64_RXENABLE;
708 value |= (addrext << B43_DMA64_RXADDREXT_SHIFT) 735 value |= (addrext << B43_DMA64_RXADDREXT_SHIFT)
@@ -710,19 +737,15 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
710 if (!parity) 737 if (!parity)
711 value |= B43_DMA64_RXPARITYDISABLE; 738 value |= B43_DMA64_RXPARITYDISABLE;
712 b43_dma_write(ring, B43_DMA64_RXCTL, value); 739 b43_dma_write(ring, B43_DMA64_RXCTL, value);
713 b43_dma_write(ring, B43_DMA64_RXRINGLO, 740 b43_dma_write(ring, B43_DMA64_RXRINGLO, addrlo);
714 (ringbase & 0xFFFFFFFF)); 741 b43_dma_write(ring, B43_DMA64_RXRINGHI, addrhi);
715 b43_dma_write(ring, B43_DMA64_RXRINGHI,
716 ((ringbase >> 32) &
717 ~SSB_DMA_TRANSLATION_MASK)
718 | trans);
719 b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots * 742 b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
720 sizeof(struct b43_dmadesc64)); 743 sizeof(struct b43_dmadesc64));
721 } else { 744 } else {
722 u32 ringbase = (u32) (ring->dmabase); 745 u32 ringbase = (u32) (ring->dmabase);
746 addrext = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_EXT);
747 addrlo = b43_dma_address(&ring->dev->dma, ringbase, B43_DMA_ADDR_LOW);
723 748
724 addrext = (ringbase & SSB_DMA_TRANSLATION_MASK)
725 >> SSB_DMA_TRANSLATION_SHIFT;
726 value = (ring->frameoffset << B43_DMA32_RXFROFF_SHIFT); 749 value = (ring->frameoffset << B43_DMA32_RXFROFF_SHIFT);
727 value |= B43_DMA32_RXENABLE; 750 value |= B43_DMA32_RXENABLE;
728 value |= (addrext << B43_DMA32_RXADDREXT_SHIFT) 751 value |= (addrext << B43_DMA32_RXADDREXT_SHIFT)
@@ -730,9 +753,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
730 if (!parity) 753 if (!parity)
731 value |= B43_DMA32_RXPARITYDISABLE; 754 value |= B43_DMA32_RXPARITYDISABLE;
732 b43_dma_write(ring, B43_DMA32_RXCTL, value); 755 b43_dma_write(ring, B43_DMA32_RXCTL, value);
733 b43_dma_write(ring, B43_DMA32_RXRING, 756 b43_dma_write(ring, B43_DMA32_RXRING, addrlo);
734 (ringbase & ~SSB_DMA_TRANSLATION_MASK)
735 | trans);
736 b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * 757 b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots *
737 sizeof(struct b43_dmadesc32)); 758 sizeof(struct b43_dmadesc32));
738 } 759 }
@@ -872,8 +893,17 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
872 ring->current_slot = -1; 893 ring->current_slot = -1;
873 } else { 894 } else {
874 if (ring->index == 0) { 895 if (ring->index == 0) {
875 ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE; 896 switch (dev->fw.hdr_format) {
876 ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET; 897 case B43_FW_HDR_598:
898 ring->rx_buffersize = B43_DMA0_RX_FW598_BUFSIZE;
899 ring->frameoffset = B43_DMA0_RX_FW598_FO;
900 break;
901 case B43_FW_HDR_410:
902 case B43_FW_HDR_351:
903 ring->rx_buffersize = B43_DMA0_RX_FW351_BUFSIZE;
904 ring->frameoffset = B43_DMA0_RX_FW351_FO;
905 break;
906 }
877 } else 907 } else
878 B43_WARN_ON(1); 908 B43_WARN_ON(1);
879 } 909 }
@@ -1066,6 +1096,25 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
1066 return 0; 1096 return 0;
1067} 1097}
1068 1098
1099/* Some hardware with 64-bit DMA seems to be bugged and looks for translation
1100 * bit in low address word instead of high one.
1101 */
1102static bool b43_dma_translation_in_low_word(struct b43_wldev *dev,
1103 enum b43_dmatype type)
1104{
1105 if (type != B43_DMA_64BIT)
1106 return 1;
1107
1108#ifdef CONFIG_B43_SSB
1109 if (dev->dev->bus_type == B43_BUS_SSB &&
1110 dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
1111 !(dev->dev->sdev->bus->host_pci->is_pcie &&
1112 ssb_read32(dev->dev->sdev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64))
1113 return 1;
1114#endif
1115 return 0;
1116}
1117
1069int b43_dma_init(struct b43_wldev *dev) 1118int b43_dma_init(struct b43_wldev *dev)
1070{ 1119{
1071 struct b43_dma *dma = &dev->dma; 1120 struct b43_dma *dma = &dev->dma;
@@ -1091,6 +1140,7 @@ int b43_dma_init(struct b43_wldev *dev)
1091 break; 1140 break;
1092#endif 1141#endif
1093 } 1142 }
1143 dma->translation_in_low = b43_dma_translation_in_low_word(dev, type);
1094 1144
1095 dma->parity = true; 1145 dma->parity = true;
1096#ifdef CONFIG_B43_BCMA 1146#ifdef CONFIG_B43_BCMA
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index cdf87094efe8..7e20b04fa51a 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -162,12 +162,15 @@ struct b43_dmadesc_generic {
162 162
163/* Misc DMA constants */ 163/* Misc DMA constants */
164#define B43_DMA_RINGMEMSIZE PAGE_SIZE 164#define B43_DMA_RINGMEMSIZE PAGE_SIZE
165#define B43_DMA0_RX_FRAMEOFFSET 30 165/* Offset of frame with actual data */
166#define B43_DMA0_RX_FW598_FO 38
167#define B43_DMA0_RX_FW351_FO 30
166 168
167/* DMA engine tuning knobs */ 169/* DMA engine tuning knobs */
168#define B43_TXRING_SLOTS 256 170#define B43_TXRING_SLOTS 256
169#define B43_RXRING_SLOTS 64 171#define B43_RXRING_SLOTS 64
170#define B43_DMA0_RX_BUFFERSIZE (B43_DMA0_RX_FRAMEOFFSET + IEEE80211_MAX_FRAME_LEN) 172#define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
173#define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
171 174
172/* Pointer poison */ 175/* Pointer poison */
173#define B43_DMA_PTR_POISON ((void *)ERR_PTR(-ENOMEM)) 176#define B43_DMA_PTR_POISON ((void *)ERR_PTR(-ENOMEM))
@@ -212,6 +215,12 @@ enum b43_dmatype {
212 B43_DMA_64BIT = 64, 215 B43_DMA_64BIT = 64,
213}; 216};
214 217
218enum b43_addrtype {
219 B43_DMA_ADDR_LOW,
220 B43_DMA_ADDR_HIGH,
221 B43_DMA_ADDR_EXT,
222};
223
215struct b43_dmaring { 224struct b43_dmaring {
216 /* Lowlevel DMA ops. */ 225 /* Lowlevel DMA ops. */
217 const struct b43_dma_ops *ops; 226 const struct b43_dma_ops *ops;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index d2661aaff50f..d2b1d1fe202b 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -66,7 +66,6 @@ MODULE_AUTHOR("Michael Buesch");
66MODULE_AUTHOR("Gábor Stefanik"); 66MODULE_AUTHOR("Gábor Stefanik");
67MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
68 68
69MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
70MODULE_FIRMWARE("b43/ucode11.fw"); 69MODULE_FIRMWARE("b43/ucode11.fw");
71MODULE_FIRMWARE("b43/ucode13.fw"); 70MODULE_FIRMWARE("b43/ucode13.fw");
72MODULE_FIRMWARE("b43/ucode14.fw"); 71MODULE_FIRMWARE("b43/ucode14.fw");
@@ -108,7 +107,7 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
108module_param_named(verbose, b43_modparam_verbose, int, 0644); 107module_param_named(verbose, b43_modparam_verbose, int, 0644);
109MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); 108MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
110 109
111static int b43_modparam_pio = B43_PIO_DEFAULT; 110static int b43_modparam_pio = 0;
112module_param_named(pio, b43_modparam_pio, int, 0644); 111module_param_named(pio, b43_modparam_pio, int, 0644);
113MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); 112MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
114 113
@@ -320,6 +319,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev);
320static int b43_wireless_core_init(struct b43_wldev *dev); 319static int b43_wireless_core_init(struct b43_wldev *dev);
321static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev); 320static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
322static int b43_wireless_core_start(struct b43_wldev *dev); 321static int b43_wireless_core_start(struct b43_wldev *dev);
322static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
323 struct ieee80211_vif *vif,
324 struct ieee80211_bss_conf *conf,
325 u32 changed);
323 326
324static int b43_ratelimit(struct b43_wl *wl) 327static int b43_ratelimit(struct b43_wl *wl)
325{ 328{
@@ -2510,6 +2513,12 @@ static int b43_upload_microcode(struct b43_wldev *dev)
2510 } 2513 }
2511 dev->fw.rev = fwrev; 2514 dev->fw.rev = fwrev;
2512 dev->fw.patch = fwpatch; 2515 dev->fw.patch = fwpatch;
2516 if (dev->fw.rev >= 598)
2517 dev->fw.hdr_format = B43_FW_HDR_598;
2518 else if (dev->fw.rev >= 410)
2519 dev->fw.hdr_format = B43_FW_HDR_410;
2520 else
2521 dev->fw.hdr_format = B43_FW_HDR_351;
2513 dev->fw.opensource = (fwdate == 0xFFFF); 2522 dev->fw.opensource = (fwdate == 0xFFFF);
2514 2523
2515 /* Default to use-all-queues. */ 2524 /* Default to use-all-queues. */
@@ -2557,7 +2566,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
2557 dev->fw.rev, dev->fw.patch); 2566 dev->fw.rev, dev->fw.patch);
2558 wiphy->hw_version = dev->dev->core_id; 2567 wiphy->hw_version = dev->dev->core_id;
2559 2568
2560 if (b43_is_old_txhdr_format(dev)) { 2569 if (dev->fw.hdr_format == B43_FW_HDR_351) {
2561 /* We're over the deadline, but we keep support for old fw 2570 /* We're over the deadline, but we keep support for old fw
2562 * until it turns out to be in major conflict with something new. */ 2571 * until it turns out to be in major conflict with something new. */
2563 b43warn(dev->wl, "You are using an old firmware image. " 2572 b43warn(dev->wl, "You are using an old firmware image. "
@@ -2943,6 +2952,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
2943 case B43_PHYTYPE_G: 2952 case B43_PHYTYPE_G:
2944 case B43_PHYTYPE_N: 2953 case B43_PHYTYPE_N:
2945 case B43_PHYTYPE_LP: 2954 case B43_PHYTYPE_LP:
2955 case B43_PHYTYPE_HT:
2946 b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1); 2956 b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
2947 b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1); 2957 b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
2948 b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1); 2958 b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
@@ -3778,14 +3788,24 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3778 struct ieee80211_conf *conf = &hw->conf; 3788 struct ieee80211_conf *conf = &hw->conf;
3779 int antenna; 3789 int antenna;
3780 int err = 0; 3790 int err = 0;
3791 bool reload_bss = false;
3781 3792
3782 mutex_lock(&wl->mutex); 3793 mutex_lock(&wl->mutex);
3783 3794
3795 dev = wl->current_dev;
3796
3784 /* Switch the band (if necessary). This might change the active core. */ 3797 /* Switch the band (if necessary). This might change the active core. */
3785 err = b43_switch_band(wl, conf->channel); 3798 err = b43_switch_band(wl, conf->channel);
3786 if (err) 3799 if (err)
3787 goto out_unlock_mutex; 3800 goto out_unlock_mutex;
3788 dev = wl->current_dev; 3801
3802 /* Need to reload all settings if the core changed */
3803 if (dev != wl->current_dev) {
3804 dev = wl->current_dev;
3805 changed = ~0;
3806 reload_bss = true;
3807 }
3808
3789 phy = &dev->phy; 3809 phy = &dev->phy;
3790 3810
3791 if (conf_is_ht(conf)) 3811 if (conf_is_ht(conf))
@@ -3846,6 +3866,9 @@ out_mac_enable:
3846out_unlock_mutex: 3866out_unlock_mutex:
3847 mutex_unlock(&wl->mutex); 3867 mutex_unlock(&wl->mutex);
3848 3868
3869 if (wl->vif && reload_bss)
3870 b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
3871
3849 return err; 3872 return err;
3850} 3873}
3851 3874
@@ -3934,7 +3957,8 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3934 if (changed & BSS_CHANGED_BEACON_INT && 3957 if (changed & BSS_CHANGED_BEACON_INT &&
3935 (b43_is_mode(wl, NL80211_IFTYPE_AP) || 3958 (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
3936 b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) || 3959 b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
3937 b43_is_mode(wl, NL80211_IFTYPE_ADHOC))) 3960 b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
3961 conf->beacon_int)
3938 b43_set_beacon_int(dev, conf->beacon_int); 3962 b43_set_beacon_int(dev, conf->beacon_int);
3939 3963
3940 if (changed & BSS_CHANGED_BASIC_RATES) 3964 if (changed & BSS_CHANGED_BASIC_RATES)
@@ -4629,8 +4653,13 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4629 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4653 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4630 4654
4631 if (b43_bus_host_is_pcmcia(dev->dev) || 4655 if (b43_bus_host_is_pcmcia(dev->dev) ||
4632 b43_bus_host_is_sdio(dev->dev) || 4656 b43_bus_host_is_sdio(dev->dev)) {
4633 dev->use_pio) { 4657 dev->__using_pio_transfers = 1;
4658 err = b43_pio_init(dev);
4659 } else if (dev->use_pio) {
4660 b43warn(dev->wl, "Forced PIO by use_pio module parameter. "
4661 "This should not be needed and will result in lower "
4662 "performance.\n");
4634 dev->__using_pio_transfers = 1; 4663 dev->__using_pio_transfers = 1;
4635 err = b43_pio_init(dev); 4664 err = b43_pio_init(dev);
4636 } else { 4665 } else {
@@ -4702,6 +4731,9 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
4702 out_mutex_unlock: 4731 out_mutex_unlock:
4703 mutex_unlock(&wl->mutex); 4732 mutex_unlock(&wl->mutex);
4704 4733
4734 if (err == 0)
4735 b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
4736
4705 return err; 4737 return err;
4706} 4738}
4707 4739
@@ -4772,6 +4804,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
4772 out_mutex_unlock: 4804 out_mutex_unlock:
4773 mutex_unlock(&wl->mutex); 4805 mutex_unlock(&wl->mutex);
4774 4806
4807 /* reload configuration */
4808 b43_op_config(hw, ~0);
4809
4775 return err; 4810 return err;
4776} 4811}
4777 4812
@@ -4928,10 +4963,18 @@ out:
4928 if (err) 4963 if (err)
4929 wl->current_dev = NULL; /* Failed to init the dev. */ 4964 wl->current_dev = NULL; /* Failed to init the dev. */
4930 mutex_unlock(&wl->mutex); 4965 mutex_unlock(&wl->mutex);
4931 if (err) 4966
4967 if (err) {
4932 b43err(wl, "Controller restart FAILED\n"); 4968 b43err(wl, "Controller restart FAILED\n");
4933 else 4969 return;
4934 b43info(wl, "Controller restarted\n"); 4970 }
4971
4972 /* reload configuration */
4973 b43_op_config(wl->hw, ~0);
4974 if (wl->vif)
4975 b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
4976
4977 b43info(wl, "Controller restarted\n");
4935} 4978}
4936 4979
4937static int b43_setup_bands(struct b43_wldev *dev, 4980static int b43_setup_bands(struct b43_wldev *dev,
@@ -5416,8 +5459,7 @@ static void b43_print_driverinfo(void)
5416 feat_sdio = "S"; 5459 feat_sdio = "S";
5417#endif 5460#endif
5418 printk(KERN_INFO "Broadcom 43xx driver loaded " 5461 printk(KERN_INFO "Broadcom 43xx driver loaded "
5419 "[ Features: %s%s%s%s%s, Firmware-ID: " 5462 "[ Features: %s%s%s%s%s ]\n",
5420 B43_SUPPORTED_FIRMWARE_ID " ]\n",
5421 feat_pci, feat_pcmcia, feat_nphy, 5463 feat_pci, feat_pcmcia, feat_nphy,
5422 feat_leds, feat_sdio); 5464 feat_leds, feat_sdio);
5423} 5465}
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 07f009ff5ee2..3ea44bb03684 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -448,6 +448,38 @@ bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
448 channel_type == NL80211_CHAN_HT40PLUS); 448 channel_type == NL80211_CHAN_HT40PLUS);
449} 449}
450 450
451/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
452void b43_phy_force_clock(struct b43_wldev *dev, bool force)
453{
454 u32 tmp;
455
456 WARN_ON(dev->phy.type != B43_PHYTYPE_N &&
457 dev->phy.type != B43_PHYTYPE_HT);
458
459 switch (dev->dev->bus_type) {
460#ifdef CONFIG_B43_BCMA
461 case B43_BUS_BCMA:
462 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
463 if (force)
464 tmp |= BCMA_IOCTL_FGC;
465 else
466 tmp &= ~BCMA_IOCTL_FGC;
467 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
468 break;
469#endif
470#ifdef CONFIG_B43_SSB
471 case B43_BUS_SSB:
472 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
473 if (force)
474 tmp |= SSB_TMSLOW_FGC;
475 else
476 tmp &= ~SSB_TMSLOW_FGC;
477 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
478 break;
479#endif
480 }
481}
482
451/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */ 483/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
452struct b43_c32 b43_cordic(int theta) 484struct b43_c32 b43_cordic(int theta)
453{ 485{
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index aa77ba612a92..9233b13fc16d 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -444,6 +444,8 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
444 444
445bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type); 445bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
446 446
447void b43_phy_force_clock(struct b43_wldev *dev, bool force);
448
447struct b43_c32 b43_cordic(int theta); 449struct b43_c32 b43_cordic(int theta);
448 450
449#endif /* LINUX_B43_PHY_COMMON_H_ */ 451#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 7c40919651a7..4d6345e8ee6b 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -152,6 +152,92 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
152} 152}
153 153
154/************************************************** 154/**************************************************
155 * Various PHY ops
156 **************************************************/
157
158static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
159{
160 u8 i, j;
161 u16 base[] = { 0x40, 0x60, 0x80 };
162
163 for (i = 0; i < ARRAY_SIZE(base); i++) {
164 for (j = 0; j < 4; j++)
165 b43_phy_write(dev, B43_PHY_EXTG(base[i] + j), 0);
166 }
167
168 for (i = 0; i < ARRAY_SIZE(base); i++)
169 b43_phy_write(dev, B43_PHY_EXTG(base[i] + 0xc), 0);
170}
171
172/* Some unknown AFE (Analog Frondned) op */
173static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
174{
175 u8 i;
176
177 const u16 ctl_regs[3][2] = {
178 { B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 },
179 { B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 },
180 { B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6},
181 };
182
183 for (i = 0; i < 3; i++) {
184 /* TODO: verify masks&sets */
185 b43_phy_set(dev, ctl_regs[i][1], 0x4);
186 b43_phy_set(dev, ctl_regs[i][0], 0x4);
187 b43_phy_mask(dev, ctl_regs[i][1], ~0x1);
188 b43_phy_set(dev, ctl_regs[i][0], 0x1);
189 b43_httab_write(dev, B43_HTTAB16(8, 5 + (i * 0x10)), 0);
190 b43_phy_mask(dev, ctl_regs[i][0], ~0x4);
191 }
192}
193
194static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
195{
196 u8 i;
197
198 u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
199 b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3);
200
201 b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq);
202 for (i = 0; i < 200; i++) {
203 if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) {
204 i = 0;
205 break;
206 }
207 msleep(1);
208 }
209 if (i)
210 b43err(dev->wl, "Forcing RF sequence timeout\n");
211
212 b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
213}
214
215static void b43_phy_ht_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
216{
217 clip_st[0] = b43_phy_read(dev, B43_PHY_HT_C1_CLIP1THRES);
218 clip_st[1] = b43_phy_read(dev, B43_PHY_HT_C2_CLIP1THRES);
219 clip_st[2] = b43_phy_read(dev, B43_PHY_HT_C3_CLIP1THRES);
220}
221
222static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
223{
224 unsigned int i;
225 u16 val;
226
227 val = 0x1E1F;
228 for (i = 0; i < 16; i++) {
229 b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
230 val -= 0x202;
231 }
232 val = 0x3E3F;
233 for (i = 0; i < 16; i++) {
234 b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val);
235 val -= 0x202;
236 }
237 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
238}
239
240/**************************************************
155 * Channel switching ops. 241 * Channel switching ops.
156 **************************************************/ 242 **************************************************/
157 243
@@ -255,8 +341,125 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
255 341
256static int b43_phy_ht_op_init(struct b43_wldev *dev) 342static int b43_phy_ht_op_init(struct b43_wldev *dev)
257{ 343{
344 u16 tmp;
345 u16 clip_state[3];
346
258 b43_phy_ht_tables_init(dev); 347 b43_phy_ht_tables_init(dev);
259 348
349 b43_phy_mask(dev, 0x0be, ~0x2);
350 b43_phy_set(dev, 0x23f, 0x7ff);
351 b43_phy_set(dev, 0x240, 0x7ff);
352 b43_phy_set(dev, 0x241, 0x7ff);
353
354 b43_phy_ht_zero_extg(dev);
355
356 b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3);
357
358 b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0);
359 b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0);
360 b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0);
361
362 b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20);
363 b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20);
364 b43_phy_write(dev, 0x20d, 0xb8);
365 b43_phy_write(dev, B43_PHY_EXTG(0x14f), 0xc8);
366 b43_phy_write(dev, 0x70, 0x50);
367 b43_phy_write(dev, 0x1ff, 0x30);
368
369 if (0) /* TODO: condition */
370 ; /* TODO: PHY op on reg 0x217 */
371
372 b43_phy_read(dev, 0xb0); /* TODO: what for? */
373 b43_phy_set(dev, 0xb0, 0x1);
374
375 b43_phy_set(dev, 0xb1, 0x91);
376 b43_phy_write(dev, 0x32f, 0x0003);
377 b43_phy_write(dev, 0x077, 0x0010);
378 b43_phy_write(dev, 0x0b4, 0x0258);
379 b43_phy_mask(dev, 0x17e, ~0x4000);
380
381 b43_phy_write(dev, 0x0b9, 0x0072);
382
383 b43_httab_write_few(dev, B43_HTTAB16(7, 0x14e), 2, 0x010f, 0x010f);
384 b43_httab_write_few(dev, B43_HTTAB16(7, 0x15e), 2, 0x010f, 0x010f);
385 b43_httab_write_few(dev, B43_HTTAB16(7, 0x16e), 2, 0x010f, 0x010f);
386
387 b43_phy_ht_afe_unk1(dev);
388
389 b43_httab_write_few(dev, B43_HTTAB16(7, 0x130), 9, 0x777, 0x111, 0x111,
390 0x777, 0x111, 0x111, 0x777, 0x111, 0x111);
391
392 b43_httab_write(dev, B43_HTTAB16(7, 0x120), 0x0777);
393 b43_httab_write(dev, B43_HTTAB16(7, 0x124), 0x0777);
394
395 b43_httab_write(dev, B43_HTTAB16(8, 0x00), 0x02);
396 b43_httab_write(dev, B43_HTTAB16(8, 0x10), 0x02);
397 b43_httab_write(dev, B43_HTTAB16(8, 0x20), 0x02);
398
399 b43_httab_write_few(dev, B43_HTTAB16(8, 0x08), 4,
400 0x8e, 0x96, 0x96, 0x96);
401 b43_httab_write_few(dev, B43_HTTAB16(8, 0x18), 4,
402 0x8f, 0x9f, 0x9f, 0x9f);
403 b43_httab_write_few(dev, B43_HTTAB16(8, 0x28), 4,
404 0x8f, 0x9f, 0x9f, 0x9f);
405
406 b43_httab_write_few(dev, B43_HTTAB16(8, 0x0c), 4, 0x2, 0x2, 0x2, 0x2);
407 b43_httab_write_few(dev, B43_HTTAB16(8, 0x1c), 4, 0x2, 0x2, 0x2, 0x2);
408 b43_httab_write_few(dev, B43_HTTAB16(8, 0x2c), 4, 0x2, 0x2, 0x2, 0x2);
409
410 b43_phy_maskset(dev, 0x0280, 0xff00, 0x3e);
411 b43_phy_maskset(dev, 0x0283, 0xff00, 0x3e);
412 b43_phy_maskset(dev, B43_PHY_OFDM(0x0141), 0xff00, 0x46);
413 b43_phy_maskset(dev, 0x0283, 0xff00, 0x40);
414
415 b43_httab_write_few(dev, B43_HTTAB16(00, 0x8), 4,
416 0x09, 0x0e, 0x13, 0x18);
417 b43_httab_write_few(dev, B43_HTTAB16(01, 0x8), 4,
418 0x09, 0x0e, 0x13, 0x18);
419 /* TODO: Did wl mean 2 instead of 40? */
420 b43_httab_write_few(dev, B43_HTTAB16(40, 0x8), 4,
421 0x09, 0x0e, 0x13, 0x18);
422
423 b43_phy_maskset(dev, B43_PHY_OFDM(0x24), 0x3f, 0xd);
424 b43_phy_maskset(dev, B43_PHY_OFDM(0x64), 0x3f, 0xd);
425 b43_phy_maskset(dev, B43_PHY_OFDM(0xa4), 0x3f, 0xd);
426
427 b43_phy_set(dev, B43_PHY_EXTG(0x060), 0x1);
428 b43_phy_set(dev, B43_PHY_EXTG(0x064), 0x1);
429 b43_phy_set(dev, B43_PHY_EXTG(0x080), 0x1);
430 b43_phy_set(dev, B43_PHY_EXTG(0x084), 0x1);
431
432 /* Copy some tables entries */
433 tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x144));
434 b43_httab_write(dev, B43_HTTAB16(7, 0x14a), tmp);
435 tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x154));
436 b43_httab_write(dev, B43_HTTAB16(7, 0x15a), tmp);
437 tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x164));
438 b43_httab_write(dev, B43_HTTAB16(7, 0x16a), tmp);
439
440 /* Reset CCA */
441 b43_phy_force_clock(dev, true);
442 tmp = b43_phy_read(dev, B43_PHY_HT_BBCFG);
443 b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp | B43_PHY_HT_BBCFG_RSTCCA);
444 b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp & ~B43_PHY_HT_BBCFG_RSTCCA);
445 b43_phy_force_clock(dev, false);
446
447 b43_mac_phy_clock_set(dev, true);
448
449 b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX);
450 b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
451
452 /* TODO: PHY op on reg 0xb0 */
453
454 /* TODO: Should we restore it? Or store it in global PHY info? */
455 b43_phy_ht_read_clip_detection(dev, clip_state);
456
457 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
458 b43_phy_ht_bphy_init(dev);
459
460 b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0),
461 B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late);
462
260 return 0; 463 return 0;
261} 464}
262 465
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 7ad7affc8df0..6544c4293b34 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -4,7 +4,11 @@
4#include "phy_common.h" 4#include "phy_common.h"
5 5
6 6
7#define B43_PHY_HT_BBCFG 0x001 /* BB config */
8#define B43_PHY_HT_BBCFG_RSTCCA 0x4000 /* Reset CCA */
9#define B43_PHY_HT_BBCFG_RSTRX 0x8000 /* Reset RX */
7#define B43_PHY_HT_BANDCTL 0x009 /* Band control */ 10#define B43_PHY_HT_BANDCTL 0x009 /* Band control */
11#define B43_PHY_HT_BANDCTL_5GHZ 0x0001 /* Use the 5GHz band */
8#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */ 12#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */
9#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */ 13#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */
10#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */ 14#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */
@@ -15,6 +19,21 @@
15#define B43_PHY_HT_BW5 0x1D2 19#define B43_PHY_HT_BW5 0x1D2
16#define B43_PHY_HT_BW6 0x1D3 20#define B43_PHY_HT_BW6 0x1D3
17 21
22#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E)
23#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E)
24#define B43_PHY_HT_C3_CLIP1THRES B43_PHY_OFDM(0x08E)
25
26#define B43_PHY_HT_RF_SEQ_MODE B43_PHY_EXTG(0x000)
27#define B43_PHY_HT_RF_SEQ_TRIG B43_PHY_EXTG(0x003)
28#define B43_PHY_HT_RF_SEQ_TRIG_RX2TX 0x0001 /* RX2TX */
29#define B43_PHY_HT_RF_SEQ_TRIG_TX2RX 0x0002 /* TX2RX */
30#define B43_PHY_HT_RF_SEQ_TRIG_UPGH 0x0004 /* Update gain H */
31#define B43_PHY_HT_RF_SEQ_TRIG_UPGL 0x0008 /* Update gain L */
32#define B43_PHY_HT_RF_SEQ_TRIG_UPGU 0x0010 /* Update gain U */
33#define B43_PHY_HT_RF_SEQ_TRIG_RST2RX 0x0020 /* Reset to RX */
34#define B43_PHY_HT_RF_SEQ_STATUS B43_PHY_EXTG(0x004)
35/* Values for the status are the same as for the trigger */
36
18#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) 37#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)
19 38
20#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110) 39#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110)
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index 9f7dbbd5ced6..4b2cd6d24ce9 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -28,25 +28,232 @@
28#include "main.h" 28#include "main.h"
29 29
30/************************************************** 30/**************************************************
31 * Radio 2064.
32 **************************************************/
33
34static void b43_radio_2064_init(struct b43_wldev *dev)
35{
36 b43_radio_write(dev, 0x09c, 0x0020);
37 b43_radio_write(dev, 0x105, 0x0008);
38 b43_radio_write(dev, 0x032, 0x0062);
39 b43_radio_write(dev, 0x033, 0x0019);
40 b43_radio_write(dev, 0x090, 0x0010);
41 b43_radio_write(dev, 0x010, 0x0000);
42 b43_radio_write(dev, 0x060, 0x007f);
43 b43_radio_write(dev, 0x061, 0x0072);
44 b43_radio_write(dev, 0x062, 0x007f);
45 b43_radio_write(dev, 0x01d, 0x0002);
46 b43_radio_write(dev, 0x01e, 0x0006);
47
48 b43_phy_write(dev, 0x4ea, 0x4688);
49 b43_phy_maskset(dev, 0x4eb, ~0x7, 0x2);
50 b43_phy_mask(dev, 0x4eb, ~0x01c0);
51 b43_phy_maskset(dev, 0x4eb, 0xff00, 0x19);
52
53 b43_lcntab_write(dev, B43_LCNTAB16(0x00, 0x55), 0);
54
55 b43_radio_mask(dev, 0x05b, (u16) ~0xff02);
56 b43_radio_set(dev, 0x004, 0x40);
57 b43_radio_set(dev, 0x120, 0x10);
58 b43_radio_set(dev, 0x078, 0x80);
59 b43_radio_set(dev, 0x129, 0x2);
60 b43_radio_set(dev, 0x057, 0x1);
61 b43_radio_set(dev, 0x05b, 0x2);
62
63 /* TODO: wait for some bit to be set */
64 b43_radio_read(dev, 0x05c);
65
66 b43_radio_mask(dev, 0x05b, (u16) ~0xff02);
67 b43_radio_mask(dev, 0x057, (u16) ~0xff01);
68
69 b43_phy_write(dev, 0x933, 0x2d6b);
70 b43_phy_write(dev, 0x934, 0x2d6b);
71 b43_phy_write(dev, 0x935, 0x2d6b);
72 b43_phy_write(dev, 0x936, 0x2d6b);
73 b43_phy_write(dev, 0x937, 0x016b);
74
75 b43_radio_mask(dev, 0x057, (u16) ~0xff02);
76 b43_radio_write(dev, 0x0c2, 0x006f);
77}
78
79/**************************************************
80 * Various PHY ops
81 **************************************************/
82
83static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev)
84{
85 u16 afe_ctl2 = b43_phy_read(dev, B43_PHY_LCN_AFE_CTL2);
86 u16 afe_ctl1 = b43_phy_read(dev, B43_PHY_LCN_AFE_CTL1);
87
88 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL2, afe_ctl2 | 0x1);
89 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1 | 0x1);
90
91 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL2, afe_ctl2 & ~0x1);
92 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1 & ~0x1);
93
94 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL2, afe_ctl2);
95 b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1);
96}
97
98static void b43_phy_lcn_clean_0x18_table(struct b43_wldev *dev)
99{
100 u8 i;
101
102 for (i = 0; i < 0x80; i++)
103 b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000);
104}
105
106static void b43_phy_lcn_clear_0x07_table(struct b43_wldev *dev)
107{
108 u8 i;
109
110 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x340);
111 for (i = 0; i < 30; i++) {
112 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, 0);
113 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, 0);
114 }
115
116 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x80);
117 for (i = 0; i < 64; i++) {
118 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, 0);
119 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, 0);
120 }
121}
122
123/**************************************************
124 * Basic PHY ops.
125 **************************************************/
126
127static int b43_phy_lcn_op_allocate(struct b43_wldev *dev)
128{
129 struct b43_phy_lcn *phy_lcn;
130
131 phy_lcn = kzalloc(sizeof(*phy_lcn), GFP_KERNEL);
132 if (!phy_lcn)
133 return -ENOMEM;
134 dev->phy.lcn = phy_lcn;
135
136 return 0;
137}
138
139static void b43_phy_lcn_op_free(struct b43_wldev *dev)
140{
141 struct b43_phy *phy = &dev->phy;
142 struct b43_phy_lcn *phy_lcn = phy->lcn;
143
144 kfree(phy_lcn);
145 phy->lcn = NULL;
146}
147
148static void b43_phy_lcn_op_prepare_structs(struct b43_wldev *dev)
149{
150 struct b43_phy *phy = &dev->phy;
151 struct b43_phy_lcn *phy_lcn = phy->lcn;
152
153 memset(phy_lcn, 0, sizeof(*phy_lcn));
154}
155
156static int b43_phy_lcn_op_init(struct b43_wldev *dev)
157{
158 b43_phy_set(dev, 0x44a, 0x80);
159 b43_phy_mask(dev, 0x44a, 0x7f);
160 b43_phy_set(dev, 0x6d1, 0x80);
161 b43_phy_write(dev, 0x6d0, 0x7);
162
163 b43_phy_lcn_afe_set_unset(dev);
164
165 b43_phy_write(dev, 0x60a, 0xa0);
166 b43_phy_write(dev, 0x46a, 0x19);
167 b43_phy_maskset(dev, 0x663, 0xFF00, 0x64);
168
169 b43_phy_lcn_tables_init(dev);
170 /* TODO: various tables ops here */
171 b43_phy_lcn_clean_0x18_table(dev);
172
173 /* TODO: some ops here */
174
175 b43_phy_lcn_clear_0x07_table(dev);
176
177 if (dev->phy.radio_ver == 0x2064)
178 b43_radio_2064_init(dev);
179 else
180 B43_WARN_ON(1);
181
182 return 0;
183}
184
185static void b43_phy_lcn_op_software_rfkill(struct b43_wldev *dev,
186 bool blocked)
187{
188 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
189 b43err(dev->wl, "MAC not suspended\n");
190
191 if (blocked) {
192 b43_phy_mask(dev, B43_PHY_LCN_RF_CTL2, ~0x7c00);
193 b43_phy_set(dev, B43_PHY_LCN_RF_CTL1, 0x1f00);
194
195 b43_phy_mask(dev, B43_PHY_LCN_RF_CTL5, ~0x7f00);
196 b43_phy_mask(dev, B43_PHY_LCN_RF_CTL4, ~0x2);
197 b43_phy_set(dev, B43_PHY_LCN_RF_CTL3, 0x808);
198
199 b43_phy_mask(dev, B43_PHY_LCN_RF_CTL7, ~0x8);
200 b43_phy_set(dev, B43_PHY_LCN_RF_CTL6, 0x8);
201 } else {
202 b43_phy_mask(dev, B43_PHY_LCN_RF_CTL1, ~0x1f00);
203 b43_phy_mask(dev, B43_PHY_LCN_RF_CTL3, ~0x808);
204 b43_phy_mask(dev, B43_PHY_LCN_RF_CTL6, ~0x8);
205 }
206}
207
208static void b43_phy_lcn_op_switch_analog(struct b43_wldev *dev, bool on)
209{
210 if (on) {
211 b43_phy_mask(dev, B43_PHY_LCN_AFE_CTL1, ~0x7);
212 } else {
213 b43_phy_set(dev, B43_PHY_LCN_AFE_CTL2, 0x7);
214 b43_phy_set(dev, B43_PHY_LCN_AFE_CTL1, 0x7);
215 }
216}
217
218static unsigned int b43_phy_lcn_op_get_default_chan(struct b43_wldev *dev)
219{
220 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
221 return 1;
222 return 36;
223}
224
225static enum b43_txpwr_result
226b43_phy_lcn_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi)
227{
228 return B43_TXPWR_RES_DONE;
229}
230
231static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
232{
233}
234
235/**************************************************
31 * PHY ops struct. 236 * PHY ops struct.
32 **************************************************/ 237 **************************************************/
33 238
34const struct b43_phy_operations b43_phyops_lcn = { 239const struct b43_phy_operations b43_phyops_lcn = {
35 /*
36 .allocate = b43_phy_lcn_op_allocate, 240 .allocate = b43_phy_lcn_op_allocate,
37 .free = b43_phy_lcn_op_free, 241 .free = b43_phy_lcn_op_free,
38 .prepare_structs = b43_phy_lcn_op_prepare_structs, 242 .prepare_structs = b43_phy_lcn_op_prepare_structs,
39 .init = b43_phy_lcn_op_init, 243 .init = b43_phy_lcn_op_init,
244 /*
40 .phy_read = b43_phy_lcn_op_read, 245 .phy_read = b43_phy_lcn_op_read,
41 .phy_write = b43_phy_lcn_op_write, 246 .phy_write = b43_phy_lcn_op_write,
42 .phy_maskset = b43_phy_lcn_op_maskset, 247 .phy_maskset = b43_phy_lcn_op_maskset,
43 .radio_read = b43_phy_lcn_op_radio_read, 248 .radio_read = b43_phy_lcn_op_radio_read,
44 .radio_write = b43_phy_lcn_op_radio_write, 249 .radio_write = b43_phy_lcn_op_radio_write,
250 */
45 .software_rfkill = b43_phy_lcn_op_software_rfkill, 251 .software_rfkill = b43_phy_lcn_op_software_rfkill,
46 .switch_analog = b43_phy_lcn_op_switch_analog, 252 .switch_analog = b43_phy_lcn_op_switch_analog,
253 /*
47 .switch_channel = b43_phy_lcn_op_switch_channel, 254 .switch_channel = b43_phy_lcn_op_switch_channel,
255 */
48 .get_default_chan = b43_phy_lcn_op_get_default_chan, 256 .get_default_chan = b43_phy_lcn_op_get_default_chan,
49 .recalc_txpower = b43_phy_lcn_op_recalc_txpower, 257 .recalc_txpower = b43_phy_lcn_op_recalc_txpower,
50 .adjust_txpower = b43_phy_lcn_op_adjust_txpower, 258 .adjust_txpower = b43_phy_lcn_op_adjust_txpower,
51 */
52}; 259};
diff --git a/drivers/net/wireless/b43/phy_lcn.h b/drivers/net/wireless/b43/phy_lcn.h
index c046c2a6cab4..25f06e8d4531 100644
--- a/drivers/net/wireless/b43/phy_lcn.h
+++ b/drivers/net/wireless/b43/phy_lcn.h
@@ -4,6 +4,20 @@
4#include "phy_common.h" 4#include "phy_common.h"
5 5
6 6
7#define B43_PHY_LCN_AFE_CTL1 B43_PHY_OFDM(0x03B)
8#define B43_PHY_LCN_AFE_CTL2 B43_PHY_OFDM(0x03C)
9#define B43_PHY_LCN_RF_CTL1 B43_PHY_OFDM(0x04C)
10#define B43_PHY_LCN_RF_CTL2 B43_PHY_OFDM(0x04D)
11#define B43_PHY_LCN_TABLE_ADDR B43_PHY_OFDM(0x055) /* Table address */
12#define B43_PHY_LCN_TABLE_DATALO B43_PHY_OFDM(0x056) /* Table data low */
13#define B43_PHY_LCN_TABLE_DATAHI B43_PHY_OFDM(0x057) /* Table data high */
14#define B43_PHY_LCN_RF_CTL3 B43_PHY_OFDM(0x0B0)
15#define B43_PHY_LCN_RF_CTL4 B43_PHY_OFDM(0x0B1)
16#define B43_PHY_LCN_RF_CTL5 B43_PHY_OFDM(0x0B7)
17#define B43_PHY_LCN_RF_CTL6 B43_PHY_OFDM(0x0F9)
18#define B43_PHY_LCN_RF_CTL7 B43_PHY_OFDM(0x0FA)
19
20
7struct b43_phy_lcn { 21struct b43_phy_lcn {
8}; 22};
9 23
@@ -11,4 +25,4 @@ struct b43_phy_lcn {
11struct b43_phy_operations; 25struct b43_phy_operations;
12extern const struct b43_phy_operations b43_phyops_lcn; 26extern const struct b43_phy_operations b43_phyops_lcn;
13 27
14#endif /* B43_PHY_LCN_H_ */ \ No newline at end of file 28#endif /* B43_PHY_LCN_H_ */
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 3b46360da99b..2eadadf5f4fc 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -600,49 +600,17 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
600 } 600 }
601} 601}
602 602
603/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
604static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
605{
606 u32 tmp;
607
608 if (dev->phy.type != B43_PHYTYPE_N)
609 return;
610
611 switch (dev->dev->bus_type) {
612#ifdef CONFIG_B43_BCMA
613 case B43_BUS_BCMA:
614 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
615 if (force)
616 tmp |= BCMA_IOCTL_FGC;
617 else
618 tmp &= ~BCMA_IOCTL_FGC;
619 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
620 break;
621#endif
622#ifdef CONFIG_B43_SSB
623 case B43_BUS_SSB:
624 tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
625 if (force)
626 tmp |= SSB_TMSLOW_FGC;
627 else
628 tmp &= ~SSB_TMSLOW_FGC;
629 ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
630 break;
631#endif
632 }
633}
634
635/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ 603/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
636static void b43_nphy_reset_cca(struct b43_wldev *dev) 604static void b43_nphy_reset_cca(struct b43_wldev *dev)
637{ 605{
638 u16 bbcfg; 606 u16 bbcfg;
639 607
640 b43_nphy_bmac_clock_fgc(dev, 1); 608 b43_phy_force_clock(dev, 1);
641 bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); 609 bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
642 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA); 610 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA);
643 udelay(1); 611 udelay(1);
644 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); 612 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
645 b43_nphy_bmac_clock_fgc(dev, 0); 613 b43_phy_force_clock(dev, 0);
646 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); 614 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
647} 615}
648 616
@@ -3715,11 +3683,11 @@ int b43_phy_initn(struct b43_wldev *dev)
3715 b43_nphy_workarounds(dev); 3683 b43_nphy_workarounds(dev);
3716 3684
3717 /* Reset CCA, in init code it differs a little from standard way */ 3685 /* Reset CCA, in init code it differs a little from standard way */
3718 b43_nphy_bmac_clock_fgc(dev, 1); 3686 b43_phy_force_clock(dev, 1);
3719 tmp = b43_phy_read(dev, B43_NPHY_BBCFG); 3687 tmp = b43_phy_read(dev, B43_NPHY_BBCFG);
3720 b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA); 3688 b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA);
3721 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA); 3689 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
3722 b43_nphy_bmac_clock_fgc(dev, 0); 3690 b43_phy_force_clock(dev, 0);
3723 3691
3724 b43_mac_phy_clock_set(dev, true); 3692 b43_mac_phy_clock_set(dev, true);
3725 3693
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 6e4228c3ed1b..fcff923b3c18 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -611,7 +611,7 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q)
611 struct b43_wldev *dev = q->dev; 611 struct b43_wldev *dev = q->dev;
612 struct b43_wl *wl = dev->wl; 612 struct b43_wl *wl = dev->wl;
613 u16 len; 613 u16 len;
614 u32 macstat; 614 u32 macstat = 0;
615 unsigned int i, padding; 615 unsigned int i, padding;
616 struct sk_buff *skb; 616 struct sk_buff *skb;
617 const char *err_msg = NULL; 617 const char *err_msg = NULL;
@@ -676,7 +676,15 @@ data_ready:
676 goto rx_error; 676 goto rx_error;
677 } 677 }
678 678
679 macstat = le32_to_cpu(rxhdr->mac_status); 679 switch (dev->fw.hdr_format) {
680 case B43_FW_HDR_598:
681 macstat = le32_to_cpu(rxhdr->format_598.mac_status);
682 break;
683 case B43_FW_HDR_410:
684 case B43_FW_HDR_351:
685 macstat = le32_to_cpu(rxhdr->format_351.mac_status);
686 break;
687 }
680 if (macstat & B43_RX_MAC_FCSERR) { 688 if (macstat & B43_RX_MAC_FCSERR) {
681 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { 689 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
682 /* Drop frames with failed FCS. */ 690 /* Drop frames with failed FCS. */
diff --git a/drivers/net/wireless/b43/tables_phy_ht.c b/drivers/net/wireless/b43/tables_phy_ht.c
index 603938657b15..677d217b5fb3 100644
--- a/drivers/net/wireless/b43/tables_phy_ht.c
+++ b/drivers/net/wireless/b43/tables_phy_ht.c
@@ -574,6 +574,42 @@ static const u32 b43_httab_0x24[] = {
574 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c, 574 0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c,
575}; 575};
576 576
577/* Some late-init table */
578const u32 b43_httab_0x1a_0xc0_late[] = {
579 0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
580 0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
581 0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
582 0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
583 0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
584 0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
585 0x10390038, 0x10390035, 0x1031003a, 0x10310036,
586 0x10310033, 0x1029003a, 0x10290037, 0x10290034,
587 0x10290031, 0x10210039, 0x10210036, 0x10210033,
588 0x10210030, 0x1019003c, 0x10190039, 0x10190036,
589 0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
590 0x10190028, 0x1011003a, 0x10110036, 0x10110033,
591 0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
592 0x10110027, 0x10110024, 0x10110022, 0x10110020,
593 0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
594 0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
595 0x10090029, 0x10090027, 0x10090025, 0x10090023,
596 0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
597 0x1009001a, 0x10090018, 0x10090017, 0x10090016,
598 0x10090015, 0x10090013, 0x10090012, 0x10090011,
599 0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
600 0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
601 0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
602 0x10090008, 0x10090008, 0x10090007, 0x10090007,
603 0x10090007, 0x10090006, 0x10090006, 0x10090005,
604 0x10090005, 0x10090005, 0x10090005, 0x10090004,
605 0x10090004, 0x10090004, 0x10090004, 0x10090003,
606 0x10090003, 0x10090003, 0x10090003, 0x10090003,
607 0x10090003, 0x10090002, 0x10090002, 0x10090002,
608 0x10090002, 0x10090002, 0x10090002, 0x10090002,
609 0x10090002, 0x10090002, 0x10090001, 0x10090001,
610 0x10090001, 0x10090001, 0x10090001, 0x10090001,
611};
612
577/************************************************** 613/**************************************************
578 * R/W ops. 614 * R/W ops.
579 **************************************************/ 615 **************************************************/
@@ -674,6 +710,51 @@ void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value)
674 return; 710 return;
675} 711}
676 712
713void b43_httab_write_few(struct b43_wldev *dev, u32 offset, size_t num, ...)
714{
715 va_list args;
716 u32 type, value;
717 unsigned int i;
718
719 type = offset & B43_HTTAB_TYPEMASK;
720 offset &= 0xFFFF;
721
722 va_start(args, num);
723 switch (type) {
724 case B43_HTTAB_8BIT:
725 b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
726 for (i = 0; i < num; i++) {
727 value = va_arg(args, int);
728 B43_WARN_ON(value & ~0xFF);
729 b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value);
730 }
731 break;
732 case B43_HTTAB_16BIT:
733 b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
734 for (i = 0; i < num; i++) {
735 value = va_arg(args, int);
736 B43_WARN_ON(value & ~0xFFFF);
737 b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value);
738 }
739 break;
740 case B43_HTTAB_32BIT:
741 b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
742 for (i = 0; i < num; i++) {
743 value = va_arg(args, int);
744 b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI,
745 value >> 16);
746 b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO,
747 value & 0xFFFF);
748 }
749 break;
750 default:
751 B43_WARN_ON(1);
752 }
753 va_end(args);
754
755 return;
756}
757
677void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, 758void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset,
678 unsigned int nr_elements, const void *_data) 759 unsigned int nr_elements, const void *_data)
679{ 760{
@@ -723,6 +804,9 @@ void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset,
723 } while (0) 804 } while (0)
724void b43_phy_ht_tables_init(struct b43_wldev *dev) 805void b43_phy_ht_tables_init(struct b43_wldev *dev)
725{ 806{
807 BUILD_BUG_ON(ARRAY_SIZE(b43_httab_0x1a_0xc0_late) !=
808 B43_HTTAB_1A_C0_LATE_SIZE);
809
726 httab_upload(dev, B43_HTTAB16(0x12, 0), b43_httab_0x12); 810 httab_upload(dev, B43_HTTAB16(0x12, 0), b43_httab_0x12);
727 httab_upload(dev, B43_HTTAB16(0x27, 0), b43_httab_0x27); 811 httab_upload(dev, B43_HTTAB16(0x27, 0), b43_httab_0x27);
728 httab_upload(dev, B43_HTTAB16(0x26, 0), b43_httab_0x26); 812 httab_upload(dev, B43_HTTAB16(0x26, 0), b43_httab_0x26);
diff --git a/drivers/net/wireless/b43/tables_phy_ht.h b/drivers/net/wireless/b43/tables_phy_ht.h
index ea3be382c894..1b5ef2bc770c 100644
--- a/drivers/net/wireless/b43/tables_phy_ht.h
+++ b/drivers/net/wireless/b43/tables_phy_ht.h
@@ -14,9 +14,13 @@ u32 b43_httab_read(struct b43_wldev *dev, u32 offset);
14void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset, 14void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset,
15 unsigned int nr_elements, void *_data); 15 unsigned int nr_elements, void *_data);
16void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value); 16void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value);
17void b43_httab_write_few(struct b43_wldev *dev, u32 offset, size_t num, ...);
17void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, 18void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset,
18 unsigned int nr_elements, const void *_data); 19 unsigned int nr_elements, const void *_data);
19 20
20void b43_phy_ht_tables_init(struct b43_wldev *dev); 21void b43_phy_ht_tables_init(struct b43_wldev *dev);
21 22
23#define B43_HTTAB_1A_C0_LATE_SIZE 128
24extern const u32 b43_httab_0x1a_0xc0_late[];
25
22#endif /* B43_TABLES_PHY_HT_H_ */ 26#endif /* B43_TABLES_PHY_HT_H_ */
diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c
index 40c1d0915dd3..0a5842808a78 100644
--- a/drivers/net/wireless/b43/tables_phy_lcn.c
+++ b/drivers/net/wireless/b43/tables_phy_lcn.c
@@ -25,10 +25,442 @@
25#include "phy_common.h" 25#include "phy_common.h"
26#include "phy_lcn.h" 26#include "phy_lcn.h"
27 27
28static const u16 b43_lcntab_0x02[] = {
29 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
30 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
31 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
32 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
33 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
34 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
35 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
36 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
37 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
38 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
39 0x014d, 0x014d, 0x014d, 0x014d,
40};
41
42static const u16 b43_lcntab_0x01[] = {
43 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
44 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
45 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
46 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
47 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
48 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
49 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
50 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
51 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
52 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
53 0x0000, 0x0000, 0x0000, 0x0000,
54};
55
56static const u32 b43_lcntab_0x0b[] = {
57 0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb,
58 0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb,
59 0x0001fea3, 0x0000024b,
60};
61
62static const u32 b43_lcntab_0x0c[] = {
63 0x00100001, 0x00200010, 0x00300001, 0x00400010,
64 0x00500022, 0x00600122, 0x00700222, 0x00800322,
65 0x00900422, 0x00a00522, 0x00b00622, 0x00c00722,
66 0x00d00822, 0x00f00922, 0x00100a22, 0x00200b22,
67 0x00300c22, 0x00400d22, 0x00500e22, 0x00600f22,
68};
69
70static const u32 b43_lcntab_0x0d[] = {
71 0x00000000, 0x00000000, 0x10000000, 0x00000000,
72 0x20000000, 0x00000000, 0x30000000, 0x00000000,
73 0x40000000, 0x00000000, 0x50000000, 0x00000000,
74 0x60000000, 0x00000000, 0x70000000, 0x00000000,
75 0x80000000, 0x00000000, 0x90000000, 0x00000008,
76 0xa0000000, 0x00000008, 0xb0000000, 0x00000008,
77 0xc0000000, 0x00000008, 0xd0000000, 0x00000008,
78 0xe0000000, 0x00000008, 0xf0000000, 0x00000008,
79 0x00000000, 0x00000009, 0x10000000, 0x00000009,
80 0x20000000, 0x00000019, 0x30000000, 0x00000019,
81 0x40000000, 0x00000019, 0x50000000, 0x00000019,
82 0x60000000, 0x00000019, 0x70000000, 0x00000019,
83 0x80000000, 0x00000019, 0x90000000, 0x00000019,
84 0xa0000000, 0x00000019, 0xb0000000, 0x00000019,
85 0xc0000000, 0x00000019, 0xd0000000, 0x00000019,
86 0xe0000000, 0x00000019, 0xf0000000, 0x00000019,
87 0x00000000, 0x0000001a, 0x10000000, 0x0000001a,
88 0x20000000, 0x0000001a, 0x30000000, 0x0000001a,
89 0x40000000, 0x0000001a, 0x50000000, 0x00000002,
90 0x60000000, 0x00000002, 0x70000000, 0x00000002,
91 0x80000000, 0x00000002, 0x90000000, 0x00000002,
92 0xa0000000, 0x00000002, 0xb0000000, 0x00000002,
93 0xc0000000, 0x0000000a, 0xd0000000, 0x0000000a,
94 0xe0000000, 0x0000000a, 0xf0000000, 0x0000000a,
95 0x00000000, 0x0000000b, 0x10000000, 0x0000000b,
96 0x20000000, 0x0000000b, 0x30000000, 0x0000000b,
97 0x40000000, 0x0000000b, 0x50000000, 0x0000001b,
98 0x60000000, 0x0000001b, 0x70000000, 0x0000001b,
99 0x80000000, 0x0000001b, 0x90000000, 0x0000001b,
100 0xa0000000, 0x0000001b, 0xb0000000, 0x0000001b,
101 0xc0000000, 0x0000001b, 0xd0000000, 0x0000001b,
102 0xe0000000, 0x0000001b, 0xf0000000, 0x0000001b,
103 0x00000000, 0x0000001c, 0x10000000, 0x0000001c,
104 0x20000000, 0x0000001c, 0x30000000, 0x0000001c,
105 0x40000000, 0x0000001c, 0x50000000, 0x0000001c,
106 0x60000000, 0x0000001c, 0x70000000, 0x0000001c,
107 0x80000000, 0x0000001c, 0x90000000, 0x0000001c,
108};
109
110static const u16 b43_lcntab_0x0e[] = {
111 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
112 0x0407, 0x0408, 0x0409, 0x040a, 0x058b, 0x058c,
113 0x058d, 0x058e, 0x058f, 0x0090, 0x0091, 0x0092,
114 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198,
115 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e,
116 0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4,
117 0x01a5, 0x0000,
118};
119
120static const u16 b43_lcntab_0x0f[] = {
121 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
122 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
123 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
124 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
125 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
126 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
127 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
128 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
129 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
130 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
131 0x000a, 0x0009, 0x0006, 0x0005,
132};
133
134static const u16 b43_lcntab_0x10[] = {
135 0x005f, 0x0036, 0x0029, 0x001f, 0x005f, 0x0036,
136 0x0029, 0x001f, 0x005f, 0x0036, 0x0029, 0x001f,
137 0x005f, 0x0036, 0x0029, 0x001f,
138};
139
140static const u16 b43_lcntab_0x11[] = {
141 0x0009, 0x000f, 0x0014, 0x0018, 0x00fe, 0x0007,
142 0x000b, 0x000f, 0x00fb, 0x00fe, 0x0001, 0x0005,
143 0x0008, 0x000b, 0x000e, 0x0011, 0x0014, 0x0017,
144 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
145 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f,
146 0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
147 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003,
148 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015,
149 0x0018, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000,
150 0x0000, 0x0000, 0x0003, 0x00eb, 0x0000, 0x0000,
151};
152
153static const u32 b43_lcntab_0x12[] = {
154 0x00000000, 0x00000000, 0x00000000, 0x00000000,
155 0x00000000, 0x00000000, 0x00000000, 0x00000000,
156 0x00000004, 0x00000000, 0x00000004, 0x00000008,
157 0x00000001, 0x00000005, 0x00000009, 0x0000000d,
158 0x0000004d, 0x0000008d, 0x0000000d, 0x0000004d,
159 0x0000008d, 0x000000cd, 0x0000004f, 0x0000008f,
160 0x000000cf, 0x000000d3, 0x00000113, 0x00000513,
161 0x00000913, 0x00000953, 0x00000d53, 0x00001153,
162 0x00001193, 0x00005193, 0x00009193, 0x0000d193,
163 0x00011193, 0x00000000, 0x00000000, 0x00000000,
164 0x00000000, 0x00000000, 0x00000000, 0x00000004,
165 0x00000000, 0x00000004, 0x00000008, 0x00000001,
166 0x00000005, 0x00000009, 0x0000000d, 0x0000004d,
167 0x0000008d, 0x0000000d, 0x0000004d, 0x0000008d,
168 0x000000cd, 0x0000004f, 0x0000008f, 0x000000cf,
169 0x000000d3, 0x00000113, 0x00000513, 0x00000913,
170 0x00000953, 0x00000d53, 0x00001153, 0x00005153,
171 0x00009153, 0x0000d153, 0x00011153, 0x00015153,
172 0x00019153, 0x0001d153, 0x00000000, 0x00000000,
173 0x00000000, 0x00000000, 0x00000000, 0x00000000,
174 0x00000000, 0x00000000, 0x00000000, 0x00000000,
175 0x00000000, 0x00000000, 0x00000000, 0x00000000,
176 0x00000000, 0x00000000, 0x00000000, 0x00000000,
177 0x00000000, 0x00000000, 0x00000000, 0x00000000,
178};
179
180static const u16 b43_lcntab_0x14[] = {
181 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
182 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
183 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
184 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
185 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
186 0x0002, 0x0003, 0x0001, 0x0003, 0x0002, 0x0001,
187 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
188 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
189 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
190 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
191 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
192 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
193 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
194 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
195 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
196 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003,
197 0x0001, 0x0003, 0x0002, 0x0001, 0x0001, 0x0001,
198 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
199 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
200 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
201 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
202 0x0001, 0x0001,
203};
204
205static const u16 b43_lcntab_0x17[] = {
206 0x001a, 0x0034, 0x004e, 0x0068, 0x009c, 0x00d0,
207 0x00ea, 0x0104, 0x0034, 0x0068, 0x009c, 0x00d0,
208 0x0138, 0x01a0, 0x01d4, 0x0208, 0x004e, 0x009c,
209 0x00ea, 0x0138, 0x01d4, 0x0270, 0x02be, 0x030c,
210 0x0068, 0x00d0, 0x0138, 0x01a0, 0x0270, 0x0340,
211 0x03a8, 0x0410, 0x0018, 0x009c, 0x00d0, 0x0104,
212 0x00ea, 0x0138, 0x0186, 0x00d0, 0x0104, 0x0104,
213 0x0138, 0x016c, 0x016c, 0x01a0, 0x0138, 0x0186,
214 0x0186, 0x01d4, 0x0222, 0x0222, 0x0270, 0x0104,
215 0x0138, 0x016c, 0x0138, 0x016c, 0x01a0, 0x01d4,
216 0x01a0, 0x01d4, 0x0208, 0x0208, 0x023c, 0x0186,
217 0x01d4, 0x0222, 0x01d4, 0x0222, 0x0270, 0x02be,
218 0x0270, 0x02be, 0x030c, 0x030c, 0x035a, 0x0036,
219 0x006c, 0x00a2, 0x00d8, 0x0144, 0x01b0, 0x01e6,
220 0x021c, 0x006c, 0x00d8, 0x0144, 0x01b0, 0x0288,
221 0x0360, 0x03cc, 0x0438, 0x00a2, 0x0144, 0x01e6,
222 0x0288, 0x03cc, 0x0510, 0x05b2, 0x0654, 0x00d8,
223 0x01b0, 0x0288, 0x0360, 0x0510, 0x06c0, 0x0798,
224 0x0870, 0x0018, 0x0144, 0x01b0, 0x021c, 0x01e6,
225 0x0288, 0x032a, 0x01b0, 0x021c, 0x021c, 0x0288,
226 0x02f4, 0x02f4, 0x0360, 0x0288, 0x032a, 0x032a,
227 0x03cc, 0x046e, 0x046e, 0x0510, 0x021c, 0x0288,
228 0x02f4, 0x0288, 0x02f4, 0x0360, 0x03cc, 0x0360,
229 0x03cc, 0x0438, 0x0438, 0x04a4, 0x032a, 0x03cc,
230 0x046e, 0x03cc, 0x046e, 0x0510, 0x05b2, 0x0510,
231 0x05b2, 0x0654, 0x0654, 0x06f6,
232};
233
234static const u16 b43_lcntab_0x00[] = {
235 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00,
236 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005,
237 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
238 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
239 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
240 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
241 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003,
242 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007,
243 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
244 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
245 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
246 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
247 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
248 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
249 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
250 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
251 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
252 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
253};
254
255static const u32 b43_lcntab_0x18[] = {
256 0x00080000, 0x00080000, 0x00080000, 0x00080000,
257 0x00080000, 0x00080000, 0x00080000, 0x00080000,
258 0x00080000, 0x00080000, 0x00080000, 0x00080000,
259 0x00080000, 0x00080000, 0x00080000, 0x00080000,
260 0x00080000, 0x00080000, 0x00080000, 0x00080000,
261 0x00080000, 0x00080000, 0x00080000, 0x00080000,
262 0x00080000, 0x00080000, 0x00080000, 0x00080000,
263 0x00080000, 0x00080000, 0x00080000, 0x00080000,
264 0x00080000, 0x00080000, 0x00080000, 0x00080000,
265 0x00080000, 0x00080000, 0x00080000, 0x00080000,
266 0x00080000, 0x00080000, 0x00080000, 0x00080000,
267 0x00080000, 0x00080000, 0x00080000, 0x00080000,
268 0x00080000, 0x00080000, 0x00080000, 0x00080000,
269 0x00080000, 0x00080000, 0x00080000, 0x00080000,
270 0x00080000, 0x00080000, 0x00080000, 0x00080000,
271 0x00080000, 0x00080000, 0x00080000, 0x00080000,
272 0x00080000, 0x00080000, 0x00080000, 0x00080000,
273 0x00080000, 0x00080000, 0x00080000, 0x00080000,
274 0x00080000, 0x00080000, 0x00080000, 0x00080000,
275 0x00080000, 0x00080000, 0x00080000, 0x00080000,
276 0x00080000, 0x00080000, 0x00080000, 0x00080000,
277 0x00080000, 0x00080000, 0x00080000, 0x00080000,
278 0x00080000, 0x00080000, 0x00080000, 0x00080000,
279 0x00080000, 0x00080000, 0x00080000, 0x00080000,
280 0x00080000, 0x00080000, 0x00080000, 0x00080000,
281 0x00080000, 0x00080000, 0x00080000, 0x00080000,
282 0x00080000, 0x00080000, 0x00080000, 0x00080000,
283 0x00080000, 0x00080000, 0x00080000, 0x00080000,
284 0x00080000, 0x00080000, 0x00080000, 0x00080000,
285 0x00080000, 0x00080000, 0x00080000, 0x00080000,
286 0x00080000, 0x00080000, 0x00080000, 0x00080000,
287 0x00080000, 0x00080000, 0x00080000, 0x00080000,
288 0x00080000, 0x00080000, 0x00080000, 0x00080000,
289 0x00080000, 0x00080000, 0x00080000, 0x00080000,
290 0x00080000, 0x00080000, 0x00080000, 0x00080000,
291 0x00080000, 0x00080000, 0x00080000, 0x00080000,
292 0x00080000, 0x00080000, 0x00080000, 0x00080000,
293 0x00080000, 0x00080000, 0x00080000, 0x00080000,
294 0x00080000, 0x00080000, 0x00080000, 0x00080000,
295 0x00080000, 0x00080000, 0x00080000, 0x00080000,
296};
297
298/**************************************************
299 * R/W ops.
300 **************************************************/
301
302u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset)
303{
304 u32 type, value;
305
306 type = offset & B43_LCNTAB_TYPEMASK;
307 offset &= ~B43_LCNTAB_TYPEMASK;
308 B43_WARN_ON(offset > 0xFFFF);
309
310 switch (type) {
311 case B43_LCNTAB_8BIT:
312 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
313 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF;
314 break;
315 case B43_LCNTAB_16BIT:
316 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
317 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
318 break;
319 case B43_LCNTAB_32BIT:
320 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
321 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI);
322 value <<= 16;
323 value |= b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
324 break;
325 default:
326 B43_WARN_ON(1);
327 value = 0;
328 }
329
330 return value;
331}
332
333void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
334 unsigned int nr_elements, void *_data)
335{
336 u32 type;
337 u8 *data = _data;
338 unsigned int i;
339
340 type = offset & B43_LCNTAB_TYPEMASK;
341 offset &= ~B43_LCNTAB_TYPEMASK;
342 B43_WARN_ON(offset > 0xFFFF);
343
344 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
345
346 for (i = 0; i < nr_elements; i++) {
347 switch (type) {
348 case B43_LCNTAB_8BIT:
349 *data = b43_phy_read(dev,
350 B43_PHY_LCN_TABLE_DATALO) & 0xFF;
351 data++;
352 break;
353 case B43_LCNTAB_16BIT:
354 *((u16 *)data) = b43_phy_read(dev,
355 B43_PHY_LCN_TABLE_DATALO);
356 data += 2;
357 break;
358 case B43_LCNTAB_32BIT:
359 *((u32 *)data) = b43_phy_read(dev,
360 B43_PHY_LCN_TABLE_DATAHI);
361 *((u32 *)data) <<= 16;
362 *((u32 *)data) |= b43_phy_read(dev,
363 B43_PHY_LCN_TABLE_DATALO);
364 data += 4;
365 break;
366 default:
367 B43_WARN_ON(1);
368 }
369 }
370}
371
372void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value)
373{
374 u32 type;
375
376 type = offset & B43_LCNTAB_TYPEMASK;
377 offset &= 0xFFFF;
378
379 switch (type) {
380 case B43_LCNTAB_8BIT:
381 B43_WARN_ON(value & ~0xFF);
382 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
383 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
384 break;
385 case B43_LCNTAB_16BIT:
386 B43_WARN_ON(value & ~0xFFFF);
387 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
388 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
389 break;
390 case B43_LCNTAB_32BIT:
391 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
392 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, value >> 16);
393 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value & 0xFFFF);
394 break;
395 default:
396 B43_WARN_ON(1);
397 }
398
399 return;
400}
401
402void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset,
403 unsigned int nr_elements, const void *_data)
404{
405 u32 type, value;
406 const u8 *data = _data;
407 unsigned int i;
408
409 type = offset & B43_LCNTAB_TYPEMASK;
410 offset &= ~B43_LCNTAB_TYPEMASK;
411 B43_WARN_ON(offset > 0xFFFF);
412
413 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
414
415 for (i = 0; i < nr_elements; i++) {
416 switch (type) {
417 case B43_LCNTAB_8BIT:
418 value = *data;
419 data++;
420 B43_WARN_ON(value & ~0xFF);
421 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
422 break;
423 case B43_LCNTAB_16BIT:
424 value = *((u16 *)data);
425 data += 2;
426 B43_WARN_ON(value & ~0xFFFF);
427 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
428 break;
429 case B43_LCNTAB_32BIT:
430 value = *((u32 *)data);
431 data += 4;
432 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI,
433 value >> 16);
434 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO,
435 value & 0xFFFF);
436 break;
437 default:
438 B43_WARN_ON(1);
439 }
440 }
441}
442
28/************************************************** 443/**************************************************
29 * Tables ops. 444 * Tables ops.
30 **************************************************/ 445 **************************************************/
31 446
447#define lcntab_upload(dev, offset, data) do { \
448 b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
449 } while (0)
32void b43_phy_lcn_tables_init(struct b43_wldev *dev) 450void b43_phy_lcn_tables_init(struct b43_wldev *dev)
33{ 451{
452 lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02);
453 lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01);
454 lcntab_upload(dev, B43_LCNTAB32(0x0b, 0), b43_lcntab_0x0b);
455 lcntab_upload(dev, B43_LCNTAB32(0x0c, 0), b43_lcntab_0x0c);
456 lcntab_upload(dev, B43_LCNTAB32(0x0d, 0), b43_lcntab_0x0d);
457 lcntab_upload(dev, B43_LCNTAB16(0x0e, 0), b43_lcntab_0x0e);
458 lcntab_upload(dev, B43_LCNTAB16(0x0f, 0), b43_lcntab_0x0f);
459 lcntab_upload(dev, B43_LCNTAB16(0x10, 0), b43_lcntab_0x10);
460 lcntab_upload(dev, B43_LCNTAB16(0x11, 0), b43_lcntab_0x11);
461 lcntab_upload(dev, B43_LCNTAB32(0x12, 0), b43_lcntab_0x12);
462 lcntab_upload(dev, B43_LCNTAB16(0x14, 0), b43_lcntab_0x14);
463 lcntab_upload(dev, B43_LCNTAB16(0x17, 0), b43_lcntab_0x17);
464 lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00);
465 lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18);
34} 466}
diff --git a/drivers/net/wireless/b43/tables_phy_lcn.h b/drivers/net/wireless/b43/tables_phy_lcn.h
index 5e31b15b81ec..b6471e89c36f 100644
--- a/drivers/net/wireless/b43/tables_phy_lcn.h
+++ b/drivers/net/wireless/b43/tables_phy_lcn.h
@@ -1,6 +1,22 @@
1#ifndef B43_TABLES_PHY_LCN_H_ 1#ifndef B43_TABLES_PHY_LCN_H_
2#define B43_TABLES_PHY_LCN_H_ 2#define B43_TABLES_PHY_LCN_H_
3 3
4/* The LCN-PHY tables. */
5#define B43_LCNTAB_TYPEMASK 0xF0000000
6#define B43_LCNTAB_8BIT 0x10000000
7#define B43_LCNTAB_16BIT 0x20000000
8#define B43_LCNTAB_32BIT 0x30000000
9#define B43_LCNTAB8(table, offset) (((table) << 10) | (offset) | B43_LCNTAB_8BIT)
10#define B43_LCNTAB16(table, offset) (((table) << 10) | (offset) | B43_LCNTAB_16BIT)
11#define B43_LCNTAB32(table, offset) (((table) << 10) | (offset) | B43_LCNTAB_32BIT)
12
13u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset);
14void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
15 unsigned int nr_elements, void *_data);
16void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value);
17void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset,
18 unsigned int nr_elements, const void *_data);
19
4void b43_phy_lcn_tables_init(struct b43_wldev *dev); 20void b43_phy_lcn_tables_init(struct b43_wldev *dev);
5 21
6#endif /* B43_TABLES_PHY_LCN_H_ */ 22#endif /* B43_TABLES_PHY_LCN_H_ */
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index b74f25ec1ab4..b8de62c22479 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -337,12 +337,19 @@ int b43_generate_txhdr(struct b43_wldev *dev,
337 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); 337 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
338 } 338 }
339 } 339 }
340 if (b43_is_old_txhdr_format(dev)) { 340 switch (dev->fw.hdr_format) {
341 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp), 341 case B43_FW_HDR_598:
342 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_598.plcp),
342 plcp_fragment_len, rate); 343 plcp_fragment_len, rate);
343 } else { 344 break;
344 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->new_format.plcp), 345 case B43_FW_HDR_351:
346 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_351.plcp),
347 plcp_fragment_len, rate);
348 break;
349 case B43_FW_HDR_410:
350 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->format_410.plcp),
345 plcp_fragment_len, rate); 351 plcp_fragment_len, rate);
352 break;
346 } 353 }
347 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb), 354 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb),
348 plcp_fragment_len, rate_fb); 355 plcp_fragment_len, rate_fb);
@@ -415,10 +422,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
415 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || 422 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
416 (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { 423 (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
417 unsigned int len; 424 unsigned int len;
418 struct ieee80211_hdr *hdr; 425 struct ieee80211_hdr *uninitialized_var(hdr);
419 int rts_rate, rts_rate_fb; 426 int rts_rate, rts_rate_fb;
420 int rts_rate_ofdm, rts_rate_fb_ofdm; 427 int rts_rate_ofdm, rts_rate_fb_ofdm;
421 struct b43_plcp_hdr6 *plcp; 428 struct b43_plcp_hdr6 *uninitialized_var(plcp);
422 struct ieee80211_rate *rts_cts_rate; 429 struct ieee80211_rate *rts_cts_rate;
423 430
424 rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info); 431 rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
@@ -429,14 +436,21 @@ int b43_generate_txhdr(struct b43_wldev *dev,
429 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); 436 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
430 437
431 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 438 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
432 struct ieee80211_cts *cts; 439 struct ieee80211_cts *uninitialized_var(cts);
433 440
434 if (b43_is_old_txhdr_format(dev)) { 441 switch (dev->fw.hdr_format) {
442 case B43_FW_HDR_598:
435 cts = (struct ieee80211_cts *) 443 cts = (struct ieee80211_cts *)
436 (txhdr->old_format.rts_frame); 444 (txhdr->format_598.rts_frame);
437 } else { 445 break;
446 case B43_FW_HDR_351:
438 cts = (struct ieee80211_cts *) 447 cts = (struct ieee80211_cts *)
439 (txhdr->new_format.rts_frame); 448 (txhdr->format_351.rts_frame);
449 break;
450 case B43_FW_HDR_410:
451 cts = (struct ieee80211_cts *)
452 (txhdr->format_410.rts_frame);
453 break;
440 } 454 }
441 ieee80211_ctstoself_get(dev->wl->hw, info->control.vif, 455 ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
442 fragment_data, fragment_len, 456 fragment_data, fragment_len,
@@ -444,14 +458,21 @@ int b43_generate_txhdr(struct b43_wldev *dev,
444 mac_ctl |= B43_TXH_MAC_SENDCTS; 458 mac_ctl |= B43_TXH_MAC_SENDCTS;
445 len = sizeof(struct ieee80211_cts); 459 len = sizeof(struct ieee80211_cts);
446 } else { 460 } else {
447 struct ieee80211_rts *rts; 461 struct ieee80211_rts *uninitialized_var(rts);
448 462
449 if (b43_is_old_txhdr_format(dev)) { 463 switch (dev->fw.hdr_format) {
464 case B43_FW_HDR_598:
450 rts = (struct ieee80211_rts *) 465 rts = (struct ieee80211_rts *)
451 (txhdr->old_format.rts_frame); 466 (txhdr->format_598.rts_frame);
452 } else { 467 break;
468 case B43_FW_HDR_351:
469 rts = (struct ieee80211_rts *)
470 (txhdr->format_351.rts_frame);
471 break;
472 case B43_FW_HDR_410:
453 rts = (struct ieee80211_rts *) 473 rts = (struct ieee80211_rts *)
454 (txhdr->new_format.rts_frame); 474 (txhdr->format_410.rts_frame);
475 break;
455 } 476 }
456 ieee80211_rts_get(dev->wl->hw, info->control.vif, 477 ieee80211_rts_get(dev->wl->hw, info->control.vif,
457 fragment_data, fragment_len, 478 fragment_data, fragment_len,
@@ -462,22 +483,36 @@ int b43_generate_txhdr(struct b43_wldev *dev,
462 len += FCS_LEN; 483 len += FCS_LEN;
463 484
464 /* Generate the PLCP headers for the RTS/CTS frame */ 485 /* Generate the PLCP headers for the RTS/CTS frame */
465 if (b43_is_old_txhdr_format(dev)) 486 switch (dev->fw.hdr_format) {
466 plcp = &txhdr->old_format.rts_plcp; 487 case B43_FW_HDR_598:
467 else 488 plcp = &txhdr->format_598.rts_plcp;
468 plcp = &txhdr->new_format.rts_plcp; 489 break;
490 case B43_FW_HDR_351:
491 plcp = &txhdr->format_351.rts_plcp;
492 break;
493 case B43_FW_HDR_410:
494 plcp = &txhdr->format_410.rts_plcp;
495 break;
496 }
469 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp, 497 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
470 len, rts_rate); 498 len, rts_rate);
471 plcp = &txhdr->rts_plcp_fb; 499 plcp = &txhdr->rts_plcp_fb;
472 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp, 500 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
473 len, rts_rate_fb); 501 len, rts_rate_fb);
474 502
475 if (b43_is_old_txhdr_format(dev)) { 503 switch (dev->fw.hdr_format) {
504 case B43_FW_HDR_598:
476 hdr = (struct ieee80211_hdr *) 505 hdr = (struct ieee80211_hdr *)
477 (&txhdr->old_format.rts_frame); 506 (&txhdr->format_598.rts_frame);
478 } else { 507 break;
508 case B43_FW_HDR_351:
509 hdr = (struct ieee80211_hdr *)
510 (&txhdr->format_351.rts_frame);
511 break;
512 case B43_FW_HDR_410:
479 hdr = (struct ieee80211_hdr *) 513 hdr = (struct ieee80211_hdr *)
480 (&txhdr->new_format.rts_frame); 514 (&txhdr->format_410.rts_frame);
515 break;
481 } 516 }
482 txhdr->rts_dur_fb = hdr->duration_id; 517 txhdr->rts_dur_fb = hdr->duration_id;
483 518
@@ -505,10 +540,17 @@ int b43_generate_txhdr(struct b43_wldev *dev,
505 } 540 }
506 541
507 /* Magic cookie */ 542 /* Magic cookie */
508 if (b43_is_old_txhdr_format(dev)) 543 switch (dev->fw.hdr_format) {
509 txhdr->old_format.cookie = cpu_to_le16(cookie); 544 case B43_FW_HDR_598:
510 else 545 txhdr->format_598.cookie = cpu_to_le16(cookie);
511 txhdr->new_format.cookie = cpu_to_le16(cookie); 546 break;
547 case B43_FW_HDR_351:
548 txhdr->format_351.cookie = cpu_to_le16(cookie);
549 break;
550 case B43_FW_HDR_410:
551 txhdr->format_410.cookie = cpu_to_le16(cookie);
552 break;
553 }
512 554
513 if (phy->type == B43_PHYTYPE_N) { 555 if (phy->type == B43_PHYTYPE_N) {
514 txhdr->phy_ctl1 = 556 txhdr->phy_ctl1 =
@@ -611,8 +653,9 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
611 struct ieee80211_hdr *wlhdr; 653 struct ieee80211_hdr *wlhdr;
612 const struct b43_rxhdr_fw4 *rxhdr = _rxhdr; 654 const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
613 __le16 fctl; 655 __le16 fctl;
614 u16 phystat0, phystat3, chanstat, mactime; 656 u16 phystat0, phystat3;
615 u32 macstat; 657 u16 uninitialized_var(chanstat), uninitialized_var(mactime);
658 u32 uninitialized_var(macstat);
616 u16 chanid; 659 u16 chanid;
617 u16 phytype; 660 u16 phytype;
618 int padding; 661 int padding;
@@ -622,9 +665,19 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
622 /* Get metadata about the frame from the header. */ 665 /* Get metadata about the frame from the header. */
623 phystat0 = le16_to_cpu(rxhdr->phy_status0); 666 phystat0 = le16_to_cpu(rxhdr->phy_status0);
624 phystat3 = le16_to_cpu(rxhdr->phy_status3); 667 phystat3 = le16_to_cpu(rxhdr->phy_status3);
625 macstat = le32_to_cpu(rxhdr->mac_status); 668 switch (dev->fw.hdr_format) {
626 mactime = le16_to_cpu(rxhdr->mac_time); 669 case B43_FW_HDR_598:
627 chanstat = le16_to_cpu(rxhdr->channel); 670 macstat = le32_to_cpu(rxhdr->format_598.mac_status);
671 mactime = le16_to_cpu(rxhdr->format_598.mac_time);
672 chanstat = le16_to_cpu(rxhdr->format_598.channel);
673 break;
674 case B43_FW_HDR_410:
675 case B43_FW_HDR_351:
676 macstat = le32_to_cpu(rxhdr->format_351.mac_status);
677 mactime = le16_to_cpu(rxhdr->format_351.mac_time);
678 chanstat = le16_to_cpu(rxhdr->format_351.channel);
679 break;
680 }
628 phytype = chanstat & B43_RX_CHAN_PHYTYPE; 681 phytype = chanstat & B43_RX_CHAN_PHYTYPE;
629 682
630 if (unlikely(macstat & B43_RX_MAC_FCSERR)) { 683 if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
@@ -744,6 +797,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
744 break; 797 break;
745 case B43_PHYTYPE_N: 798 case B43_PHYTYPE_N:
746 case B43_PHYTYPE_LP: 799 case B43_PHYTYPE_LP:
800 case B43_PHYTYPE_HT:
747 /* chanid is the SHM channel cookie. Which is the plain 801 /* chanid is the SHM channel cookie. Which is the plain
748 * channel number in b43. */ 802 * channel number in b43. */
749 if (chanstat & B43_RX_CHAN_5GHZ) { 803 if (chanstat & B43_RX_CHAN_5GHZ) {
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 42debb5cd6fa..f6e8bc436d5a 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -46,7 +46,24 @@ struct b43_txhdr {
46 __le32 timeout; /* Timeout */ 46 __le32 timeout; /* Timeout */
47 47
48 union { 48 union {
49 /* The new r410 format. */ 49 /* Tested with 598.314, 644.1001 and 666.2 */
50 struct {
51 __le16 mimo_antenna; /* MIMO antenna select */
52 __le16 preload_size; /* Preload size */
53 PAD_BYTES(2);
54 __le16 cookie; /* TX frame cookie */
55 __le16 tx_status; /* TX status */
56 __le16 max_n_mpdus;
57 __le16 max_a_bytes_mrt;
58 __le16 max_a_bytes_fbr;
59 __le16 min_m_bytes;
60 struct b43_plcp_hdr6 rts_plcp; /* RTS PLCP header */
61 __u8 rts_frame[16]; /* The RTS frame (if used) */
62 PAD_BYTES(2);
63 struct b43_plcp_hdr6 plcp; /* Main PLCP header */
64 } format_598 __packed;
65
66 /* Tested with 410.2160, 478.104 and 508.* */
50 struct { 67 struct {
51 __le16 mimo_antenna; /* MIMO antenna select */ 68 __le16 mimo_antenna; /* MIMO antenna select */
52 __le16 preload_size; /* Preload size */ 69 __le16 preload_size; /* Preload size */
@@ -57,9 +74,9 @@ struct b43_txhdr {
57 __u8 rts_frame[16]; /* The RTS frame (if used) */ 74 __u8 rts_frame[16]; /* The RTS frame (if used) */
58 PAD_BYTES(2); 75 PAD_BYTES(2);
59 struct b43_plcp_hdr6 plcp; /* Main PLCP header */ 76 struct b43_plcp_hdr6 plcp; /* Main PLCP header */
60 } new_format __packed; 77 } format_410 __packed;
61 78
62 /* The old r351 format. */ 79 /* Tested with 351.126 */
63 struct { 80 struct {
64 PAD_BYTES(2); 81 PAD_BYTES(2);
65 __le16 cookie; /* TX frame cookie */ 82 __le16 cookie; /* TX frame cookie */
@@ -68,7 +85,7 @@ struct b43_txhdr {
68 __u8 rts_frame[16]; /* The RTS frame (if used) */ 85 __u8 rts_frame[16]; /* The RTS frame (if used) */
69 PAD_BYTES(2); 86 PAD_BYTES(2);
70 struct b43_plcp_hdr6 plcp; /* Main PLCP header */ 87 struct b43_plcp_hdr6 plcp; /* Main PLCP header */
71 } old_format __packed; 88 } format_351 __packed;
72 89
73 } __packed; 90 } __packed;
74} __packed; 91} __packed;
@@ -166,19 +183,18 @@ struct b43_tx_legacy_rate_phy_ctl_entry {
166#define B43_TXH_PHY1_MODUL_QAM256 0x2000 /* QAM256 */ 183#define B43_TXH_PHY1_MODUL_QAM256 0x2000 /* QAM256 */
167 184
168 185
169/* r351 firmware compatibility stuff. */
170static inline
171bool b43_is_old_txhdr_format(struct b43_wldev *dev)
172{
173 return (dev->fw.rev <= 351);
174}
175
176static inline 186static inline
177size_t b43_txhdr_size(struct b43_wldev *dev) 187size_t b43_txhdr_size(struct b43_wldev *dev)
178{ 188{
179 if (b43_is_old_txhdr_format(dev)) 189 switch (dev->fw.hdr_format) {
190 case B43_FW_HDR_598:
191 return 112 + sizeof(struct b43_plcp_hdr6);
192 case B43_FW_HDR_410:
193 return 104 + sizeof(struct b43_plcp_hdr6);
194 case B43_FW_HDR_351:
180 return 100 + sizeof(struct b43_plcp_hdr6); 195 return 100 + sizeof(struct b43_plcp_hdr6);
181 return 104 + sizeof(struct b43_plcp_hdr6); 196 }
197 return 0;
182} 198}
183 199
184 200
@@ -234,9 +250,23 @@ struct b43_rxhdr_fw4 {
234 } __packed; 250 } __packed;
235 __le16 phy_status2; /* PHY RX Status 2 */ 251 __le16 phy_status2; /* PHY RX Status 2 */
236 __le16 phy_status3; /* PHY RX Status 3 */ 252 __le16 phy_status3; /* PHY RX Status 3 */
237 __le32 mac_status; /* MAC RX status */ 253 union {
238 __le16 mac_time; 254 /* Tested with 598.314, 644.1001 and 666.2 */
239 __le16 channel; 255 struct {
256 __le16 phy_status4; /* PHY RX Status 4 */
257 __le16 phy_status5; /* PHY RX Status 5 */
258 __le32 mac_status; /* MAC RX status */
259 __le16 mac_time;
260 __le16 channel;
261 } format_598 __packed;
262
263 /* Tested with 351.126, 410.2160, 478.104 and 508.* */
264 struct {
265 __le32 mac_status; /* MAC RX status */
266 __le16 mac_time;
267 __le16 channel;
268 } format_351 __packed;
269 } __packed;
240} __packed; 270} __packed;
241 271
242/* PHY RX Status 0 */ 272/* PHY RX Status 0 */
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index ad4e743e4765..12b518251581 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -22,10 +22,6 @@
22#include "phy.h" 22#include "phy.h"
23 23
24 24
25/* The unique identifier of the firmware that's officially supported by this
26 * driver version. */
27#define B43legacy_SUPPORTED_FIRMWARE_ID "FW10"
28
29#define B43legacy_IRQWAIT_MAX_RETRIES 20 25#define B43legacy_IRQWAIT_MAX_RETRIES 20
30 26
31/* MMIO offsets */ 27/* MMIO offsets */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index aae8dfcb852e..468d1836548e 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -60,7 +60,6 @@ MODULE_AUTHOR("Stefano Brivio");
60MODULE_AUTHOR("Michael Buesch"); 60MODULE_AUTHOR("Michael Buesch");
61MODULE_LICENSE("GPL"); 61MODULE_LICENSE("GPL");
62 62
63MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID);
64MODULE_FIRMWARE("b43legacy/ucode2.fw"); 63MODULE_FIRMWARE("b43legacy/ucode2.fw");
65MODULE_FIRMWARE("b43legacy/ucode4.fw"); 64MODULE_FIRMWARE("b43legacy/ucode4.fw");
66 65
@@ -3947,8 +3946,7 @@ static void b43legacy_print_driverinfo(void)
3947 feat_dma = "D"; 3946 feat_dma = "D";
3948#endif 3947#endif
3949 printk(KERN_INFO "Broadcom 43xx-legacy driver loaded " 3948 printk(KERN_INFO "Broadcom 43xx-legacy driver loaded "
3950 "[ Features: %s%s%s%s, Firmware-ID: " 3949 "[ Features: %s%s%s%s ]\n",
3951 B43legacy_SUPPORTED_FIRMWARE_ID " ]\n",
3952 feat_pci, feat_leds, feat_pio, feat_dma); 3950 feat_pci, feat_leds, feat_pio, feat_dma);
3953} 3951}
3954 3952
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index 1453eec82a99..91f2ca90c70f 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -238,28 +238,3 @@ hostsleep
238 echo "1" > hostsleep : enable host sleep. 238 echo "1" > hostsleep : enable host sleep.
239 echo "0" > hostsleep : disable host sleep 239 echo "0" > hostsleep : disable host sleep
240 240
241========================
242IWCONFIG COMMANDS
243========================
244power period
245
246 This command is used to configure the station in deep sleep mode /
247 auto deep sleep mode.
248
249 The timer is implemented to monitor the activities (command, event,
250 etc.). When an activity is detected station will exit from deep
251 sleep mode automatically and restart the timer. At timer expiry
252 (no activity for defined time period) the deep sleep mode is entered
253 automatically.
254
255 Note: this command is for SDIO interface only.
256
257 Usage:
258 To enable deep sleep mode do:
259 iwconfig wlan0 power period 0
260 To enable auto deep sleep mode with idle time period 5 seconds do:
261 iwconfig wlan0 power period 5
262 To disable deep sleep/auto deep sleep mode do:
263 iwconfig wlan0 power period -1
264
265==============================================================================
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 814838916b82..b9ff0dc53e8d 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -190,8 +190,8 @@ static inline int lbs_iface_active(struct lbs_private *priv)
190 int r; 190 int r;
191 191
192 r = netif_running(priv->dev); 192 r = netif_running(priv->dev);
193 if (priv->mesh_dev); 193 if (priv->mesh_dev)
194 r |= netif_running(priv->dev); 194 r |= netif_running(priv->mesh_dev);
195 195
196 return r; 196 return r;
197} 197}
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index b28241c6e737..37ca2f90ad63 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1480,8 +1480,8 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1480 return -ENOMEM; 1480 return -ENOMEM;
1481 } 1481 }
1482 beacon_ie = kzalloc(ie_len, GFP_KERNEL); 1482 beacon_ie = kzalloc(ie_len, GFP_KERNEL);
1483 if (!bss_desc) { 1483 if (!beacon_ie) {
1484 dev_err(priv->adapter->dev, " failed to alloc bss_desc\n"); 1484 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
1485 return -ENOMEM; 1485 return -ENOMEM;
1486 } 1486 }
1487 memcpy(beacon_ie, ie_buf, ie_len); 1487 memcpy(beacon_ie, ie_buf, ie_len);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index da36dbf8d871..771280a47ea7 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -4097,9 +4097,6 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
4097 4097
4098 if (rc) 4098 if (rc)
4099 goto out; 4099 goto out;
4100
4101 mwl8k_vif->is_hw_crypto_enabled = false;
4102
4103 } 4100 }
4104out: 4101out:
4105 return rc; 4102 return rc;
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 54cc0bba66b9..8b6f363b3f7d 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -145,6 +145,7 @@ static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
145 145
146static int p54_generate_band(struct ieee80211_hw *dev, 146static int p54_generate_band(struct ieee80211_hw *dev,
147 struct p54_channel_list *list, 147 struct p54_channel_list *list,
148 unsigned int *chan_num,
148 enum ieee80211_band band) 149 enum ieee80211_band band)
149{ 150{
150 struct p54_common *priv = dev->priv; 151 struct p54_common *priv = dev->priv;
@@ -190,7 +191,14 @@ static int p54_generate_band(struct ieee80211_hw *dev,
190 191
191 tmp->channels[j].band = chan->band; 192 tmp->channels[j].band = chan->band;
192 tmp->channels[j].center_freq = chan->freq; 193 tmp->channels[j].center_freq = chan->freq;
194 priv->survey[*chan_num].channel = &tmp->channels[j];
195 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM |
196 SURVEY_INFO_CHANNEL_TIME |
197 SURVEY_INFO_CHANNEL_TIME_BUSY |
198 SURVEY_INFO_CHANNEL_TIME_TX;
199 tmp->channels[j].hw_value = (*chan_num);
193 j++; 200 j++;
201 (*chan_num)++;
194 } 202 }
195 203
196 if (j == 0) { 204 if (j == 0) {
@@ -263,7 +271,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
263{ 271{
264 struct p54_common *priv = dev->priv; 272 struct p54_common *priv = dev->priv;
265 struct p54_channel_list *list; 273 struct p54_channel_list *list;
266 unsigned int i, j, max_channel_num; 274 unsigned int i, j, k, max_channel_num;
267 int ret = 0; 275 int ret = 0;
268 u16 freq; 276 u16 freq;
269 277
@@ -283,6 +291,13 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
283 ret = -ENOMEM; 291 ret = -ENOMEM;
284 goto free; 292 goto free;
285 } 293 }
294 priv->chan_num = max_channel_num;
295 priv->survey = kzalloc(sizeof(struct survey_info) * max_channel_num,
296 GFP_KERNEL);
297 if (!priv->survey) {
298 ret = -ENOMEM;
299 goto free;
300 }
286 301
287 list->max_entries = max_channel_num; 302 list->max_entries = max_channel_num;
288 list->channels = kzalloc(sizeof(struct p54_channel_entry) * 303 list->channels = kzalloc(sizeof(struct p54_channel_entry) *
@@ -321,8 +336,9 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
321 sort(list->channels, list->entries, sizeof(struct p54_channel_entry), 336 sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
322 p54_compare_channels, NULL); 337 p54_compare_channels, NULL);
323 338
339 k = 0;
324 for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) { 340 for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
325 if (p54_generate_band(dev, list, i) == 0) 341 if (p54_generate_band(dev, list, &k, i) == 0)
326 j++; 342 j++;
327 } 343 }
328 if (j == 0) { 344 if (j == 0) {
@@ -335,6 +351,10 @@ free:
335 kfree(list->channels); 351 kfree(list->channels);
336 kfree(list); 352 kfree(list);
337 } 353 }
354 if (ret) {
355 kfree(priv->survey);
356 priv->survey = NULL;
357 }
338 358
339 return ret; 359 return ret;
340} 360}
@@ -853,10 +873,12 @@ err:
853 kfree(priv->output_limit); 873 kfree(priv->output_limit);
854 kfree(priv->curve_data); 874 kfree(priv->curve_data);
855 kfree(priv->rssi_db); 875 kfree(priv->rssi_db);
876 kfree(priv->survey);
856 priv->iq_autocal = NULL; 877 priv->iq_autocal = NULL;
857 priv->output_limit = NULL; 878 priv->output_limit = NULL;
858 priv->curve_data = NULL; 879 priv->curve_data = NULL;
859 priv->rssi_db = NULL; 880 priv->rssi_db = NULL;
881 priv->survey = NULL;
860 882
861 wiphy_err(dev->wiphy, "eeprom parse failed!\n"); 883 wiphy_err(dev->wiphy, "eeprom parse failed!\n");
862 return err; 884 return err;
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index b6a061cbbdec..53a3408931be 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -385,6 +385,7 @@ int p54_setup_mac(struct p54_common *priv)
385 setup->v2.osc_start_delay = cpu_to_le16(65535); 385 setup->v2.osc_start_delay = cpu_to_le16(65535);
386 } 386 }
387 p54_tx(priv, skb); 387 p54_tx(priv, skb);
388 priv->phy_idle = mode == P54_FILTER_TYPE_HIBERNATE;
388 return 0; 389 return 0;
389} 390}
390 391
@@ -626,6 +627,7 @@ int p54_set_ps(struct p54_common *priv)
626 psm->exclude[0] = WLAN_EID_TIM; 627 psm->exclude[0] = WLAN_EID_TIM;
627 628
628 p54_tx(priv, skb); 629 p54_tx(priv, skb);
630 priv->phy_ps = mode != P54_PSM_CAM;
629 return 0; 631 return 0;
630} 632}
631 633
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index a5a6d9e647bb..726a9343f514 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -204,13 +204,11 @@ static void p54_stop(struct ieee80211_hw *dev)
204 struct p54_common *priv = dev->priv; 204 struct p54_common *priv = dev->priv;
205 int i; 205 int i;
206 206
207 mutex_lock(&priv->conf_mutex);
208 priv->mode = NL80211_IFTYPE_UNSPECIFIED; 207 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
209 priv->softled_state = 0; 208 priv->softled_state = 0;
210 p54_set_leds(priv);
211
212 cancel_delayed_work_sync(&priv->work); 209 cancel_delayed_work_sync(&priv->work);
213 210 mutex_lock(&priv->conf_mutex);
211 p54_set_leds(priv);
214 priv->stop(dev); 212 priv->stop(dev);
215 skb_queue_purge(&priv->tx_pending); 213 skb_queue_purge(&priv->tx_pending);
216 skb_queue_purge(&priv->tx_queue); 214 skb_queue_purge(&priv->tx_queue);
@@ -278,6 +276,42 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
278 mutex_unlock(&priv->conf_mutex); 276 mutex_unlock(&priv->conf_mutex);
279} 277}
280 278
279static int p54_wait_for_stats(struct ieee80211_hw *dev)
280{
281 struct p54_common *priv = dev->priv;
282 int ret;
283
284 priv->update_stats = true;
285 ret = p54_fetch_statistics(priv);
286 if (ret)
287 return ret;
288
289 ret = wait_for_completion_interruptible_timeout(&priv->stat_comp, HZ);
290 if (ret == 0)
291 return -ETIMEDOUT;
292
293 return 0;
294}
295
296static void p54_reset_stats(struct p54_common *priv)
297{
298 struct ieee80211_channel *chan = priv->curchan;
299
300 if (chan) {
301 struct survey_info *info = &priv->survey[chan->hw_value];
302
303 /* only reset channel statistics, don't touch .filled, etc. */
304 info->channel_time = 0;
305 info->channel_time_busy = 0;
306 info->channel_time_tx = 0;
307 }
308
309 priv->update_stats = true;
310 priv->survey_raw.active = 0;
311 priv->survey_raw.cca = 0;
312 priv->survey_raw.tx = 0;
313}
314
281static int p54_config(struct ieee80211_hw *dev, u32 changed) 315static int p54_config(struct ieee80211_hw *dev, u32 changed)
282{ 316{
283 int ret = 0; 317 int ret = 0;
@@ -288,19 +322,36 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
288 if (changed & IEEE80211_CONF_CHANGE_POWER) 322 if (changed & IEEE80211_CONF_CHANGE_POWER)
289 priv->output_power = conf->power_level << 2; 323 priv->output_power = conf->power_level << 2;
290 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 324 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
325 struct ieee80211_channel *oldchan;
326 WARN_ON(p54_wait_for_stats(dev));
327 oldchan = priv->curchan;
328 priv->curchan = NULL;
291 ret = p54_scan(priv, P54_SCAN_EXIT, 0); 329 ret = p54_scan(priv, P54_SCAN_EXIT, 0);
292 if (ret) 330 if (ret) {
331 priv->curchan = oldchan;
293 goto out; 332 goto out;
333 }
334 /*
335 * TODO: Use the LM_SCAN_TRAP to determine the current
336 * operating channel.
337 */
338 priv->curchan = priv->hw->conf.channel;
339 p54_reset_stats(priv);
340 WARN_ON(p54_fetch_statistics(priv));
294 } 341 }
295 if (changed & IEEE80211_CONF_CHANGE_PS) { 342 if (changed & IEEE80211_CONF_CHANGE_PS) {
343 WARN_ON(p54_wait_for_stats(dev));
296 ret = p54_set_ps(priv); 344 ret = p54_set_ps(priv);
297 if (ret) 345 if (ret)
298 goto out; 346 goto out;
347 WARN_ON(p54_wait_for_stats(dev));
299 } 348 }
300 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 349 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
350 WARN_ON(p54_wait_for_stats(dev));
301 ret = p54_setup_mac(priv); 351 ret = p54_setup_mac(priv);
302 if (ret) 352 if (ret)
303 goto out; 353 goto out;
354 WARN_ON(p54_wait_for_stats(dev));
304 } 355 }
305 356
306out: 357out:
@@ -384,7 +435,9 @@ static void p54_work(struct work_struct *work)
384 * 2. cancel stuck frames / reset the device if necessary. 435 * 2. cancel stuck frames / reset the device if necessary.
385 */ 436 */
386 437
387 p54_fetch_statistics(priv); 438 mutex_lock(&priv->conf_mutex);
439 WARN_ON_ONCE(p54_fetch_statistics(priv));
440 mutex_unlock(&priv->conf_mutex);
388} 441}
389 442
390static int p54_get_stats(struct ieee80211_hw *dev, 443static int p54_get_stats(struct ieee80211_hw *dev,
@@ -541,16 +594,47 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx,
541 struct survey_info *survey) 594 struct survey_info *survey)
542{ 595{
543 struct p54_common *priv = dev->priv; 596 struct p54_common *priv = dev->priv;
544 struct ieee80211_conf *conf = &dev->conf; 597 struct ieee80211_channel *chan;
598 int err, tries;
599 bool in_use = false;
545 600
546 if (idx != 0) 601 if (idx >= priv->chan_num)
547 return -ENOENT; 602 return -ENOENT;
548 603
549 survey->channel = conf->channel; 604#define MAX_TRIES 1
550 survey->filled = SURVEY_INFO_NOISE_DBM; 605 for (tries = 0; tries < MAX_TRIES; tries++) {
551 survey->noise = clamp_t(s8, priv->noise, -128, 127); 606 chan = priv->curchan;
607 if (chan && chan->hw_value == idx) {
608 mutex_lock(&priv->conf_mutex);
609 err = p54_wait_for_stats(dev);
610 mutex_unlock(&priv->conf_mutex);
611 if (err)
612 return err;
613
614 in_use = true;
615 }
552 616
553 return 0; 617 memcpy(survey, &priv->survey[idx], sizeof(*survey));
618
619 if (in_use) {
620 /* test if the reported statistics are valid. */
621 if (survey->channel_time != 0) {
622 survey->filled |= SURVEY_INFO_IN_USE;
623 } else {
624 /*
625 * hw/fw has not accumulated enough sample sets.
626 * Wait for 100ms, this ought to be enough to
627 * to get at least one non-null set of channel
628 * usage statistics.
629 */
630 msleep(100);
631 continue;
632 }
633 }
634 return 0;
635 }
636 return -ETIMEDOUT;
637#undef MAX_TRIES
554} 638}
555 639
556static unsigned int p54_flush_count(struct p54_common *priv) 640static unsigned int p54_flush_count(struct p54_common *priv)
@@ -686,11 +770,14 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
686 770
687 mutex_init(&priv->conf_mutex); 771 mutex_init(&priv->conf_mutex);
688 mutex_init(&priv->eeprom_mutex); 772 mutex_init(&priv->eeprom_mutex);
773 init_completion(&priv->stat_comp);
689 init_completion(&priv->eeprom_comp); 774 init_completion(&priv->eeprom_comp);
690 init_completion(&priv->beacon_comp); 775 init_completion(&priv->beacon_comp);
691 INIT_DELAYED_WORK(&priv->work, p54_work); 776 INIT_DELAYED_WORK(&priv->work, p54_work);
692 777
693 memset(&priv->mc_maclist[0], ~0, ETH_ALEN); 778 memset(&priv->mc_maclist[0], ~0, ETH_ALEN);
779 priv->curchan = NULL;
780 p54_reset_stats(priv);
694 return dev; 781 return dev;
695} 782}
696EXPORT_SYMBOL_GPL(p54_init_common); 783EXPORT_SYMBOL_GPL(p54_init_common);
@@ -730,11 +817,13 @@ void p54_free_common(struct ieee80211_hw *dev)
730 kfree(priv->curve_data); 817 kfree(priv->curve_data);
731 kfree(priv->rssi_db); 818 kfree(priv->rssi_db);
732 kfree(priv->used_rxkeys); 819 kfree(priv->used_rxkeys);
820 kfree(priv->survey);
733 priv->iq_autocal = NULL; 821 priv->iq_autocal = NULL;
734 priv->output_limit = NULL; 822 priv->output_limit = NULL;
735 priv->curve_data = NULL; 823 priv->curve_data = NULL;
736 priv->rssi_db = NULL; 824 priv->rssi_db = NULL;
737 priv->used_rxkeys = NULL; 825 priv->used_rxkeys = NULL;
826 priv->survey = NULL;
738 ieee80211_free_hw(dev); 827 ieee80211_free_hw(dev);
739} 828}
740EXPORT_SYMBOL_GPL(p54_free_common); 829EXPORT_SYMBOL_GPL(p54_free_common);
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 799d05e12595..452fa3a64aa1 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -199,6 +199,22 @@ struct p54_common {
199 u8 tx_diversity_mask; 199 u8 tx_diversity_mask;
200 unsigned int output_power; 200 unsigned int output_power;
201 struct p54_rssi_db_entry *cur_rssi; 201 struct p54_rssi_db_entry *cur_rssi;
202 struct ieee80211_channel *curchan;
203 struct survey_info *survey;
204 unsigned int chan_num;
205 struct completion stat_comp;
206 bool update_stats;
207 struct {
208 unsigned int timestamp;
209 unsigned int cached_cca;
210 unsigned int cached_tx;
211 unsigned int cached_rssi;
212 u64 active;
213 u64 cca;
214 u64 tx;
215 u64 rssi;
216 } survey_raw;
217
202 int noise; 218 int noise;
203 /* calibration, output power limit and rssi<->dBm conversation data */ 219 /* calibration, output power limit and rssi<->dBm conversation data */
204 struct pda_iq_autocal_entry *iq_autocal; 220 struct pda_iq_autocal_entry *iq_autocal;
@@ -220,6 +236,8 @@ struct p54_common {
220 u32 basic_rate_mask; 236 u32 basic_rate_mask;
221 u16 aid; 237 u16 aid;
222 u8 coverage_class; 238 u8 coverage_class;
239 bool phy_idle;
240 bool phy_ps;
223 bool powersave_override; 241 bool powersave_override;
224 __le32 beacon_req_id; 242 __le32 beacon_req_id;
225 struct completion beacon_comp; 243 struct completion beacon_comp;
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 042842e704de..44a3bd4b0f43 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -507,6 +507,8 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
507 struct p54_hdr *hdr = (struct p54_hdr *) skb->data; 507 struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
508 struct p54_statistics *stats = (struct p54_statistics *) hdr->data; 508 struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
509 struct sk_buff *tmp; 509 struct sk_buff *tmp;
510 struct ieee80211_channel *chan;
511 unsigned int i, rssi, tx, cca, dtime, dtotal, dcca, dtx, drssi, unit;
510 u32 tsf32; 512 u32 tsf32;
511 513
512 if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED)) 514 if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
@@ -523,8 +525,72 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
523 525
524 priv->noise = p54_rssi_to_dbm(priv, le32_to_cpu(stats->noise)); 526 priv->noise = p54_rssi_to_dbm(priv, le32_to_cpu(stats->noise));
525 527
528 /*
529 * STSW450X LMAC API page 26 - 3.8 Statistics
530 * "The exact measurement period can be derived from the
531 * timestamp member".
532 */
533 dtime = tsf32 - priv->survey_raw.timestamp;
534
535 /*
536 * STSW450X LMAC API page 26 - 3.8.1 Noise histogram
537 * The LMAC samples RSSI, CCA and transmit state at regular
538 * periods (typically 8 times per 1k [as in 1024] usec).
539 */
540 cca = le32_to_cpu(stats->sample_cca);
541 tx = le32_to_cpu(stats->sample_tx);
542 rssi = 0;
543 for (i = 0; i < ARRAY_SIZE(stats->sample_noise); i++)
544 rssi += le32_to_cpu(stats->sample_noise[i]);
545
546 dcca = cca - priv->survey_raw.cached_cca;
547 drssi = rssi - priv->survey_raw.cached_rssi;
548 dtx = tx - priv->survey_raw.cached_tx;
549 dtotal = dcca + drssi + dtx;
550
551 /*
552 * update statistics when more than a second is over since the
553 * last call, or when a update is badly needed.
554 */
555 if (dtotal && (priv->update_stats || dtime >= USEC_PER_SEC) &&
556 dtime >= dtotal) {
557 priv->survey_raw.timestamp = tsf32;
558 priv->update_stats = false;
559 unit = dtime / dtotal;
560
561 if (dcca) {
562 priv->survey_raw.cca += dcca * unit;
563 priv->survey_raw.cached_cca = cca;
564 }
565 if (dtx) {
566 priv->survey_raw.tx += dtx * unit;
567 priv->survey_raw.cached_tx = tx;
568 }
569 if (drssi) {
570 priv->survey_raw.rssi += drssi * unit;
571 priv->survey_raw.cached_rssi = rssi;
572 }
573
574 /* 1024 usec / 8 times = 128 usec / time */
575 if (!(priv->phy_ps || priv->phy_idle))
576 priv->survey_raw.active += dtotal * unit;
577 else
578 priv->survey_raw.active += (dcca + dtx) * unit;
579 }
580
581 chan = priv->curchan;
582 if (chan) {
583 struct survey_info *survey = &priv->survey[chan->hw_value];
584 survey->noise = clamp_t(s8, priv->noise, -128, 127);
585 survey->channel_time = priv->survey_raw.active / 1024;
586 survey->channel_time_tx = priv->survey_raw.tx / 1024;
587 survey->channel_time_busy = priv->survey_raw.cca / 1024 +
588 survey->channel_time_tx;
589 }
590
526 tmp = p54_find_and_unlink_skb(priv, hdr->req_id); 591 tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
527 dev_kfree_skb_any(tmp); 592 dev_kfree_skb_any(tmp);
593 complete(&priv->stat_comp);
528} 594}
529 595
530static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) 596static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 0b598db38da9..098fc557a88d 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -664,6 +664,167 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
664 return hw_rate; 664 return hw_rate;
665} 665}
666 666
667/* mac80211's rate_idx is like this:
668 *
669 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
670 *
671 * B/G rate:
672 * (rx_status->flag & RX_FLAG_HT) = 0,
673 * DESC92_RATE1M-->DESC92_RATE54M ==> idx is 0-->11,
674 *
675 * N rate:
676 * (rx_status->flag & RX_FLAG_HT) = 1,
677 * DESC92_RATEMCS0-->DESC92_RATEMCS15 ==> idx is 0-->15
678 *
679 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
680 * A rate:
681 * (rx_status->flag & RX_FLAG_HT) = 0,
682 * DESC92_RATE6M-->DESC92_RATE54M ==> idx is 0-->7,
683 *
684 * N rate:
685 * (rx_status->flag & RX_FLAG_HT) = 1,
686 * DESC92_RATEMCS0-->DESC92_RATEMCS15 ==> idx is 0-->15
687 */
688int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
689 bool isht, u8 desc_rate, bool first_ampdu)
690{
691 int rate_idx;
692
693 if (false == isht) {
694 if (IEEE80211_BAND_2GHZ == hw->conf.channel->band) {
695 switch (desc_rate) {
696 case DESC92_RATE1M:
697 rate_idx = 0;
698 break;
699 case DESC92_RATE2M:
700 rate_idx = 1;
701 break;
702 case DESC92_RATE5_5M:
703 rate_idx = 2;
704 break;
705 case DESC92_RATE11M:
706 rate_idx = 3;
707 break;
708 case DESC92_RATE6M:
709 rate_idx = 4;
710 break;
711 case DESC92_RATE9M:
712 rate_idx = 5;
713 break;
714 case DESC92_RATE12M:
715 rate_idx = 6;
716 break;
717 case DESC92_RATE18M:
718 rate_idx = 7;
719 break;
720 case DESC92_RATE24M:
721 rate_idx = 8;
722 break;
723 case DESC92_RATE36M:
724 rate_idx = 9;
725 break;
726 case DESC92_RATE48M:
727 rate_idx = 10;
728 break;
729 case DESC92_RATE54M:
730 rate_idx = 11;
731 break;
732 default:
733 rate_idx = 0;
734 break;
735 }
736 } else {
737 switch (desc_rate) {
738 case DESC92_RATE6M:
739 rate_idx = 0;
740 break;
741 case DESC92_RATE9M:
742 rate_idx = 1;
743 break;
744 case DESC92_RATE12M:
745 rate_idx = 2;
746 break;
747 case DESC92_RATE18M:
748 rate_idx = 3;
749 break;
750 case DESC92_RATE24M:
751 rate_idx = 4;
752 break;
753 case DESC92_RATE36M:
754 rate_idx = 5;
755 break;
756 case DESC92_RATE48M:
757 rate_idx = 6;
758 break;
759 case DESC92_RATE54M:
760 rate_idx = 7;
761 break;
762 default:
763 rate_idx = 0;
764 break;
765 }
766 }
767
768 } else {
769
770 switch (desc_rate) {
771 case DESC92_RATEMCS0:
772 rate_idx = 0;
773 break;
774 case DESC92_RATEMCS1:
775 rate_idx = 1;
776 break;
777 case DESC92_RATEMCS2:
778 rate_idx = 2;
779 break;
780 case DESC92_RATEMCS3:
781 rate_idx = 3;
782 break;
783 case DESC92_RATEMCS4:
784 rate_idx = 4;
785 break;
786 case DESC92_RATEMCS5:
787 rate_idx = 5;
788 break;
789 case DESC92_RATEMCS6:
790 rate_idx = 6;
791 break;
792 case DESC92_RATEMCS7:
793 rate_idx = 7;
794 break;
795 case DESC92_RATEMCS8:
796 rate_idx = 8;
797 break;
798 case DESC92_RATEMCS9:
799 rate_idx = 9;
800 break;
801 case DESC92_RATEMCS10:
802 rate_idx = 10;
803 break;
804 case DESC92_RATEMCS11:
805 rate_idx = 11;
806 break;
807 case DESC92_RATEMCS12:
808 rate_idx = 12;
809 break;
810 case DESC92_RATEMCS13:
811 rate_idx = 13;
812 break;
813 case DESC92_RATEMCS14:
814 rate_idx = 14;
815 break;
816 case DESC92_RATEMCS15:
817 rate_idx = 15;
818 break;
819 default:
820 rate_idx = 0;
821 break;
822 }
823 }
824 return rate_idx;
825}
826EXPORT_SYMBOL(rtlwifi_rate_mapping);
827
667void rtl_get_tcb_desc(struct ieee80211_hw *hw, 828void rtl_get_tcb_desc(struct ieee80211_hw *hw,
668 struct ieee80211_tx_info *info, 829 struct ieee80211_tx_info *info,
669 struct ieee80211_sta *sta, 830 struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index a91f3eee59c8..4ae905983d0d 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -140,4 +140,6 @@ u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
140void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); 140void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
141u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid); 141u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid);
142extern struct attribute_group rtl_attribute_group; 142extern struct attribute_group rtl_attribute_group;
143int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
144 bool isht, u8 desc_rate, bool first_ampdu);
143#endif 145#endif
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c
index 5fa73852cb66..b2f897acb238 100644
--- a/drivers/net/wireless/rtlwifi/debug.c
+++ b/drivers/net/wireless/rtlwifi/debug.c
@@ -28,12 +28,16 @@
28 28
29#include "wifi.h" 29#include "wifi.h"
30 30
31static unsigned int debug = DBG_EMERG;
32module_param(debug, uint, 0);
33MODULE_PARM_DESC(debug, "Set global debug level for rtlwifi (0,2-5)");
34
31void rtl_dbgp_flag_init(struct ieee80211_hw *hw) 35void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
32{ 36{
33 struct rtl_priv *rtlpriv = rtl_priv(hw); 37 struct rtl_priv *rtlpriv = rtl_priv(hw);
34 u8 i; 38 u8 i;
35 39
36 rtlpriv->dbg.global_debuglevel = DBG_EMERG; 40 rtlpriv->dbg.global_debuglevel = debug;
37 41
38 rtlpriv->dbg.global_debugcomponents = 42 rtlpriv->dbg.global_debugcomponents =
39 COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND | 43 COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 35ff7df41a1d..11f43196e61d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -220,41 +220,6 @@ enum rtl_desc_qsel {
220 QSLT_CMD = 0x13, 220 QSLT_CMD = 0x13,
221}; 221};
222 222
223enum rtl_desc92c_rate {
224 DESC92C_RATE1M = 0x00,
225 DESC92C_RATE2M = 0x01,
226 DESC92C_RATE5_5M = 0x02,
227 DESC92C_RATE11M = 0x03,
228
229 DESC92C_RATE6M = 0x04,
230 DESC92C_RATE9M = 0x05,
231 DESC92C_RATE12M = 0x06,
232 DESC92C_RATE18M = 0x07,
233 DESC92C_RATE24M = 0x08,
234 DESC92C_RATE36M = 0x09,
235 DESC92C_RATE48M = 0x0a,
236 DESC92C_RATE54M = 0x0b,
237
238 DESC92C_RATEMCS0 = 0x0c,
239 DESC92C_RATEMCS1 = 0x0d,
240 DESC92C_RATEMCS2 = 0x0e,
241 DESC92C_RATEMCS3 = 0x0f,
242 DESC92C_RATEMCS4 = 0x10,
243 DESC92C_RATEMCS5 = 0x11,
244 DESC92C_RATEMCS6 = 0x12,
245 DESC92C_RATEMCS7 = 0x13,
246 DESC92C_RATEMCS8 = 0x14,
247 DESC92C_RATEMCS9 = 0x15,
248 DESC92C_RATEMCS10 = 0x16,
249 DESC92C_RATEMCS11 = 0x17,
250 DESC92C_RATEMCS12 = 0x18,
251 DESC92C_RATEMCS13 = 0x19,
252 DESC92C_RATEMCS14 = 0x1a,
253 DESC92C_RATEMCS15 = 0x1b,
254 DESC92C_RATEMCS15_SG = 0x1c,
255 DESC92C_RATEMCS32 = 0x20,
256};
257
258struct phy_sts_cck_8192s_t { 223struct phy_sts_cck_8192s_t {
259 u8 adc_pwdb_X[4]; 224 u8 adc_pwdb_X[4];
260 u8 sq_rpt; 225 u8 sq_rpt;
@@ -267,108 +232,4 @@ struct h2c_cmd_8192c {
267 u8 *p_cmdbuffer; 232 u8 *p_cmdbuffer;
268}; 233};
269 234
270/* NOTE: reference to rtl8192c_rates struct */
271static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT,
272 u8 desc_rate, bool first_ampdu)
273{
274 struct rtl_priv *rtlpriv = rtl_priv(hw);
275 int rate_idx = 0;
276
277 if (first_ampdu) {
278 if (false == isHT) {
279 switch (desc_rate) {
280 case DESC92C_RATE1M:
281 rate_idx = 0;
282 break;
283 case DESC92C_RATE2M:
284 rate_idx = 1;
285 break;
286 case DESC92C_RATE5_5M:
287 rate_idx = 2;
288 break;
289 case DESC92C_RATE11M:
290 rate_idx = 3;
291 break;
292 case DESC92C_RATE6M:
293 rate_idx = 4;
294 break;
295 case DESC92C_RATE9M:
296 rate_idx = 5;
297 break;
298 case DESC92C_RATE12M:
299 rate_idx = 6;
300 break;
301 case DESC92C_RATE18M:
302 rate_idx = 7;
303 break;
304 case DESC92C_RATE24M:
305 rate_idx = 8;
306 break;
307 case DESC92C_RATE36M:
308 rate_idx = 9;
309 break;
310 case DESC92C_RATE48M:
311 rate_idx = 10;
312 break;
313 case DESC92C_RATE54M:
314 rate_idx = 11;
315 break;
316 default:
317 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
318 ("Rate %d is not support, set to "
319 "1M rate.\n", desc_rate));
320 rate_idx = 0;
321 break;
322 }
323 } else {
324 rate_idx = 11;
325 }
326 return rate_idx;
327 }
328 switch (desc_rate) {
329 case DESC92C_RATE1M:
330 rate_idx = 0;
331 break;
332 case DESC92C_RATE2M:
333 rate_idx = 1;
334 break;
335 case DESC92C_RATE5_5M:
336 rate_idx = 2;
337 break;
338 case DESC92C_RATE11M:
339 rate_idx = 3;
340 break;
341 case DESC92C_RATE6M:
342 rate_idx = 4;
343 break;
344 case DESC92C_RATE9M:
345 rate_idx = 5;
346 break;
347 case DESC92C_RATE12M:
348 rate_idx = 6;
349 break;
350 case DESC92C_RATE18M:
351 rate_idx = 7;
352 break;
353 case DESC92C_RATE24M:
354 rate_idx = 8;
355 break;
356 case DESC92C_RATE36M:
357 rate_idx = 9;
358 break;
359 case DESC92C_RATE48M:
360 rate_idx = 10;
361 break;
362 case DESC92C_RATE54M:
363 rate_idx = 11;
364 break;
365 /* TODO: How to mapping MCS rate? */
366 /* NOTE: referenc to __ieee80211_rx */
367 default:
368 rate_idx = 11;
369 break;
370 }
371 return rate_idx;
372}
373
374#endif 235#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 373dc78af1dc..4c34c4c1ae56 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -318,21 +318,21 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {
318 .maps[RTL_IMR_ROK] = IMR_ROK, 318 .maps[RTL_IMR_ROK] = IMR_ROK,
319 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), 319 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
320 320
321 .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, 321 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
322 .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, 322 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
323 .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, 323 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
324 .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, 324 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
325 .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, 325 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
326 .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, 326 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
327 .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, 327 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
328 .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, 328 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
329 .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, 329 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
330 .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, 330 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
331 .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, 331 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
332 .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, 332 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
333 333
334 .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, 334 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
335 .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, 335 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
336}; 336};
337 337
338DEFINE_PCI_DEVICE_TABLE(rtl92ce_pci_ids) = { 338DEFINE_PCI_DEVICE_TABLE(rtl92ce_pci_ids) = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index 230bbe900d8d..4fb5ae24dee0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -48,104 +48,6 @@ static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
48 return skb->priority; 48 return skb->priority;
49} 49}
50 50
51static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
52{
53 int rate_idx;
54
55 if (first_ampdu) {
56 if (false == isht) {
57 switch (desc_rate) {
58 case DESC92C_RATE1M:
59 rate_idx = 0;
60 break;
61 case DESC92C_RATE2M:
62 rate_idx = 1;
63 break;
64 case DESC92C_RATE5_5M:
65 rate_idx = 2;
66 break;
67 case DESC92C_RATE11M:
68 rate_idx = 3;
69 break;
70 case DESC92C_RATE6M:
71 rate_idx = 4;
72 break;
73 case DESC92C_RATE9M:
74 rate_idx = 5;
75 break;
76 case DESC92C_RATE12M:
77 rate_idx = 6;
78 break;
79 case DESC92C_RATE18M:
80 rate_idx = 7;
81 break;
82 case DESC92C_RATE24M:
83 rate_idx = 8;
84 break;
85 case DESC92C_RATE36M:
86 rate_idx = 9;
87 break;
88 case DESC92C_RATE48M:
89 rate_idx = 10;
90 break;
91 case DESC92C_RATE54M:
92 rate_idx = 11;
93 break;
94 default:
95 rate_idx = 0;
96 break;
97 }
98 } else {
99 rate_idx = 11;
100 }
101
102 return rate_idx;
103 }
104
105 switch (desc_rate) {
106 case DESC92C_RATE1M:
107 rate_idx = 0;
108 break;
109 case DESC92C_RATE2M:
110 rate_idx = 1;
111 break;
112 case DESC92C_RATE5_5M:
113 rate_idx = 2;
114 break;
115 case DESC92C_RATE11M:
116 rate_idx = 3;
117 break;
118 case DESC92C_RATE6M:
119 rate_idx = 4;
120 break;
121 case DESC92C_RATE9M:
122 rate_idx = 5;
123 break;
124 case DESC92C_RATE12M:
125 rate_idx = 6;
126 break;
127 case DESC92C_RATE18M:
128 rate_idx = 7;
129 break;
130 case DESC92C_RATE24M:
131 rate_idx = 8;
132 break;
133 case DESC92C_RATE36M:
134 rate_idx = 9;
135 break;
136 case DESC92C_RATE48M:
137 rate_idx = 10;
138 break;
139 case DESC92C_RATE54M:
140 rate_idx = 11;
141 break;
142 default:
143 rate_idx = 11;
144 break;
145 }
146 return rate_idx;
147}
148
149static u8 _rtl92c_query_rxpwrpercentage(char antpower) 51static u8 _rtl92c_query_rxpwrpercentage(char antpower)
150{ 52{
151 if ((antpower <= -100) || (antpower >= 20)) 53 if ((antpower <= -100) || (antpower >= 20))
@@ -336,8 +238,8 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
336 pstats->rxpower = rx_pwr_all; 238 pstats->rxpower = rx_pwr_all;
337 pstats->recvsignalpower = rx_pwr_all; 239 pstats->recvsignalpower = rx_pwr_all;
338 240
339 if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 && 241 if (pdesc->rxht && pdesc->rxmcs >= DESC92_RATEMCS8 &&
340 pdesc->rxmcs <= DESC92C_RATEMCS15) 242 pdesc->rxmcs <= DESC92_RATEMCS15)
341 max_spatial_stream = 2; 243 max_spatial_stream = 2;
342 else 244 else
343 max_spatial_stream = 1; 245 max_spatial_stream = 1;
@@ -670,12 +572,10 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
670 if (stats->decrypted) 572 if (stats->decrypted)
671 rx_status->flag |= RX_FLAG_DECRYPTED; 573 rx_status->flag |= RX_FLAG_DECRYPTED;
672 574
673 rx_status->rate_idx = _rtl92ce_rate_mapping((bool) 575 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
674 GET_RX_DESC_RXHT(pdesc), 576 (bool)GET_RX_DESC_RXHT(pdesc),
675 (u8) 577 (u8)GET_RX_DESC_RXMCS(pdesc),
676 GET_RX_DESC_RXMCS(pdesc), 578 (bool)GET_RX_DESC_PAGGR(pdesc));
677 (bool)
678 GET_RX_DESC_PAGGR(pdesc));
679 579
680 rx_status->mactime = GET_RX_DESC_TSFL(pdesc); 580 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
681 if (phystatus) { 581 if (phystatus) {
@@ -768,7 +668,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
768 SET_TX_DESC_RTS_BW(pdesc, 0); 668 SET_TX_DESC_RTS_BW(pdesc, 0);
769 SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc); 669 SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
770 SET_TX_DESC_RTS_SHORT(pdesc, 670 SET_TX_DESC_RTS_SHORT(pdesc,
771 ((tcb_desc->rts_rate <= DESC92C_RATE54M) ? 671 ((tcb_desc->rts_rate <= DESC92_RATE54M) ?
772 (tcb_desc->rts_use_shortpreamble ? 1 : 0) 672 (tcb_desc->rts_use_shortpreamble ? 1 : 0)
773 : (tcb_desc->rts_use_shortgi ? 1 : 0))); 673 : (tcb_desc->rts_use_shortgi ? 1 : 0)));
774 674
@@ -886,7 +786,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
886 if (firstseg) 786 if (firstseg)
887 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); 787 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
888 788
889 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); 789 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
890 790
891 SET_TX_DESC_SEQ(pdesc, 0); 791 SET_TX_DESC_SEQ(pdesc, 0);
892 792
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
index 0f1177137501..81ae64234f80 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
@@ -538,10 +538,10 @@ do { \
538} while (0); 538} while (0);
539 539
540#define RX_HAL_IS_CCK_RATE(_pdesc)\ 540#define RX_HAL_IS_CCK_RATE(_pdesc)\
541 (_pdesc->rxmcs == DESC92C_RATE1M || \ 541 (_pdesc->rxmcs == DESC92_RATE1M || \
542 _pdesc->rxmcs == DESC92C_RATE2M || \ 542 _pdesc->rxmcs == DESC92_RATE2M || \
543 _pdesc->rxmcs == DESC92C_RATE5_5M || \ 543 _pdesc->rxmcs == DESC92_RATE5_5M || \
544 _pdesc->rxmcs == DESC92C_RATE11M) 544 _pdesc->rxmcs == DESC92_RATE11M)
545 545
546struct rx_fwinfo_92c { 546struct rx_fwinfo_92c {
547 u8 gain_trsw[4]; 547 u8 gain_trsw[4];
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index 194fc693c1fa..060a06f4a885 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -892,8 +892,8 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
892 pstats->rxpower = rx_pwr_all; 892 pstats->rxpower = rx_pwr_all;
893 pstats->recvsignalpower = rx_pwr_all; 893 pstats->recvsignalpower = rx_pwr_all;
894 if (GET_RX_DESC_RX_MCS(pdesc) && 894 if (GET_RX_DESC_RX_MCS(pdesc) &&
895 GET_RX_DESC_RX_MCS(pdesc) >= DESC92C_RATEMCS8 && 895 GET_RX_DESC_RX_MCS(pdesc) >= DESC92_RATEMCS8 &&
896 GET_RX_DESC_RX_MCS(pdesc) <= DESC92C_RATEMCS15) 896 GET_RX_DESC_RX_MCS(pdesc) <= DESC92_RATEMCS15)
897 max_spatial_stream = 2; 897 max_spatial_stream = 2;
898 else 898 else
899 max_spatial_stream = 1; 899 max_spatial_stream = 1;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
index 298fdb724aa5..35529f701fc0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
@@ -88,10 +88,10 @@ void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter);
88u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw); 88u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw);
89 89
90#define RX_HAL_IS_CCK_RATE(_pdesc)\ 90#define RX_HAL_IS_CCK_RATE(_pdesc)\
91 (GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE1M ||\ 91 (GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE1M ||\
92 GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE2M ||\ 92 GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE2M ||\
93 GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE5_5M ||\ 93 GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE5_5M ||\
94 GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE11M) 94 GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE11M)
95 95
96struct rx_fwinfo_92c { 96struct rx_fwinfo_92c {
97 u8 gain_trsw[4]; 97 u8 gain_trsw[4];
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
index 17a8e9628512..1e851aae58db 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
@@ -104,7 +104,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
104 tx_agc[RF90_PATH_A] = 0x10101010; 104 tx_agc[RF90_PATH_A] = 0x10101010;
105 tx_agc[RF90_PATH_B] = 0x10101010; 105 tx_agc[RF90_PATH_B] = 0x10101010;
106 } else if (rtlpriv->dm.dynamic_txhighpower_lvl == 106 } else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
107 TXHIGHPWRLEVEL_LEVEL2) { 107 TXHIGHPWRLEVEL_LEVEL1) {
108 tx_agc[RF90_PATH_A] = 0x00000000; 108 tx_agc[RF90_PATH_A] = 0x00000000;
109 tx_agc[RF90_PATH_B] = 0x00000000; 109 tx_agc[RF90_PATH_B] = 0x00000000;
110 } else{ 110 } else{
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index ef63c0df006a..424b8a0323e2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -241,20 +241,20 @@ static struct rtl_hal_cfg rtl92cu_hal_cfg = {
241 .maps[RTL_IMR_ROK] = IMR_ROK, 241 .maps[RTL_IMR_ROK] = IMR_ROK,
242 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), 242 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
243 243
244 .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, 244 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
245 .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, 245 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
246 .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, 246 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
247 .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, 247 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
248 .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, 248 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
249 .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, 249 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
250 .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, 250 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
251 .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, 251 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
252 .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, 252 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
253 .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, 253 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
254 .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, 254 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
255 .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, 255 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
256 .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, 256 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
257 .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, 257 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
258}; 258};
259 259
260#define USB_VENDER_ID_REALTEK 0x0bda 260#define USB_VENDER_ID_REALTEK 0x0bda
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 906e7aa55bc3..c4161148e0d8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -337,10 +337,10 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
337 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 337 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
338 if (stats->decrypted) 338 if (stats->decrypted)
339 rx_status->flag |= RX_FLAG_DECRYPTED; 339 rx_status->flag |= RX_FLAG_DECRYPTED;
340 rx_status->rate_idx = _rtl92c_rate_mapping(hw, 340 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
341 (bool)GET_RX_DESC_RX_HT(pdesc), 341 (bool)GET_RX_DESC_RX_HT(pdesc),
342 (u8)GET_RX_DESC_RX_MCS(pdesc), 342 (u8)GET_RX_DESC_RX_MCS(pdesc),
343 (bool)GET_RX_DESC_PAGGR(pdesc)); 343 (bool)GET_RX_DESC_PAGGR(pdesc));
344 rx_status->mactime = GET_RX_DESC_TSFL(pdesc); 344 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
345 if (phystatus) { 345 if (phystatus) {
346 p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); 346 p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE);
@@ -406,11 +406,10 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
406 if (GET_RX_DESC_RX_HT(rxdesc)) 406 if (GET_RX_DESC_RX_HT(rxdesc))
407 rx_status->flag |= RX_FLAG_HT; 407 rx_status->flag |= RX_FLAG_HT;
408 /* Data rate */ 408 /* Data rate */
409 rx_status->rate_idx = _rtl92c_rate_mapping(hw, 409 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
410 (bool)GET_RX_DESC_RX_HT(rxdesc), 410 (bool)GET_RX_DESC_RX_HT(rxdesc),
411 (u8)GET_RX_DESC_RX_MCS(rxdesc), 411 (u8)GET_RX_DESC_RX_MCS(rxdesc),
412 (bool)GET_RX_DESC_PAGGR(rxdesc) 412 (bool)GET_RX_DESC_PAGGR(rxdesc));
413 );
414 /* There is a phy status after this rx descriptor. */ 413 /* There is a phy status after this rx descriptor. */
415 if (GET_RX_DESC_PHY_STATUS(rxdesc)) { 414 if (GET_RX_DESC_PHY_STATUS(rxdesc)) {
416 p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE); 415 p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE);
@@ -545,7 +544,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
545 SET_TX_DESC_RTS_BW(txdesc, 0); 544 SET_TX_DESC_RTS_BW(txdesc, 0);
546 SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc); 545 SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc);
547 SET_TX_DESC_RTS_SHORT(txdesc, 546 SET_TX_DESC_RTS_SHORT(txdesc,
548 ((tcb_desc->rts_rate <= DESC92C_RATE54M) ? 547 ((tcb_desc->rts_rate <= DESC92_RATE54M) ?
549 (tcb_desc->rts_use_shortpreamble ? 1 : 0) 548 (tcb_desc->rts_use_shortpreamble ? 1 : 0)
550 : (tcb_desc->rts_use_shortgi ? 1 : 0))); 549 : (tcb_desc->rts_use_shortgi ? 1 : 0)));
551 if (mac->bw_40) { 550 if (mac->bw_40) {
@@ -643,7 +642,7 @@ void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
643 } 642 }
644 SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */ 643 SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */
645 SET_TX_DESC_OWN(pDesc, 1); 644 SET_TX_DESC_OWN(pDesc, 1);
646 SET_TX_DESC_TX_RATE(pDesc, DESC92C_RATE1M); 645 SET_TX_DESC_TX_RATE(pDesc, DESC92_RATE1M);
647 _rtl_tx_desc_checksum(pDesc); 646 _rtl_tx_desc_checksum(pDesc);
648} 647}
649 648
@@ -659,7 +658,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
659 memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); 658 memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE);
660 if (firstseg) 659 if (firstseg)
661 SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); 660 SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE);
662 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); 661 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
663 SET_TX_DESC_SEQ(pdesc, 0); 662 SET_TX_DESC_SEQ(pdesc, 0);
664 SET_TX_DESC_LINIP(pdesc, 0); 663 SET_TX_DESC_LINIP(pdesc, 0);
665 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); 664 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
index f0f5f9bfbb7b..aff7e19714ff 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
@@ -193,41 +193,6 @@ enum rtl_desc_qsel {
193 QSLT_CMD = 0x13, 193 QSLT_CMD = 0x13,
194}; 194};
195 195
196enum rtl_desc92d_rate {
197 DESC92D_RATE1M = 0x00,
198 DESC92D_RATE2M = 0x01,
199 DESC92D_RATE5_5M = 0x02,
200 DESC92D_RATE11M = 0x03,
201
202 DESC92D_RATE6M = 0x04,
203 DESC92D_RATE9M = 0x05,
204 DESC92D_RATE12M = 0x06,
205 DESC92D_RATE18M = 0x07,
206 DESC92D_RATE24M = 0x08,
207 DESC92D_RATE36M = 0x09,
208 DESC92D_RATE48M = 0x0a,
209 DESC92D_RATE54M = 0x0b,
210
211 DESC92D_RATEMCS0 = 0x0c,
212 DESC92D_RATEMCS1 = 0x0d,
213 DESC92D_RATEMCS2 = 0x0e,
214 DESC92D_RATEMCS3 = 0x0f,
215 DESC92D_RATEMCS4 = 0x10,
216 DESC92D_RATEMCS5 = 0x11,
217 DESC92D_RATEMCS6 = 0x12,
218 DESC92D_RATEMCS7 = 0x13,
219 DESC92D_RATEMCS8 = 0x14,
220 DESC92D_RATEMCS9 = 0x15,
221 DESC92D_RATEMCS10 = 0x16,
222 DESC92D_RATEMCS11 = 0x17,
223 DESC92D_RATEMCS12 = 0x18,
224 DESC92D_RATEMCS13 = 0x19,
225 DESC92D_RATEMCS14 = 0x1a,
226 DESC92D_RATEMCS15 = 0x1b,
227 DESC92D_RATEMCS15_SG = 0x1c,
228 DESC92D_RATEMCS32 = 0x20,
229};
230
231enum channel_plan { 196enum channel_plan {
232 CHPL_FCC = 0, 197 CHPL_FCC = 0,
233 CHPL_IC = 1, 198 CHPL_IC = 1,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index 351765df517d..f6419b7ed2f4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -340,21 +340,21 @@ static struct rtl_hal_cfg rtl92de_hal_cfg = {
340 .maps[RTL_IMR_ROK] = IMR_ROK, 340 .maps[RTL_IMR_ROK] = IMR_ROK,
341 .maps[RTL_IBSS_INT_MASKS] = (IMR_BcnInt | IMR_TBDOK | IMR_TBDER), 341 .maps[RTL_IBSS_INT_MASKS] = (IMR_BcnInt | IMR_TBDOK | IMR_TBDER),
342 342
343 .maps[RTL_RC_CCK_RATE1M] = DESC92D_RATE1M, 343 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
344 .maps[RTL_RC_CCK_RATE2M] = DESC92D_RATE2M, 344 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
345 .maps[RTL_RC_CCK_RATE5_5M] = DESC92D_RATE5_5M, 345 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
346 .maps[RTL_RC_CCK_RATE11M] = DESC92D_RATE11M, 346 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
347 .maps[RTL_RC_OFDM_RATE6M] = DESC92D_RATE6M, 347 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
348 .maps[RTL_RC_OFDM_RATE9M] = DESC92D_RATE9M, 348 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
349 .maps[RTL_RC_OFDM_RATE12M] = DESC92D_RATE12M, 349 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
350 .maps[RTL_RC_OFDM_RATE18M] = DESC92D_RATE18M, 350 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
351 .maps[RTL_RC_OFDM_RATE24M] = DESC92D_RATE24M, 351 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
352 .maps[RTL_RC_OFDM_RATE36M] = DESC92D_RATE36M, 352 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
353 .maps[RTL_RC_OFDM_RATE48M] = DESC92D_RATE48M, 353 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
354 .maps[RTL_RC_OFDM_RATE54M] = DESC92D_RATE54M, 354 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
355 355
356 .maps[RTL_RC_HT_RATEMCS7] = DESC92D_RATEMCS7, 356 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
357 .maps[RTL_RC_HT_RATEMCS15] = DESC92D_RATEMCS15, 357 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
358}; 358};
359 359
360static struct pci_device_id rtl92de_pci_ids[] __devinitdata = { 360static struct pci_device_id rtl92de_pci_ids[] __devinitdata = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
index dc86fcb0b3a3..3637c0c33525 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -48,99 +48,6 @@ static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
48 return skb->priority; 48 return skb->priority;
49} 49}
50 50
51static int _rtl92de_rate_mapping(bool isht, u8 desc_rate)
52{
53 int rate_idx;
54
55 if (false == isht) {
56 switch (desc_rate) {
57 case DESC92D_RATE1M:
58 rate_idx = 0;
59 break;
60 case DESC92D_RATE2M:
61 rate_idx = 1;
62 break;
63 case DESC92D_RATE5_5M:
64 rate_idx = 2;
65 break;
66 case DESC92D_RATE11M:
67 rate_idx = 3;
68 break;
69 case DESC92D_RATE6M:
70 rate_idx = 4;
71 break;
72 case DESC92D_RATE9M:
73 rate_idx = 5;
74 break;
75 case DESC92D_RATE12M:
76 rate_idx = 6;
77 break;
78 case DESC92D_RATE18M:
79 rate_idx = 7;
80 break;
81 case DESC92D_RATE24M:
82 rate_idx = 8;
83 break;
84 case DESC92D_RATE36M:
85 rate_idx = 9;
86 break;
87 case DESC92D_RATE48M:
88 rate_idx = 10;
89 break;
90 case DESC92D_RATE54M:
91 rate_idx = 11;
92 break;
93 default:
94 rate_idx = 0;
95 break;
96 }
97 return rate_idx;
98 } else {
99 switch (desc_rate) {
100 case DESC92D_RATE1M:
101 rate_idx = 0;
102 break;
103 case DESC92D_RATE2M:
104 rate_idx = 1;
105 break;
106 case DESC92D_RATE5_5M:
107 rate_idx = 2;
108 break;
109 case DESC92D_RATE11M:
110 rate_idx = 3;
111 break;
112 case DESC92D_RATE6M:
113 rate_idx = 4;
114 break;
115 case DESC92D_RATE9M:
116 rate_idx = 5;
117 break;
118 case DESC92D_RATE12M:
119 rate_idx = 6;
120 break;
121 case DESC92D_RATE18M:
122 rate_idx = 7;
123 break;
124 case DESC92D_RATE24M:
125 rate_idx = 8;
126 break;
127 case DESC92D_RATE36M:
128 rate_idx = 9;
129 break;
130 case DESC92D_RATE48M:
131 rate_idx = 10;
132 break;
133 case DESC92D_RATE54M:
134 rate_idx = 11;
135 break;
136 default:
137 rate_idx = 11;
138 break;
139 }
140 return rate_idx;
141 }
142}
143
144static u8 _rtl92d_query_rxpwrpercentage(char antpower) 51static u8 _rtl92d_query_rxpwrpercentage(char antpower)
145{ 52{
146 if ((antpower <= -100) || (antpower >= 20)) 53 if ((antpower <= -100) || (antpower >= 20))
@@ -328,8 +235,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
328 pstats->rx_pwdb_all = pwdb_all; 235 pstats->rx_pwdb_all = pwdb_all;
329 pstats->rxpower = rx_pwr_all; 236 pstats->rxpower = rx_pwr_all;
330 pstats->recvsignalpower = rx_pwr_all; 237 pstats->recvsignalpower = rx_pwr_all;
331 if (pdesc->rxht && pdesc->rxmcs >= DESC92D_RATEMCS8 && 238 if (pdesc->rxht && pdesc->rxmcs >= DESC92_RATEMCS8 &&
332 pdesc->rxmcs <= DESC92D_RATEMCS15) 239 pdesc->rxmcs <= DESC92_RATEMCS15)
333 max_spatial_stream = 2; 240 max_spatial_stream = 2;
334 else 241 else
335 max_spatial_stream = 1; 242 max_spatial_stream = 1;
@@ -609,10 +516,10 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
609 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 516 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
610 if (stats->decrypted) 517 if (stats->decrypted)
611 rx_status->flag |= RX_FLAG_DECRYPTED; 518 rx_status->flag |= RX_FLAG_DECRYPTED;
612 rx_status->rate_idx = _rtl92de_rate_mapping((bool) 519 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
613 GET_RX_DESC_RXHT(pdesc), 520 (bool)GET_RX_DESC_RXHT(pdesc),
614 (u8) 521 (u8)GET_RX_DESC_RXMCS(pdesc),
615 GET_RX_DESC_RXMCS(pdesc)); 522 (bool)GET_RX_DESC_PAGGR(pdesc));
616 rx_status->mactime = GET_RX_DESC_TSFL(pdesc); 523 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
617 if (phystatus) { 524 if (phystatus) {
618 p_drvinfo = (struct rx_fwinfo_92d *)(skb->data + 525 p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
@@ -705,14 +612,14 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
705 } 612 }
706 /* 5G have no CCK rate */ 613 /* 5G have no CCK rate */
707 if (rtlhal->current_bandtype == BAND_ON_5G) 614 if (rtlhal->current_bandtype == BAND_ON_5G)
708 if (ptcb_desc->hw_rate < DESC92D_RATE6M) 615 if (ptcb_desc->hw_rate < DESC92_RATE6M)
709 ptcb_desc->hw_rate = DESC92D_RATE6M; 616 ptcb_desc->hw_rate = DESC92_RATE6M;
710 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate); 617 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
711 if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) 618 if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
712 SET_TX_DESC_DATA_SHORTGI(pdesc, 1); 619 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
713 620
714 if (rtlhal->macphymode == DUALMAC_DUALPHY && 621 if (rtlhal->macphymode == DUALMAC_DUALPHY &&
715 ptcb_desc->hw_rate == DESC92D_RATEMCS7) 622 ptcb_desc->hw_rate == DESC92_RATEMCS7)
716 SET_TX_DESC_DATA_SHORTGI(pdesc, 1); 623 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
717 624
718 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 625 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
@@ -728,13 +635,13 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
728 SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); 635 SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
729 /* 5G have no CCK rate */ 636 /* 5G have no CCK rate */
730 if (rtlhal->current_bandtype == BAND_ON_5G) 637 if (rtlhal->current_bandtype == BAND_ON_5G)
731 if (ptcb_desc->rts_rate < DESC92D_RATE6M) 638 if (ptcb_desc->rts_rate < DESC92_RATE6M)
732 ptcb_desc->rts_rate = DESC92D_RATE6M; 639 ptcb_desc->rts_rate = DESC92_RATE6M;
733 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); 640 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
734 SET_TX_DESC_RTS_BW(pdesc, 0); 641 SET_TX_DESC_RTS_BW(pdesc, 0);
735 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); 642 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
736 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= 643 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
737 DESC92D_RATE54M) ? 644 DESC92_RATE54M) ?
738 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : 645 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
739 (ptcb_desc->rts_use_shortgi ? 1 : 0))); 646 (ptcb_desc->rts_use_shortgi ? 1 : 0)));
740 if (bw_40) { 647 if (bw_40) {
@@ -844,9 +751,9 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
844 * The braces are needed no matter what checkpatch says 751 * The braces are needed no matter what checkpatch says
845 */ 752 */
846 if (rtlhal->current_bandtype == BAND_ON_5G) { 753 if (rtlhal->current_bandtype == BAND_ON_5G) {
847 SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE6M); 754 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE6M);
848 } else { 755 } else {
849 SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE1M); 756 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
850 } 757 }
851 SET_TX_DESC_SEQ(pdesc, 0); 758 SET_TX_DESC_SEQ(pdesc, 0);
852 SET_TX_DESC_LINIP(pdesc, 0); 759 SET_TX_DESC_LINIP(pdesc, 0);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
index 992d6766e667..6c2236868c9a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
@@ -538,10 +538,10 @@ do { \
538} while (0); 538} while (0);
539 539
540#define RX_HAL_IS_CCK_RATE(_pdesc)\ 540#define RX_HAL_IS_CCK_RATE(_pdesc)\
541 (_pdesc->rxmcs == DESC92D_RATE1M || \ 541 (_pdesc->rxmcs == DESC92_RATE1M || \
542 _pdesc->rxmcs == DESC92D_RATE2M || \ 542 _pdesc->rxmcs == DESC92_RATE2M || \
543 _pdesc->rxmcs == DESC92D_RATE5_5M || \ 543 _pdesc->rxmcs == DESC92_RATE5_5M || \
544 _pdesc->rxmcs == DESC92D_RATE11M) 544 _pdesc->rxmcs == DESC92_RATE11M)
545 545
546/* For 92D early mode */ 546/* For 92D early mode */
547#define SET_EARLYMODE_PKTNUM(__paddr, __value) \ 547#define SET_EARLYMODE_PKTNUM(__paddr, __value) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index 69828f2b3fab..68204ea175dd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -33,37 +33,6 @@
33#define RX_CMD_QUEUE 1 33#define RX_CMD_QUEUE 1
34#define RX_MAX_QUEUE 2 34#define RX_MAX_QUEUE 2
35 35
36#define DESC92S_RATE1M 0x00
37#define DESC92S_RATE2M 0x01
38#define DESC92S_RATE5_5M 0x02
39#define DESC92S_RATE11M 0x03
40#define DESC92S_RATE6M 0x04
41#define DESC92S_RATE9M 0x05
42#define DESC92S_RATE12M 0x06
43#define DESC92S_RATE18M 0x07
44#define DESC92S_RATE24M 0x08
45#define DESC92S_RATE36M 0x09
46#define DESC92S_RATE48M 0x0a
47#define DESC92S_RATE54M 0x0b
48#define DESC92S_RATEMCS0 0x0c
49#define DESC92S_RATEMCS1 0x0d
50#define DESC92S_RATEMCS2 0x0e
51#define DESC92S_RATEMCS3 0x0f
52#define DESC92S_RATEMCS4 0x10
53#define DESC92S_RATEMCS5 0x11
54#define DESC92S_RATEMCS6 0x12
55#define DESC92S_RATEMCS7 0x13
56#define DESC92S_RATEMCS8 0x14
57#define DESC92S_RATEMCS9 0x15
58#define DESC92S_RATEMCS10 0x16
59#define DESC92S_RATEMCS11 0x17
60#define DESC92S_RATEMCS12 0x18
61#define DESC92S_RATEMCS13 0x19
62#define DESC92S_RATEMCS14 0x1a
63#define DESC92S_RATEMCS15 0x1b
64#define DESC92S_RATEMCS15_SG 0x1c
65#define DESC92S_RATEMCS32 0x20
66
67#define SHORT_SLOT_TIME 9 36#define SHORT_SLOT_TIME 9
68#define NON_SHORT_SLOT_TIME 20 37#define NON_SHORT_SLOT_TIME 20
69 38
@@ -491,10 +460,10 @@ do { \
491 SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val) 460 SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val)
492 461
493#define RX_HAL_IS_CCK_RATE(_pdesc)\ 462#define RX_HAL_IS_CCK_RATE(_pdesc)\
494 (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE1M || \ 463 (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE1M || \
495 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE2M || \ 464 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE2M || \
496 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE5_5M ||\ 465 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE5_5M ||\
497 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE11M) 466 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE11M)
498 467
499enum rf_optype { 468enum rf_optype {
500 RF_OP_BY_SW_3WIRE = 0, 469 RF_OP_BY_SW_3WIRE = 0,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index 3876078a63de..0055a1c845a2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -348,21 +348,21 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = {
348 .maps[RTL_IMR_ROK] = IMR_ROK, 348 .maps[RTL_IMR_ROK] = IMR_ROK,
349 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), 349 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
350 350
351 .maps[RTL_RC_CCK_RATE1M] = DESC92S_RATE1M, 351 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M,
352 .maps[RTL_RC_CCK_RATE2M] = DESC92S_RATE2M, 352 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M,
353 .maps[RTL_RC_CCK_RATE5_5M] = DESC92S_RATE5_5M, 353 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M,
354 .maps[RTL_RC_CCK_RATE11M] = DESC92S_RATE11M, 354 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M,
355 .maps[RTL_RC_OFDM_RATE6M] = DESC92S_RATE6M, 355 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M,
356 .maps[RTL_RC_OFDM_RATE9M] = DESC92S_RATE9M, 356 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M,
357 .maps[RTL_RC_OFDM_RATE12M] = DESC92S_RATE12M, 357 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M,
358 .maps[RTL_RC_OFDM_RATE18M] = DESC92S_RATE18M, 358 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M,
359 .maps[RTL_RC_OFDM_RATE24M] = DESC92S_RATE24M, 359 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M,
360 .maps[RTL_RC_OFDM_RATE36M] = DESC92S_RATE36M, 360 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M,
361 .maps[RTL_RC_OFDM_RATE48M] = DESC92S_RATE48M, 361 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M,
362 .maps[RTL_RC_OFDM_RATE54M] = DESC92S_RATE54M, 362 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M,
363 363
364 .maps[RTL_RC_HT_RATEMCS7] = DESC92S_RATEMCS7, 364 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7,
365 .maps[RTL_RC_HT_RATEMCS15] = DESC92S_RATEMCS15, 365 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
366}; 366};
367 367
368static struct pci_device_id rtl92se_pci_ids[] __devinitdata = { 368static struct pci_device_id rtl92se_pci_ids[] __devinitdata = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index cffe30851f79..d9aeae7f8bdb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -51,104 +51,6 @@ static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue)
51 return skb->priority; 51 return skb->priority;
52} 52}
53 53
54static int _rtl92se_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
55{
56 int rate_idx = 0;
57
58 if (first_ampdu) {
59 if (false == isht) {
60 switch (desc_rate) {
61 case DESC92S_RATE1M:
62 rate_idx = 0;
63 break;
64 case DESC92S_RATE2M:
65 rate_idx = 1;
66 break;
67 case DESC92S_RATE5_5M:
68 rate_idx = 2;
69 break;
70 case DESC92S_RATE11M:
71 rate_idx = 3;
72 break;
73 case DESC92S_RATE6M:
74 rate_idx = 4;
75 break;
76 case DESC92S_RATE9M:
77 rate_idx = 5;
78 break;
79 case DESC92S_RATE12M:
80 rate_idx = 6;
81 break;
82 case DESC92S_RATE18M:
83 rate_idx = 7;
84 break;
85 case DESC92S_RATE24M:
86 rate_idx = 8;
87 break;
88 case DESC92S_RATE36M:
89 rate_idx = 9;
90 break;
91 case DESC92S_RATE48M:
92 rate_idx = 10;
93 break;
94 case DESC92S_RATE54M:
95 rate_idx = 11;
96 break;
97 default:
98 rate_idx = 0;
99 break;
100 }
101 } else {
102 rate_idx = 11;
103 }
104
105 return rate_idx;
106 }
107
108 switch (desc_rate) {
109 case DESC92S_RATE1M:
110 rate_idx = 0;
111 break;
112 case DESC92S_RATE2M:
113 rate_idx = 1;
114 break;
115 case DESC92S_RATE5_5M:
116 rate_idx = 2;
117 break;
118 case DESC92S_RATE11M:
119 rate_idx = 3;
120 break;
121 case DESC92S_RATE6M:
122 rate_idx = 4;
123 break;
124 case DESC92S_RATE9M:
125 rate_idx = 5;
126 break;
127 case DESC92S_RATE12M:
128 rate_idx = 6;
129 break;
130 case DESC92S_RATE18M:
131 rate_idx = 7;
132 break;
133 case DESC92S_RATE24M:
134 rate_idx = 8;
135 break;
136 case DESC92S_RATE36M:
137 rate_idx = 9;
138 break;
139 case DESC92S_RATE48M:
140 rate_idx = 10;
141 break;
142 case DESC92S_RATE54M:
143 rate_idx = 11;
144 break;
145 default:
146 rate_idx = 11;
147 break;
148 }
149 return rate_idx;
150}
151
152static u8 _rtl92s_query_rxpwrpercentage(char antpower) 54static u8 _rtl92s_query_rxpwrpercentage(char antpower)
153{ 55{
154 if ((antpower <= -100) || (antpower >= 20)) 56 if ((antpower <= -100) || (antpower >= 20))
@@ -345,8 +247,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
345 pstats->recvsignalpower = rx_pwr_all; 247 pstats->recvsignalpower = rx_pwr_all;
346 248
347 if (GET_RX_STATUS_DESC_RX_HT(pdesc) && 249 if (GET_RX_STATUS_DESC_RX_HT(pdesc) &&
348 GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92S_RATEMCS8 && 250 GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92_RATEMCS8 &&
349 GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92S_RATEMCS15) 251 GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92_RATEMCS15)
350 max_spatial_stream = 2; 252 max_spatial_stream = 2;
351 else 253 else
352 max_spatial_stream = 1; 254 max_spatial_stream = 1;
@@ -654,10 +556,10 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
654 if (stats->decrypted) 556 if (stats->decrypted)
655 rx_status->flag |= RX_FLAG_DECRYPTED; 557 rx_status->flag |= RX_FLAG_DECRYPTED;
656 558
657 rx_status->rate_idx = _rtl92se_rate_mapping((bool) 559 rx_status->rate_idx = rtlwifi_rate_mapping(hw,
658 GET_RX_STATUS_DESC_RX_HT(pdesc), 560 (bool)GET_RX_STATUS_DESC_RX_HT(pdesc),
659 (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc), 561 (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc),
660 (bool)GET_RX_STATUS_DESC_PAGGR(pdesc)); 562 (bool)GET_RX_STATUS_DESC_PAGGR(pdesc));
661 563
662 564
663 rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc); 565 rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc);
@@ -723,14 +625,14 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
723 SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid); 625 SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
724 626
725 SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >= 627 SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
726 DESC92S_RATEMCS0) ? 1 : 0)); 628 DESC92_RATEMCS0) ? 1 : 0));
727 629
728 if (rtlhal->version == VERSION_8192S_ACUT) { 630 if (rtlhal->version == VERSION_8192S_ACUT) {
729 if (ptcb_desc->hw_rate == DESC92S_RATE1M || 631 if (ptcb_desc->hw_rate == DESC92_RATE1M ||
730 ptcb_desc->hw_rate == DESC92S_RATE2M || 632 ptcb_desc->hw_rate == DESC92_RATE2M ||
731 ptcb_desc->hw_rate == DESC92S_RATE5_5M || 633 ptcb_desc->hw_rate == DESC92_RATE5_5M ||
732 ptcb_desc->hw_rate == DESC92S_RATE11M) { 634 ptcb_desc->hw_rate == DESC92_RATE11M) {
733 ptcb_desc->hw_rate = DESC92S_RATE12M; 635 ptcb_desc->hw_rate = DESC92_RATE12M;
734 } 636 }
735 } 637 }
736 638
@@ -759,7 +661,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
759 SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0); 661 SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
760 SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc); 662 SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
761 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= 663 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
762 DESC92S_RATE54M) ? 664 DESC92_RATE54M) ?
763 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) 665 (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
764 : (ptcb_desc->rts_use_shortgi ? 1 : 0))); 666 : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
765 667
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index d3c3ffd38984..8a9091968f31 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -386,6 +386,41 @@ enum rtl_hal_state {
386 _HAL_STATE_START = 1, 386 _HAL_STATE_START = 1,
387}; 387};
388 388
389enum rtl_desc92_rate {
390 DESC92_RATE1M = 0x00,
391 DESC92_RATE2M = 0x01,
392 DESC92_RATE5_5M = 0x02,
393 DESC92_RATE11M = 0x03,
394
395 DESC92_RATE6M = 0x04,
396 DESC92_RATE9M = 0x05,
397 DESC92_RATE12M = 0x06,
398 DESC92_RATE18M = 0x07,
399 DESC92_RATE24M = 0x08,
400 DESC92_RATE36M = 0x09,
401 DESC92_RATE48M = 0x0a,
402 DESC92_RATE54M = 0x0b,
403
404 DESC92_RATEMCS0 = 0x0c,
405 DESC92_RATEMCS1 = 0x0d,
406 DESC92_RATEMCS2 = 0x0e,
407 DESC92_RATEMCS3 = 0x0f,
408 DESC92_RATEMCS4 = 0x10,
409 DESC92_RATEMCS5 = 0x11,
410 DESC92_RATEMCS6 = 0x12,
411 DESC92_RATEMCS7 = 0x13,
412 DESC92_RATEMCS8 = 0x14,
413 DESC92_RATEMCS9 = 0x15,
414 DESC92_RATEMCS10 = 0x16,
415 DESC92_RATEMCS11 = 0x17,
416 DESC92_RATEMCS12 = 0x18,
417 DESC92_RATEMCS13 = 0x19,
418 DESC92_RATEMCS14 = 0x1a,
419 DESC92_RATEMCS15 = 0x1b,
420 DESC92_RATEMCS15_SG = 0x1c,
421 DESC92_RATEMCS32 = 0x20,
422};
423
389enum rtl_var_map { 424enum rtl_var_map {
390 /*reg map */ 425 /*reg map */
391 SYS_ISO_CTRL = 0, 426 SYS_ISO_CTRL = 0,
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c
index c77e0543e502..f81a93e5b59d 100644
--- a/drivers/nfc/pn533.c
+++ b/drivers/nfc/pn533.c
@@ -1246,7 +1246,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb)
1246{ 1246{
1247 int payload_len = skb->len; 1247 int payload_len = skb->len;
1248 struct pn533_frame *out_frame; 1248 struct pn533_frame *out_frame;
1249 struct sk_buff *discarded;
1250 u8 tg; 1249 u8 tg;
1251 1250
1252 nfc_dev_dbg(&dev->interface->dev, "%s - Sending %d bytes", __func__, 1251 nfc_dev_dbg(&dev->interface->dev, "%s - Sending %d bytes", __func__,
@@ -1260,18 +1259,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb)
1260 return -ENOSYS; 1259 return -ENOSYS;
1261 } 1260 }
1262 1261
1263 /* Reserving header space */
1264 if (skb_cow_head(skb, PN533_CMD_DATAEXCH_HEAD_LEN)) {
1265 nfc_dev_err(&dev->interface->dev, "Error to add header data");
1266 return -ENOMEM;
1267 }
1268
1269 /* Reserving tail space, see pn533_tx_frame_finish */
1270 if (skb_cow_data(skb, PN533_FRAME_TAIL_SIZE, &discarded) < 0) {
1271 nfc_dev_err(&dev->interface->dev, "Error to add tail data");
1272 return -ENOMEM;
1273 }
1274
1275 skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); 1262 skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN);
1276 out_frame = (struct pn533_frame *) skb->data; 1263 out_frame = (struct pn533_frame *) skb->data;
1277 1264
@@ -1536,7 +1523,9 @@ static int pn533_probe(struct usb_interface *interface,
1536 | NFC_PROTO_ISO14443_MASK 1523 | NFC_PROTO_ISO14443_MASK
1537 | NFC_PROTO_NFC_DEP_MASK; 1524 | NFC_PROTO_NFC_DEP_MASK;
1538 1525
1539 dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols); 1526 dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
1527 PN533_CMD_DATAEXCH_HEAD_LEN,
1528 PN533_FRAME_TAIL_SIZE);
1540 if (!dev->nfc_dev) 1529 if (!dev->nfc_dev)
1541 goto kill_tasklet; 1530 goto kill_tasklet;
1542 1531
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 29c7d4f9d1ae..d0cbdb0cf9d5 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1260,16 +1260,34 @@ void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
1260} 1260}
1261EXPORT_SYMBOL(ssb_device_disable); 1261EXPORT_SYMBOL(ssb_device_disable);
1262 1262
1263/* Some chipsets need routing known for PCIe and 64-bit DMA */
1264static bool ssb_dma_translation_special_bit(struct ssb_device *dev)
1265{
1266 u16 chip_id = dev->bus->chip_id;
1267
1268 if (dev->id.coreid == SSB_DEV_80211) {
1269 return (chip_id == 0x4322 || chip_id == 43221 ||
1270 chip_id == 43231 || chip_id == 43222);
1271 }
1272
1273 return 0;
1274}
1275
1263u32 ssb_dma_translation(struct ssb_device *dev) 1276u32 ssb_dma_translation(struct ssb_device *dev)
1264{ 1277{
1265 switch (dev->bus->bustype) { 1278 switch (dev->bus->bustype) {
1266 case SSB_BUSTYPE_SSB: 1279 case SSB_BUSTYPE_SSB:
1267 return 0; 1280 return 0;
1268 case SSB_BUSTYPE_PCI: 1281 case SSB_BUSTYPE_PCI:
1269 if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64) 1282 if (pci_is_pcie(dev->bus->host_pci) &&
1283 ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64) {
1270 return SSB_PCIE_DMA_H32; 1284 return SSB_PCIE_DMA_H32;
1271 else 1285 } else {
1272 return SSB_PCI_DMA; 1286 if (ssb_dma_translation_special_bit(dev))
1287 return SSB_PCIE_DMA_H32;
1288 else
1289 return SSB_PCI_DMA;
1290 }
1273 default: 1291 default:
1274 __ssb_dma_not_implemented(dev); 1292 __ssb_dma_not_implemented(dev);
1275 } 1293 }
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 6083725dd22e..a7ae33d06f24 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -283,6 +283,22 @@
283#define BCMA_CC_PPL_PCHI_OFF 5 283#define BCMA_CC_PPL_PCHI_OFF 5
284#define BCMA_CC_PPL_PCHI_MASK 0x0000003f 284#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
285 285
286/* BCM4331 ChipControl numbers. */
287#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
288#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
289#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
290#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
291#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
292#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
293#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
294#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
295#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
296#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
297#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
298#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
299#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
300#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
301
286/* Data for the PMU, if available. 302/* Data for the PMU, if available.
287 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) 303 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
288 */ 304 */
@@ -342,6 +358,8 @@ extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
342extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); 358extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
343extern void bcma_chipco_resume(struct bcma_drv_cc *cc); 359extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
344 360
361void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
362
345extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, 363extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
346 u32 ticks); 364 u32 ticks);
347 365
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 54c878960872..37f95f2e10f9 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -629,9 +629,14 @@ struct ieee80211_rann_ie {
629 u8 rann_ttl; 629 u8 rann_ttl;
630 u8 rann_addr[6]; 630 u8 rann_addr[6];
631 u32 rann_seq; 631 u32 rann_seq;
632 u32 rann_interval;
632 u32 rann_metric; 633 u32 rann_metric;
633} __attribute__ ((packed)); 634} __attribute__ ((packed));
634 635
636enum ieee80211_rann_flags {
637 RANN_FLAG_IS_GATE = 1 << 0,
638};
639
635#define WLAN_SA_QUERY_TR_ID_LEN 2 640#define WLAN_SA_QUERY_TR_ID_LEN 2
636 641
637struct ieee80211_mgmt { 642struct ieee80211_mgmt {
@@ -736,19 +741,10 @@ struct ieee80211_mgmt {
736 __le16 params; 741 __le16 params;
737 __le16 reason_code; 742 __le16 reason_code;
738 } __attribute__((packed)) delba; 743 } __attribute__((packed)) delba;
739 struct{ 744 struct {
740 u8 action_code; 745 u8 action_code;
741 /* capab_info for open and confirm,
742 * reason for close
743 */
744 __le16 aux;
745 /* Followed in plink_confirm by status
746 * code, AID and supported rates,
747 * and directly by supported rates in
748 * plink_open and plink_close
749 */
750 u8 variable[0]; 746 u8 variable[0];
751 } __attribute__((packed)) plink_action; 747 } __attribute__((packed)) self_prot;
752 struct{ 748 struct{
753 u8 action_code; 749 u8 action_code;
754 u8 variable[0]; 750 u8 variable[0];
@@ -816,9 +812,11 @@ struct ieee80211_bar {
816} __attribute__((packed)); 812} __attribute__((packed));
817 813
818/* 802.11 BAR control masks */ 814/* 802.11 BAR control masks */
819#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 815#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000
820#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 816#define IEEE80211_BAR_CTRL_MULTI_TID 0x0002
821 817#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004
818#define IEEE80211_BAR_CTRL_TID_INFO_MASK 0xf000
819#define IEEE80211_BAR_CTRL_TID_INFO_SHIFT 12
822 820
823#define IEEE80211_HT_MCS_MASK_LEN 10 821#define IEEE80211_HT_MCS_MASK_LEN 10
824 822
@@ -1194,11 +1192,6 @@ enum ieee80211_eid {
1194 WLAN_EID_MESH_ID = 114, 1192 WLAN_EID_MESH_ID = 114,
1195 WLAN_EID_LINK_METRIC_REPORT = 115, 1193 WLAN_EID_LINK_METRIC_REPORT = 115,
1196 WLAN_EID_CONGESTION_NOTIFICATION = 116, 1194 WLAN_EID_CONGESTION_NOTIFICATION = 116,
1197 /* Note that the Peer Link IE has been replaced with the similar
1198 * Peer Management IE. We will keep the former definition until mesh
1199 * code is changed to comply with latest 802.11s drafts.
1200 */
1201 WLAN_EID_PEER_LINK = 55, /* no longer in 802.11s drafts */
1202 WLAN_EID_PEER_MGMT = 117, 1195 WLAN_EID_PEER_MGMT = 117,
1203 WLAN_EID_CHAN_SWITCH_PARAM = 118, 1196 WLAN_EID_CHAN_SWITCH_PARAM = 118,
1204 WLAN_EID_MESH_AWAKE_WINDOW = 119, 1197 WLAN_EID_MESH_AWAKE_WINDOW = 119,
@@ -1281,9 +1274,6 @@ enum ieee80211_category {
1281 WLAN_CATEGORY_MULTIHOP_ACTION = 14, 1274 WLAN_CATEGORY_MULTIHOP_ACTION = 14,
1282 WLAN_CATEGORY_SELF_PROTECTED = 15, 1275 WLAN_CATEGORY_SELF_PROTECTED = 15,
1283 WLAN_CATEGORY_WMM = 17, 1276 WLAN_CATEGORY_WMM = 17,
1284 /* TODO: remove MESH_PATH_SEL after mesh is updated
1285 * to current 802.11s draft */
1286 WLAN_CATEGORY_MESH_PATH_SEL = 32,
1287 WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, 1277 WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
1288 WLAN_CATEGORY_VENDOR_SPECIFIC = 127, 1278 WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
1289}; 1279};
@@ -1309,6 +1299,31 @@ enum ieee80211_ht_actioncode {
1309 WLAN_HT_ACTION_ASEL_IDX_FEEDBACK = 7, 1299 WLAN_HT_ACTION_ASEL_IDX_FEEDBACK = 7,
1310}; 1300};
1311 1301
1302/* Self Protected Action codes */
1303enum ieee80211_self_protected_actioncode {
1304 WLAN_SP_RESERVED = 0,
1305 WLAN_SP_MESH_PEERING_OPEN = 1,
1306 WLAN_SP_MESH_PEERING_CONFIRM = 2,
1307 WLAN_SP_MESH_PEERING_CLOSE = 3,
1308 WLAN_SP_MGK_INFORM = 4,
1309 WLAN_SP_MGK_ACK = 5,
1310};
1311
1312/* Mesh action codes */
1313enum ieee80211_mesh_actioncode {
1314 WLAN_MESH_ACTION_LINK_METRIC_REPORT,
1315 WLAN_MESH_ACTION_HWMP_PATH_SELECTION,
1316 WLAN_MESH_ACTION_GATE_ANNOUNCEMENT,
1317 WLAN_MESH_ACTION_CONGESTION_CONTROL_NOTIFICATION,
1318 WLAN_MESH_ACTION_MCCA_SETUP_REQUEST,
1319 WLAN_MESH_ACTION_MCCA_SETUP_REPLY,
1320 WLAN_MESH_ACTION_MCCA_ADVERTISEMENT_REQUEST,
1321 WLAN_MESH_ACTION_MCCA_ADVERTISEMENT,
1322 WLAN_MESH_ACTION_MCCA_TEARDOWN,
1323 WLAN_MESH_ACTION_TBTT_ADJUSTMENT_REQUEST,
1324 WLAN_MESH_ACTION_TBTT_ADJUSTMENT_RESPONSE,
1325};
1326
1312/* Security key length */ 1327/* Security key length */
1313enum ieee80211_key_len { 1328enum ieee80211_key_len {
1314 WLAN_KEY_LEN_WEP40 = 5, 1329 WLAN_KEY_LEN_WEP40 = 5,
diff --git a/include/linux/nfc.h b/include/linux/nfc.h
index 330a4c5db588..c525e0b5876b 100644
--- a/include/linux/nfc.h
+++ b/include/linux/nfc.h
@@ -123,4 +123,6 @@ struct sockaddr_nfc {
123#define NFC_SOCKPROTO_RAW 0 123#define NFC_SOCKPROTO_RAW 0
124#define NFC_SOCKPROTO_MAX 1 124#define NFC_SOCKPROTO_MAX 1
125 125
126#define NFC_HEADER_SIZE 1
127
126#endif /*__LINUX_NFC_H */ 128#endif /*__LINUX_NFC_H */
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 89dec16b4697..0343504082a8 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1042,6 +1042,9 @@ enum nl80211_commands {
1042 * (Re)Association Response frames when the driver (or firmware) replies to 1042 * (Re)Association Response frames when the driver (or firmware) replies to
1043 * (Re)Association Request frames. 1043 * (Re)Association Request frames.
1044 * 1044 *
1045 * @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration
1046 * of the station, see &enum nl80211_sta_wme_attr.
1047 *
1045 * @NL80211_ATTR_MAX: highest attribute number currently defined 1048 * @NL80211_ATTR_MAX: highest attribute number currently defined
1046 * @__NL80211_ATTR_AFTER_LAST: internal use 1049 * @__NL80211_ATTR_AFTER_LAST: internal use
1047 */ 1050 */
@@ -1252,6 +1255,8 @@ enum nl80211_attrs {
1252 NL80211_ATTR_IE_PROBE_RESP, 1255 NL80211_ATTR_IE_PROBE_RESP,
1253 NL80211_ATTR_IE_ASSOC_RESP, 1256 NL80211_ATTR_IE_ASSOC_RESP,
1254 1257
1258 NL80211_ATTR_STA_WME,
1259
1255 /* add attributes here, update the policy in nl80211.c */ 1260 /* add attributes here, update the policy in nl80211.c */
1256 1261
1257 __NL80211_ATTR_AFTER_LAST, 1262 __NL80211_ATTR_AFTER_LAST,
@@ -1861,6 +1866,13 @@ enum nl80211_mntr_flags {
1861 * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a 1866 * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
1862 * source mesh point for path selection elements. 1867 * source mesh point for path selection elements.
1863 * 1868 *
1869 * @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between
1870 * root announcements are transmitted.
1871 *
1872 * @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has
1873 * access to a broader network beyond the MBSS. This is done via Root
1874 * Announcement frames.
1875 *
1864 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute 1876 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
1865 * 1877 *
1866 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use 1878 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -1882,6 +1894,8 @@ enum nl80211_meshconf_params {
1882 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, 1894 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
1883 NL80211_MESHCONF_HWMP_ROOTMODE, 1895 NL80211_MESHCONF_HWMP_ROOTMODE,
1884 NL80211_MESHCONF_ELEMENT_TTL, 1896 NL80211_MESHCONF_ELEMENT_TTL,
1897 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
1898 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
1885 1899
1886 /* keep last */ 1900 /* keep last */
1887 __NL80211_MESHCONF_ATTR_AFTER_LAST, 1901 __NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -2473,4 +2487,22 @@ enum nl80211_hidden_ssid {
2473 NL80211_HIDDEN_SSID_ZERO_CONTENTS 2487 NL80211_HIDDEN_SSID_ZERO_CONTENTS
2474}; 2488};
2475 2489
2490/**
2491 * enum nl80211_sta_wme_attr - station WME attributes
2492 * @__NL80211_STA_WME_INVALID: invalid number for nested attribute
2493 * @NL80211_STA_WME_QUEUES: bitmap of uapsd queues.
2494 * @NL80211_STA_WME_MAX_SP: max service period.
2495 * @__NL80211_STA_WME_AFTER_LAST: internal
2496 * @NL80211_STA_WME_MAX: highest station WME attribute
2497 */
2498enum nl80211_sta_wme_attr {
2499 __NL80211_STA_WME_INVALID,
2500 NL80211_STA_WME_UAPSD_QUEUES,
2501 NL80211_STA_WME_MAX_SP,
2502
2503 /* keep last */
2504 __NL80211_STA_WME_AFTER_LAST,
2505 NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1
2506};
2507
2476#endif /* __LINUX_NL80211_H */ 2508#endif /* __LINUX_NL80211_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d86a15d87e58..88112ca59c8e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -452,6 +452,8 @@ struct station_parameters {
452 u8 plink_action; 452 u8 plink_action;
453 u8 plink_state; 453 u8 plink_state;
454 struct ieee80211_ht_cap *ht_capa; 454 struct ieee80211_ht_cap *ht_capa;
455 u8 uapsd_queues;
456 u8 max_sp;
455}; 457};
456 458
457/** 459/**
@@ -755,6 +757,12 @@ struct mesh_config {
755 u16 dot11MeshHWMPpreqMinInterval; 757 u16 dot11MeshHWMPpreqMinInterval;
756 u16 dot11MeshHWMPnetDiameterTraversalTime; 758 u16 dot11MeshHWMPnetDiameterTraversalTime;
757 u8 dot11MeshHWMPRootMode; 759 u8 dot11MeshHWMPRootMode;
760 u16 dot11MeshHWMPRannInterval;
761 /* This is missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol
762 * set to true only means that the station will announce others it's a
763 * mesh gate, but not necessarily using the gate announcement protocol.
764 * Still keeping the same nomenclature to be in sync with the spec. */
765 bool dot11MeshGateAnnouncementProtocol;
758}; 766};
759 767
760/** 768/**
@@ -2291,7 +2299,7 @@ struct ieee802_11_elems {
2291 struct ieee80211_ht_info *ht_info_elem; 2299 struct ieee80211_ht_info *ht_info_elem;
2292 struct ieee80211_meshconf_ie *mesh_config; 2300 struct ieee80211_meshconf_ie *mesh_config;
2293 u8 *mesh_id; 2301 u8 *mesh_id;
2294 u8 *peer_link; 2302 u8 *peering;
2295 u8 *preq; 2303 u8 *preq;
2296 u8 *prep; 2304 u8 *prep;
2297 u8 *perr; 2305 u8 *perr;
@@ -2318,7 +2326,7 @@ struct ieee802_11_elems {
2318 u8 wmm_info_len; 2326 u8 wmm_info_len;
2319 u8 wmm_param_len; 2327 u8 wmm_param_len;
2320 u8 mesh_id_len; 2328 u8 mesh_id_len;
2321 u8 peer_link_len; 2329 u8 peering_len;
2322 u8 preq_len; 2330 u8 preq_len;
2323 u8 prep_len; 2331 u8 prep_len;
2324 u8 perr_len; 2332 u8 perr_len;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 2f01d84ca52f..2e752df57510 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -954,6 +954,8 @@ struct ieee80211_sta {
954 u16 aid; 954 u16 aid;
955 struct ieee80211_sta_ht_cap ht_cap; 955 struct ieee80211_sta_ht_cap ht_cap;
956 bool wme; 956 bool wme;
957 u8 uapsd_queues;
958 u8 max_sp;
957 959
958 /* must be last */ 960 /* must be last */
959 u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); 961 u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
diff --git a/include/net/nfc.h b/include/net/nfc.h
index cc0130312f70..87b51fe15b70 100644
--- a/include/net/nfc.h
+++ b/include/net/nfc.h
@@ -82,6 +82,9 @@ struct nfc_dev {
82 struct nfc_genl_data genl_data; 82 struct nfc_genl_data genl_data;
83 u32 supported_protocols; 83 u32 supported_protocols;
84 84
85 int tx_headroom;
86 int tx_tailroom;
87
85 struct nfc_ops *ops; 88 struct nfc_ops *ops;
86}; 89};
87#define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) 90#define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev)
@@ -89,7 +92,9 @@ struct nfc_dev {
89extern struct class nfc_class; 92extern struct class nfc_class;
90 93
91struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, 94struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
92 u32 supported_protocols); 95 u32 supported_protocols,
96 int tx_headroom,
97 int tx_tailroom);
93 98
94/** 99/**
95 * nfc_free_device - free nfc device 100 * nfc_free_device - free nfc device
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index 356d6e3dc20a..eb7d3c2d4274 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -3,11 +3,19 @@
3/* 3/*
4 * regulatory support structures 4 * regulatory support structures
5 * 5 *
6 * Copyright 2008-2009 Luis R. Rodriguez <lrodriguez@atheros.com> 6 * Copyright 2008-2009 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Permission to use, copy, modify, and/or distribute this software for any
9 * it under the terms of the GNU General Public License version 2 as 9 * purpose with or without fee is hereby granted, provided that the above
10 * published by the Free Software Foundation. 10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
11 */ 19 */
12 20
13 21
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index f5fdfcbf552a..d1886b59bec4 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -199,6 +199,19 @@ config MAC80211_VERBOSE_MPL_DEBUG
199 199
200 Do not select this option. 200 Do not select this option.
201 201
202config MAC80211_VERBOSE_MPATH_DEBUG
203 bool "Verbose mesh path debugging"
204 depends on MAC80211_DEBUG_MENU
205 depends on MAC80211_MESH
206 ---help---
207 Selecting this option causes mac80211 to print out very
208 verbose mesh path selection debugging messages (when mac80211
209 is taking part in a mesh network).
210 It should not be selected on production systems as those
211 messages are remotely triggerable.
212
213 Do not select this option.
214
202config MAC80211_VERBOSE_MHWMP_DEBUG 215config MAC80211_VERBOSE_MHWMP_DEBUG
203 bool "Verbose mesh HWMP routing debugging" 216 bool "Verbose mesh HWMP routing debugging"
204 depends on MAC80211_DEBUG_MENU 217 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index b7075f33dc06..018108d1a2fd 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -128,7 +128,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
128 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN); 128 memcpy(bar->ta, sdata->vif.addr, ETH_ALEN);
129 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; 129 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
130 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; 130 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
131 bar_control |= (u16)(tid << 12); 131 bar_control |= (u16)(tid << IEEE80211_BAR_CTRL_TID_INFO_SHIFT);
132 bar->control = cpu_to_le16(bar_control); 132 bar->control = cpu_to_le16(bar_control);
133 bar->start_seq_num = cpu_to_le16(ssn); 133 bar->start_seq_num = cpu_to_le16(ssn);
134 134
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a589addf6ce1..4baa03b1c251 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -697,6 +697,9 @@ static void sta_apply_parameters(struct ieee80211_local *local,
697 } 697 }
698 spin_unlock_irqrestore(&sta->flaglock, flags); 698 spin_unlock_irqrestore(&sta->flaglock, flags);
699 699
700 sta->sta.uapsd_queues = params->uapsd_queues;
701 sta->sta.max_sp = params->max_sp;
702
700 /* 703 /*
701 * cfg80211 validates this (1-2007) and allows setting the AID 704 * cfg80211 validates this (1-2007) and allows setting the AID
702 * only when creating a new station entry 705 * only when creating a new station entry
@@ -1137,6 +1140,22 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1137 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode; 1140 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
1138 ieee80211_mesh_root_setup(ifmsh); 1141 ieee80211_mesh_root_setup(ifmsh);
1139 } 1142 }
1143 if (_chg_mesh_attr(NL80211_MESHCONF_GATE_ANNOUNCEMENTS, mask)) {
1144 /* our current gate announcement implementation rides on root
1145 * announcements, so require this ifmsh to also be a root node
1146 * */
1147 if (nconf->dot11MeshGateAnnouncementProtocol &&
1148 !conf->dot11MeshHWMPRootMode) {
1149 conf->dot11MeshHWMPRootMode = 1;
1150 ieee80211_mesh_root_setup(ifmsh);
1151 }
1152 conf->dot11MeshGateAnnouncementProtocol =
1153 nconf->dot11MeshGateAnnouncementProtocol;
1154 }
1155 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) {
1156 conf->dot11MeshHWMPRannInterval =
1157 nconf->dot11MeshHWMPRannInterval;
1158 }
1140 return 0; 1159 return 0;
1141} 1160}
1142 1161
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 9ea7c0d0103f..6e8eab7919e2 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -372,6 +372,10 @@ IEEE80211_IF_FILE(min_discovery_timeout,
372 u.mesh.mshcfg.min_discovery_timeout, DEC); 372 u.mesh.mshcfg.min_discovery_timeout, DEC);
373IEEE80211_IF_FILE(dot11MeshHWMPRootMode, 373IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
374 u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); 374 u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
375IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
376 u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
377IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
378 u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
375#endif 379#endif
376 380
377 381
@@ -485,7 +489,9 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
485 MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries); 489 MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries);
486 MESHPARAMS_ADD(path_refresh_time); 490 MESHPARAMS_ADD(path_refresh_time);
487 MESHPARAMS_ADD(min_discovery_timeout); 491 MESHPARAMS_ADD(min_discovery_timeout);
488 492 MESHPARAMS_ADD(dot11MeshHWMPRootMode);
493 MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
494 MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
489#undef MESHPARAMS_ADD 495#undef MESHPARAMS_ADD
490} 496}
491#endif 497#endif
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ea7419050846..c204cee1189c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -514,6 +514,7 @@ struct ieee80211_if_mesh {
514 struct mesh_config mshcfg; 514 struct mesh_config mshcfg;
515 u32 mesh_seqnum; 515 u32 mesh_seqnum;
516 bool accepting_plinks; 516 bool accepting_plinks;
517 int num_gates;
517 const u8 *ie; 518 const u8 *ie;
518 u8 ie_len; 519 u8 ie_len;
519 enum { 520 enum {
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 29e9980c8e60..28ab510e621a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -13,10 +13,6 @@
13#include "ieee80211_i.h" 13#include "ieee80211_i.h"
14#include "mesh.h" 14#include "mesh.h"
15 15
16#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
17#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
18#define IEEE80211_MESH_RANN_INTERVAL (1 * HZ)
19
20#define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01 16#define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01
21#define MESHCONF_CAPAB_FORWARDING 0x08 17#define MESHCONF_CAPAB_FORWARDING 0x08
22 18
@@ -27,6 +23,17 @@
27int mesh_allocated; 23int mesh_allocated;
28static struct kmem_cache *rm_cache; 24static struct kmem_cache *rm_cache;
29 25
26#ifdef CONFIG_MAC80211_MESH
27bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
28{
29 return (mgmt->u.action.u.mesh_action.action_code ==
30 WLAN_MESH_ACTION_HWMP_PATH_SELECTION);
31}
32#else
33bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
34{ return false; }
35#endif
36
30void ieee80211s_init(void) 37void ieee80211s_init(void)
31{ 38{
32 mesh_pathtbl_init(); 39 mesh_pathtbl_init();
@@ -204,36 +211,185 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
204 return 0; 211 return 0;
205} 212}
206 213
207void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) 214int
215mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
216{
217 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
218 u8 *pos, neighbors;
219 u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie);
220
221 if (skb_tailroom(skb) < 2 + meshconf_len)
222 return -ENOMEM;
223
224 pos = skb_put(skb, 2 + meshconf_len);
225 *pos++ = WLAN_EID_MESH_CONFIG;
226 *pos++ = meshconf_len;
227
228 /* Active path selection protocol ID */
229 *pos++ = ifmsh->mesh_pp_id;
230 /* Active path selection metric ID */
231 *pos++ = ifmsh->mesh_pm_id;
232 /* Congestion control mode identifier */
233 *pos++ = ifmsh->mesh_cc_id;
234 /* Synchronization protocol identifier */
235 *pos++ = ifmsh->mesh_sp_id;
236 /* Authentication Protocol identifier */
237 *pos++ = ifmsh->mesh_auth_id;
238 /* Mesh Formation Info - number of neighbors */
239 neighbors = atomic_read(&ifmsh->mshstats.estab_plinks);
240 /* Number of neighbor mesh STAs or 15 whichever is smaller */
241 neighbors = (neighbors > 15) ? 15 : neighbors;
242 *pos++ = neighbors << 1;
243 /* Mesh capability */
244 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
245 *pos = MESHCONF_CAPAB_FORWARDING;
246 *pos++ |= ifmsh->accepting_plinks ?
247 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
248 *pos++ = 0x00;
249
250 return 0;
251}
252
253int
254mesh_add_meshid_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
255{
256 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
257 u8 *pos;
258
259 if (skb_tailroom(skb) < 2 + ifmsh->mesh_id_len)
260 return -ENOMEM;
261
262 pos = skb_put(skb, 2 + ifmsh->mesh_id_len);
263 *pos++ = WLAN_EID_MESH_ID;
264 *pos++ = ifmsh->mesh_id_len;
265 if (ifmsh->mesh_id_len)
266 memcpy(pos, ifmsh->mesh_id, ifmsh->mesh_id_len);
267
268 return 0;
269}
270
271int
272mesh_add_vendor_ies(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
273{
274 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
275 u8 offset, len;
276 const u8 *data;
277
278 if (!ifmsh->ie || !ifmsh->ie_len)
279 return 0;
280
281 /* fast-forward to vendor IEs */
282 offset = ieee80211_ie_split_vendor(ifmsh->ie, ifmsh->ie_len, 0);
283
284 if (offset) {
285 len = ifmsh->ie_len - offset;
286 data = ifmsh->ie + offset;
287 if (skb_tailroom(skb) < len)
288 return -ENOMEM;
289 memcpy(skb_put(skb, len), data, len);
290 }
291
292 return 0;
293}
294
295int
296mesh_add_rsn_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
297{
298 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
299 u8 len = 0;
300 const u8 *data;
301
302 if (!ifmsh->ie || !ifmsh->ie_len)
303 return 0;
304
305 /* find RSN IE */
306 data = ifmsh->ie;
307 while (data < ifmsh->ie + ifmsh->ie_len) {
308 if (*data == WLAN_EID_RSN) {
309 len = data[1] + 2;
310 break;
311 }
312 data++;
313 }
314
315 if (len) {
316 if (skb_tailroom(skb) < len)
317 return -ENOMEM;
318 memcpy(skb_put(skb, len), data, len);
319 }
320
321 return 0;
322}
323
324int
325mesh_add_srates_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
208{ 326{
209 struct ieee80211_local *local = sdata->local; 327 struct ieee80211_local *local = sdata->local;
210 struct ieee80211_supported_band *sband; 328 struct ieee80211_supported_band *sband;
211 u8 *pos; 329 int rate;
212 int len, i, rate; 330 u8 i, rates, *pos;
213 u8 neighbors;
214 331
215 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 332 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
216 len = sband->n_bitrates; 333 rates = sband->n_bitrates;
217 if (len > 8) 334 if (rates > 8)
218 len = 8; 335 rates = 8;
219 pos = skb_put(skb, len + 2); 336
337 if (skb_tailroom(skb) < rates + 2)
338 return -ENOMEM;
339
340 pos = skb_put(skb, rates + 2);
220 *pos++ = WLAN_EID_SUPP_RATES; 341 *pos++ = WLAN_EID_SUPP_RATES;
221 *pos++ = len; 342 *pos++ = rates;
222 for (i = 0; i < len; i++) { 343 for (i = 0; i < rates; i++) {
223 rate = sband->bitrates[i].bitrate; 344 rate = sband->bitrates[i].bitrate;
224 *pos++ = (u8) (rate / 5); 345 *pos++ = (u8) (rate / 5);
225 } 346 }
226 347
227 if (sband->n_bitrates > len) { 348 return 0;
228 pos = skb_put(skb, sband->n_bitrates - len + 2); 349}
350
351int
352mesh_add_ext_srates_ie(struct sk_buff *skb,
353 struct ieee80211_sub_if_data *sdata)
354{
355 struct ieee80211_local *local = sdata->local;
356 struct ieee80211_supported_band *sband;
357 int rate;
358 u8 i, exrates, *pos;
359
360 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
361 exrates = sband->n_bitrates;
362 if (exrates > 8)
363 exrates -= 8;
364 else
365 exrates = 0;
366
367 if (skb_tailroom(skb) < exrates + 2)
368 return -ENOMEM;
369
370 if (exrates) {
371 pos = skb_put(skb, exrates + 2);
229 *pos++ = WLAN_EID_EXT_SUPP_RATES; 372 *pos++ = WLAN_EID_EXT_SUPP_RATES;
230 *pos++ = sband->n_bitrates - len; 373 *pos++ = exrates;
231 for (i = len; i < sband->n_bitrates; i++) { 374 for (i = 8; i < sband->n_bitrates; i++) {
232 rate = sband->bitrates[i].bitrate; 375 rate = sband->bitrates[i].bitrate;
233 *pos++ = (u8) (rate / 5); 376 *pos++ = (u8) (rate / 5);
234 } 377 }
235 } 378 }
379 return 0;
380}
236 381
382int mesh_add_ds_params_ie(struct sk_buff *skb,
383 struct ieee80211_sub_if_data *sdata)
384{
385 struct ieee80211_local *local = sdata->local;
386 struct ieee80211_supported_band *sband;
387 u8 *pos;
388
389 if (skb_tailroom(skb) < 3)
390 return -ENOMEM;
391
392 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
237 if (sband->band == IEEE80211_BAND_2GHZ) { 393 if (sband->band == IEEE80211_BAND_2GHZ) {
238 pos = skb_put(skb, 2 + 1); 394 pos = skb_put(skb, 2 + 1);
239 *pos++ = WLAN_EID_DS_PARAMS; 395 *pos++ = WLAN_EID_DS_PARAMS;
@@ -241,53 +397,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
241 *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq); 397 *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq);
242 } 398 }
243 399
244 pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len); 400 return 0;
245 *pos++ = WLAN_EID_MESH_ID;
246 *pos++ = sdata->u.mesh.mesh_id_len;
247 if (sdata->u.mesh.mesh_id_len)
248 memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len);
249
250 pos = skb_put(skb, 2 + sizeof(struct ieee80211_meshconf_ie));
251 *pos++ = WLAN_EID_MESH_CONFIG;
252 *pos++ = sizeof(struct ieee80211_meshconf_ie);
253
254 /* Active path selection protocol ID */
255 *pos++ = sdata->u.mesh.mesh_pp_id;
256
257 /* Active path selection metric ID */
258 *pos++ = sdata->u.mesh.mesh_pm_id;
259
260 /* Congestion control mode identifier */
261 *pos++ = sdata->u.mesh.mesh_cc_id;
262
263 /* Synchronization protocol identifier */
264 *pos++ = sdata->u.mesh.mesh_sp_id;
265
266 /* Authentication Protocol identifier */
267 *pos++ = sdata->u.mesh.mesh_auth_id;
268
269 /* Mesh Formation Info - number of neighbors */
270 neighbors = atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
271 /* Number of neighbor mesh STAs or 15 whichever is smaller */
272 neighbors = (neighbors > 15) ? 15 : neighbors;
273 *pos++ = neighbors << 1;
274
275 /* Mesh capability */
276 sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata);
277 *pos = MESHCONF_CAPAB_FORWARDING;
278 *pos++ |= sdata->u.mesh.accepting_plinks ?
279 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
280 *pos++ = 0x00;
281
282 if (sdata->u.mesh.ie) {
283 int len = sdata->u.mesh.ie_len;
284 const u8 *data = sdata->u.mesh.ie;
285 if (skb_tailroom(skb) > len)
286 memcpy(skb_put(skb, len), data, len);
287 }
288} 401}
289 402
290
291static void ieee80211_mesh_path_timer(unsigned long data) 403static void ieee80211_mesh_path_timer(unsigned long data)
292{ 404{
293 struct ieee80211_sub_if_data *sdata = 405 struct ieee80211_sub_if_data *sdata =
@@ -425,7 +537,8 @@ static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
425 537
426 mesh_path_tx_root_frame(sdata); 538 mesh_path_tx_root_frame(sdata);
427 mod_timer(&ifmsh->mesh_path_root_timer, 539 mod_timer(&ifmsh->mesh_path_root_timer,
428 round_jiffies(jiffies + IEEE80211_MESH_RANN_INTERVAL)); 540 round_jiffies(TU_TO_EXP_TIME(
541 ifmsh->mshcfg.dot11MeshHWMPRannInterval)));
429} 542}
430 543
431#ifdef CONFIG_PM 544#ifdef CONFIG_PM
@@ -433,7 +546,7 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
433{ 546{
434 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 547 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
435 548
436 /* use atomic bitops in case both timers fire at the same time */ 549 /* use atomic bitops in case all timers fire at the same time */
437 550
438 if (del_timer_sync(&ifmsh->housekeeping_timer)) 551 if (del_timer_sync(&ifmsh->housekeeping_timer))
439 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); 552 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
@@ -557,11 +670,18 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
557 struct ieee80211_rx_status *rx_status) 670 struct ieee80211_rx_status *rx_status)
558{ 671{
559 switch (mgmt->u.action.category) { 672 switch (mgmt->u.action.category) {
560 case WLAN_CATEGORY_MESH_ACTION: 673 case WLAN_CATEGORY_SELF_PROTECTED:
561 mesh_rx_plink_frame(sdata, mgmt, len, rx_status); 674 switch (mgmt->u.action.u.self_prot.action_code) {
675 case WLAN_SP_MESH_PEERING_OPEN:
676 case WLAN_SP_MESH_PEERING_CLOSE:
677 case WLAN_SP_MESH_PEERING_CONFIRM:
678 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
679 break;
680 }
562 break; 681 break;
563 case WLAN_CATEGORY_MESH_PATH_SEL: 682 case WLAN_CATEGORY_MESH_ACTION:
564 mesh_rx_path_sel_frame(sdata, mgmt, len); 683 if (mesh_action_is_path_sel(mgmt))
684 mesh_rx_path_sel_frame(sdata, mgmt, len);
565 break; 685 break;
566 } 686 }
567} 687}
@@ -633,6 +753,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
633 ifmsh->accepting_plinks = true; 753 ifmsh->accepting_plinks = true;
634 ifmsh->preq_id = 0; 754 ifmsh->preq_id = 0;
635 ifmsh->sn = 0; 755 ifmsh->sn = 0;
756 ifmsh->num_gates = 0;
636 atomic_set(&ifmsh->mpaths, 0); 757 atomic_set(&ifmsh->mpaths, 0);
637 mesh_rmc_init(sdata); 758 mesh_rmc_init(sdata);
638 ifmsh->last_preq = jiffies; 759 ifmsh->last_preq = jiffies;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 249e733362e7..20272072171f 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -81,6 +81,7 @@ enum mesh_deferred_task_flags {
81 * @discovery_retries: number of discovery retries 81 * @discovery_retries: number of discovery retries
82 * @flags: mesh path flags, as specified on &enum mesh_path_flags 82 * @flags: mesh path flags, as specified on &enum mesh_path_flags
83 * @state_lock: mesh path state lock 83 * @state_lock: mesh path state lock
84 * @is_gate: the destination station of this path is a mesh gate
84 * 85 *
85 * 86 *
86 * The combination of dst and sdata is unique in the mesh path table. Since the 87 * The combination of dst and sdata is unique in the mesh path table. Since the
@@ -104,6 +105,7 @@ struct mesh_path {
104 u8 discovery_retries; 105 u8 discovery_retries;
105 enum mesh_path_flags flags; 106 enum mesh_path_flags flags;
106 spinlock_t state_lock; 107 spinlock_t state_lock;
108 bool is_gate;
107}; 109};
108 110
109/** 111/**
@@ -120,6 +122,9 @@ struct mesh_path {
120 * buckets 122 * buckets
121 * @mean_chain_len: maximum average length for the hash buckets' list, if it is 123 * @mean_chain_len: maximum average length for the hash buckets' list, if it is
122 * reached, the table will grow 124 * reached, the table will grow
125 * @known_gates: list of known mesh gates and their mpaths by the station. The
126 * gate's mpath may or may not be resolved and active.
127 *
123 * rcu_head: RCU head to free the table 128 * rcu_head: RCU head to free the table
124 */ 129 */
125struct mesh_table { 130struct mesh_table {
@@ -133,6 +138,8 @@ struct mesh_table {
133 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); 138 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
134 int size_order; 139 int size_order;
135 int mean_chain_len; 140 int mean_chain_len;
141 struct hlist_head *known_gates;
142 spinlock_t gates_lock;
136 143
137 struct rcu_head rcu_head; 144 struct rcu_head rcu_head;
138}; 145};
@@ -166,6 +173,8 @@ struct mesh_rmc {
166 u32 idx_mask; 173 u32 idx_mask;
167}; 174};
168 175
176#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
177#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
169 178
170#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */ 179#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
171 180
@@ -177,14 +186,6 @@ struct mesh_rmc {
177/* Maximum number of paths per interface */ 186/* Maximum number of paths per interface */
178#define MESH_MAX_MPATHS 1024 187#define MESH_MAX_MPATHS 1024
179 188
180/* Pending ANA approval */
181#define MESH_PATH_SEL_ACTION 0
182
183/* PERR reason codes */
184#define PEER_RCODE_UNSPECIFIED 11
185#define PERR_RCODE_NO_ROUTE 12
186#define PERR_RCODE_DEST_UNREACH 13
187
188/* Public interfaces */ 189/* Public interfaces */
189/* Various */ 190/* Various */
190int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 191int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
@@ -199,6 +200,20 @@ bool mesh_matches_local(struct ieee802_11_elems *ie,
199void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); 200void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
200void mesh_mgmt_ies_add(struct sk_buff *skb, 201void mesh_mgmt_ies_add(struct sk_buff *skb,
201 struct ieee80211_sub_if_data *sdata); 202 struct ieee80211_sub_if_data *sdata);
203int mesh_add_meshconf_ie(struct sk_buff *skb,
204 struct ieee80211_sub_if_data *sdata);
205int mesh_add_meshid_ie(struct sk_buff *skb,
206 struct ieee80211_sub_if_data *sdata);
207int mesh_add_rsn_ie(struct sk_buff *skb,
208 struct ieee80211_sub_if_data *sdata);
209int mesh_add_vendor_ies(struct sk_buff *skb,
210 struct ieee80211_sub_if_data *sdata);
211int mesh_add_srates_ie(struct sk_buff *skb,
212 struct ieee80211_sub_if_data *sdata);
213int mesh_add_ext_srates_ie(struct sk_buff *skb,
214 struct ieee80211_sub_if_data *sdata);
215int mesh_add_ds_params_ie(struct sk_buff *skb,
216 struct ieee80211_sub_if_data *sdata);
202void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 217void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
203int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 218int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
204void ieee80211s_init(void); 219void ieee80211s_init(void);
@@ -227,6 +242,10 @@ void mesh_path_flush(struct ieee80211_sub_if_data *sdata);
227void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 242void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
228 struct ieee80211_mgmt *mgmt, size_t len); 243 struct ieee80211_mgmt *mgmt, size_t len);
229int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); 244int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
245
246int mesh_path_add_gate(struct mesh_path *mpath);
247int mesh_path_send_to_gates(struct mesh_path *mpath);
248int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
230/* Mesh plinks */ 249/* Mesh plinks */
231void mesh_neighbour_update(u8 *hw_addr, u32 rates, 250void mesh_neighbour_update(u8 *hw_addr, u32 rates,
232 struct ieee80211_sub_if_data *sdata, 251 struct ieee80211_sub_if_data *sdata,
@@ -262,6 +281,7 @@ void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
262void mesh_path_restart(struct ieee80211_sub_if_data *sdata); 281void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
263void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); 282void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
264 283
284bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
265extern int mesh_paths_generation; 285extern int mesh_paths_generation;
266 286
267#ifdef CONFIG_MAC80211_MESH 287#ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 3d8e55ae6ab6..fd4f76a3e139 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -11,7 +11,8 @@
11#include "mesh.h" 11#include "mesh.h"
12 12
13#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG 13#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG
14#define mhwmp_dbg(fmt, args...) printk(KERN_DEBUG "Mesh HWMP: " fmt, ##args) 14#define mhwmp_dbg(fmt, args...) \
15 printk(KERN_DEBUG "Mesh HWMP (%s): " fmt "\n", sdata->name, ##args)
15#else 16#else
16#define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) 17#define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0)
17#endif 18#endif
@@ -68,12 +69,12 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
68#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) 69#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x)
69#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) 70#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x)
70#define PREP_IE_TTL(x) PREQ_IE_TTL(x) 71#define PREP_IE_TTL(x) PREQ_IE_TTL(x)
71#define PREP_IE_ORIG_ADDR(x) (x + 3) 72#define PREP_IE_ORIG_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21)
72#define PREP_IE_ORIG_SN(x) u32_field_get(x, 9, 0) 73#define PREP_IE_ORIG_SN(x) u32_field_get(x, 27, AE_F_SET(x))
73#define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x)) 74#define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x))
74#define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x)) 75#define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x))
75#define PREP_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21) 76#define PREP_IE_TARGET_ADDR(x) (x + 3)
76#define PREP_IE_TARGET_SN(x) u32_field_get(x, 27, AE_F_SET(x)) 77#define PREP_IE_TARGET_SN(x) u32_field_get(x, 9, 0)
77 78
78#define PERR_IE_TTL(x) (*(x)) 79#define PERR_IE_TTL(x) (*(x))
79#define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) 80#define PERR_IE_TARGET_FLAGS(x) (*(x + 2))
@@ -132,24 +133,25 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
132 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 133 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
133 /* BSSID == SA */ 134 /* BSSID == SA */
134 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 135 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
135 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; 136 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
136 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 137 mgmt->u.action.u.mesh_action.action_code =
138 WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
137 139
138 switch (action) { 140 switch (action) {
139 case MPATH_PREQ: 141 case MPATH_PREQ:
140 mhwmp_dbg("sending PREQ to %pM\n", target); 142 mhwmp_dbg("sending PREQ to %pM", target);
141 ie_len = 37; 143 ie_len = 37;
142 pos = skb_put(skb, 2 + ie_len); 144 pos = skb_put(skb, 2 + ie_len);
143 *pos++ = WLAN_EID_PREQ; 145 *pos++ = WLAN_EID_PREQ;
144 break; 146 break;
145 case MPATH_PREP: 147 case MPATH_PREP:
146 mhwmp_dbg("sending PREP to %pM\n", target); 148 mhwmp_dbg("sending PREP to %pM", target);
147 ie_len = 31; 149 ie_len = 31;
148 pos = skb_put(skb, 2 + ie_len); 150 pos = skb_put(skb, 2 + ie_len);
149 *pos++ = WLAN_EID_PREP; 151 *pos++ = WLAN_EID_PREP;
150 break; 152 break;
151 case MPATH_RANN: 153 case MPATH_RANN:
152 mhwmp_dbg("sending RANN from %pM\n", orig_addr); 154 mhwmp_dbg("sending RANN from %pM", orig_addr);
153 ie_len = sizeof(struct ieee80211_rann_ie); 155 ie_len = sizeof(struct ieee80211_rann_ie);
154 pos = skb_put(skb, 2 + ie_len); 156 pos = skb_put(skb, 2 + ie_len);
155 *pos++ = WLAN_EID_RANN; 157 *pos++ = WLAN_EID_RANN;
@@ -163,29 +165,37 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
163 *pos++ = flags; 165 *pos++ = flags;
164 *pos++ = hop_count; 166 *pos++ = hop_count;
165 *pos++ = ttl; 167 *pos++ = ttl;
166 if (action == MPATH_PREQ) { 168 if (action == MPATH_PREP) {
167 memcpy(pos, &preq_id, 4); 169 memcpy(pos, target, ETH_ALEN);
170 pos += ETH_ALEN;
171 memcpy(pos, &target_sn, 4);
168 pos += 4; 172 pos += 4;
169 } 173 } else {
170 memcpy(pos, orig_addr, ETH_ALEN); 174 if (action == MPATH_PREQ) {
171 pos += ETH_ALEN; 175 memcpy(pos, &preq_id, 4);
172 memcpy(pos, &orig_sn, 4); 176 pos += 4;
173 pos += 4; 177 }
174 if (action != MPATH_RANN) { 178 memcpy(pos, orig_addr, ETH_ALEN);
175 memcpy(pos, &lifetime, 4); 179 pos += ETH_ALEN;
180 memcpy(pos, &orig_sn, 4);
176 pos += 4; 181 pos += 4;
177 } 182 }
183 memcpy(pos, &lifetime, 4); /* interval for RANN */
184 pos += 4;
178 memcpy(pos, &metric, 4); 185 memcpy(pos, &metric, 4);
179 pos += 4; 186 pos += 4;
180 if (action == MPATH_PREQ) { 187 if (action == MPATH_PREQ) {
181 /* destination count */ 188 *pos++ = 1; /* destination count */
182 *pos++ = 1;
183 *pos++ = target_flags; 189 *pos++ = target_flags;
184 }
185 if (action != MPATH_RANN) {
186 memcpy(pos, target, ETH_ALEN); 190 memcpy(pos, target, ETH_ALEN);
187 pos += ETH_ALEN; 191 pos += ETH_ALEN;
188 memcpy(pos, &target_sn, 4); 192 memcpy(pos, &target_sn, 4);
193 pos += 4;
194 } else if (action == MPATH_PREP) {
195 memcpy(pos, orig_addr, ETH_ALEN);
196 pos += ETH_ALEN;
197 memcpy(pos, &orig_sn, 4);
198 pos += 4;
189 } 199 }
190 200
191 ieee80211_tx_skb(sdata, skb); 201 ieee80211_tx_skb(sdata, skb);
@@ -224,9 +234,11 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
224 234
225 memcpy(mgmt->da, ra, ETH_ALEN); 235 memcpy(mgmt->da, ra, ETH_ALEN);
226 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 236 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
227 /* BSSID is left zeroed, wildcard value */ 237 /* BSSID == SA */
228 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL; 238 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
229 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 239 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
240 mgmt->u.action.u.mesh_action.action_code =
241 WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
230 ie_len = 15; 242 ie_len = 15;
231 pos = skb_put(skb, 2 + ie_len); 243 pos = skb_put(skb, 2 + ie_len);
232 *pos++ = WLAN_EID_PERR; 244 *pos++ = WLAN_EID_PERR;
@@ -483,10 +495,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
483 orig_sn = PREQ_IE_ORIG_SN(preq_elem); 495 orig_sn = PREQ_IE_ORIG_SN(preq_elem);
484 target_flags = PREQ_IE_TARGET_F(preq_elem); 496 target_flags = PREQ_IE_TARGET_F(preq_elem);
485 497
486 mhwmp_dbg("received PREQ from %pM\n", orig_addr); 498 mhwmp_dbg("received PREQ from %pM", orig_addr);
487 499
488 if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) { 500 if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) {
489 mhwmp_dbg("PREQ is for us\n"); 501 mhwmp_dbg("PREQ is for us");
490 forward = false; 502 forward = false;
491 reply = true; 503 reply = true;
492 metric = 0; 504 metric = 0;
@@ -522,7 +534,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
522 lifetime = PREQ_IE_LIFETIME(preq_elem); 534 lifetime = PREQ_IE_LIFETIME(preq_elem);
523 ttl = ifmsh->mshcfg.element_ttl; 535 ttl = ifmsh->mshcfg.element_ttl;
524 if (ttl != 0) { 536 if (ttl != 0) {
525 mhwmp_dbg("replying to the PREQ\n"); 537 mhwmp_dbg("replying to the PREQ");
526 mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr, 538 mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr,
527 cpu_to_le32(target_sn), 0, orig_addr, 539 cpu_to_le32(target_sn), 0, orig_addr,
528 cpu_to_le32(orig_sn), mgmt->sa, 0, ttl, 540 cpu_to_le32(orig_sn), mgmt->sa, 0, ttl,
@@ -542,7 +554,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
542 ifmsh->mshstats.dropped_frames_ttl++; 554 ifmsh->mshstats.dropped_frames_ttl++;
543 return; 555 return;
544 } 556 }
545 mhwmp_dbg("forwarding the PREQ from %pM\n", orig_addr); 557 mhwmp_dbg("forwarding the PREQ from %pM", orig_addr);
546 --ttl; 558 --ttl;
547 flags = PREQ_IE_FLAGS(preq_elem); 559 flags = PREQ_IE_FLAGS(preq_elem);
548 preq_id = PREQ_IE_PREQ_ID(preq_elem); 560 preq_id = PREQ_IE_PREQ_ID(preq_elem);
@@ -577,7 +589,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
577 u8 next_hop[ETH_ALEN]; 589 u8 next_hop[ETH_ALEN];
578 u32 target_sn, orig_sn, lifetime; 590 u32 target_sn, orig_sn, lifetime;
579 591
580 mhwmp_dbg("received PREP from %pM\n", PREP_IE_ORIG_ADDR(prep_elem)); 592 mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem));
581 593
582 /* Note that we divert from the draft nomenclature and denominate 594 /* Note that we divert from the draft nomenclature and denominate
583 * destination to what the draft refers to as origininator. So in this 595 * destination to what the draft refers to as origininator. So in this
@@ -683,6 +695,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
683 u8 ttl, flags, hopcount; 695 u8 ttl, flags, hopcount;
684 u8 *orig_addr; 696 u8 *orig_addr;
685 u32 orig_sn, metric; 697 u32 orig_sn, metric;
698 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
699 bool root_is_gate;
686 700
687 ttl = rann->rann_ttl; 701 ttl = rann->rann_ttl;
688 if (ttl <= 1) { 702 if (ttl <= 1) {
@@ -691,12 +705,19 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
691 } 705 }
692 ttl--; 706 ttl--;
693 flags = rann->rann_flags; 707 flags = rann->rann_flags;
708 root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
694 orig_addr = rann->rann_addr; 709 orig_addr = rann->rann_addr;
695 orig_sn = rann->rann_seq; 710 orig_sn = rann->rann_seq;
696 hopcount = rann->rann_hopcount; 711 hopcount = rann->rann_hopcount;
697 hopcount++; 712 hopcount++;
698 metric = rann->rann_metric; 713 metric = rann->rann_metric;
699 mhwmp_dbg("received RANN from %pM\n", orig_addr); 714
715 /* Ignore our own RANNs */
716 if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
717 return;
718
719 mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr,
720 root_is_gate);
700 721
701 rcu_read_lock(); 722 rcu_read_lock();
702 mpath = mesh_path_lookup(orig_addr, sdata); 723 mpath = mesh_path_lookup(orig_addr, sdata);
@@ -708,18 +729,28 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
708 sdata->u.mesh.mshstats.dropped_frames_no_route++; 729 sdata->u.mesh.mshstats.dropped_frames_no_route++;
709 return; 730 return;
710 } 731 }
711 mesh_queue_preq(mpath,
712 PREQ_Q_F_START | PREQ_Q_F_REFRESH);
713 } 732 }
733
734 if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
735 time_after(jiffies, mpath->exp_time - 1*HZ)) &&
736 !(mpath->flags & MESH_PATH_FIXED)) {
737 mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
738 orig_addr);
739 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
740 }
741
714 if (mpath->sn < orig_sn) { 742 if (mpath->sn < orig_sn) {
715 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 743 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
716 cpu_to_le32(orig_sn), 744 cpu_to_le32(orig_sn),
717 0, NULL, 0, broadcast_addr, 745 0, NULL, 0, broadcast_addr,
718 hopcount, ttl, 0, 746 hopcount, ttl, cpu_to_le32(interval),
719 cpu_to_le32(metric + mpath->metric), 747 cpu_to_le32(metric + mpath->metric),
720 0, sdata); 748 0, sdata);
721 mpath->sn = orig_sn; 749 mpath->sn = orig_sn;
722 } 750 }
751 if (root_is_gate)
752 mesh_path_add_gate(mpath);
753
723 rcu_read_unlock(); 754 rcu_read_unlock();
724} 755}
725 756
@@ -787,7 +818,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
787 818
788 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); 819 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC);
789 if (!preq_node) { 820 if (!preq_node) {
790 mhwmp_dbg("could not allocate PREQ node\n"); 821 mhwmp_dbg("could not allocate PREQ node");
791 return; 822 return;
792 } 823 }
793 824
@@ -796,7 +827,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
796 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); 827 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
797 kfree(preq_node); 828 kfree(preq_node);
798 if (printk_ratelimit()) 829 if (printk_ratelimit())
799 mhwmp_dbg("PREQ node queue full\n"); 830 mhwmp_dbg("PREQ node queue full");
800 return; 831 return;
801 } 832 }
802 833
@@ -981,35 +1012,46 @@ void mesh_path_timer(unsigned long data)
981{ 1012{
982 struct mesh_path *mpath = (void *) data; 1013 struct mesh_path *mpath = (void *) data;
983 struct ieee80211_sub_if_data *sdata = mpath->sdata; 1014 struct ieee80211_sub_if_data *sdata = mpath->sdata;
1015 int ret;
984 1016
985 if (sdata->local->quiescing) 1017 if (sdata->local->quiescing)
986 return; 1018 return;
987 1019
988 spin_lock_bh(&mpath->state_lock); 1020 spin_lock_bh(&mpath->state_lock);
989 if (mpath->flags & MESH_PATH_RESOLVED || 1021 if (mpath->flags & MESH_PATH_RESOLVED ||
990 (!(mpath->flags & MESH_PATH_RESOLVING))) 1022 (!(mpath->flags & MESH_PATH_RESOLVING))) {
991 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); 1023 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
992 else if (mpath->discovery_retries < max_preq_retries(sdata)) { 1024 spin_unlock_bh(&mpath->state_lock);
1025 } else if (mpath->discovery_retries < max_preq_retries(sdata)) {
993 ++mpath->discovery_retries; 1026 ++mpath->discovery_retries;
994 mpath->discovery_timeout *= 2; 1027 mpath->discovery_timeout *= 2;
1028 spin_unlock_bh(&mpath->state_lock);
995 mesh_queue_preq(mpath, 0); 1029 mesh_queue_preq(mpath, 0);
996 } else { 1030 } else {
997 mpath->flags = 0; 1031 mpath->flags = 0;
998 mpath->exp_time = jiffies; 1032 mpath->exp_time = jiffies;
999 mesh_path_flush_pending(mpath); 1033 spin_unlock_bh(&mpath->state_lock);
1034 if (!mpath->is_gate && mesh_gate_num(sdata) > 0) {
1035 ret = mesh_path_send_to_gates(mpath);
1036 if (ret)
1037 mhwmp_dbg("no gate was reachable");
1038 } else
1039 mesh_path_flush_pending(mpath);
1000 } 1040 }
1001
1002 spin_unlock_bh(&mpath->state_lock);
1003} 1041}
1004 1042
1005void 1043void
1006mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) 1044mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1007{ 1045{
1008 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1046 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1047 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
1048 u8 flags;
1009 1049
1010 mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->vif.addr, 1050 flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
1051 ? RANN_FLAG_IS_GATE : 0;
1052 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
1011 cpu_to_le32(++ifmsh->sn), 1053 cpu_to_le32(++ifmsh->sn),
1012 0, NULL, 0, broadcast_addr, 1054 0, NULL, 0, broadcast_addr,
1013 0, sdata->u.mesh.mshcfg.element_ttl, 1055 0, sdata->u.mesh.mshcfg.element_ttl,
1014 0, 0, 0, sdata); 1056 cpu_to_le32(interval), 0, 0, sdata);
1015} 1057}
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index dc7ae8d31aaf..7fde32159fdc 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -17,6 +17,12 @@
17#include "ieee80211_i.h" 17#include "ieee80211_i.h"
18#include "mesh.h" 18#include "mesh.h"
19 19
20#ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG
21#define mpath_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args)
22#else
23#define mpath_dbg(fmt, args...) do { (void)(0); } while (0)
24#endif
25
20/* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */ 26/* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */
21#define INIT_PATHS_SIZE_ORDER 2 27#define INIT_PATHS_SIZE_ORDER 2
22 28
@@ -60,6 +66,8 @@ static inline struct mesh_table *resize_dereference_mpp_paths(void)
60 lockdep_is_held(&pathtbl_resize_lock)); 66 lockdep_is_held(&pathtbl_resize_lock));
61} 67}
62 68
69static int mesh_gate_add(struct mesh_table *tbl, struct mesh_path *mpath);
70
63/* 71/*
64 * CAREFUL -- "tbl" must not be an expression, 72 * CAREFUL -- "tbl" must not be an expression,
65 * in particular not an rcu_dereference(), since 73 * in particular not an rcu_dereference(), since
@@ -103,6 +111,7 @@ static struct mesh_table *mesh_table_alloc(int size_order)
103 sizeof(newtbl->hash_rnd)); 111 sizeof(newtbl->hash_rnd));
104 for (i = 0; i <= newtbl->hash_mask; i++) 112 for (i = 0; i <= newtbl->hash_mask; i++)
105 spin_lock_init(&newtbl->hashwlock[i]); 113 spin_lock_init(&newtbl->hashwlock[i]);
114 spin_lock_init(&newtbl->gates_lock);
106 115
107 return newtbl; 116 return newtbl;
108} 117}
@@ -118,6 +127,7 @@ static void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
118{ 127{
119 struct hlist_head *mesh_hash; 128 struct hlist_head *mesh_hash;
120 struct hlist_node *p, *q; 129 struct hlist_node *p, *q;
130 struct mpath_node *gate;
121 int i; 131 int i;
122 132
123 mesh_hash = tbl->hash_buckets; 133 mesh_hash = tbl->hash_buckets;
@@ -129,6 +139,17 @@ static void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
129 } 139 }
130 spin_unlock_bh(&tbl->hashwlock[i]); 140 spin_unlock_bh(&tbl->hashwlock[i]);
131 } 141 }
142 if (free_leafs) {
143 spin_lock_bh(&tbl->gates_lock);
144 hlist_for_each_entry_safe(gate, p, q,
145 tbl->known_gates, list) {
146 hlist_del(&gate->list);
147 kfree(gate);
148 }
149 kfree(tbl->known_gates);
150 spin_unlock_bh(&tbl->gates_lock);
151 }
152
132 __mesh_table_free(tbl); 153 __mesh_table_free(tbl);
133} 154}
134 155
@@ -146,6 +167,7 @@ static int mesh_table_grow(struct mesh_table *oldtbl,
146 newtbl->free_node = oldtbl->free_node; 167 newtbl->free_node = oldtbl->free_node;
147 newtbl->mean_chain_len = oldtbl->mean_chain_len; 168 newtbl->mean_chain_len = oldtbl->mean_chain_len;
148 newtbl->copy_node = oldtbl->copy_node; 169 newtbl->copy_node = oldtbl->copy_node;
170 newtbl->known_gates = oldtbl->known_gates;
149 atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries)); 171 atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries));
150 172
151 oldhash = oldtbl->hash_buckets; 173 oldhash = oldtbl->hash_buckets;
@@ -205,6 +227,111 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
205 spin_unlock_irqrestore(&mpath->frame_queue.lock, flags); 227 spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
206} 228}
207 229
230static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
231 struct mesh_path *gate_mpath)
232{
233 struct ieee80211_hdr *hdr;
234 struct ieee80211s_hdr *mshdr;
235 int mesh_hdrlen, hdrlen;
236 char *next_hop;
237
238 hdr = (struct ieee80211_hdr *) skb->data;
239 hdrlen = ieee80211_hdrlen(hdr->frame_control);
240 mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
241
242 if (!(mshdr->flags & MESH_FLAGS_AE)) {
243 /* size of the fixed part of the mesh header */
244 mesh_hdrlen = 6;
245
246 /* make room for the two extended addresses */
247 skb_push(skb, 2 * ETH_ALEN);
248 memmove(skb->data, hdr, hdrlen + mesh_hdrlen);
249
250 hdr = (struct ieee80211_hdr *) skb->data;
251
252 /* we preserve the previous mesh header and only add
253 * the new addreses */
254 mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
255 mshdr->flags = MESH_FLAGS_AE_A5_A6;
256 memcpy(mshdr->eaddr1, hdr->addr3, ETH_ALEN);
257 memcpy(mshdr->eaddr2, hdr->addr4, ETH_ALEN);
258 }
259
260 /* update next hop */
261 hdr = (struct ieee80211_hdr *) skb->data;
262 rcu_read_lock();
263 next_hop = rcu_dereference(gate_mpath->next_hop)->sta.addr;
264 memcpy(hdr->addr1, next_hop, ETH_ALEN);
265 rcu_read_unlock();
266 memcpy(hdr->addr3, dst_addr, ETH_ALEN);
267}
268
269/**
270 *
271 * mesh_path_move_to_queue - Move or copy frames from one mpath queue to another
272 *
273 * This function is used to transfer or copy frames from an unresolved mpath to
274 * a gate mpath. The function also adds the Address Extension field and
275 * updates the next hop.
276 *
277 * If a frame already has an Address Extension field, only the next hop and
278 * destination addresses are updated.
279 *
280 * The gate mpath must be an active mpath with a valid mpath->next_hop.
281 *
282 * @mpath: An active mpath the frames will be sent to (i.e. the gate)
283 * @from_mpath: The failed mpath
284 * @copy: When true, copy all the frames to the new mpath queue. When false,
285 * move them.
286 */
287static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
288 struct mesh_path *from_mpath,
289 bool copy)
290{
291 struct sk_buff *skb, *cp_skb = NULL;
292 struct sk_buff_head gateq, failq;
293 unsigned long flags;
294 int num_skbs;
295
296 BUG_ON(gate_mpath == from_mpath);
297 BUG_ON(!gate_mpath->next_hop);
298
299 __skb_queue_head_init(&gateq);
300 __skb_queue_head_init(&failq);
301
302 spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
303 skb_queue_splice_init(&from_mpath->frame_queue, &failq);
304 spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);
305
306 num_skbs = skb_queue_len(&failq);
307
308 while (num_skbs--) {
309 skb = __skb_dequeue(&failq);
310 if (copy)
311 cp_skb = skb_copy(skb, GFP_ATOMIC);
312
313 prepare_for_gate(skb, gate_mpath->dst, gate_mpath);
314 __skb_queue_tail(&gateq, skb);
315
316 if (copy && cp_skb)
317 __skb_queue_tail(&failq, cp_skb);
318 }
319
320 spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags);
321 skb_queue_splice(&gateq, &gate_mpath->frame_queue);
322 mpath_dbg("Mpath queue for gate %pM has %d frames\n",
323 gate_mpath->dst,
324 skb_queue_len(&gate_mpath->frame_queue));
325 spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags);
326
327 if (!copy)
328 return;
329
330 spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
331 skb_queue_splice(&failq, &from_mpath->frame_queue);
332 spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);
333}
334
208 335
209/** 336/**
210 * mesh_path_lookup - look up a path in the mesh path table 337 * mesh_path_lookup - look up a path in the mesh path table
@@ -304,6 +431,109 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
304 return NULL; 431 return NULL;
305} 432}
306 433
434static void mesh_gate_node_reclaim(struct rcu_head *rp)
435{
436 struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
437 kfree(node);
438}
439
440/**
441 * mesh_gate_add - mark mpath as path to a mesh gate and add to known_gates
442 * @mesh_tbl: table which contains known_gates list
443 * @mpath: mpath to known mesh gate
444 *
445 * Returns: 0 on success
446 *
447 */
448static int mesh_gate_add(struct mesh_table *tbl, struct mesh_path *mpath)
449{
450 struct mpath_node *gate, *new_gate;
451 struct hlist_node *n;
452 int err;
453
454 rcu_read_lock();
455 tbl = rcu_dereference(tbl);
456
457 hlist_for_each_entry_rcu(gate, n, tbl->known_gates, list)
458 if (gate->mpath == mpath) {
459 err = -EEXIST;
460 goto err_rcu;
461 }
462
463 new_gate = kzalloc(sizeof(struct mpath_node), GFP_ATOMIC);
464 if (!new_gate) {
465 err = -ENOMEM;
466 goto err_rcu;
467 }
468
469 mpath->is_gate = true;
470 mpath->sdata->u.mesh.num_gates++;
471 new_gate->mpath = mpath;
472 spin_lock_bh(&tbl->gates_lock);
473 hlist_add_head_rcu(&new_gate->list, tbl->known_gates);
474 spin_unlock_bh(&tbl->gates_lock);
475 rcu_read_unlock();
476 mpath_dbg("Mesh path (%s): Recorded new gate: %pM. %d known gates\n",
477 mpath->sdata->name, mpath->dst,
478 mpath->sdata->u.mesh.num_gates);
479 return 0;
480err_rcu:
481 rcu_read_unlock();
482 return err;
483}
484
485/**
486 * mesh_gate_del - remove a mesh gate from the list of known gates
487 * @tbl: table which holds our list of known gates
488 * @mpath: gate mpath
489 *
490 * Returns: 0 on success
491 *
492 * Locking: must be called inside rcu_read_lock() section
493 */
494static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
495{
496 struct mpath_node *gate;
497 struct hlist_node *p, *q;
498
499 tbl = rcu_dereference(tbl);
500
501 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list)
502 if (gate->mpath == mpath) {
503 spin_lock_bh(&tbl->gates_lock);
504 hlist_del_rcu(&gate->list);
505 call_rcu(&gate->rcu, mesh_gate_node_reclaim);
506 spin_unlock_bh(&tbl->gates_lock);
507 mpath->sdata->u.mesh.num_gates--;
508 mpath->is_gate = false;
509 mpath_dbg("Mesh path (%s): Deleted gate: %pM. "
510 "%d known gates\n", mpath->sdata->name,
511 mpath->dst, mpath->sdata->u.mesh.num_gates);
512 break;
513 }
514
515 return 0;
516}
517
518/**
519 *
520 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table
521 * @mpath: gate path to add to table
522 */
523int mesh_path_add_gate(struct mesh_path *mpath)
524{
525 return mesh_gate_add(mesh_paths, mpath);
526}
527
528/**
529 * mesh_gate_num - number of gates known to this interface
530 * @sdata: subif data
531 */
532int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
533{
534 return sdata->u.mesh.num_gates;
535}
536
307/** 537/**
308 * mesh_path_add - allocate and add a new path to the mesh path table 538 * mesh_path_add - allocate and add a new path to the mesh path table
309 * @addr: destination address of the path (ETH_ALEN length) 539 * @addr: destination address of the path (ETH_ALEN length)
@@ -481,6 +711,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
481 new_mpath->flags = 0; 711 new_mpath->flags = 0;
482 skb_queue_head_init(&new_mpath->frame_queue); 712 skb_queue_head_init(&new_mpath->frame_queue);
483 new_node->mpath = new_mpath; 713 new_node->mpath = new_mpath;
714 init_timer(&new_mpath->timer);
484 new_mpath->exp_time = jiffies; 715 new_mpath->exp_time = jiffies;
485 spin_lock_init(&new_mpath->state_lock); 716 spin_lock_init(&new_mpath->state_lock);
486 717
@@ -539,6 +770,7 @@ void mesh_plink_broken(struct sta_info *sta)
539 struct hlist_node *p; 770 struct hlist_node *p;
540 struct ieee80211_sub_if_data *sdata = sta->sdata; 771 struct ieee80211_sub_if_data *sdata = sta->sdata;
541 int i; 772 int i;
773 __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
542 774
543 rcu_read_lock(); 775 rcu_read_lock();
544 tbl = rcu_dereference(mesh_paths); 776 tbl = rcu_dereference(mesh_paths);
@@ -553,8 +785,7 @@ void mesh_plink_broken(struct sta_info *sta)
553 spin_unlock_bh(&mpath->state_lock); 785 spin_unlock_bh(&mpath->state_lock);
554 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, 786 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl,
555 mpath->dst, cpu_to_le32(mpath->sn), 787 mpath->dst, cpu_to_le32(mpath->sn),
556 cpu_to_le16(PERR_RCODE_DEST_UNREACH), 788 reason, bcast, sdata);
557 bcast, sdata);
558 } else 789 } else
559 spin_unlock_bh(&mpath->state_lock); 790 spin_unlock_bh(&mpath->state_lock);
560 } 791 }
@@ -647,12 +878,14 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
647 mpath = node->mpath; 878 mpath = node->mpath;
648 if (mpath->sdata == sdata && 879 if (mpath->sdata == sdata &&
649 memcmp(addr, mpath->dst, ETH_ALEN) == 0) { 880 memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
650 spin_lock(&mpath->state_lock); 881 spin_lock_bh(&mpath->state_lock);
882 if (mpath->is_gate)
883 mesh_gate_del(tbl, mpath);
651 mpath->flags |= MESH_PATH_RESOLVING; 884 mpath->flags |= MESH_PATH_RESOLVING;
652 hlist_del_rcu(&node->list); 885 hlist_del_rcu(&node->list);
653 call_rcu(&node->rcu, mesh_path_node_reclaim); 886 call_rcu(&node->rcu, mesh_path_node_reclaim);
654 atomic_dec(&tbl->entries); 887 atomic_dec(&tbl->entries);
655 spin_unlock(&mpath->state_lock); 888 spin_unlock_bh(&mpath->state_lock);
656 goto enddel; 889 goto enddel;
657 } 890 }
658 } 891 }
@@ -681,6 +914,58 @@ void mesh_path_tx_pending(struct mesh_path *mpath)
681} 914}
682 915
683/** 916/**
917 * mesh_path_send_to_gates - sends pending frames to all known mesh gates
918 *
919 * @mpath: mesh path whose queue will be emptied
920 *
921 * If there is only one gate, the frames are transferred from the failed mpath
922 * queue to that gate's queue. If there are more than one gates, the frames
923 * are copied from each gate to the next. After frames are copied, the
924 * mpath queues are emptied onto the transmission queue.
925 */
926int mesh_path_send_to_gates(struct mesh_path *mpath)
927{
928 struct ieee80211_sub_if_data *sdata = mpath->sdata;
929 struct hlist_node *n;
930 struct mesh_table *tbl;
931 struct mesh_path *from_mpath = mpath;
932 struct mpath_node *gate = NULL;
933 bool copy = false;
934 struct hlist_head *known_gates;
935
936 rcu_read_lock();
937 tbl = rcu_dereference(mesh_paths);
938 known_gates = tbl->known_gates;
939 rcu_read_unlock();
940
941 if (!known_gates)
942 return -EHOSTUNREACH;
943
944 hlist_for_each_entry_rcu(gate, n, known_gates, list) {
945 if (gate->mpath->sdata != sdata)
946 continue;
947
948 if (gate->mpath->flags & MESH_PATH_ACTIVE) {
949 mpath_dbg("Forwarding to %pM\n", gate->mpath->dst);
950 mesh_path_move_to_queue(gate->mpath, from_mpath, copy);
951 from_mpath = gate->mpath;
952 copy = true;
953 } else {
954 mpath_dbg("Not forwarding %p\n", gate->mpath);
955 mpath_dbg("flags %x\n", gate->mpath->flags);
956 }
957 }
958
959 hlist_for_each_entry_rcu(gate, n, known_gates, list)
960 if (gate->mpath->sdata == sdata) {
961 mpath_dbg("Sending to %pM\n", gate->mpath->dst);
962 mesh_path_tx_pending(gate->mpath);
963 }
964
965 return (from_mpath == mpath) ? -EHOSTUNREACH : 0;
966}
967
968/**
684 * mesh_path_discard_frame - discard a frame whose path could not be resolved 969 * mesh_path_discard_frame - discard a frame whose path could not be resolved
685 * 970 *
686 * @skb: frame to discard 971 * @skb: frame to discard
@@ -699,6 +984,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
699 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 984 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
700 struct mesh_path *mpath; 985 struct mesh_path *mpath;
701 u32 sn = 0; 986 u32 sn = 0;
987 __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
702 988
703 if (memcmp(hdr->addr4, sdata->vif.addr, ETH_ALEN) != 0) { 989 if (memcmp(hdr->addr4, sdata->vif.addr, ETH_ALEN) != 0) {
704 u8 *ra, *da; 990 u8 *ra, *da;
@@ -709,8 +995,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
709 if (mpath) 995 if (mpath)
710 sn = ++mpath->sn; 996 sn = ++mpath->sn;
711 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data, 997 mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data,
712 cpu_to_le32(sn), 998 cpu_to_le32(sn), reason, ra, sdata);
713 cpu_to_le16(PERR_RCODE_NO_ROUTE), ra, sdata);
714 } 999 }
715 1000
716 kfree_skb(skb); 1001 kfree_skb(skb);
@@ -728,8 +1013,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath)
728{ 1013{
729 struct sk_buff *skb; 1014 struct sk_buff *skb;
730 1015
731 while ((skb = skb_dequeue(&mpath->frame_queue)) && 1016 while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL)
732 (mpath->flags & MESH_PATH_ACTIVE))
733 mesh_path_discard_frame(skb, mpath->sdata); 1017 mesh_path_discard_frame(skb, mpath->sdata);
734} 1018}
735 1019
@@ -797,6 +1081,9 @@ int mesh_pathtbl_init(void)
797 tbl_path->free_node = &mesh_path_node_free; 1081 tbl_path->free_node = &mesh_path_node_free;
798 tbl_path->copy_node = &mesh_path_node_copy; 1082 tbl_path->copy_node = &mesh_path_node_copy;
799 tbl_path->mean_chain_len = MEAN_CHAIN_LEN; 1083 tbl_path->mean_chain_len = MEAN_CHAIN_LEN;
1084 tbl_path->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
1085 INIT_HLIST_HEAD(tbl_path->known_gates);
1086
800 1087
801 tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); 1088 tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
802 if (!tbl_mpp) { 1089 if (!tbl_mpp) {
@@ -806,6 +1093,8 @@ int mesh_pathtbl_init(void)
806 tbl_mpp->free_node = &mesh_path_node_free; 1093 tbl_mpp->free_node = &mesh_path_node_free;
807 tbl_mpp->copy_node = &mesh_path_node_copy; 1094 tbl_mpp->copy_node = &mesh_path_node_copy;
808 tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN; 1095 tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN;
1096 tbl_mpp->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC);
1097 INIT_HLIST_HEAD(tbl_mpp->known_gates);
809 1098
810 /* Need no locking since this is during init */ 1099 /* Need no locking since this is during init */
811 RCU_INIT_POINTER(mesh_paths, tbl_path); 1100 RCU_INIT_POINTER(mesh_paths, tbl_path);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index f4adc0917888..1a00d0f701c3 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -19,35 +19,18 @@
19#define mpl_dbg(fmt, args...) do { (void)(0); } while (0) 19#define mpl_dbg(fmt, args...) do { (void)(0); } while (0)
20#endif 20#endif
21 21
22#define PLINK_GET_LLID(p) (p + 4) 22#define PLINK_GET_LLID(p) (p + 2)
23#define PLINK_GET_PLID(p) (p + 6) 23#define PLINK_GET_PLID(p) (p + 4)
24 24
25#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 25#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
26 jiffies + HZ * t / 1000)) 26 jiffies + HZ * t / 1000))
27 27
28/* Peer link cancel reasons, all subject to ANA approval */
29#define MESH_LINK_CANCELLED 2
30#define MESH_MAX_NEIGHBORS 3
31#define MESH_CAPABILITY_POLICY_VIOLATION 4
32#define MESH_CLOSE_RCVD 5
33#define MESH_MAX_RETRIES 6
34#define MESH_CONFIRM_TIMEOUT 7
35#define MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS 8
36#define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE 9
37#define MESH_SECURITY_FAILED_VERIFICATION 10
38
39#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries) 28#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
40#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout) 29#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
41#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout) 30#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
42#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) 31#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
43#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) 32#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
44 33
45enum plink_frame_type {
46 PLINK_OPEN = 1,
47 PLINK_CONFIRM,
48 PLINK_CLOSE
49};
50
51enum plink_event { 34enum plink_event {
52 PLINK_UNDEFINED, 35 PLINK_UNDEFINED,
53 OPN_ACPT, 36 OPN_ACPT,
@@ -157,16 +140,16 @@ void mesh_plink_deactivate(struct sta_info *sta)
157} 140}
158 141
159static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 142static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
160 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, 143 enum ieee80211_self_protected_actioncode action,
161 __le16 reason) { 144 u8 *da, __le16 llid, __le16 plid, __le16 reason) {
162 struct ieee80211_local *local = sdata->local; 145 struct ieee80211_local *local = sdata->local;
163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + 146 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
164 sdata->u.mesh.ie_len); 147 sdata->u.mesh.ie_len);
165 struct ieee80211_mgmt *mgmt; 148 struct ieee80211_mgmt *mgmt;
166 bool include_plid = false; 149 bool include_plid = false;
167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; 150 int ie_len = 4;
151 u16 peering_proto = 0;
168 u8 *pos; 152 u8 *pos;
169 int ie_len;
170 153
171 if (!skb) 154 if (!skb)
172 return -1; 155 return -1;
@@ -175,63 +158,75 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
175 * common action part (1) 158 * common action part (1)
176 */ 159 */
177 mgmt = (struct ieee80211_mgmt *) 160 mgmt = (struct ieee80211_mgmt *)
178 skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action)); 161 skb_put(skb, 25 + sizeof(mgmt->u.action.u.self_prot));
179 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action)); 162 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.self_prot));
180 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 163 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
181 IEEE80211_STYPE_ACTION); 164 IEEE80211_STYPE_ACTION);
182 memcpy(mgmt->da, da, ETH_ALEN); 165 memcpy(mgmt->da, da, ETH_ALEN);
183 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 166 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
184 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 167 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
185 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION; 168 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
186 mgmt->u.action.u.plink_action.action_code = action; 169 mgmt->u.action.u.self_prot.action_code = action;
187 170
188 if (action == PLINK_CLOSE) 171 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
189 mgmt->u.action.u.plink_action.aux = reason; 172 /* capability info */
190 else { 173 pos = skb_put(skb, 2);
191 mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0); 174 memset(pos, 0, 2);
192 if (action == PLINK_CONFIRM) { 175 if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
193 pos = skb_put(skb, 4); 176 /* AID */
194 /* two-byte status code followed by two-byte AID */ 177 pos = skb_put(skb, 2);
195 memset(pos, 0, 2);
196 memcpy(pos + 2, &plid, 2); 178 memcpy(pos + 2, &plid, 2);
197 } 179 }
198 mesh_mgmt_ies_add(skb, sdata); 180 if (mesh_add_srates_ie(skb, sdata) ||
181 mesh_add_ext_srates_ie(skb, sdata) ||
182 mesh_add_rsn_ie(skb, sdata) ||
183 mesh_add_meshid_ie(skb, sdata) ||
184 mesh_add_meshconf_ie(skb, sdata))
185 return -1;
186 } else { /* WLAN_SP_MESH_PEERING_CLOSE */
187 if (mesh_add_meshid_ie(skb, sdata))
188 return -1;
199 } 189 }
200 190
201 /* Add Peer Link Management element */ 191 /* Add Mesh Peering Management element */
202 switch (action) { 192 switch (action) {
203 case PLINK_OPEN: 193 case WLAN_SP_MESH_PEERING_OPEN:
204 ie_len = 6;
205 break; 194 break;
206 case PLINK_CONFIRM: 195 case WLAN_SP_MESH_PEERING_CONFIRM:
207 ie_len = 8; 196 ie_len += 2;
208 include_plid = true; 197 include_plid = true;
209 break; 198 break;
210 case PLINK_CLOSE: 199 case WLAN_SP_MESH_PEERING_CLOSE:
211 default: 200 if (plid) {
212 if (!plid) 201 ie_len += 2;
213 ie_len = 8;
214 else {
215 ie_len = 10;
216 include_plid = true; 202 include_plid = true;
217 } 203 }
204 ie_len += 2; /* reason code */
218 break; 205 break;
206 default:
207 return -EINVAL;
219 } 208 }
220 209
210 if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
211 return -ENOMEM;
212
221 pos = skb_put(skb, 2 + ie_len); 213 pos = skb_put(skb, 2 + ie_len);
222 *pos++ = WLAN_EID_PEER_LINK; 214 *pos++ = WLAN_EID_PEER_MGMT;
223 *pos++ = ie_len; 215 *pos++ = ie_len;
224 memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto)); 216 memcpy(pos, &peering_proto, 2);
225 pos += 4; 217 pos += 2;
226 memcpy(pos, &llid, 2); 218 memcpy(pos, &llid, 2);
219 pos += 2;
227 if (include_plid) { 220 if (include_plid) {
228 pos += 2;
229 memcpy(pos, &plid, 2); 221 memcpy(pos, &plid, 2);
230 }
231 if (action == PLINK_CLOSE) {
232 pos += 2; 222 pos += 2;
223 }
224 if (action == WLAN_SP_MESH_PEERING_CLOSE) {
233 memcpy(pos, &reason, 2); 225 memcpy(pos, &reason, 2);
226 pos += 2;
234 } 227 }
228 if (mesh_add_vendor_ies(skb, sdata))
229 return -1;
235 230
236 ieee80211_tx_skb(sdata, skb); 231 ieee80211_tx_skb(sdata, skb);
237 return 0; 232 return 0;
@@ -322,21 +317,21 @@ static void mesh_plink_timer(unsigned long data)
322 ++sta->plink_retries; 317 ++sta->plink_retries;
323 mod_plink_timer(sta, sta->plink_timeout); 318 mod_plink_timer(sta, sta->plink_timeout);
324 spin_unlock_bh(&sta->lock); 319 spin_unlock_bh(&sta->lock);
325 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid, 320 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
326 0, 0); 321 sta->sta.addr, llid, 0, 0);
327 break; 322 break;
328 } 323 }
329 reason = cpu_to_le16(MESH_MAX_RETRIES); 324 reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
330 /* fall through on else */ 325 /* fall through on else */
331 case NL80211_PLINK_CNF_RCVD: 326 case NL80211_PLINK_CNF_RCVD:
332 /* confirm timer */ 327 /* confirm timer */
333 if (!reason) 328 if (!reason)
334 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 329 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
335 sta->plink_state = NL80211_PLINK_HOLDING; 330 sta->plink_state = NL80211_PLINK_HOLDING;
336 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 331 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
337 spin_unlock_bh(&sta->lock); 332 spin_unlock_bh(&sta->lock);
338 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid, 333 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
339 reason); 334 sta->sta.addr, llid, plid, reason);
340 break; 335 break;
341 case NL80211_PLINK_HOLDING: 336 case NL80211_PLINK_HOLDING:
342 /* holding timer */ 337 /* holding timer */
@@ -396,7 +391,7 @@ int mesh_plink_open(struct sta_info *sta)
396 mpl_dbg("Mesh plink: starting establishment with %pM\n", 391 mpl_dbg("Mesh plink: starting establishment with %pM\n",
397 sta->sta.addr); 392 sta->sta.addr);
398 393
399 return mesh_plink_frame_tx(sdata, PLINK_OPEN, 394 return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
400 sta->sta.addr, llid, 0, 0); 395 sta->sta.addr, llid, 0, 0);
401} 396}
402 397
@@ -422,7 +417,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
422 struct ieee802_11_elems elems; 417 struct ieee802_11_elems elems;
423 struct sta_info *sta; 418 struct sta_info *sta;
424 enum plink_event event; 419 enum plink_event event;
425 enum plink_frame_type ftype; 420 enum ieee80211_self_protected_actioncode ftype;
426 size_t baselen; 421 size_t baselen;
427 bool deactivated, matches_local = true; 422 bool deactivated, matches_local = true;
428 u8 ie_len; 423 u8 ie_len;
@@ -449,14 +444,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
449 return; 444 return;
450 } 445 }
451 446
452 baseaddr = mgmt->u.action.u.plink_action.variable; 447 baseaddr = mgmt->u.action.u.self_prot.variable;
453 baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt; 448 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
454 if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) { 449 if (mgmt->u.action.u.self_prot.action_code ==
450 WLAN_SP_MESH_PEERING_CONFIRM) {
455 baseaddr += 4; 451 baseaddr += 4;
456 baselen += 4; 452 baselen += 4;
457 } 453 }
458 ieee802_11_parse_elems(baseaddr, len - baselen, &elems); 454 ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
459 if (!elems.peer_link) { 455 if (!elems.peering) {
460 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 456 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
461 return; 457 return;
462 } 458 }
@@ -466,31 +462,34 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
466 return; 462 return;
467 } 463 }
468 464
469 ftype = mgmt->u.action.u.plink_action.action_code; 465 ftype = mgmt->u.action.u.self_prot.action_code;
470 ie_len = elems.peer_link_len; 466 ie_len = elems.peering_len;
471 if ((ftype == PLINK_OPEN && ie_len != 6) || 467 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
472 (ftype == PLINK_CONFIRM && ie_len != 8) || 468 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
473 (ftype == PLINK_CLOSE && ie_len != 8 && ie_len != 10)) { 469 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
470 && ie_len != 8)) {
474 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n", 471 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
475 ftype, ie_len); 472 ftype, ie_len);
476 return; 473 return;
477 } 474 }
478 475
479 if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) { 476 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
477 (!elems.mesh_id || !elems.mesh_config)) {
480 mpl_dbg("Mesh plink: missing necessary ie\n"); 478 mpl_dbg("Mesh plink: missing necessary ie\n");
481 return; 479 return;
482 } 480 }
483 /* Note the lines below are correct, the llid in the frame is the plid 481 /* Note the lines below are correct, the llid in the frame is the plid
484 * from the point of view of this host. 482 * from the point of view of this host.
485 */ 483 */
486 memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2); 484 memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
487 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10)) 485 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
488 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2); 486 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
487 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
489 488
490 rcu_read_lock(); 489 rcu_read_lock();
491 490
492 sta = sta_info_get(sdata, mgmt->sa); 491 sta = sta_info_get(sdata, mgmt->sa);
493 if (!sta && ftype != PLINK_OPEN) { 492 if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
494 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); 493 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
495 rcu_read_unlock(); 494 rcu_read_unlock();
496 return; 495 return;
@@ -509,30 +508,30 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
509 508
510 /* Now we will figure out the appropriate event... */ 509 /* Now we will figure out the appropriate event... */
511 event = PLINK_UNDEFINED; 510 event = PLINK_UNDEFINED;
512 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { 511 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
512 (!mesh_matches_local(&elems, sdata))) {
513 matches_local = false; 513 matches_local = false;
514 switch (ftype) { 514 switch (ftype) {
515 case PLINK_OPEN: 515 case WLAN_SP_MESH_PEERING_OPEN:
516 event = OPN_RJCT; 516 event = OPN_RJCT;
517 break; 517 break;
518 case PLINK_CONFIRM: 518 case WLAN_SP_MESH_PEERING_CONFIRM:
519 event = CNF_RJCT; 519 event = CNF_RJCT;
520 break; 520 break;
521 case PLINK_CLOSE: 521 default:
522 /* avoid warning */
523 break; 522 break;
524 } 523 }
525 } 524 }
526 525
527 if (!sta && !matches_local) { 526 if (!sta && !matches_local) {
528 rcu_read_unlock(); 527 rcu_read_unlock();
529 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 528 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
530 llid = 0; 529 llid = 0;
531 mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, 530 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
532 plid, reason); 531 mgmt->sa, llid, plid, reason);
533 return; 532 return;
534 } else if (!sta) { 533 } else if (!sta) {
535 /* ftype == PLINK_OPEN */ 534 /* ftype == WLAN_SP_MESH_PEERING_OPEN */
536 u32 rates; 535 u32 rates;
537 536
538 rcu_read_unlock(); 537 rcu_read_unlock();
@@ -557,21 +556,21 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
557 } else if (matches_local) { 556 } else if (matches_local) {
558 spin_lock_bh(&sta->lock); 557 spin_lock_bh(&sta->lock);
559 switch (ftype) { 558 switch (ftype) {
560 case PLINK_OPEN: 559 case WLAN_SP_MESH_PEERING_OPEN:
561 if (!mesh_plink_free_count(sdata) || 560 if (!mesh_plink_free_count(sdata) ||
562 (sta->plid && sta->plid != plid)) 561 (sta->plid && sta->plid != plid))
563 event = OPN_IGNR; 562 event = OPN_IGNR;
564 else 563 else
565 event = OPN_ACPT; 564 event = OPN_ACPT;
566 break; 565 break;
567 case PLINK_CONFIRM: 566 case WLAN_SP_MESH_PEERING_CONFIRM:
568 if (!mesh_plink_free_count(sdata) || 567 if (!mesh_plink_free_count(sdata) ||
569 (sta->llid != llid || sta->plid != plid)) 568 (sta->llid != llid || sta->plid != plid))
570 event = CNF_IGNR; 569 event = CNF_IGNR;
571 else 570 else
572 event = CNF_ACPT; 571 event = CNF_ACPT;
573 break; 572 break;
574 case PLINK_CLOSE: 573 case WLAN_SP_MESH_PEERING_CLOSE:
575 if (sta->plink_state == NL80211_PLINK_ESTAB) 574 if (sta->plink_state == NL80211_PLINK_ESTAB)
576 /* Do not check for llid or plid. This does not 575 /* Do not check for llid or plid. This does not
577 * follow the standard but since multiple plinks 576 * follow the standard but since multiple plinks
@@ -620,10 +619,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
620 sta->llid = llid; 619 sta->llid = llid;
621 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 620 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
622 spin_unlock_bh(&sta->lock); 621 spin_unlock_bh(&sta->lock);
623 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid, 622 mesh_plink_frame_tx(sdata,
624 0, 0); 623 WLAN_SP_MESH_PEERING_OPEN,
625 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, 624 sta->sta.addr, llid, 0, 0);
626 llid, plid, 0); 625 mesh_plink_frame_tx(sdata,
626 WLAN_SP_MESH_PEERING_CONFIRM,
627 sta->sta.addr, llid, plid, 0);
627 break; 628 break;
628 default: 629 default:
629 spin_unlock_bh(&sta->lock); 630 spin_unlock_bh(&sta->lock);
@@ -635,10 +636,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
635 switch (event) { 636 switch (event) {
636 case OPN_RJCT: 637 case OPN_RJCT:
637 case CNF_RJCT: 638 case CNF_RJCT:
638 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 639 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
639 case CLS_ACPT: 640 case CLS_ACPT:
640 if (!reason) 641 if (!reason)
641 reason = cpu_to_le16(MESH_CLOSE_RCVD); 642 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
642 sta->reason = reason; 643 sta->reason = reason;
643 sta->plink_state = NL80211_PLINK_HOLDING; 644 sta->plink_state = NL80211_PLINK_HOLDING;
644 if (!mod_plink_timer(sta, 645 if (!mod_plink_timer(sta,
@@ -647,8 +648,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
647 648
648 llid = sta->llid; 649 llid = sta->llid;
649 spin_unlock_bh(&sta->lock); 650 spin_unlock_bh(&sta->lock);
650 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 651 mesh_plink_frame_tx(sdata,
651 plid, reason); 652 WLAN_SP_MESH_PEERING_CLOSE,
653 sta->sta.addr, llid, plid, reason);
652 break; 654 break;
653 case OPN_ACPT: 655 case OPN_ACPT:
654 /* retry timer is left untouched */ 656 /* retry timer is left untouched */
@@ -656,8 +658,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
656 sta->plid = plid; 658 sta->plid = plid;
657 llid = sta->llid; 659 llid = sta->llid;
658 spin_unlock_bh(&sta->lock); 660 spin_unlock_bh(&sta->lock);
659 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 661 mesh_plink_frame_tx(sdata,
660 plid, 0); 662 WLAN_SP_MESH_PEERING_CONFIRM,
663 sta->sta.addr, llid, plid, 0);
661 break; 664 break;
662 case CNF_ACPT: 665 case CNF_ACPT:
663 sta->plink_state = NL80211_PLINK_CNF_RCVD; 666 sta->plink_state = NL80211_PLINK_CNF_RCVD;
@@ -677,10 +680,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
677 switch (event) { 680 switch (event) {
678 case OPN_RJCT: 681 case OPN_RJCT:
679 case CNF_RJCT: 682 case CNF_RJCT:
680 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 683 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
681 case CLS_ACPT: 684 case CLS_ACPT:
682 if (!reason) 685 if (!reason)
683 reason = cpu_to_le16(MESH_CLOSE_RCVD); 686 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
684 sta->reason = reason; 687 sta->reason = reason;
685 sta->plink_state = NL80211_PLINK_HOLDING; 688 sta->plink_state = NL80211_PLINK_HOLDING;
686 if (!mod_plink_timer(sta, 689 if (!mod_plink_timer(sta,
@@ -689,14 +692,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
689 692
690 llid = sta->llid; 693 llid = sta->llid;
691 spin_unlock_bh(&sta->lock); 694 spin_unlock_bh(&sta->lock);
692 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 695 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
693 plid, reason); 696 sta->sta.addr, llid, plid, reason);
694 break; 697 break;
695 case OPN_ACPT: 698 case OPN_ACPT:
696 llid = sta->llid; 699 llid = sta->llid;
697 spin_unlock_bh(&sta->lock); 700 spin_unlock_bh(&sta->lock);
698 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 701 mesh_plink_frame_tx(sdata,
699 plid, 0); 702 WLAN_SP_MESH_PEERING_CONFIRM,
703 sta->sta.addr, llid, plid, 0);
700 break; 704 break;
701 case CNF_ACPT: 705 case CNF_ACPT:
702 del_timer(&sta->plink_timer); 706 del_timer(&sta->plink_timer);
@@ -717,10 +721,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
717 switch (event) { 721 switch (event) {
718 case OPN_RJCT: 722 case OPN_RJCT:
719 case CNF_RJCT: 723 case CNF_RJCT:
720 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); 724 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
721 case CLS_ACPT: 725 case CLS_ACPT:
722 if (!reason) 726 if (!reason)
723 reason = cpu_to_le16(MESH_CLOSE_RCVD); 727 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
724 sta->reason = reason; 728 sta->reason = reason;
725 sta->plink_state = NL80211_PLINK_HOLDING; 729 sta->plink_state = NL80211_PLINK_HOLDING;
726 if (!mod_plink_timer(sta, 730 if (!mod_plink_timer(sta,
@@ -729,8 +733,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
729 733
730 llid = sta->llid; 734 llid = sta->llid;
731 spin_unlock_bh(&sta->lock); 735 spin_unlock_bh(&sta->lock);
732 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 736 mesh_plink_frame_tx(sdata,
733 plid, reason); 737 WLAN_SP_MESH_PEERING_CLOSE,
738 sta->sta.addr, llid, plid, reason);
734 break; 739 break;
735 case OPN_ACPT: 740 case OPN_ACPT:
736 del_timer(&sta->plink_timer); 741 del_timer(&sta->plink_timer);
@@ -740,8 +745,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
740 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 745 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
741 mpl_dbg("Mesh plink with %pM ESTABLISHED\n", 746 mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
742 sta->sta.addr); 747 sta->sta.addr);
743 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 748 mesh_plink_frame_tx(sdata,
744 plid, 0); 749 WLAN_SP_MESH_PEERING_CONFIRM,
750 sta->sta.addr, llid, plid, 0);
745 break; 751 break;
746 default: 752 default:
747 spin_unlock_bh(&sta->lock); 753 spin_unlock_bh(&sta->lock);
@@ -752,7 +758,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
752 case NL80211_PLINK_ESTAB: 758 case NL80211_PLINK_ESTAB:
753 switch (event) { 759 switch (event) {
754 case CLS_ACPT: 760 case CLS_ACPT:
755 reason = cpu_to_le16(MESH_CLOSE_RCVD); 761 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
756 sta->reason = reason; 762 sta->reason = reason;
757 deactivated = __mesh_plink_deactivate(sta); 763 deactivated = __mesh_plink_deactivate(sta);
758 sta->plink_state = NL80211_PLINK_HOLDING; 764 sta->plink_state = NL80211_PLINK_HOLDING;
@@ -761,14 +767,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
761 spin_unlock_bh(&sta->lock); 767 spin_unlock_bh(&sta->lock);
762 if (deactivated) 768 if (deactivated)
763 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 769 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
764 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, 770 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
765 plid, reason); 771 sta->sta.addr, llid, plid, reason);
766 break; 772 break;
767 case OPN_ACPT: 773 case OPN_ACPT:
768 llid = sta->llid; 774 llid = sta->llid;
769 spin_unlock_bh(&sta->lock); 775 spin_unlock_bh(&sta->lock);
770 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid, 776 mesh_plink_frame_tx(sdata,
771 plid, 0); 777 WLAN_SP_MESH_PEERING_CONFIRM,
778 sta->sta.addr, llid, plid, 0);
772 break; 779 break;
773 default: 780 default:
774 spin_unlock_bh(&sta->lock); 781 spin_unlock_bh(&sta->lock);
@@ -790,8 +797,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
790 llid = sta->llid; 797 llid = sta->llid;
791 reason = sta->reason; 798 reason = sta->reason;
792 spin_unlock_bh(&sta->lock); 799 spin_unlock_bh(&sta->lock);
793 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, 800 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
794 llid, plid, reason); 801 sta->sta.addr, llid, plid, reason);
795 break; 802 break;
796 default: 803 default:
797 spin_unlock_bh(&sta->lock); 804 spin_unlock_bh(&sta->lock);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d6470c7fd6ce..60a6f273cd30 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1482,10 +1482,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1482 1482
1483 ifmgd->aid = aid; 1483 ifmgd->aid = aid;
1484 1484
1485 sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); 1485 mutex_lock(&sdata->local->sta_mtx);
1486 if (!sta) { 1486 /*
1487 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1487 * station info was already allocated and inserted before
1488 " the AP\n", sdata->name); 1488 * the association and should be available to us
1489 */
1490 sta = sta_info_get_rx(sdata, cbss->bssid);
1491 if (WARN_ON(!sta)) {
1492 mutex_unlock(&sdata->local->sta_mtx);
1489 return false; 1493 return false;
1490 } 1494 }
1491 1495
@@ -1556,7 +1560,8 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1556 if (elems.wmm_param) 1560 if (elems.wmm_param)
1557 set_sta_flags(sta, WLAN_STA_WME); 1561 set_sta_flags(sta, WLAN_STA_WME);
1558 1562
1559 err = sta_info_insert(sta); 1563 /* sta_info_reinsert will also unlock the mutex lock */
1564 err = sta_info_reinsert(sta);
1560 sta = NULL; 1565 sta = NULL;
1561 if (err) { 1566 if (err) {
1562 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1567 printk(KERN_DEBUG "%s: failed to insert STA entry for"
@@ -2429,6 +2434,32 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2429 return 0; 2434 return 0;
2430} 2435}
2431 2436
2437/* create and insert a dummy station entry */
2438static int ieee80211_pre_assoc(struct ieee80211_sub_if_data *sdata,
2439 u8 *bssid) {
2440 struct sta_info *sta;
2441 int err;
2442
2443 sta = sta_info_alloc(sdata, bssid, GFP_KERNEL);
2444 if (!sta) {
2445 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
2446 " the AP\n", sdata->name);
2447 return -ENOMEM;
2448 }
2449
2450 sta->dummy = true;
2451
2452 err = sta_info_insert(sta);
2453 sta = NULL;
2454 if (err) {
2455 printk(KERN_DEBUG "%s: failed to insert Dummy STA entry for"
2456 " the AP (error %d)\n", sdata->name, err);
2457 return err;
2458 }
2459
2460 return 0;
2461}
2462
2432static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, 2463static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2433 struct sk_buff *skb) 2464 struct sk_buff *skb)
2434{ 2465{
@@ -2436,9 +2467,11 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2436 struct ieee80211_mgmt *mgmt; 2467 struct ieee80211_mgmt *mgmt;
2437 struct ieee80211_rx_status *rx_status; 2468 struct ieee80211_rx_status *rx_status;
2438 struct ieee802_11_elems elems; 2469 struct ieee802_11_elems elems;
2470 struct cfg80211_bss *cbss = wk->assoc.bss;
2439 u16 status; 2471 u16 status;
2440 2472
2441 if (!skb) { 2473 if (!skb) {
2474 sta_info_destroy_addr(wk->sdata, cbss->bssid);
2442 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta); 2475 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
2443 goto destroy; 2476 goto destroy;
2444 } 2477 }
@@ -2468,12 +2501,16 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2468 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) { 2501 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
2469 mutex_unlock(&wk->sdata->u.mgd.mtx); 2502 mutex_unlock(&wk->sdata->u.mgd.mtx);
2470 /* oops -- internal error -- send timeout for now */ 2503 /* oops -- internal error -- send timeout for now */
2504 sta_info_destroy_addr(wk->sdata, cbss->bssid);
2471 cfg80211_send_assoc_timeout(wk->sdata->dev, 2505 cfg80211_send_assoc_timeout(wk->sdata->dev,
2472 wk->filter_ta); 2506 wk->filter_ta);
2473 return WORK_DONE_DESTROY; 2507 return WORK_DONE_DESTROY;
2474 } 2508 }
2475 2509
2476 mutex_unlock(&wk->sdata->u.mgd.mtx); 2510 mutex_unlock(&wk->sdata->u.mgd.mtx);
2511 } else {
2512 /* assoc failed - destroy the dummy station entry */
2513 sta_info_destroy_addr(wk->sdata, cbss->bssid);
2477 } 2514 }
2478 2515
2479 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); 2516 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
@@ -2492,7 +2529,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2492 struct ieee80211_bss *bss = (void *)req->bss->priv; 2529 struct ieee80211_bss *bss = (void *)req->bss->priv;
2493 struct ieee80211_work *wk; 2530 struct ieee80211_work *wk;
2494 const u8 *ssid; 2531 const u8 *ssid;
2495 int i; 2532 int i, err;
2496 2533
2497 mutex_lock(&ifmgd->mtx); 2534 mutex_lock(&ifmgd->mtx);
2498 if (ifmgd->associated) { 2535 if (ifmgd->associated) {
@@ -2517,6 +2554,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2517 if (!wk) 2554 if (!wk)
2518 return -ENOMEM; 2555 return -ENOMEM;
2519 2556
2557 /*
2558 * create a dummy station info entry in order
2559 * to start accepting incoming EAPOL packets from the station
2560 */
2561 err = ieee80211_pre_assoc(sdata, req->bss->bssid);
2562 if (err) {
2563 kfree(wk);
2564 return err;
2565 }
2566
2520 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 2567 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2521 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 2568 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2522 2569
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fe2c2a717793..f45fd2fedc24 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -850,8 +850,21 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
850 ieee80211_is_pspoll(hdr->frame_control)) && 850 ieee80211_is_pspoll(hdr->frame_control)) &&
851 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 851 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
852 rx->sdata->vif.type != NL80211_IFTYPE_WDS && 852 rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
853 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) 853 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
854 if (rx->sta && rx->sta->dummy &&
855 ieee80211_is_data_present(hdr->frame_control)) {
856 u16 ethertype;
857 u8 *payload;
858
859 payload = rx->skb->data +
860 ieee80211_hdrlen(hdr->frame_control);
861 ethertype = (payload[6] << 8) | payload[7];
862 if (cpu_to_be16(ethertype) ==
863 rx->sdata->control_port_protocol)
864 return RX_CONTINUE;
865 }
854 return RX_DROP_MONITOR; 866 return RX_DROP_MONITOR;
867 }
855 868
856 return RX_CONTINUE; 869 return RX_CONTINUE;
857} 870}
@@ -2220,12 +2233,29 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2220 goto handled; 2233 goto handled;
2221 } 2234 }
2222 break; 2235 break;
2236 case WLAN_CATEGORY_SELF_PROTECTED:
2237 switch (mgmt->u.action.u.self_prot.action_code) {
2238 case WLAN_SP_MESH_PEERING_OPEN:
2239 case WLAN_SP_MESH_PEERING_CLOSE:
2240 case WLAN_SP_MESH_PEERING_CONFIRM:
2241 if (!ieee80211_vif_is_mesh(&sdata->vif))
2242 goto invalid;
2243 if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
2244 /* userspace handles this frame */
2245 break;
2246 goto queue;
2247 case WLAN_SP_MGK_INFORM:
2248 case WLAN_SP_MGK_ACK:
2249 if (!ieee80211_vif_is_mesh(&sdata->vif))
2250 goto invalid;
2251 break;
2252 }
2253 break;
2223 case WLAN_CATEGORY_MESH_ACTION: 2254 case WLAN_CATEGORY_MESH_ACTION:
2224 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2255 if (!ieee80211_vif_is_mesh(&sdata->vif))
2225 break; 2256 break;
2226 goto queue; 2257 if (mesh_action_is_path_sel(mgmt) &&
2227 case WLAN_CATEGORY_MESH_PATH_SEL: 2258 (!mesh_path_sel_is_hwmp(sdata)))
2228 if (!mesh_path_sel_is_hwmp(sdata))
2229 break; 2259 break;
2230 goto queue; 2260 goto queue;
2231 } 2261 }
@@ -2686,7 +2716,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2686 } else if (!ieee80211_bssid_match(bssid, 2716 } else if (!ieee80211_bssid_match(bssid,
2687 sdata->vif.addr)) { 2717 sdata->vif.addr)) {
2688 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && 2718 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
2689 !ieee80211_is_beacon(hdr->frame_control)) 2719 !ieee80211_is_beacon(hdr->frame_control) &&
2720 !(ieee80211_is_action(hdr->frame_control) &&
2721 sdata->vif.p2p))
2690 return 0; 2722 return 0;
2691 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2723 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2692 } 2724 }
@@ -2791,7 +2823,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2791 if (ieee80211_is_data(fc)) { 2823 if (ieee80211_is_data(fc)) {
2792 prev_sta = NULL; 2824 prev_sta = NULL;
2793 2825
2794 for_each_sta_info(local, hdr->addr2, sta, tmp) { 2826 for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
2795 if (!prev_sta) { 2827 if (!prev_sta) {
2796 prev_sta = sta; 2828 prev_sta = sta;
2797 continue; 2829 continue;
@@ -2835,7 +2867,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2835 continue; 2867 continue;
2836 } 2868 }
2837 2869
2838 rx.sta = sta_info_get_bss(prev, hdr->addr2); 2870 rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
2839 rx.sdata = prev; 2871 rx.sdata = prev;
2840 ieee80211_prepare_and_rx_handle(&rx, skb, false); 2872 ieee80211_prepare_and_rx_handle(&rx, skb, false);
2841 2873
@@ -2843,7 +2875,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2843 } 2875 }
2844 2876
2845 if (prev) { 2877 if (prev) {
2846 rx.sta = sta_info_get_bss(prev, hdr->addr2); 2878 rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
2847 rx.sdata = prev; 2879 rx.sdata = prev;
2848 2880
2849 if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) 2881 if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 0bdbf3b8f28b..6bc17fb80ee9 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -100,6 +100,27 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
100 lockdep_is_held(&local->sta_lock) || 100 lockdep_is_held(&local->sta_lock) ||
101 lockdep_is_held(&local->sta_mtx)); 101 lockdep_is_held(&local->sta_mtx));
102 while (sta) { 102 while (sta) {
103 if (sta->sdata == sdata && !sta->dummy &&
104 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
105 break;
106 sta = rcu_dereference_check(sta->hnext,
107 lockdep_is_held(&local->sta_lock) ||
108 lockdep_is_held(&local->sta_mtx));
109 }
110 return sta;
111}
112
113/* get a station info entry even if it is a dummy station*/
114struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
115 const u8 *addr)
116{
117 struct ieee80211_local *local = sdata->local;
118 struct sta_info *sta;
119
120 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
121 lockdep_is_held(&local->sta_lock) ||
122 lockdep_is_held(&local->sta_mtx));
123 while (sta) {
103 if (sta->sdata == sdata && 124 if (sta->sdata == sdata &&
104 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 125 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
105 break; 126 break;
@@ -126,6 +147,32 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
126 while (sta) { 147 while (sta) {
127 if ((sta->sdata == sdata || 148 if ((sta->sdata == sdata ||
128 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && 149 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
150 !sta->dummy &&
151 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
152 break;
153 sta = rcu_dereference_check(sta->hnext,
154 lockdep_is_held(&local->sta_lock) ||
155 lockdep_is_held(&local->sta_mtx));
156 }
157 return sta;
158}
159
160/*
161 * Get sta info either from the specified interface
162 * or from one of its vlans (including dummy stations)
163 */
164struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
165 const u8 *addr)
166{
167 struct ieee80211_local *local = sdata->local;
168 struct sta_info *sta;
169
170 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
171 lockdep_is_held(&local->sta_lock) ||
172 lockdep_is_held(&local->sta_mtx));
173 while (sta) {
174 if ((sta->sdata == sdata ||
175 (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
129 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 176 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
130 break; 177 break;
131 sta = rcu_dereference_check(sta->hnext, 178 sta = rcu_dereference_check(sta->hnext,
@@ -280,7 +327,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
280 return sta; 327 return sta;
281} 328}
282 329
283static int sta_info_finish_insert(struct sta_info *sta, bool async) 330static int sta_info_finish_insert(struct sta_info *sta,
331 bool async, bool dummy_reinsert)
284{ 332{
285 struct ieee80211_local *local = sta->local; 333 struct ieee80211_local *local = sta->local;
286 struct ieee80211_sub_if_data *sdata = sta->sdata; 334 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -290,51 +338,58 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async)
290 338
291 lockdep_assert_held(&local->sta_mtx); 339 lockdep_assert_held(&local->sta_mtx);
292 340
293 /* notify driver */ 341 if (!sta->dummy || dummy_reinsert) {
294 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 342 /* notify driver */
295 sdata = container_of(sdata->bss, 343 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
296 struct ieee80211_sub_if_data, 344 sdata = container_of(sdata->bss,
297 u.ap); 345 struct ieee80211_sub_if_data,
298 err = drv_sta_add(local, sdata, &sta->sta); 346 u.ap);
299 if (err) { 347 err = drv_sta_add(local, sdata, &sta->sta);
300 if (!async) 348 if (err) {
301 return err; 349 if (!async)
302 printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to driver (%d)" 350 return err;
303 " - keeping it anyway.\n", 351 printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to "
304 sdata->name, sta->sta.addr, err); 352 "driver (%d) - keeping it anyway.\n",
305 } else { 353 sdata->name, sta->sta.addr, err);
306 sta->uploaded = true; 354 } else {
355 sta->uploaded = true;
307#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 356#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
308 if (async) 357 if (async)
309 wiphy_debug(local->hw.wiphy, 358 wiphy_debug(local->hw.wiphy,
310 "Finished adding IBSS STA %pM\n", 359 "Finished adding IBSS STA %pM\n",
311 sta->sta.addr); 360 sta->sta.addr);
312#endif 361#endif
362 }
363
364 sdata = sta->sdata;
313 } 365 }
314 366
315 sdata = sta->sdata; 367 if (!dummy_reinsert) {
368 if (!async) {
369 local->num_sta++;
370 local->sta_generation++;
371 smp_mb();
316 372
317 if (!async) { 373 /* make the station visible */
318 local->num_sta++; 374 spin_lock_irqsave(&local->sta_lock, flags);
319 local->sta_generation++; 375 sta_info_hash_add(local, sta);
320 smp_mb(); 376 spin_unlock_irqrestore(&local->sta_lock, flags);
377 }
321 378
322 /* make the station visible */ 379 list_add(&sta->list, &local->sta_list);
323 spin_lock_irqsave(&local->sta_lock, flags); 380 } else {
324 sta_info_hash_add(local, sta); 381 sta->dummy = false;
325 spin_unlock_irqrestore(&local->sta_lock, flags);
326 } 382 }
327 383
328 list_add(&sta->list, &local->sta_list); 384 if (!sta->dummy) {
329 385 ieee80211_sta_debugfs_add(sta);
330 ieee80211_sta_debugfs_add(sta); 386 rate_control_add_sta_debugfs(sta);
331 rate_control_add_sta_debugfs(sta);
332
333 memset(&sinfo, 0, sizeof(sinfo));
334 sinfo.filled = 0;
335 sinfo.generation = local->sta_generation;
336 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
337 387
388 memset(&sinfo, 0, sizeof(sinfo));
389 sinfo.filled = 0;
390 sinfo.generation = local->sta_generation;
391 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
392 }
338 393
339 return 0; 394 return 0;
340} 395}
@@ -351,7 +406,7 @@ static void sta_info_finish_pending(struct ieee80211_local *local)
351 list_del(&sta->list); 406 list_del(&sta->list);
352 spin_unlock_irqrestore(&local->sta_lock, flags); 407 spin_unlock_irqrestore(&local->sta_lock, flags);
353 408
354 sta_info_finish_insert(sta, true); 409 sta_info_finish_insert(sta, true, false);
355 410
356 spin_lock_irqsave(&local->sta_lock, flags); 411 spin_lock_irqsave(&local->sta_lock, flags);
357 } 412 }
@@ -368,106 +423,117 @@ static void sta_info_finish_work(struct work_struct *work)
368 mutex_unlock(&local->sta_mtx); 423 mutex_unlock(&local->sta_mtx);
369} 424}
370 425
371int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) 426static int sta_info_insert_check(struct sta_info *sta)
372{ 427{
373 struct ieee80211_local *local = sta->local;
374 struct ieee80211_sub_if_data *sdata = sta->sdata; 428 struct ieee80211_sub_if_data *sdata = sta->sdata;
375 unsigned long flags;
376 int err = 0;
377 429
378 /* 430 /*
379 * Can't be a WARN_ON because it can be triggered through a race: 431 * Can't be a WARN_ON because it can be triggered through a race:
380 * something inserts a STA (on one CPU) without holding the RTNL 432 * something inserts a STA (on one CPU) without holding the RTNL
381 * and another CPU turns off the net device. 433 * and another CPU turns off the net device.
382 */ 434 */
383 if (unlikely(!ieee80211_sdata_running(sdata))) { 435 if (unlikely(!ieee80211_sdata_running(sdata)))
384 err = -ENETDOWN; 436 return -ENETDOWN;
385 rcu_read_lock();
386 goto out_free;
387 }
388 437
389 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 || 438 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->vif.addr) == 0 ||
390 is_multicast_ether_addr(sta->sta.addr))) { 439 is_multicast_ether_addr(sta->sta.addr)))
391 err = -EINVAL; 440 return -EINVAL;
441
442 return 0;
443}
444
445static int sta_info_insert_ibss(struct sta_info *sta) __acquires(RCU)
446{
447 struct ieee80211_local *local = sta->local;
448 struct ieee80211_sub_if_data *sdata = sta->sdata;
449 unsigned long flags;
450
451 spin_lock_irqsave(&local->sta_lock, flags);
452 /* check if STA exists already */
453 if (sta_info_get_bss_rx(sdata, sta->sta.addr)) {
454 spin_unlock_irqrestore(&local->sta_lock, flags);
392 rcu_read_lock(); 455 rcu_read_lock();
393 goto out_free; 456 return -EEXIST;
394 } 457 }
395 458
396 /* 459 local->num_sta++;
397 * In ad-hoc mode, we sometimes need to insert stations 460 local->sta_generation++;
398 * from tasklet context from the RX path. To avoid races, 461 smp_mb();
399 * always do so in that case -- see the comment below. 462 sta_info_hash_add(local, sta);
400 */
401 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
402 spin_lock_irqsave(&local->sta_lock, flags);
403 /* check if STA exists already */
404 if (sta_info_get_bss(sdata, sta->sta.addr)) {
405 spin_unlock_irqrestore(&local->sta_lock, flags);
406 rcu_read_lock();
407 err = -EEXIST;
408 goto out_free;
409 }
410
411 local->num_sta++;
412 local->sta_generation++;
413 smp_mb();
414 sta_info_hash_add(local, sta);
415 463
416 list_add_tail(&sta->list, &local->sta_pending_list); 464 list_add_tail(&sta->list, &local->sta_pending_list);
417 465
418 rcu_read_lock(); 466 rcu_read_lock();
419 spin_unlock_irqrestore(&local->sta_lock, flags); 467 spin_unlock_irqrestore(&local->sta_lock, flags);
420 468
421#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 469#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
422 wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n", 470 wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n",
423 sta->sta.addr); 471 sta->sta.addr);
424#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 472#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
425 473
426 ieee80211_queue_work(&local->hw, &local->sta_finish_work); 474 ieee80211_queue_work(&local->hw, &local->sta_finish_work);
427 475
428 return 0; 476 return 0;
429 } 477}
478
479/*
480 * should be called with sta_mtx locked
481 * this function replaces the mutex lock
482 * with a RCU lock
483 */
484static int sta_info_insert_non_ibss(struct sta_info *sta) __acquires(RCU)
485{
486 struct ieee80211_local *local = sta->local;
487 struct ieee80211_sub_if_data *sdata = sta->sdata;
488 unsigned long flags;
489 struct sta_info *exist_sta;
490 bool dummy_reinsert = false;
491 int err = 0;
492
493 lockdep_assert_held(&local->sta_mtx);
430 494
431 /* 495 /*
432 * On first glance, this will look racy, because the code 496 * On first glance, this will look racy, because the code
433 * below this point, which inserts a station with sleeping, 497 * in this function, which inserts a station with sleeping,
434 * unlocks the sta_lock between checking existence in the 498 * unlocks the sta_lock between checking existence in the
435 * hash table and inserting into it. 499 * hash table and inserting into it.
436 * 500 *
437 * However, it is not racy against itself because it keeps 501 * However, it is not racy against itself because it keeps
438 * the mutex locked. It still seems to race against the 502 * the mutex locked.
439 * above code that atomically inserts the station... That,
440 * however, is not true because the above code can only
441 * be invoked for IBSS interfaces, and the below code will
442 * not be -- and the two do not race against each other as
443 * the hash table also keys off the interface.
444 */ 503 */
445 504
446 might_sleep();
447
448 mutex_lock(&local->sta_mtx);
449
450 spin_lock_irqsave(&local->sta_lock, flags); 505 spin_lock_irqsave(&local->sta_lock, flags);
451 /* check if STA exists already */ 506 /*
452 if (sta_info_get_bss(sdata, sta->sta.addr)) { 507 * check if STA exists already.
453 spin_unlock_irqrestore(&local->sta_lock, flags); 508 * only accept a scenario of a second call to sta_info_insert_non_ibss
454 mutex_unlock(&local->sta_mtx); 509 * with a dummy station entry that was inserted earlier
455 rcu_read_lock(); 510 * in that case - assume that the dummy station flag should
456 err = -EEXIST; 511 * be removed.
457 goto out_free; 512 */
513 exist_sta = sta_info_get_bss_rx(sdata, sta->sta.addr);
514 if (exist_sta) {
515 if (exist_sta == sta && sta->dummy) {
516 dummy_reinsert = true;
517 } else {
518 spin_unlock_irqrestore(&local->sta_lock, flags);
519 mutex_unlock(&local->sta_mtx);
520 rcu_read_lock();
521 return -EEXIST;
522 }
458 } 523 }
459 524
460 spin_unlock_irqrestore(&local->sta_lock, flags); 525 spin_unlock_irqrestore(&local->sta_lock, flags);
461 526
462 err = sta_info_finish_insert(sta, false); 527 err = sta_info_finish_insert(sta, false, dummy_reinsert);
463 if (err) { 528 if (err) {
464 mutex_unlock(&local->sta_mtx); 529 mutex_unlock(&local->sta_mtx);
465 rcu_read_lock(); 530 rcu_read_lock();
466 goto out_free; 531 return err;
467 } 532 }
468 533
469#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 534#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
470 wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); 535 wiphy_debug(local->hw.wiphy, "Inserted %sSTA %pM\n",
536 sta->dummy ? "dummy " : "", sta->sta.addr);
471#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 537#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
472 538
473 /* move reference to rcu-protected */ 539 /* move reference to rcu-protected */
@@ -478,6 +544,51 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
478 mesh_accept_plinks_update(sdata); 544 mesh_accept_plinks_update(sdata);
479 545
480 return 0; 546 return 0;
547}
548
549int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU)
550{
551 struct ieee80211_local *local = sta->local;
552 struct ieee80211_sub_if_data *sdata = sta->sdata;
553 int err = 0;
554
555 err = sta_info_insert_check(sta);
556 if (err) {
557 rcu_read_lock();
558 goto out_free;
559 }
560
561 /*
562 * In ad-hoc mode, we sometimes need to insert stations
563 * from tasklet context from the RX path. To avoid races,
564 * always do so in that case -- see the comment below.
565 */
566 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
567 err = sta_info_insert_ibss(sta);
568 if (err)
569 goto out_free;
570
571 return 0;
572 }
573
574 /*
575 * It might seem that the function called below is in race against
576 * the function call above that atomically inserts the station... That,
577 * however, is not true because the above code can only
578 * be invoked for IBSS interfaces, and the below code will
579 * not be -- and the two do not race against each other as
580 * the hash table also keys off the interface.
581 */
582
583 might_sleep();
584
585 mutex_lock(&local->sta_mtx);
586
587 err = sta_info_insert_non_ibss(sta);
588 if (err)
589 goto out_free;
590
591 return 0;
481 out_free: 592 out_free:
482 BUG_ON(!err); 593 BUG_ON(!err);
483 __sta_info_free(local, sta); 594 __sta_info_free(local, sta);
@@ -493,6 +604,25 @@ int sta_info_insert(struct sta_info *sta)
493 return err; 604 return err;
494} 605}
495 606
607/* Caller must hold sta->local->sta_mtx */
608int sta_info_reinsert(struct sta_info *sta)
609{
610 struct ieee80211_local *local = sta->local;
611 int err = 0;
612
613 err = sta_info_insert_check(sta);
614 if (err) {
615 mutex_unlock(&local->sta_mtx);
616 return err;
617 }
618
619 might_sleep();
620
621 err = sta_info_insert_non_ibss(sta);
622 rcu_read_unlock();
623 return err;
624}
625
496static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 626static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
497{ 627{
498 /* 628 /*
@@ -733,7 +863,7 @@ int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr)
733 int ret; 863 int ret;
734 864
735 mutex_lock(&sdata->local->sta_mtx); 865 mutex_lock(&sdata->local->sta_mtx);
736 sta = sta_info_get(sdata, addr); 866 sta = sta_info_get_rx(sdata, addr);
737 ret = __sta_info_destroy(sta); 867 ret = __sta_info_destroy(sta);
738 mutex_unlock(&sdata->local->sta_mtx); 868 mutex_unlock(&sdata->local->sta_mtx);
739 869
@@ -747,7 +877,7 @@ int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
747 int ret; 877 int ret;
748 878
749 mutex_lock(&sdata->local->sta_mtx); 879 mutex_lock(&sdata->local->sta_mtx);
750 sta = sta_info_get_bss(sdata, addr); 880 sta = sta_info_get_bss_rx(sdata, addr);
751 ret = __sta_info_destroy(sta); 881 ret = __sta_info_destroy(sta);
752 mutex_unlock(&sdata->local->sta_mtx); 882 mutex_unlock(&sdata->local->sta_mtx);
753 883
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 28beb78e601e..e9eb565506da 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -238,10 +238,12 @@ struct sta_ampdu_mlme {
238 * @plink_timer: peer link watch timer 238 * @plink_timer: peer link watch timer
239 * @plink_timer_was_running: used by suspend/resume to restore timers 239 * @plink_timer_was_running: used by suspend/resume to restore timers
240 * @debugfs: debug filesystem info 240 * @debugfs: debug filesystem info
241 * @sta: station information we share with the driver
242 * @dead: set to true when sta is unlinked 241 * @dead: set to true when sta is unlinked
243 * @uploaded: set to true when sta is uploaded to the driver 242 * @uploaded: set to true when sta is uploaded to the driver
244 * @lost_packets: number of consecutive lost packets 243 * @lost_packets: number of consecutive lost packets
244 * @dummy: indicate a dummy station created for receiving
245 * EAP frames before association
246 * @sta: station information we share with the driver
245 */ 247 */
246struct sta_info { 248struct sta_info {
247 /* General information, mostly static */ 249 /* General information, mostly static */
@@ -336,6 +338,9 @@ struct sta_info {
336 338
337 unsigned int lost_packets; 339 unsigned int lost_packets;
338 340
341 /* should be right in front of sta to be in the same cache line */
342 bool dummy;
343
339 /* keep last! */ 344 /* keep last! */
340 struct ieee80211_sta sta; 345 struct ieee80211_sta sta;
341}; 346};
@@ -436,9 +441,15 @@ rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
436struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, 441struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
437 const u8 *addr); 442 const u8 *addr);
438 443
444struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
445 const u8 *addr);
446
439struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, 447struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
440 const u8 *addr); 448 const u8 *addr);
441 449
450struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
451 const u8 *addr);
452
442static inline 453static inline
443void for_each_sta_info_type_check(struct ieee80211_local *local, 454void for_each_sta_info_type_check(struct ieee80211_local *local,
444 const u8 *addr, 455 const u8 *addr,
@@ -459,6 +470,22 @@ void for_each_sta_info_type_check(struct ieee80211_local *local,
459 _sta = nxt, \ 470 _sta = nxt, \
460 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ 471 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \
461 ) \ 472 ) \
473 /* run code only if address matches and it's not a dummy sta */ \
474 if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0 && \
475 !_sta->dummy)
476
477#define for_each_sta_info_rx(local, _addr, _sta, nxt) \
478 for ( /* initialise loop */ \
479 _sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
480 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL; \
481 /* typecheck */ \
482 for_each_sta_info_type_check(local, (_addr), _sta, nxt),\
483 /* continue condition */ \
484 _sta; \
485 /* advance loop */ \
486 _sta = nxt, \
487 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \
488 ) \
462 /* compare address and run code only if it matches */ \ 489 /* compare address and run code only if it matches */ \
463 if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0) 490 if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0)
464 491
@@ -484,6 +511,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
484int sta_info_insert(struct sta_info *sta); 511int sta_info_insert(struct sta_info *sta);
485int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU); 512int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
486int sta_info_insert_atomic(struct sta_info *sta); 513int sta_info_insert_atomic(struct sta_info *sta);
514int sta_info_reinsert(struct sta_info *sta);
487 515
488int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, 516int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
489 const u8 *addr); 517 const u8 *addr);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index a89cca3491b4..e51bd2a1a073 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -187,6 +187,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
187 int rates_idx = -1; 187 int rates_idx = -1;
188 bool send_to_cooked; 188 bool send_to_cooked;
189 bool acked; 189 bool acked;
190 struct ieee80211_bar *bar;
191 u16 tid;
190 192
191 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 193 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
192 if (info->status.rates[i].idx < 0) { 194 if (info->status.rates[i].idx < 0) {
@@ -243,6 +245,22 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
243 tid, ssn); 245 tid, ssn);
244 } 246 }
245 247
248 if (!acked && ieee80211_is_back_req(fc)) {
249 /*
250 * BAR failed, let's tear down the BA session as a
251 * last resort as some STAs (Intel 5100 on Windows)
252 * can get stuck when the BA window isn't flushed
253 * correctly.
254 */
255 bar = (struct ieee80211_bar *) skb->data;
256 if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) {
257 tid = (bar->control &
258 IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
259 IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
260 ieee80211_stop_tx_ba_session(&sta->sta, tid);
261 }
262 }
263
246 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { 264 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
247 ieee80211_handle_filtered_frame(local, sta, skb); 265 ieee80211_handle_filtered_frame(local, sta, skb);
248 rcu_read_unlock(); 266 rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 69fd494f32f9..01072639666f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2295,13 +2295,23 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2295 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 2295 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
2296 mgmt->u.beacon.beacon_int = 2296 mgmt->u.beacon.beacon_int =
2297 cpu_to_le16(sdata->vif.bss_conf.beacon_int); 2297 cpu_to_le16(sdata->vif.bss_conf.beacon_int);
2298 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ 2298 mgmt->u.beacon.capab_info |= cpu_to_le16(
2299 sdata->u.mesh.security ? WLAN_CAPABILITY_PRIVACY : 0);
2299 2300
2300 pos = skb_put(skb, 2); 2301 pos = skb_put(skb, 2);
2301 *pos++ = WLAN_EID_SSID; 2302 *pos++ = WLAN_EID_SSID;
2302 *pos++ = 0x0; 2303 *pos++ = 0x0;
2303 2304
2304 mesh_mgmt_ies_add(skb, sdata); 2305 if (mesh_add_srates_ie(skb, sdata) ||
2306 mesh_add_ds_params_ie(skb, sdata) ||
2307 mesh_add_ext_srates_ie(skb, sdata) ||
2308 mesh_add_rsn_ie(skb, sdata) ||
2309 mesh_add_meshid_ie(skb, sdata) ||
2310 mesh_add_meshconf_ie(skb, sdata) ||
2311 mesh_add_vendor_ies(skb, sdata)) {
2312 pr_err("o11s: couldn't add ies!\n");
2313 goto out;
2314 }
2305 } else { 2315 } else {
2306 WARN_ON(1); 2316 WARN_ON(1);
2307 goto out; 2317 goto out;
diff --git a/net/nfc/core.c b/net/nfc/core.c
index b6fd4e1f2057..284e2f6a14ff 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -322,7 +322,9 @@ struct nfc_dev *nfc_get_device(unsigned idx)
322 * @supported_protocols: NFC protocols supported by the device 322 * @supported_protocols: NFC protocols supported by the device
323 */ 323 */
324struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, 324struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
325 u32 supported_protocols) 325 u32 supported_protocols,
326 int tx_headroom,
327 int tx_tailroom)
326{ 328{
327 static atomic_t dev_no = ATOMIC_INIT(0); 329 static atomic_t dev_no = ATOMIC_INIT(0);
328 struct nfc_dev *dev; 330 struct nfc_dev *dev;
@@ -345,6 +347,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
345 347
346 dev->ops = ops; 348 dev->ops = ops;
347 dev->supported_protocols = supported_protocols; 349 dev->supported_protocols = supported_protocols;
350 dev->tx_headroom = tx_headroom;
351 dev->tx_tailroom = tx_tailroom;
348 352
349 spin_lock_init(&dev->targets_lock); 353 spin_lock_init(&dev->targets_lock);
350 nfc_genl_data_init(&dev->genl_data); 354 nfc_genl_data_init(&dev->genl_data);
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index 52de84a55115..9fd652a51424 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -123,11 +123,7 @@ error:
123 123
124static int rawsock_add_header(struct sk_buff *skb) 124static int rawsock_add_header(struct sk_buff *skb)
125{ 125{
126 126 *skb_push(skb, NFC_HEADER_SIZE) = 0;
127 if (skb_cow_head(skb, 1))
128 return -ENOMEM;
129
130 *skb_push(skb, 1) = 0;
131 127
132 return 0; 128 return 0;
133} 129}
@@ -197,6 +193,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
197 struct msghdr *msg, size_t len) 193 struct msghdr *msg, size_t len)
198{ 194{
199 struct sock *sk = sock->sk; 195 struct sock *sk = sock->sk;
196 struct nfc_dev *dev = nfc_rawsock(sk)->dev;
200 struct sk_buff *skb; 197 struct sk_buff *skb;
201 int rc; 198 int rc;
202 199
@@ -208,11 +205,13 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
208 if (sock->state != SS_CONNECTED) 205 if (sock->state != SS_CONNECTED)
209 return -ENOTCONN; 206 return -ENOTCONN;
210 207
211 skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, 208 skb = sock_alloc_send_skb(sk, len + dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE,
212 &rc); 209 msg->msg_flags & MSG_DONTWAIT, &rc);
213 if (!skb) 210 if (!skb)
214 return rc; 211 return rc;
215 212
213 skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
214
216 rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); 215 rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
217 if (rc < 0) { 216 if (rc < 0) {
218 kfree_skb(skb); 217 kfree_skb(skb);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 5c116083eeca..4423e64c7d98 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -12,6 +12,7 @@
12#define MESH_HOLD_T 100 12#define MESH_HOLD_T 100
13 13
14#define MESH_PATH_TIMEOUT 5000 14#define MESH_PATH_TIMEOUT 5000
15#define MESH_RANN_INTERVAL 5000
15 16
16/* 17/*
17 * Minimum interval between two consecutive PREQs originated by the same 18 * Minimum interval between two consecutive PREQs originated by the same
@@ -49,6 +50,8 @@ const struct mesh_config default_mesh_config = {
49 .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, 50 .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES,
50 .path_refresh_time = MESH_PATH_REFRESH_TIME, 51 .path_refresh_time = MESH_PATH_REFRESH_TIME,
51 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, 52 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
53 .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
54 .dot11MeshGateAnnouncementProtocol = false,
52}; 55};
53 56
54const struct mesh_setup default_mesh_setup = { 57const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2aa6a2189842..bddb5595c659 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2545,6 +2545,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2545 return err; 2545 return err;
2546} 2546}
2547 2547
2548static struct nla_policy
2549nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
2550 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
2551 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
2552};
2553
2548static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) 2554static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2549{ 2555{
2550 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2556 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2590,6 +2596,27 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2590 if (parse_station_flags(info, &params)) 2596 if (parse_station_flags(info, &params))
2591 return -EINVAL; 2597 return -EINVAL;
2592 2598
2599 /* parse WME attributes if sta is WME capable */
2600 if ((params.sta_flags_set & NL80211_STA_FLAG_WME) &&
2601 info->attrs[NL80211_ATTR_STA_WME]) {
2602 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
2603 struct nlattr *nla;
2604
2605 nla = info->attrs[NL80211_ATTR_STA_WME];
2606 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
2607 nl80211_sta_wme_policy);
2608 if (err)
2609 return err;
2610
2611 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
2612 params.uapsd_queues =
2613 nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
2614
2615 if (tb[NL80211_STA_WME_MAX_SP])
2616 params.max_sp =
2617 nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
2618 }
2619
2593 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2620 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2594 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 2621 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2595 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && 2622 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
@@ -3035,6 +3062,10 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
3035 cur_params.dot11MeshHWMPnetDiameterTraversalTime); 3062 cur_params.dot11MeshHWMPnetDiameterTraversalTime);
3036 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, 3063 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
3037 cur_params.dot11MeshHWMPRootMode); 3064 cur_params.dot11MeshHWMPRootMode);
3065 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3066 cur_params.dot11MeshHWMPRannInterval);
3067 NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3068 cur_params.dot11MeshGateAnnouncementProtocol);
3038 nla_nest_end(msg, pinfoattr); 3069 nla_nest_end(msg, pinfoattr);
3039 genlmsg_end(msg, hdr); 3070 genlmsg_end(msg, hdr);
3040 return genlmsg_reply(msg, info); 3071 return genlmsg_reply(msg, info);
@@ -3062,6 +3093,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3062 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, 3093 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
3063 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, 3094 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
3064 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 3095 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
3096 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
3097 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
3098 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
3065}; 3099};
3066 3100
3067static const struct nla_policy 3101static const struct nla_policy
@@ -3140,6 +3174,14 @@ do {\
3140 dot11MeshHWMPRootMode, mask, 3174 dot11MeshHWMPRootMode, mask,
3141 NL80211_MESHCONF_HWMP_ROOTMODE, 3175 NL80211_MESHCONF_HWMP_ROOTMODE,
3142 nla_get_u8); 3176 nla_get_u8);
3177 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3178 dot11MeshHWMPRannInterval, mask,
3179 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3180 nla_get_u16);
3181 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3182 dot11MeshGateAnnouncementProtocol, mask,
3183 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3184 nla_get_u8);
3143 if (mask_out) 3185 if (mask_out)
3144 *mask_out = mask; 3186 *mask_out = mask;
3145 3187
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 844ddb0aa653..eef82f79554d 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1158,9 +1158,9 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1158 if (elen >= sizeof(struct ieee80211_meshconf_ie)) 1158 if (elen >= sizeof(struct ieee80211_meshconf_ie))
1159 elems->mesh_config = (void *)pos; 1159 elems->mesh_config = (void *)pos;
1160 break; 1160 break;
1161 case WLAN_EID_PEER_LINK: 1161 case WLAN_EID_PEER_MGMT:
1162 elems->peer_link = pos; 1162 elems->peering = pos;
1163 elems->peer_link_len = elen; 1163 elems->peering_len = elen;
1164 break; 1164 break;
1165 case WLAN_EID_PREQ: 1165 case WLAN_EID_PREQ:
1166 elems->preq = pos; 1166 elems->preq = pos;