diff options
| author | John W. Linville <linville@tuxdriver.com> | 2011-08-29 14:52:20 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2011-08-29 14:52:20 -0400 |
| commit | ba6e5eb107b4b26444cb67ce6fb8eb0973a97964 (patch) | |
| tree | 9377baf652e0cd8360372020b0386e238d07a30d | |
| parent | f3116f62cb56ef5efd172371fab688bb27529f69 (diff) | |
| parent | a508a6ea234571e0e7d1e9f2455fc1eca54d1fef (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
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/ | |||
| 1230 | F: drivers/block/aoe/ | 1230 | F: drivers/block/aoe/ |
| 1231 | 1231 | ||
| 1232 | ATHEROS ATH GENERIC UTILITIES | 1232 | ATHEROS ATH GENERIC UTILITIES |
| 1233 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> | 1233 | M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com> |
| 1234 | L: linux-wireless@vger.kernel.org | 1234 | L: linux-wireless@vger.kernel.org |
| 1235 | S: Supported | 1235 | S: Supported |
| 1236 | F: drivers/net/wireless/ath/* | 1236 | F: drivers/net/wireless/ath/* |
| @@ -1238,7 +1238,7 @@ F: drivers/net/wireless/ath/* | |||
| 1238 | ATHEROS ATH5K WIRELESS DRIVER | 1238 | ATHEROS ATH5K WIRELESS DRIVER |
| 1239 | M: Jiri Slaby <jirislaby@gmail.com> | 1239 | M: Jiri Slaby <jirislaby@gmail.com> |
| 1240 | M: Nick Kossifidis <mickflemm@gmail.com> | 1240 | M: Nick Kossifidis <mickflemm@gmail.com> |
| 1241 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> | 1241 | M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com> |
| 1242 | M: Bob Copeland <me@bobcopeland.com> | 1242 | M: Bob Copeland <me@bobcopeland.com> |
| 1243 | L: linux-wireless@vger.kernel.org | 1243 | L: linux-wireless@vger.kernel.org |
| 1244 | L: ath5k-devel@lists.ath5k.org | 1244 | L: ath5k-devel@lists.ath5k.org |
| @@ -1247,10 +1247,10 @@ S: Maintained | |||
| 1247 | F: drivers/net/wireless/ath/ath5k/ | 1247 | F: drivers/net/wireless/ath/ath5k/ |
| 1248 | 1248 | ||
| 1249 | ATHEROS ATH9K WIRELESS DRIVER | 1249 | ATHEROS ATH9K WIRELESS DRIVER |
| 1250 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> | 1250 | M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com> |
| 1251 | M: Jouni Malinen <jmalinen@atheros.com> | 1251 | M: Jouni Malinen <jouni@qca.qualcomm.com> |
| 1252 | M: Vasanthakumar Thiagarajan <vasanth@atheros.com> | 1252 | M: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> |
| 1253 | M: Senthil Balasubramanian <senthilkumar@atheros.com> | 1253 | M: Senthil Balasubramanian <senthilb@qca.qualcomm.com> |
| 1254 | L: linux-wireless@vger.kernel.org | 1254 | L: linux-wireless@vger.kernel.org |
| 1255 | L: ath9k-devel@lists.ath9k.org | 1255 | L: ath9k-devel@lists.ath9k.org |
| 1256 | W: http://wireless.kernel.org/en/users/Drivers/ath9k | 1256 | W: http://wireless.kernel.org/en/users/Drivers/ath9k |
| @@ -1278,7 +1278,7 @@ F: drivers/input/misc/ati_remote2.c | |||
| 1278 | ATLX ETHERNET DRIVERS | 1278 | ATLX ETHERNET DRIVERS |
| 1279 | M: Jay Cliburn <jcliburn@gmail.com> | 1279 | M: Jay Cliburn <jcliburn@gmail.com> |
| 1280 | M: Chris Snook <chris.snook@gmail.com> | 1280 | M: Chris Snook <chris.snook@gmail.com> |
| 1281 | M: Jie Yang <jie.yang@atheros.com> | 1281 | M: Jie Yang <yangjie@qca.qualcomm.com> |
| 1282 | L: netdev@vger.kernel.org | 1282 | L: netdev@vger.kernel.org |
| 1283 | W: http://sourceforge.net/projects/atl1 | 1283 | W: http://sourceforge.net/projects/atl1 |
| 1284 | W: http://atl1.sourceforge.net | 1284 | W: http://atl1.sourceforge.net |
| @@ -4503,6 +4503,17 @@ W: http://www.qlogic.com | |||
| 4503 | S: Supported | 4503 | S: Supported |
| 4504 | F: drivers/net/ethernet/qlogic/netxen/ | 4504 | F: drivers/net/ethernet/qlogic/netxen/ |
| 4505 | 4505 | ||
| 4506 | NFC SUBSYSTEM | ||
| 4507 | M: Lauro Ramos Venancio <lauro.venancio@openbossa.org> | ||
| 4508 | M: Aloisio Almeida Jr <aloisio.almeida@openbossa.org> | ||
| 4509 | M: Samuel Ortiz <sameo@linux.intel.com> | ||
| 4510 | L: linux-wireless@vger.kernel.org | ||
| 4511 | S: Maintained | ||
| 4512 | F: net/nfc/ | ||
| 4513 | F: include/linux/nfc.h | ||
| 4514 | F: include/net/nfc.h | ||
| 4515 | F: drivers/nfc/ | ||
| 4516 | |||
| 4506 | NFS, SUNRPC, AND LOCKD CLIENTS | 4517 | NFS, SUNRPC, AND LOCKD CLIENTS |
| 4507 | M: Trond Myklebust <Trond.Myklebust@netapp.com> | 4518 | M: Trond Myklebust <Trond.Myklebust@netapp.com> |
| 4508 | L: linux-nfs@vger.kernel.org | 4519 | L: 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. */ | ||
| 94 | void 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 | |||
| 93 | void bcma_pmu_workarounds(struct bcma_drv_cc *cc) | 111 | void 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 | */ |
| 305 | static void ar9002_hw_configpcipowersave(struct ath_hw *ah, | 305 | static 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 | */ |
| 518 | static void ar9003_hw_configpcipowersave(struct ath_hw *ah, | 599 | static 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, | |||
| 415 | static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, | 415 | static 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 | ||
| 450 | static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, | 426 | static 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 | ||
| 543 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) | 543 | static 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 | ||
| 1127 | void 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 | |||
| 22 | static 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 | |||
| 35 | static 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 | |||
| 48 | static 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 | |||
| 211 | static 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 | |||
| 223 | static 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 | |||
| 329 | static 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 | |||
| 435 | static 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 | |||
| 541 | static 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 | |||
| 548 | static 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 | |||
| 705 | static 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 | |||
| 811 | static 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 | |||
| 1071 | static 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 | |||
| 1076 | static 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 | |||
| 1182 | static 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 | |||
| 1192 | static 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 | |||
| 1452 | static 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 | |||
| 1596 | static 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 | |||
| 1652 | static const u32 ar9580_1p0_pcie_phy_clkreq_enable_L1[][2] = { | ||
| 1653 | /* Addr allmodes */ | ||
| 1654 | {0x00004040, 0x0835365e}, | ||
| 1655 | {0x00004040, 0x0008003b}, | ||
| 1656 | {0x00004044, 0x00000000}, | ||
| 1657 | }; | ||
| 1658 | |||
| 1659 | static const u32 ar9580_1p0_pcie_phy_clkreq_disable_L1[][2] = { | ||
| 1660 | /* Addr allmodes */ | ||
| 1661 | {0x00004040, 0x0831365e}, | ||
| 1662 | {0x00004040, 0x0008003b}, | ||
| 1663 | {0x00004044, 0x00000000}, | ||
| 1664 | }; | ||
| 1665 | |||
| 1666 | static 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; | |||
| 664 | extern bool is_ath9k_unloaded; | 663 | extern bool is_ath9k_unloaded; |
| 665 | 664 | ||
| 666 | irqreturn_t ath_isr(int irq, void *dev); | 665 | irqreturn_t ath_isr(int irq, void *dev); |
| 667 | void ath9k_init_crypto(struct ath_softc *sc); | ||
| 668 | int ath9k_init_device(u16 devid, struct ath_softc *sc, | 666 | int 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); |
| 670 | void ath9k_deinit_device(struct ath_softc *sc); | 668 | void 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 | } |
| 170 | EXPORT_SYMBOL(ath9k_cmn_update_txpow); | 170 | EXPORT_SYMBOL(ath9k_cmn_update_txpow); |
| 171 | 171 | ||
| 172 | void 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 | } | ||
| 196 | EXPORT_SYMBOL(ath9k_cmn_init_crypto); | ||
| 197 | |||
| 172 | static int __init ath9k_cmn_init(void) | 198 | static 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); |
| 63 | void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, | 63 | void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, |
| 64 | u16 new_txpow, u16 *txpower); | 64 | u16 new_txpow, u16 *txpower); |
| 65 | void 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 | ||
| 1166 | static 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 | |||
| 1212 | static 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 | |||
| 1166 | static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | 1219 | static 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 | ||
| 575 | static 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 | |||
| 594 | static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) | 575 | static 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 | |||
| 1740 | static 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 | |||
| 1739 | struct ieee80211_ops ath9k_htc_ops = { | 1755 | struct 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 | ||
| 24 | static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah, | 24 | static 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 | ||
| 31 | static inline void ath9k_hw_rxena(struct ath_hw *ah) | 33 | static 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 | */ |
| 607 | struct ath_hw_ops { | 608 | struct 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); | |||
| 1037 | void ath9k_hw_proc_mib_event(struct ath_hw *ah); | 1037 | void ath9k_hw_proc_mib_event(struct ath_hw *ah); |
| 1038 | void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); | 1038 | void 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 | ||
| 407 | void 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 | |||
| 432 | static int ath9k_init_btcoex(struct ath_softc *sc) | 407 | static 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) | |||
| 564 | EXPORT_SYMBOL(ath9k_hw_resettxqueue); | 551 | EXPORT_SYMBOL(ath9k_hw_resettxqueue); |
| 565 | 552 | ||
| 566 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | 553 | int 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, | |||
| 687 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); | 687 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); |
| 688 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); | 688 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); |
| 689 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | 689 | int 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); |
| 691 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | 691 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, |
| 692 | u32 size, u32 flags); | 692 | u32 size, u32 flags); |
| 693 | bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); | 693 | bool 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: | |||
| 565 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 565 | static 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 | ||
| 2406 | static 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 | |||
| 2403 | struct ieee80211_ops ath9k_ops = { | 2420 | struct 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 */ |
| 39 | static void ath_pci_read_cachesize(struct ath_common *common, int *csz) | 41 | static 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 | */ | ||
| 94 | static 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 | |||
| 108 | static void ath_pci_extn_synch_enable(struct ath_common *common) | 93 | static 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 */ | ||
| 119 | static void ath_pci_aspm_init(struct ath_common *common) | 105 | static 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, | |||
| 603 | static u8 ath_rc_get_highest_rix(struct ath_softc *sc, | 603 | static 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 | |||
| 896 | enum ath_usb_dev { | 910 | enum 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 | ||
| 574 | static 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 | |||
| 574 | static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | 593 | static 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 | */ |
| 646 | static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | 665 | static 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 | |||
| 43 | config 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 | ||
| 442 | enum carl9170_ps_off_override_reasons { | 466 | enum 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 | ||
| 169 | int 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 | |||
| 168 | int carl9170_powersave(struct ar9170 *ar, const bool ps) | 202 | int 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); | |||
| 50 | int carl9170_reboot(struct ar9170 *ar); | 50 | int carl9170_reboot(struct ar9170 *ar); |
| 51 | int carl9170_mac_reset(struct ar9170 *ar); | 51 | int carl9170_mac_reset(struct ar9170 *ar); |
| 52 | int carl9170_powersave(struct ar9170 *ar, const bool power_on); | 52 | int carl9170_powersave(struct ar9170 *ar, const bool power_on); |
| 53 | int carl9170_collect_tally(struct ar9170 *ar); | ||
| 53 | int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, | 54 | int 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 | ||
| 290 | struct 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 | |||
| 289 | struct carl9170_rsp { | 299 | struct 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 | ||
| 424 | static void carl9170_cancel_worker(struct ar9170 *ar) | 427 | static 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 | ||
| 801 | static 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 | |||
| 823 | static 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 | ||
| 798 | static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) | 839 | static 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 | ||
| 1422 | static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx, | 1471 | #ifdef CONFIG_CARL9170_HWRNG |
| 1423 | struct survey_info *survey) | 1472 | static 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 | |||
| 1514 | static 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 | |||
| 1534 | static 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 | |||
| 1542 | static 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 | |||
| 1574 | static 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 | |||
| 1609 | found: | ||
| 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 | ||
| 1707 | static int carl9170_reg_notifier(struct wiphy *wiphy, | 1903 | static 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 | |||
| 173 | config 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 | ||
| 693 | enum 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. */ |
| 698 | struct b43_firmware { | 700 | struct 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 */ |
| 975 | void b43info(struct b43_wl *wl, const char *fmt, ...) | 974 | void 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 | ||
| 50 | static 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. */ |
| 52 | static | 84 | static |
| @@ -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 | */ | ||
| 1102 | static 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 | |||
| 1069 | int b43_dma_init(struct b43_wldev *dev) | 1118 | int 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 | ||
| 218 | enum b43_addrtype { | ||
| 219 | B43_DMA_ADDR_LOW, | ||
| 220 | B43_DMA_ADDR_HIGH, | ||
| 221 | B43_DMA_ADDR_EXT, | ||
| 222 | }; | ||
| 223 | |||
| 215 | struct b43_dmaring { | 224 | struct 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"); | |||
| 66 | MODULE_AUTHOR("Gábor Stefanik"); | 66 | MODULE_AUTHOR("Gábor Stefanik"); |
| 67 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
| 68 | 68 | ||
| 69 | MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); | ||
| 70 | MODULE_FIRMWARE("b43/ucode11.fw"); | 69 | MODULE_FIRMWARE("b43/ucode11.fw"); |
| 71 | MODULE_FIRMWARE("b43/ucode13.fw"); | 70 | MODULE_FIRMWARE("b43/ucode13.fw"); |
| 72 | MODULE_FIRMWARE("b43/ucode14.fw"); | 71 | MODULE_FIRMWARE("b43/ucode14.fw"); |
| @@ -108,7 +107,7 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; | |||
| 108 | module_param_named(verbose, b43_modparam_verbose, int, 0644); | 107 | module_param_named(verbose, b43_modparam_verbose, int, 0644); |
| 109 | MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); | 108 | MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); |
| 110 | 109 | ||
| 111 | static int b43_modparam_pio = B43_PIO_DEFAULT; | 110 | static int b43_modparam_pio = 0; |
| 112 | module_param_named(pio, b43_modparam_pio, int, 0644); | 111 | module_param_named(pio, b43_modparam_pio, int, 0644); |
| 113 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); | 112 | MODULE_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); | |||
| 320 | static int b43_wireless_core_init(struct b43_wldev *dev); | 319 | static int b43_wireless_core_init(struct b43_wldev *dev); |
| 321 | static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev); | 320 | static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev); |
| 322 | static int b43_wireless_core_start(struct b43_wldev *dev); | 321 | static int b43_wireless_core_start(struct b43_wldev *dev); |
| 322 | static 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 | ||
| 324 | static int b43_ratelimit(struct b43_wl *wl) | 327 | static 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: | |||
| 3846 | out_unlock_mutex: | 3866 | out_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 | ||
| 4937 | static int b43_setup_bands(struct b43_wldev *dev, | 4980 | static 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 */ | ||
| 452 | void 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 */ |
| 452 | struct b43_c32 b43_cordic(int theta) | 484 | struct 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 | ||
| 445 | bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type); | 445 | bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type); |
| 446 | 446 | ||
| 447 | void b43_phy_force_clock(struct b43_wldev *dev, bool force); | ||
| 448 | |||
| 447 | struct b43_c32 b43_cordic(int theta); | 449 | struct 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 | |||
| 158 | static 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 */ | ||
| 173 | static 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 | |||
| 194 | static 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 | |||
| 215 | static 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 | |||
| 222 | static 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 | ||
| 256 | static int b43_phy_ht_op_init(struct b43_wldev *dev) | 342 | static 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 | |||
| 34 | static 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 | |||
| 83 | static 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 | |||
| 98 | static 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 | |||
| 106 | static 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 | |||
| 127 | static 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 | |||
| 139 | static 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 | |||
| 148 | static 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 | |||
| 156 | static 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 | |||
| 185 | static 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 | |||
| 208 | static 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 | |||
| 218 | static 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 | |||
| 225 | static enum b43_txpwr_result | ||
| 226 | b43_phy_lcn_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi) | ||
| 227 | { | ||
| 228 | return B43_TXPWR_RES_DONE; | ||
| 229 | } | ||
| 230 | |||
| 231 | static 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 | ||
| 34 | const struct b43_phy_operations b43_phyops_lcn = { | 239 | const 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 | |||
| 7 | struct b43_phy_lcn { | 21 | struct b43_phy_lcn { |
| 8 | }; | 22 | }; |
| 9 | 23 | ||
| @@ -11,4 +25,4 @@ struct b43_phy_lcn { | |||
| 11 | struct b43_phy_operations; | 25 | struct b43_phy_operations; |
| 12 | extern const struct b43_phy_operations b43_phyops_lcn; | 26 | extern 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 */ | ||
| 604 | static 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 */ |
| 636 | static void b43_nphy_reset_cca(struct b43_wldev *dev) | 604 | static 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 */ | ||
| 578 | const 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 | ||
| 713 | void 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 | |||
| 677 | void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, | 758 | void 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) |
| 724 | void b43_phy_ht_tables_init(struct b43_wldev *dev) | 805 | void 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); | |||
| 14 | void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset, | 14 | void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset, |
| 15 | unsigned int nr_elements, void *_data); | 15 | unsigned int nr_elements, void *_data); |
| 16 | void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value); | 16 | void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value); |
| 17 | void b43_httab_write_few(struct b43_wldev *dev, u32 offset, size_t num, ...); | ||
| 17 | void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset, | 18 | void 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 | ||
| 20 | void b43_phy_ht_tables_init(struct b43_wldev *dev); | 21 | void b43_phy_ht_tables_init(struct b43_wldev *dev); |
| 21 | 22 | ||
| 23 | #define B43_HTTAB_1A_C0_LATE_SIZE 128 | ||
| 24 | extern 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 | ||
| 28 | static 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 | |||
| 42 | static 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 | |||
| 56 | static const u32 b43_lcntab_0x0b[] = { | ||
| 57 | 0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb, | ||
| 58 | 0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb, | ||
| 59 | 0x0001fea3, 0x0000024b, | ||
| 60 | }; | ||
| 61 | |||
| 62 | static 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 | |||
| 70 | static 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 | |||
| 110 | static 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 | |||
| 120 | static 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 | |||
| 134 | static 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 | |||
| 140 | static 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 | |||
| 153 | static 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 | |||
| 180 | static 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 | |||
| 205 | static 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 | |||
| 234 | static 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 | |||
| 255 | static 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 | |||
| 302 | u32 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 | |||
| 333 | void 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 | |||
| 372 | void 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 | |||
| 402 | void 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) | ||
| 32 | void b43_phy_lcn_tables_init(struct b43_wldev *dev) | 450 | void 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 | |||
| 13 | u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset); | ||
| 14 | void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset, | ||
| 15 | unsigned int nr_elements, void *_data); | ||
| 16 | void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value); | ||
| 17 | void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset, | ||
| 18 | unsigned int nr_elements, const void *_data); | ||
| 19 | |||
| 4 | void b43_phy_lcn_tables_init(struct b43_wldev *dev); | 20 | void 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. */ | ||
| 170 | static inline | ||
| 171 | bool b43_is_old_txhdr_format(struct b43_wldev *dev) | ||
| 172 | { | ||
| 173 | return (dev->fw.rev <= 351); | ||
| 174 | } | ||
| 175 | |||
| 176 | static inline | 186 | static inline |
| 177 | size_t b43_txhdr_size(struct b43_wldev *dev) | 187 | size_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"); | |||
| 60 | MODULE_AUTHOR("Michael Buesch"); | 60 | MODULE_AUTHOR("Michael Buesch"); |
| 61 | MODULE_LICENSE("GPL"); | 61 | MODULE_LICENSE("GPL"); |
| 62 | 62 | ||
| 63 | MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID); | ||
| 64 | MODULE_FIRMWARE("b43legacy/ucode2.fw"); | 63 | MODULE_FIRMWARE("b43legacy/ucode2.fw"); |
| 65 | MODULE_FIRMWARE("b43legacy/ucode4.fw"); | 64 | MODULE_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 | ======================== | ||
| 242 | IWCONFIG COMMANDS | ||
| 243 | ======================== | ||
| 244 | power 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 | } |
| 4104 | out: | 4101 | out: |
| 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 | ||
| 146 | static int p54_generate_band(struct ieee80211_hw *dev, | 146 | static 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 | ||
| 279 | static 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 | |||
| 296 | static 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 | |||
| 281 | static int p54_config(struct ieee80211_hw *dev, u32 changed) | 315 | static 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 | ||
| 306 | out: | 357 | out: |
| @@ -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 | ||
| 390 | static int p54_get_stats(struct ieee80211_hw *dev, | 443 | static 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 | ||
| 556 | static unsigned int p54_flush_count(struct p54_common *priv) | 640 | static 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 | } |
| 696 | EXPORT_SYMBOL_GPL(p54_init_common); | 783 | EXPORT_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 | } |
| 740 | EXPORT_SYMBOL_GPL(p54_free_common); | 829 | EXPORT_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 | ||
| 530 | static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) | 596 | static 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 | */ | ||
| 688 | int 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 | } | ||
| 826 | EXPORT_SYMBOL(rtlwifi_rate_mapping); | ||
| 827 | |||
| 667 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, | 828 | void 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); | |||
| 140 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); | 140 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); |
| 141 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid); | 141 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid); |
| 142 | extern struct attribute_group rtl_attribute_group; | 142 | extern struct attribute_group rtl_attribute_group; |
| 143 | int 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 | ||
| 31 | static unsigned int debug = DBG_EMERG; | ||
| 32 | module_param(debug, uint, 0); | ||
| 33 | MODULE_PARM_DESC(debug, "Set global debug level for rtlwifi (0,2-5)"); | ||
| 34 | |||
| 31 | void rtl_dbgp_flag_init(struct ieee80211_hw *hw) | 35 | void 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 | ||
| 223 | enum 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 | |||
| 258 | struct phy_sts_cck_8192s_t { | 223 | struct 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 */ | ||
| 271 | static 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 | ||
| 338 | DEFINE_PCI_DEVICE_TABLE(rtl92ce_pci_ids) = { | 338 | DEFINE_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 | ||
| 51 | static 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 | |||
| 149 | static u8 _rtl92c_query_rxpwrpercentage(char antpower) | 51 | static 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 | ||
| 546 | struct rx_fwinfo_92c { | 546 | struct 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); | |||
| 88 | u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw); | 88 | u32 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 | ||
| 96 | struct rx_fwinfo_92c { | 96 | struct 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 | ||
| 196 | enum 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 | |||
| 231 | enum channel_plan { | 196 | enum 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 | ||
| 360 | static struct pci_device_id rtl92de_pci_ids[] __devinitdata = { | 360 | static 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 | ||
| 51 | static 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 | |||
| 144 | static u8 _rtl92d_query_rxpwrpercentage(char antpower) | 51 | static 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 | ||
| 499 | enum rf_optype { | 468 | enum 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 | ||
| 368 | static struct pci_device_id rtl92se_pci_ids[] __devinitdata = { | 368 | static 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 | ||
| 54 | static 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 | |||
| 152 | static u8 _rtl92s_query_rxpwrpercentage(char antpower) | 54 | static 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 | ||
| 389 | enum 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 | |||
| 389 | enum rtl_var_map { | 424 | enum 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 | } |
| 1261 | EXPORT_SYMBOL(ssb_device_disable); | 1261 | EXPORT_SYMBOL(ssb_device_disable); |
| 1262 | 1262 | ||
| 1263 | /* Some chipsets need routing known for PCIe and 64-bit DMA */ | ||
| 1264 | static 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 | |||
| 1263 | u32 ssb_dma_translation(struct ssb_device *dev) | 1276 | u32 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); | |||
| 342 | extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); | 358 | extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); |
| 343 | extern void bcma_chipco_resume(struct bcma_drv_cc *cc); | 359 | extern void bcma_chipco_resume(struct bcma_drv_cc *cc); |
| 344 | 360 | ||
| 361 | void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); | ||
| 362 | |||
| 345 | extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, | 363 | extern 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 | ||
| 636 | enum 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 | ||
| 637 | struct ieee80211_mgmt { | 642 | struct 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 */ | ||
| 1303 | enum 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 */ | ||
| 1313 | enum 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 */ |
| 1313 | enum ieee80211_key_len { | 1328 | enum 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 | */ | ||
| 2498 | enum 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 { | |||
| 89 | extern struct class nfc_class; | 92 | extern struct class nfc_class; |
| 90 | 93 | ||
| 91 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | 94 | struct 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 | ||
| 202 | config 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 | |||
| 202 | config MAC80211_VERBOSE_MHWMP_DEBUG | 215 | config 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); |
| 373 | IEEE80211_IF_FILE(dot11MeshHWMPRootMode, | 373 | IEEE80211_IF_FILE(dot11MeshHWMPRootMode, |
| 374 | u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); | 374 | u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); |
| 375 | IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, | ||
| 376 | u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); | ||
| 377 | IEEE80211_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 @@ | |||
| 27 | int mesh_allocated; | 23 | int mesh_allocated; |
| 28 | static struct kmem_cache *rm_cache; | 24 | static struct kmem_cache *rm_cache; |
| 29 | 25 | ||
| 26 | #ifdef CONFIG_MAC80211_MESH | ||
| 27 | bool 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 | ||
| 33 | bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) | ||
| 34 | { return false; } | ||
| 35 | #endif | ||
| 36 | |||
| 30 | void ieee80211s_init(void) | 37 | void 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 | ||
| 207 | void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | 214 | int |
| 215 | mesh_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 | |||
| 253 | int | ||
| 254 | mesh_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 | |||
| 271 | int | ||
| 272 | mesh_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 | |||
| 295 | int | ||
| 296 | mesh_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 | |||
| 324 | int | ||
| 325 | mesh_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 | |||
| 351 | int | ||
| 352 | mesh_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 | ||
| 382 | int 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 | |||
| 291 | static void ieee80211_mesh_path_timer(unsigned long data) | 403 | static 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 | */ |
| 125 | struct mesh_table { | 130 | struct 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 */ |
| 190 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, | 191 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, |
| @@ -199,6 +200,20 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, | |||
| 199 | void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); | 200 | void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); |
| 200 | void mesh_mgmt_ies_add(struct sk_buff *skb, | 201 | void mesh_mgmt_ies_add(struct sk_buff *skb, |
| 201 | struct ieee80211_sub_if_data *sdata); | 202 | struct ieee80211_sub_if_data *sdata); |
| 203 | int mesh_add_meshconf_ie(struct sk_buff *skb, | ||
| 204 | struct ieee80211_sub_if_data *sdata); | ||
| 205 | int mesh_add_meshid_ie(struct sk_buff *skb, | ||
| 206 | struct ieee80211_sub_if_data *sdata); | ||
| 207 | int mesh_add_rsn_ie(struct sk_buff *skb, | ||
| 208 | struct ieee80211_sub_if_data *sdata); | ||
| 209 | int mesh_add_vendor_ies(struct sk_buff *skb, | ||
| 210 | struct ieee80211_sub_if_data *sdata); | ||
| 211 | int mesh_add_srates_ie(struct sk_buff *skb, | ||
| 212 | struct ieee80211_sub_if_data *sdata); | ||
| 213 | int mesh_add_ext_srates_ie(struct sk_buff *skb, | ||
| 214 | struct ieee80211_sub_if_data *sdata); | ||
| 215 | int mesh_add_ds_params_ie(struct sk_buff *skb, | ||
| 216 | struct ieee80211_sub_if_data *sdata); | ||
| 202 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); | 217 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); |
| 203 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); | 218 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); |
| 204 | void ieee80211s_init(void); | 219 | void ieee80211s_init(void); |
| @@ -227,6 +242,10 @@ void mesh_path_flush(struct ieee80211_sub_if_data *sdata); | |||
| 227 | void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, | 242 | void 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); |
| 229 | int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); | 244 | int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); |
| 245 | |||
| 246 | int mesh_path_add_gate(struct mesh_path *mpath); | ||
| 247 | int mesh_path_send_to_gates(struct mesh_path *mpath); | ||
| 248 | int mesh_gate_num(struct ieee80211_sub_if_data *sdata); | ||
| 230 | /* Mesh plinks */ | 249 | /* Mesh plinks */ |
| 231 | void mesh_neighbour_update(u8 *hw_addr, u32 rates, | 250 | void 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); | |||
| 262 | void mesh_path_restart(struct ieee80211_sub_if_data *sdata); | 281 | void mesh_path_restart(struct ieee80211_sub_if_data *sdata); |
| 263 | void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); | 282 | void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); |
| 264 | 283 | ||
| 284 | bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); | ||
| 265 | extern int mesh_paths_generation; | 285 | extern 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 | ||
| 1005 | void | 1043 | void |
| 1006 | mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) | 1044 | mesh_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 | ||
| 69 | static 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 | ||
| 230 | static 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 | */ | ||
| 287 | static 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 | ||
| 434 | static 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 | */ | ||
| 448 | static 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; | ||
| 480 | err_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 | */ | ||
| 494 | static 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 | */ | ||
| 523 | int 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 | */ | ||
| 532 | int 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 | */ | ||
| 926 | int 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 | ||
| 45 | enum plink_frame_type { | ||
| 46 | PLINK_OPEN = 1, | ||
| 47 | PLINK_CONFIRM, | ||
| 48 | PLINK_CLOSE | ||
| 49 | }; | ||
| 50 | |||
| 51 | enum plink_event { | 34 | enum 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 | ||
| 159 | static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | 142 | static 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 */ | ||
| 2438 | static 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 | |||
| 2432 | static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | 2463 | static 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*/ | ||
| 114 | struct 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 | */ | ||
| 164 | struct 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 | ||
| 283 | static int sta_info_finish_insert(struct sta_info *sta, bool async) | 330 | static 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 | ||
| 371 | int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) | 426 | static 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 | |||
| 445 | static 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 | */ | ||
| 484 | static 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 | |||
| 549 | int 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 */ | ||
| 608 | int 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 | |||
| 496 | static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) | 626 | static 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 | */ |
| 246 | struct sta_info { | 248 | struct 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) | |||
| 436 | struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | 441 | struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, |
| 437 | const u8 *addr); | 442 | const u8 *addr); |
| 438 | 443 | ||
| 444 | struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata, | ||
| 445 | const u8 *addr); | ||
| 446 | |||
| 439 | struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | 447 | struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, |
| 440 | const u8 *addr); | 448 | const u8 *addr); |
| 441 | 449 | ||
| 450 | struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata, | ||
| 451 | const u8 *addr); | ||
| 452 | |||
| 442 | static inline | 453 | static inline |
| 443 | void for_each_sta_info_type_check(struct ieee80211_local *local, | 454 | void 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, | |||
| 484 | int sta_info_insert(struct sta_info *sta); | 511 | int sta_info_insert(struct sta_info *sta); |
| 485 | int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU); | 512 | int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU); |
| 486 | int sta_info_insert_atomic(struct sta_info *sta); | 513 | int sta_info_insert_atomic(struct sta_info *sta); |
| 514 | int sta_info_reinsert(struct sta_info *sta); | ||
| 487 | 515 | ||
| 488 | int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, | 516 | int 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 | */ |
| 324 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | 324 | struct 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 | ||
| 124 | static int rawsock_add_header(struct sk_buff *skb) | 124 | static 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 | ||
| 54 | const struct mesh_setup default_mesh_setup = { | 57 | const 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 | ||
| 2548 | static struct nla_policy | ||
| 2549 | nl80211_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 | |||
| 2548 | static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | 2554 | static 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, ¶ms)) | 2596 | if (parse_station_flags(info, ¶ms)) |
| 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 | ||
| 3067 | static const struct nla_policy | 3101 | static 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; |
