Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem

+7451 -6547
+2 -2
Documentation/networking/regulatory.txt
··· 159 159 REG_RULE(2412-20, 2484+20, 40, 6, 20, 0), 160 160 /* IEEE 802.11a, channels 34..48 */ 161 161 REG_RULE(5170-20, 5240+20, 40, 6, 20, 162 - NL80211_RRF_PASSIVE_SCAN), 162 + NL80211_RRF_NO_IR), 163 163 /* IEEE 802.11a, channels 52..64 */ 164 164 REG_RULE(5260-20, 5320+20, 40, 6, 20, 165 - NL80211_RRF_NO_IBSS | 165 + NL80211_RRF_NO_IR| 166 166 NL80211_RRF_DFS), 167 167 } 168 168 };
+8 -11
MAINTAINERS
··· 1458 1458 S: Supported 1459 1459 F: drivers/net/wireless/ath/ath6kl/ 1460 1460 1461 - ATHEROS ATH9K WIRELESS DRIVER 1462 - M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com> 1463 - M: Jouni Malinen <jouni@qca.qualcomm.com> 1464 - M: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> 1465 - M: Senthil Balasubramanian <senthilb@qca.qualcomm.com> 1466 - L: linux-wireless@vger.kernel.org 1467 - L: ath9k-devel@lists.ath9k.org 1468 - W: http://wireless.kernel.org/en/users/Drivers/ath9k 1469 - S: Supported 1470 - F: drivers/net/wireless/ath/ath9k/ 1471 - 1472 1461 WILOCITY WIL6210 WIRELESS DRIVER 1473 1462 M: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> 1474 1463 L: linux-wireless@vger.kernel.org ··· 6916 6927 T: git git://linuxtv.org/anttip/media_tree.git 6917 6928 S: Maintained 6918 6929 F: drivers/media/tuners/qt1010* 6930 + 6931 + QUALCOMM ATHEROS ATH9K WIRELESS DRIVER 6932 + M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com> 6933 + L: linux-wireless@vger.kernel.org 6934 + L: ath9k-devel@lists.ath9k.org 6935 + W: http://wireless.kernel.org/en/users/Drivers/ath9k 6936 + S: Supported 6937 + F: drivers/net/wireless/ath/ath9k/ 6919 6938 6920 6939 QUALCOMM ATHEROS ATH10K WIRELESS DRIVER 6921 6940 M: Kalle Valo <kvalo@qca.qualcomm.com>
-1
drivers/bcma/host_pci.c
··· 238 238 pci_release_regions(dev); 239 239 pci_disable_device(dev); 240 240 kfree(bus); 241 - pci_set_drvdata(dev, NULL); 242 241 } 243 242 244 243 #ifdef CONFIG_PM_SLEEP
+2 -2
drivers/net/wireless/ath/ath10k/mac.c
··· 1351 1351 ch->allow_vht = true; 1352 1352 1353 1353 ch->allow_ibss = 1354 - !(channel->flags & IEEE80211_CHAN_NO_IBSS); 1354 + !(channel->flags & IEEE80211_CHAN_NO_IR); 1355 1355 1356 1356 ch->ht40plus = 1357 1357 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS); 1358 1358 1359 - passive = channel->flags & IEEE80211_CHAN_PASSIVE_SCAN; 1359 + passive = channel->flags & IEEE80211_CHAN_NO_IR; 1360 1360 ch->passive = passive; 1361 1361 1362 1362 ch->freq = channel->center_freq;
+8 -3
drivers/net/wireless/ath/ath6kl/cfg80211.c
··· 1109 1109 (mode == WMI_11G_HT20) ? 1110 1110 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); 1111 1111 1112 + mutex_lock(&vif->wdev.mtx); 1112 1113 cfg80211_ch_switch_notify(vif->ndev, &chandef); 1114 + mutex_unlock(&vif->wdev.mtx); 1113 1115 } 1114 1116 1115 1117 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, ··· 3171 3169 } 3172 3170 3173 3171 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3174 - struct ieee80211_channel *chan, bool offchan, 3175 - unsigned int wait, const u8 *buf, size_t len, 3176 - bool no_cck, bool dont_wait_for_ack, u64 *cookie) 3172 + struct cfg80211_mgmt_tx_params *params, u64 *cookie) 3177 3173 { 3178 3174 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); 3179 3175 struct ath6kl *ar = ath6kl_priv(vif->ndev); 3176 + struct ieee80211_channel *chan = params->chan; 3177 + const u8 *buf = params->buf; 3178 + size_t len = params->len; 3179 + unsigned int wait = params->wait; 3180 + bool no_cck = params->no_cck; 3180 3181 u32 id, freq; 3181 3182 const struct ieee80211_mgmt *mgmt; 3182 3183 bool more_data, queued;
+9 -1
drivers/net/wireless/ath/ath9k/Kconfig
··· 86 86 87 87 config ATH9K_TX99 88 88 bool "Atheros ath9k TX99 testing support" 89 - depends on CFG80211_CERTIFICATION_ONUS 89 + depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS 90 90 default n 91 91 ---help--- 92 92 Say N. This should only be enabled on systems undergoing ··· 103 103 Regulatory bodies around the world require that wireless device 104 104 be evaluated to meet the RF exposure limits set forth in the 105 105 governmental SAR regulations. 106 + 107 + config ATH9K_WOW 108 + bool "Wake on Wireless LAN support (EXPERIMENTAL)" 109 + depends on ATH9K && PM 110 + default n 111 + ---help--- 112 + This option enables Wake on Wireless LAN support for certain cards. 113 + Currently, AR9462 is supported. 106 114 107 115 config ATH9K_LEGACY_RATE_CONTROL 108 116 bool "Atheros ath9k rate control"
+5 -3
drivers/net/wireless/ath/ath9k/Makefile
··· 13 13 ath9k-$(CONFIG_ATH9K_AHB) += ahb.o 14 14 ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o 15 15 ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o 16 - ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \ 17 - dfs.o 18 - ath9k-$(CONFIG_PM_SLEEP) += wow.o 16 + ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o 17 + ath9k-$(CONFIG_ATH9K_TX99) += tx99.o 18 + ath9k-$(CONFIG_ATH9K_WOW) += wow.o 19 19 20 20 obj-$(CONFIG_ATH9K) += ath9k.o 21 21 ··· 40 40 ar9003_mac.o \ 41 41 ar9003_eeprom.o \ 42 42 ar9003_paprd.o 43 + 44 + ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o 43 45 44 46 ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ 45 47 ar9003_mci.o
+19 -12
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
··· 352 352 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 353 353 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 354 354 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 355 - {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, 355 + {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982}, 356 356 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 357 357 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 358 358 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, ··· 378 378 {0x00009814, 0x9280c00a}, 379 379 {0x00009818, 0x00000000}, 380 380 {0x0000981c, 0x00020028}, 381 - {0x00009834, 0x6400a290}, 381 + {0x00009834, 0x6400a190}, 382 382 {0x00009838, 0x0108ecff}, 383 - {0x0000983c, 0x0d000600}, 383 + {0x0000983c, 0x14000600}, 384 384 {0x00009880, 0x201fff00}, 385 385 {0x00009884, 0x00001042}, 386 386 {0x000098a4, 0x00200400}, ··· 401 401 {0x00009d04, 0x40206c10}, 402 402 {0x00009d08, 0x009c4060}, 403 403 {0x00009d0c, 0x9883800a}, 404 - {0x00009d10, 0x01834061}, 404 + {0x00009d10, 0x01884061}, 405 405 {0x00009d14, 0x00c0040b}, 406 406 {0x00009d18, 0x00000000}, 407 407 {0x00009e08, 0x0038230c}, ··· 459 459 {0x0000a3e8, 0x20202020}, 460 460 {0x0000a3ec, 0x20202020}, 461 461 {0x0000a3f0, 0x00000000}, 462 - {0x0000a3f4, 0x00000246}, 462 + {0x0000a3f4, 0x00000000}, 463 463 {0x0000a3f8, 0x0c9bd380}, 464 464 {0x0000a3fc, 0x000f0f01}, 465 465 {0x0000a400, 0x8fa91f01}, ··· 644 644 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 645 645 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 646 646 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 647 - {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, 647 + {0x0000a410, 0x000050d4, 0x000050d4, 0x000050d9, 0x000050d9}, 648 648 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 649 649 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, 650 650 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, ··· 1086 1086 {0x0000b074, 0x00000000}, 1087 1087 {0x0000b078, 0x00000000}, 1088 1088 {0x0000b07c, 0x00000000}, 1089 - {0x0000b080, 0x2a2d2f32}, 1090 - {0x0000b084, 0x21232328}, 1089 + {0x0000b080, 0x23232323}, 1090 + {0x0000b084, 0x21232323}, 1091 1091 {0x0000b088, 0x19191c1e}, 1092 1092 {0x0000b08c, 0x12141417}, 1093 1093 {0x0000b090, 0x07070e0e}, ··· 1385 1385 {0x000081f8, 0x00000000}, 1386 1386 {0x000081fc, 0x00000000}, 1387 1387 {0x00008240, 0x00100000}, 1388 - {0x00008244, 0x0010f424}, 1388 + {0x00008244, 0x0010f400}, 1389 1389 {0x00008248, 0x00000800}, 1390 - {0x0000824c, 0x0001e848}, 1390 + {0x0000824c, 0x0001e800}, 1391 1391 {0x00008250, 0x00000000}, 1392 1392 {0x00008254, 0x00000000}, 1393 1393 {0x00008258, 0x00000000}, ··· 1726 1726 1727 1727 static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = { 1728 1728 /* Addr allmodes */ 1729 - {0x00004040, 0x08253e5e}, 1729 + {0x00004040, 0x0825365e}, 1730 1730 {0x00004040, 0x0008003b}, 1731 1731 {0x00004044, 0x00000000}, 1732 1732 }; 1733 1733 1734 1734 static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = { 1735 1735 /* Addr allmodes */ 1736 - {0x00004040, 0x08213e5e}, 1736 + {0x00004040, 0x0821365e}, 1737 1737 {0x00004040, 0x0008003b}, 1738 1738 {0x00004044, 0x00000000}, 1739 + }; 1740 + 1741 + static const u32 ar9300_2p2_baseband_core_txfir_coeff_japan_2484[][2] = { 1742 + /* Addr allmodes */ 1743 + {0x0000a398, 0x00000000}, 1744 + {0x0000a39c, 0x6f7f0301}, 1745 + {0x0000a3a0, 0xca9228ee}, 1739 1746 }; 1740 1747 1741 1748 #endif /* INITVALS_9003_2P2_H */
+100 -14
drivers/net/wireless/ath/ath9k/ar9003_calib.c
··· 1040 1040 } 1041 1041 } 1042 1042 1043 - static bool ar9003_hw_init_cal(struct ath_hw *ah, 1044 - struct ath9k_channel *chan) 1043 + static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, 1044 + struct ath9k_channel *chan) 1045 1045 { 1046 1046 struct ath_common *common = ath9k_hw_common(ah); 1047 1047 struct ath9k_hw_cal_data *caldata = ah->caldata; 1048 1048 bool txiqcal_done = false; 1049 1049 bool is_reusable = true, status = true; 1050 - bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; 1050 + bool run_rtt_cal = false, run_agc_cal; 1051 1051 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); 1052 1052 u32 rx_delay = 0; 1053 1053 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | ··· 1119 1119 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1120 1120 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 1121 1121 txiqcal_done = run_agc_cal = true; 1122 - } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) { 1123 - run_agc_cal = true; 1124 - sep_iq_cal = true; 1125 1122 } 1126 1123 1127 1124 skip_tx_iqcal: 1128 1125 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1129 1126 ar9003_mci_init_cal_req(ah, &is_reusable); 1130 - 1131 - if (sep_iq_cal) { 1132 - txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); 1133 - REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 1134 - udelay(5); 1135 - REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 1136 - } 1137 1127 1138 1128 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1139 1129 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); ··· 1218 1228 return true; 1219 1229 } 1220 1230 1231 + static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, 1232 + struct ath9k_channel *chan) 1233 + { 1234 + struct ath_common *common = ath9k_hw_common(ah); 1235 + struct ath9k_hw_cal_data *caldata = ah->caldata; 1236 + bool txiqcal_done = false; 1237 + bool is_reusable = true, status = true; 1238 + bool run_agc_cal = false, sep_iq_cal = false; 1239 + 1240 + /* Use chip chainmask only for calibration */ 1241 + ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); 1242 + 1243 + if (ah->enabled_cals & TX_CL_CAL) { 1244 + REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); 1245 + run_agc_cal = true; 1246 + } 1247 + 1248 + if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) 1249 + goto skip_tx_iqcal; 1250 + 1251 + /* Do Tx IQ Calibration */ 1252 + REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, 1253 + AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, 1254 + DELPT); 1255 + 1256 + /* 1257 + * For AR9485 or later chips, TxIQ cal runs as part of 1258 + * AGC calibration. Specifically, AR9550 in SoC chips. 1259 + */ 1260 + if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { 1261 + txiqcal_done = true; 1262 + run_agc_cal = true; 1263 + } else { 1264 + sep_iq_cal = true; 1265 + run_agc_cal = true; 1266 + } 1267 + 1268 + /* 1269 + * In the SoC family, this will run for AR9300, AR9331 and AR9340. 1270 + */ 1271 + if (sep_iq_cal) { 1272 + txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); 1273 + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 1274 + udelay(5); 1275 + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 1276 + } 1277 + 1278 + skip_tx_iqcal: 1279 + if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { 1280 + /* Calibrate the AGC */ 1281 + REG_WRITE(ah, AR_PHY_AGC_CONTROL, 1282 + REG_READ(ah, AR_PHY_AGC_CONTROL) | 1283 + AR_PHY_AGC_CONTROL_CAL); 1284 + 1285 + /* Poll for offset calibration complete */ 1286 + status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 1287 + AR_PHY_AGC_CONTROL_CAL, 1288 + 0, AH_WAIT_TIMEOUT); 1289 + } 1290 + 1291 + if (!status) { 1292 + ath_dbg(common, CALIBRATE, 1293 + "offset calibration failed to complete in %d ms; noisy environment?\n", 1294 + AH_WAIT_TIMEOUT / 1000); 1295 + return false; 1296 + } 1297 + 1298 + if (txiqcal_done) 1299 + ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); 1300 + 1301 + /* Revert chainmask to runtime parameters */ 1302 + ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 1303 + 1304 + /* Initialize list pointers */ 1305 + ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; 1306 + 1307 + INIT_CAL(&ah->iq_caldata); 1308 + INSERT_CAL(ah, &ah->iq_caldata); 1309 + ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); 1310 + 1311 + /* Initialize current pointer to first element in list */ 1312 + ah->cal_list_curr = ah->cal_list; 1313 + 1314 + if (ah->cal_list_curr) 1315 + ath9k_hw_reset_calibration(ah, ah->cal_list_curr); 1316 + 1317 + if (caldata) 1318 + caldata->CalValid = 0; 1319 + 1320 + return true; 1321 + } 1322 + 1221 1323 void ar9003_hw_attach_calib_ops(struct ath_hw *ah) 1222 1324 { 1223 1325 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1224 1326 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 1225 1327 1328 + if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah)) 1329 + priv_ops->init_cal = ar9003_hw_init_cal_pcoem; 1330 + else 1331 + priv_ops->init_cal = ar9003_hw_init_cal_soc; 1332 + 1226 1333 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; 1227 - priv_ops->init_cal = ar9003_hw_init_cal; 1228 1334 priv_ops->setup_calibration = ar9003_hw_setup_calibration; 1229 1335 1230 1336 ops->calibrate = ar9003_hw_calibrate;
+96 -26
drivers/net/wireless/ath/ath9k/ar9003_hw.c
··· 26 26 #include "ar9462_2p0_initvals.h" 27 27 #include "ar9462_2p1_initvals.h" 28 28 #include "ar9565_1p0_initvals.h" 29 + #include "ar9565_1p1_initvals.h" 29 30 30 31 /* General hardware code for the AR9003 hadware family */ 31 32 ··· 149 148 ar9340Modes_high_ob_db_tx_gain_table_1p0); 150 149 151 150 INIT_INI_ARRAY(&ah->iniModesFastClock, 152 - ar9340Modes_fast_clock_1p0); 151 + ar9340Modes_fast_clock_1p0); 152 + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 153 + ar9340_1p0_baseband_core_txfir_coeff_japan_2484); 153 154 154 155 if (!ah->is_clk_25mhz) 155 156 INIT_INI_ARRAY(&ah->iniAdditional, ··· 226 223 ar9462_2p1_modes_fast_clock); 227 224 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 228 225 ar9462_2p1_baseband_core_txfir_coeff_japan_2484); 226 + INIT_INI_ARRAY(&ah->iniPcieSerdes, 227 + ar9462_2p1_pciephy_clkreq_disable_L1); 228 + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 229 + ar9462_2p1_pciephy_clkreq_disable_L1); 229 230 } else if (AR_SREV_9462_20(ah)) { 230 231 231 232 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); ··· 254 247 ar9462_2p0_soc_postamble); 255 248 256 249 INIT_INI_ARRAY(&ah->iniModesRxGain, 257 - ar9462_common_rx_gain_table_2p0); 250 + ar9462_2p0_common_rx_gain); 258 251 259 252 /* Awake -> Sleep Setting */ 260 253 INIT_INI_ARRAY(&ah->iniPcieSerdes, 261 - ar9462_pciephy_clkreq_disable_L1_2p0); 254 + ar9462_2p0_pciephy_clkreq_disable_L1); 262 255 /* Sleep -> Awake Setting */ 263 256 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 264 - ar9462_pciephy_clkreq_disable_L1_2p0); 257 + ar9462_2p0_pciephy_clkreq_disable_L1); 265 258 266 259 /* Fast clock modal settings */ 267 260 INIT_INI_ARRAY(&ah->iniModesFastClock, 268 - ar9462_modes_fast_clock_2p0); 261 + ar9462_2p0_modes_fast_clock); 269 262 270 263 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 271 264 ar9462_2p0_baseband_core_txfir_coeff_japan_2484); ··· 337 330 ar9580_1p0_low_ob_db_tx_gain_table); 338 331 339 332 INIT_INI_ARRAY(&ah->iniModesFastClock, 340 - ar9580_1p0_modes_fast_clock); 333 + ar9580_1p0_modes_fast_clock); 334 + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 335 + ar9580_1p0_baseband_core_txfir_coeff_japan_2484); 336 + } else if (AR_SREV_9565_11_OR_LATER(ah)) { 337 + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 338 + ar9565_1p1_mac_core); 339 + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], 340 + ar9565_1p1_mac_postamble); 341 + 342 + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], 343 + ar9565_1p1_baseband_core); 344 + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], 345 + ar9565_1p1_baseband_postamble); 346 + 347 + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], 348 + ar9565_1p1_radio_core); 349 + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], 350 + ar9565_1p1_radio_postamble); 351 + 352 + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], 353 + ar9565_1p1_soc_preamble); 354 + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], 355 + ar9565_1p1_soc_postamble); 356 + 357 + INIT_INI_ARRAY(&ah->iniModesRxGain, 358 + ar9565_1p1_Common_rx_gain_table); 359 + INIT_INI_ARRAY(&ah->iniModesTxGain, 360 + ar9565_1p1_Modes_lowest_ob_db_tx_gain_table); 361 + 362 + INIT_INI_ARRAY(&ah->iniPcieSerdes, 363 + ar9565_1p1_pciephy_clkreq_disable_L1); 364 + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 365 + ar9565_1p1_pciephy_clkreq_disable_L1); 366 + 367 + INIT_INI_ARRAY(&ah->iniModesFastClock, 368 + ar9565_1p1_modes_fast_clock); 369 + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 370 + ar9565_1p1_baseband_core_txfir_coeff_japan_2484); 341 371 } else if (AR_SREV_9565(ah)) { 342 372 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 343 373 ar9565_1p0_mac_core); ··· 455 411 456 412 /* Fast clock modal settings */ 457 413 INIT_INI_ARRAY(&ah->iniModesFastClock, 458 - ar9300Modes_fast_clock_2p2); 414 + ar9300Modes_fast_clock_2p2); 415 + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 416 + ar9300_2p2_baseband_core_txfir_coeff_japan_2484); 459 417 } 460 418 } 461 419 ··· 486 440 ar9462_2p1_modes_low_ob_db_tx_gain); 487 441 else if (AR_SREV_9462_20(ah)) 488 442 INIT_INI_ARRAY(&ah->iniModesTxGain, 489 - ar9462_modes_low_ob_db_tx_gain_table_2p0); 443 + ar9462_2p0_modes_low_ob_db_tx_gain); 444 + else if (AR_SREV_9565_11(ah)) 445 + INIT_INI_ARRAY(&ah->iniModesTxGain, 446 + ar9565_1p1_modes_low_ob_db_tx_gain_table); 490 447 else if (AR_SREV_9565(ah)) 491 448 INIT_INI_ARRAY(&ah->iniModesTxGain, 492 449 ar9565_1p0_modes_low_ob_db_tx_gain_table); ··· 523 474 ar9462_2p1_modes_high_ob_db_tx_gain); 524 475 else if (AR_SREV_9462_20(ah)) 525 476 INIT_INI_ARRAY(&ah->iniModesTxGain, 526 - ar9462_modes_high_ob_db_tx_gain_table_2p0); 477 + ar9462_2p0_modes_high_ob_db_tx_gain); 478 + else if (AR_SREV_9565_11(ah)) 479 + INIT_INI_ARRAY(&ah->iniModesTxGain, 480 + ar9565_1p1_modes_high_ob_db_tx_gain_table); 527 481 else if (AR_SREV_9565(ah)) 528 482 INIT_INI_ARRAY(&ah->iniModesTxGain, 529 483 ar9565_1p0_modes_high_ob_db_tx_gain_table); ··· 552 500 else if (AR_SREV_9580(ah)) 553 501 INIT_INI_ARRAY(&ah->iniModesTxGain, 554 502 ar9580_1p0_low_ob_db_tx_gain_table); 503 + else if (AR_SREV_9565_11(ah)) 504 + INIT_INI_ARRAY(&ah->iniModesTxGain, 505 + ar9565_1p1_modes_low_ob_db_tx_gain_table); 555 506 else if (AR_SREV_9565(ah)) 556 507 INIT_INI_ARRAY(&ah->iniModesTxGain, 557 508 ar9565_1p0_modes_low_ob_db_tx_gain_table); ··· 580 525 else if (AR_SREV_9580(ah)) 581 526 INIT_INI_ARRAY(&ah->iniModesTxGain, 582 527 ar9580_1p0_high_power_tx_gain_table); 528 + else if (AR_SREV_9565_11(ah)) 529 + INIT_INI_ARRAY(&ah->iniModesTxGain, 530 + ar9565_1p1_modes_high_power_tx_gain_table); 583 531 else if (AR_SREV_9565(ah)) 584 532 INIT_INI_ARRAY(&ah->iniModesTxGain, 585 533 ar9565_1p0_modes_high_power_tx_gain_table); ··· 604 546 ar9462_2p1_modes_mix_ob_db_tx_gain); 605 547 else if (AR_SREV_9462_20(ah)) 606 548 INIT_INI_ARRAY(&ah->iniModesTxGain, 607 - ar9462_modes_mix_ob_db_tx_gain_table_2p0); 549 + ar9462_2p0_modes_mix_ob_db_tx_gain); 608 550 else 609 551 INIT_INI_ARRAY(&ah->iniModesTxGain, 610 552 ar9300Modes_mixed_ob_db_tx_gain_table_2p2); ··· 639 581 ar9580_1p0_type6_tx_gain_table); 640 582 } 641 583 584 + static void ar9003_tx_gain_table_mode7(struct ath_hw *ah) 585 + { 586 + if (AR_SREV_9340(ah)) 587 + INIT_INI_ARRAY(&ah->iniModesTxGain, 588 + ar9340_cus227_tx_gain_table_1p0); 589 + } 590 + 642 591 typedef void (*ath_txgain_tab)(struct ath_hw *ah); 643 592 644 593 static void ar9003_tx_gain_table_apply(struct ath_hw *ah) ··· 658 593 ar9003_tx_gain_table_mode4, 659 594 ar9003_tx_gain_table_mode5, 660 595 ar9003_tx_gain_table_mode6, 596 + ar9003_tx_gain_table_mode7, 661 597 }; 662 598 int idx = ar9003_hw_get_tx_gain_idx(ah); 663 599 ··· 695 629 ar9462_2p1_common_rx_gain); 696 630 else if (AR_SREV_9462_20(ah)) 697 631 INIT_INI_ARRAY(&ah->iniModesRxGain, 698 - ar9462_common_rx_gain_table_2p0); 632 + ar9462_2p0_common_rx_gain); 633 + else if (AR_SREV_9565_11(ah)) 634 + INIT_INI_ARRAY(&ah->iniModesRxGain, 635 + ar9565_1p1_Common_rx_gain_table); 699 636 else if (AR_SREV_9565(ah)) 700 637 INIT_INI_ARRAY(&ah->iniModesRxGain, 701 638 ar9565_1p0_Common_rx_gain_table); ··· 726 657 ar9462_2p1_common_wo_xlna_rx_gain); 727 658 else if (AR_SREV_9462_20(ah)) 728 659 INIT_INI_ARRAY(&ah->iniModesRxGain, 729 - ar9462_common_wo_xlna_rx_gain_table_2p0); 660 + ar9462_2p0_common_wo_xlna_rx_gain); 730 661 else if (AR_SREV_9550(ah)) { 731 662 INIT_INI_ARRAY(&ah->iniModesRxGain, 732 663 ar955x_1p0_common_wo_xlna_rx_gain_table); ··· 735 666 } else if (AR_SREV_9580(ah)) 736 667 INIT_INI_ARRAY(&ah->iniModesRxGain, 737 668 ar9580_1p0_wo_xlna_rx_gain_table); 669 + else if (AR_SREV_9565_11(ah)) 670 + INIT_INI_ARRAY(&ah->iniModesRxGain, 671 + ar9565_1p1_common_wo_xlna_rx_gain_table); 738 672 else if (AR_SREV_9565(ah)) 739 673 INIT_INI_ARRAY(&ah->iniModesRxGain, 740 674 ar9565_1p0_common_wo_xlna_rx_gain_table); ··· 759 687 ar9462_2p1_baseband_postamble_5g_xlna); 760 688 } else if (AR_SREV_9462_20(ah)) { 761 689 INIT_INI_ARRAY(&ah->iniModesRxGain, 762 - ar9462_common_mixed_rx_gain_table_2p0); 690 + ar9462_2p0_common_mixed_rx_gain); 763 691 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, 764 692 ar9462_2p0_baseband_core_mix_rxgain); 765 693 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble, ··· 773 701 { 774 702 if (AR_SREV_9462_21(ah)) { 775 703 INIT_INI_ARRAY(&ah->iniModesRxGain, 776 - ar9462_2p1_common_5g_xlna_only_rx_gain); 704 + ar9462_2p1_common_5g_xlna_only_rxgain); 777 705 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 778 706 ar9462_2p1_baseband_postamble_5g_xlna); 779 707 } else if (AR_SREV_9462_20(ah)) { 780 708 INIT_INI_ARRAY(&ah->iniModesRxGain, 781 - ar9462_2p0_5g_xlna_only_rxgain); 709 + ar9462_2p0_common_5g_xlna_only_rxgain); 782 710 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 783 711 ar9462_2p0_baseband_postamble_5g_xlna); 784 712 } ··· 822 750 static void ar9003_hw_configpcipowersave(struct ath_hw *ah, 823 751 bool power_off) 824 752 { 753 + unsigned int i; 754 + struct ar5416IniArray *array; 755 + 825 756 /* 826 757 * Increase L1 Entry Latency. Some WB222 boards don't have 827 758 * this change in eeprom/OTP. ··· 850 775 * Configire PCIE after Ini init. SERDES values now come from ini file 851 776 * This enables PCIe low power mode. 852 777 */ 853 - if (ah->config.pcieSerDesWrite) { 854 - unsigned int i; 855 - struct ar5416IniArray *array; 778 + array = power_off ? &ah->iniPcieSerdes : 779 + &ah->iniPcieSerdesLowPower; 856 780 857 - array = power_off ? &ah->iniPcieSerdes : 858 - &ah->iniPcieSerdesLowPower; 859 - 860 - for (i = 0; i < array->ia_rows; i++) { 861 - REG_WRITE(ah, 862 - INI_RA(array, i, 0), 863 - INI_RA(array, i, 1)); 864 - } 781 + for (i = 0; i < array->ia_rows; i++) { 782 + REG_WRITE(ah, 783 + INI_RA(array, i, 0), 784 + INI_RA(array, i, 1)); 865 785 } 866 786 } 867 787
+5 -4
drivers/net/wireless/ath/ath9k/ar9003_phy.c
··· 641 641 else 642 642 ah->enabled_cals &= ~TX_IQ_CAL; 643 643 644 - if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) 645 - ah->enabled_cals |= TX_CL_CAL; 646 - else 647 - ah->enabled_cals &= ~TX_CL_CAL; 648 644 } 645 + 646 + if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) 647 + ah->enabled_cals |= TX_CL_CAL; 648 + else 649 + ah->enabled_cals &= ~TX_CL_CAL; 649 650 } 650 651 651 652 static void ar9003_hw_prog_ini(struct ath_hw *ah,
+422
drivers/net/wireless/ath/ath9k/ar9003_wow.c
··· 1 + /* 2 + * Copyright (c) 2012 Qualcomm Atheros, Inc. 3 + * 4 + * Permission to use, copy, modify, and/or distribute this software for any 5 + * purpose with or without fee is hereby granted, provided that the above 6 + * copyright notice and this permission notice appear in all copies. 7 + * 8 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + 17 + #include <linux/export.h> 18 + #include "ath9k.h" 19 + #include "reg.h" 20 + #include "hw-ops.h" 21 + 22 + const char *ath9k_hw_wow_event_to_string(u32 wow_event) 23 + { 24 + if (wow_event & AH_WOW_MAGIC_PATTERN_EN) 25 + return "Magic pattern"; 26 + if (wow_event & AH_WOW_USER_PATTERN_EN) 27 + return "User pattern"; 28 + if (wow_event & AH_WOW_LINK_CHANGE) 29 + return "Link change"; 30 + if (wow_event & AH_WOW_BEACON_MISS) 31 + return "Beacon miss"; 32 + 33 + return "unknown reason"; 34 + } 35 + EXPORT_SYMBOL(ath9k_hw_wow_event_to_string); 36 + 37 + static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 38 + { 39 + struct ath_common *common = ath9k_hw_common(ah); 40 + 41 + REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 42 + 43 + /* set rx disable bit */ 44 + REG_WRITE(ah, AR_CR, AR_CR_RXD); 45 + 46 + if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) { 47 + ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", 48 + REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); 49 + return; 50 + } 51 + 52 + REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 53 + } 54 + 55 + static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) 56 + { 57 + struct ath_common *common = ath9k_hw_common(ah); 58 + u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN]; 59 + u32 ctl[13] = {0}; 60 + u32 data_word[KAL_NUM_DATA_WORDS]; 61 + u8 i; 62 + u32 wow_ka_data_word0; 63 + 64 + memcpy(sta_mac_addr, common->macaddr, ETH_ALEN); 65 + memcpy(ap_mac_addr, common->curbssid, ETH_ALEN); 66 + 67 + /* set the transmit buffer */ 68 + ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16)); 69 + ctl[1] = 0; 70 + ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */ 71 + ctl[4] = 0; 72 + ctl[7] = (ah->txchainmask) << 2; 73 + ctl[2] = 0xf << 16; /* tx_tries 0 */ 74 + 75 + for (i = 0; i < KAL_NUM_DESC_WORDS; i++) 76 + REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 77 + 78 + REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 79 + 80 + data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) | 81 + (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16); 82 + data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | 83 + (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); 84 + data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) | 85 + (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); 86 + data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) | 87 + (sta_mac_addr[3] << 8) | (sta_mac_addr[2]); 88 + data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | 89 + (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); 90 + data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); 91 + 92 + if (AR_SREV_9462_20(ah)) { 93 + /* AR9462 2.0 has an extra descriptor word (time based 94 + * discard) compared to other chips */ 95 + REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); 96 + wow_ka_data_word0 = AR_WOW_TXBUF(13); 97 + } else { 98 + wow_ka_data_word0 = AR_WOW_TXBUF(12); 99 + } 100 + 101 + for (i = 0; i < KAL_NUM_DATA_WORDS; i++) 102 + REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]); 103 + 104 + } 105 + 106 + void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 107 + u8 *user_mask, int pattern_count, 108 + int pattern_len) 109 + { 110 + int i; 111 + u32 pattern_val, mask_val; 112 + u32 set, clr; 113 + 114 + /* FIXME: should check count by querying the hardware capability */ 115 + if (pattern_count >= MAX_NUM_PATTERN) 116 + return; 117 + 118 + REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count)); 119 + 120 + /* set the registers for pattern */ 121 + for (i = 0; i < MAX_PATTERN_SIZE; i += 4) { 122 + memcpy(&pattern_val, user_pattern, 4); 123 + REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i), 124 + pattern_val); 125 + user_pattern += 4; 126 + } 127 + 128 + /* set the registers for mask */ 129 + for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) { 130 + memcpy(&mask_val, user_mask, 4); 131 + REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val); 132 + user_mask += 4; 133 + } 134 + 135 + /* set the pattern length to be matched 136 + * 137 + * AR_WOW_LENGTH1_REG1 138 + * bit 31:24 pattern 0 length 139 + * bit 23:16 pattern 1 length 140 + * bit 15:8 pattern 2 length 141 + * bit 7:0 pattern 3 length 142 + * 143 + * AR_WOW_LENGTH1_REG2 144 + * bit 31:24 pattern 4 length 145 + * bit 23:16 pattern 5 length 146 + * bit 15:8 pattern 6 length 147 + * bit 7:0 pattern 7 length 148 + * 149 + * the below logic writes out the new 150 + * pattern length for the corresponding 151 + * pattern_count, while masking out the 152 + * other fields 153 + */ 154 + 155 + ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 156 + 157 + if (pattern_count < 4) { 158 + /* Pattern 0-3 uses AR_WOW_LENGTH1 register */ 159 + set = (pattern_len & AR_WOW_LENGTH_MAX) << 160 + AR_WOW_LEN1_SHIFT(pattern_count); 161 + clr = AR_WOW_LENGTH1_MASK(pattern_count); 162 + REG_RMW(ah, AR_WOW_LENGTH1, set, clr); 163 + } else { 164 + /* Pattern 4-7 uses AR_WOW_LENGTH2 register */ 165 + set = (pattern_len & AR_WOW_LENGTH_MAX) << 166 + AR_WOW_LEN2_SHIFT(pattern_count); 167 + clr = AR_WOW_LENGTH2_MASK(pattern_count); 168 + REG_RMW(ah, AR_WOW_LENGTH2, set, clr); 169 + } 170 + 171 + } 172 + EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern); 173 + 174 + u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) 175 + { 176 + u32 wow_status = 0; 177 + u32 val = 0, rval; 178 + 179 + /* 180 + * read the WoW status register to know 181 + * the wakeup reason 182 + */ 183 + rval = REG_READ(ah, AR_WOW_PATTERN); 184 + val = AR_WOW_STATUS(rval); 185 + 186 + /* 187 + * mask only the WoW events that we have enabled. Sometimes 188 + * we have spurious WoW events from the AR_WOW_PATTERN 189 + * register. This mask will clean it up. 190 + */ 191 + 192 + val &= ah->wow_event_mask; 193 + 194 + if (val) { 195 + if (val & AR_WOW_MAGIC_PAT_FOUND) 196 + wow_status |= AH_WOW_MAGIC_PATTERN_EN; 197 + if (AR_WOW_PATTERN_FOUND(val)) 198 + wow_status |= AH_WOW_USER_PATTERN_EN; 199 + if (val & AR_WOW_KEEP_ALIVE_FAIL) 200 + wow_status |= AH_WOW_LINK_CHANGE; 201 + if (val & AR_WOW_BEACON_FAIL) 202 + wow_status |= AH_WOW_BEACON_MISS; 203 + } 204 + 205 + /* 206 + * set and clear WOW_PME_CLEAR registers for the chip to 207 + * generate next wow signal. 208 + * disable D3 before accessing other registers ? 209 + */ 210 + 211 + /* do we need to check the bit value 0x01000000 (7-10) ?? */ 212 + REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR, 213 + AR_PMCTRL_PWR_STATE_D1D3); 214 + 215 + /* 216 + * clear all events 217 + */ 218 + REG_WRITE(ah, AR_WOW_PATTERN, 219 + AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); 220 + 221 + /* 222 + * restore the beacon threshold to init value 223 + */ 224 + REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 225 + 226 + /* 227 + * Restore the way the PCI-E reset, Power-On-Reset, external 228 + * PCIE_POR_SHORT pins are tied to its original value. 229 + * Previously just before WoW sleep, we untie the PCI-E 230 + * reset to our Chip's Power On Reset so that any PCI-E 231 + * reset from the bus will not reset our chip 232 + */ 233 + if (ah->is_pciexpress) 234 + ath9k_hw_configpcipowersave(ah, false); 235 + 236 + ah->wow_event_mask = 0; 237 + 238 + return wow_status; 239 + } 240 + EXPORT_SYMBOL(ath9k_hw_wow_wakeup); 241 + 242 + void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) 243 + { 244 + u32 wow_event_mask; 245 + u32 set, clr; 246 + 247 + /* 248 + * wow_event_mask is a mask to the AR_WOW_PATTERN register to 249 + * indicate which WoW events we have enabled. The WoW events 250 + * are from the 'pattern_enable' in this function and 251 + * 'pattern_count' of ath9k_hw_wow_apply_pattern() 252 + */ 253 + wow_event_mask = ah->wow_event_mask; 254 + 255 + /* 256 + * Untie Power-on-Reset from the PCI-E-Reset. When we are in 257 + * WOW sleep, we do want the Reset from the PCI-E to disturb 258 + * our hw state 259 + */ 260 + if (ah->is_pciexpress) { 261 + /* 262 + * we need to untie the internal POR (power-on-reset) 263 + * to the external PCI-E reset. We also need to tie 264 + * the PCI-E Phy reset to the PCI-E reset. 265 + */ 266 + set = AR_WA_RESET_EN | AR_WA_POR_SHORT; 267 + clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE; 268 + REG_RMW(ah, AR_WA, set, clr); 269 + } 270 + 271 + /* 272 + * set the power states appropriately and enable PME 273 + */ 274 + set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA | 275 + AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR; 276 + 277 + /* 278 + * set and clear WOW_PME_CLEAR registers for the chip 279 + * to generate next wow signal. 280 + */ 281 + REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 282 + clr = AR_PMCTRL_WOW_PME_CLR; 283 + REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); 284 + 285 + /* 286 + * Setup for: 287 + * - beacon misses 288 + * - magic pattern 289 + * - keep alive timeout 290 + * - pattern matching 291 + */ 292 + 293 + /* 294 + * Program default values for pattern backoff, aifs/slot/KAL count, 295 + * beacon miss timeout, KAL timeout, etc. 296 + */ 297 + set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF); 298 + REG_SET_BIT(ah, AR_WOW_PATTERN, set); 299 + 300 + set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) | 301 + AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) | 302 + AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT); 303 + REG_SET_BIT(ah, AR_WOW_COUNT, set); 304 + 305 + if (pattern_enable & AH_WOW_BEACON_MISS) 306 + set = AR_WOW_BEACON_TIMO; 307 + /* We are not using beacon miss, program a large value */ 308 + else 309 + set = AR_WOW_BEACON_TIMO_MAX; 310 + 311 + REG_WRITE(ah, AR_WOW_BCN_TIMO, set); 312 + 313 + /* 314 + * Keep alive timo in ms except AR9280 315 + */ 316 + if (!pattern_enable) 317 + set = AR_WOW_KEEP_ALIVE_NEVER; 318 + else 319 + set = KAL_TIMEOUT * 32; 320 + 321 + REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set); 322 + 323 + /* 324 + * Keep alive delay in us. based on 'power on clock', 325 + * therefore in usec 326 + */ 327 + set = KAL_DELAY * 1000; 328 + REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set); 329 + 330 + /* 331 + * Create keep alive pattern to respond to beacons 332 + */ 333 + ath9k_wow_create_keep_alive_pattern(ah); 334 + 335 + /* 336 + * Configure MAC WoW Registers 337 + */ 338 + set = 0; 339 + /* Send keep alive timeouts anyway */ 340 + clr = AR_WOW_KEEP_ALIVE_AUTO_DIS; 341 + 342 + if (pattern_enable & AH_WOW_LINK_CHANGE) 343 + wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL; 344 + else 345 + set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 346 + 347 + set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 348 + REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); 349 + 350 + /* 351 + * we are relying on a bmiss failure. ensure we have 352 + * enough threshold to prevent false positives 353 + */ 354 + REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, 355 + AR_WOW_BMISSTHRESHOLD); 356 + 357 + set = 0; 358 + clr = 0; 359 + 360 + if (pattern_enable & AH_WOW_BEACON_MISS) { 361 + set = AR_WOW_BEACON_FAIL_EN; 362 + wow_event_mask |= AR_WOW_BEACON_FAIL; 363 + } else { 364 + clr = AR_WOW_BEACON_FAIL_EN; 365 + } 366 + 367 + REG_RMW(ah, AR_WOW_BCN_EN, set, clr); 368 + 369 + set = 0; 370 + clr = 0; 371 + /* 372 + * Enable the magic packet registers 373 + */ 374 + if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) { 375 + set = AR_WOW_MAGIC_EN; 376 + wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND; 377 + } else { 378 + clr = AR_WOW_MAGIC_EN; 379 + } 380 + set |= AR_WOW_MAC_INTR_EN; 381 + REG_RMW(ah, AR_WOW_PATTERN, set, clr); 382 + 383 + REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B, 384 + AR_WOW_PATTERN_SUPPORTED); 385 + 386 + /* 387 + * Set the power states appropriately and enable PME 388 + */ 389 + clr = 0; 390 + set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN | 391 + AR_PMCTRL_PWR_PM_CTRL_ENA; 392 + 393 + clr = AR_PCIE_PM_CTRL_ENA; 394 + REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 395 + 396 + /* 397 + * this is needed to prevent the chip waking up 398 + * the host within 3-4 seconds with certain 399 + * platform/BIOS. The fix is to enable 400 + * D1 & D3 to match original definition and 401 + * also match the OTP value. Anyway this 402 + * is more related to SW WOW. 403 + */ 404 + clr = AR_PMCTRL_PWR_STATE_D1D3; 405 + REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); 406 + 407 + set = AR_PMCTRL_PWR_STATE_D1D3_REAL; 408 + REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 409 + 410 + REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 411 + 412 + /* to bring down WOW power low margin */ 413 + set = BIT(13); 414 + REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set); 415 + /* HW WoW */ 416 + clr = BIT(5); 417 + REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr); 418 + 419 + ath9k_hw_set_powermode_wow_sleep(ah); 420 + ah->wow_event_mask = wow_event_mask; 421 + } 422 + EXPORT_SYMBOL(ath9k_hw_wow_enable);
+118 -272
drivers/net/wireless/ath/ath9k/ar9340_initvals.h
··· 18 18 #ifndef INITVALS_9340_H 19 19 #define INITVALS_9340_H 20 20 21 + #define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble 22 + 23 + #define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble 24 + 25 + #define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2 26 + 27 + #define ar9340Common_rx_gain_table_1p0 ar9300Common_rx_gain_table_2p2 28 + 29 + #define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2 30 + 31 + #define ar9340_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484 32 + 21 33 static const u32 ar9340_1p0_radio_postamble[][5] = { 22 34 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 23 35 {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800}, ··· 111 99 {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, 112 100 {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, 113 101 }; 114 - 115 - #define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2 116 102 117 103 static const u32 ar9340_1p0_radio_core[][2] = { 118 104 /* Addr allmodes */ ··· 225 215 {0x0000824c, 0x0001e800}, 226 216 }; 227 217 228 - #define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble 229 - 230 - #define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble 231 - 232 218 static const u32 ar9340_1p0_baseband_postamble[][5] = { 233 219 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 234 220 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 235 221 {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e}, 236 222 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, 237 - {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, 223 + {0x00009828, 0x06903081, 0x06903081, 0x09103881, 0x09103881}, 238 224 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, 239 225 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, 240 226 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, ··· 346 340 {0x0000a370, 0x00000000}, 347 341 {0x0000a390, 0x00000001}, 348 342 {0x0000a394, 0x00000444}, 349 - {0x0000a398, 0x001f0e0f}, 350 - {0x0000a39c, 0x0075393f}, 351 - {0x0000a3a0, 0xb79f6427}, 343 + {0x0000a398, 0x00000000}, 344 + {0x0000a39c, 0x210d0401}, 345 + {0x0000a3a0, 0xab9a7144}, 352 346 {0x0000a3a4, 0x00000000}, 353 347 {0x0000a3a8, 0xaaaaaaaa}, 354 348 {0x0000a3ac, 0x3c466478}, ··· 718 712 {0x0000b2e0, 0xfe896600, 0xfe896600, 0xfd339c84, 0xfd339c84}, 719 713 {0x0000b2e4, 0xff01f800, 0xff01f800, 0xfec3e000, 0xfec3e000}, 720 714 {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000}, 721 - }; 722 - 723 - static const u32 ar9340Common_rx_gain_table_1p0[][2] = { 724 - /* Addr allmodes */ 725 - {0x0000a000, 0x00010000}, 726 - {0x0000a004, 0x00030002}, 727 - {0x0000a008, 0x00050004}, 728 - {0x0000a00c, 0x00810080}, 729 - {0x0000a010, 0x00830082}, 730 - {0x0000a014, 0x01810180}, 731 - {0x0000a018, 0x01830182}, 732 - {0x0000a01c, 0x01850184}, 733 - {0x0000a020, 0x01890188}, 734 - {0x0000a024, 0x018b018a}, 735 - {0x0000a028, 0x018d018c}, 736 - {0x0000a02c, 0x01910190}, 737 - {0x0000a030, 0x01930192}, 738 - {0x0000a034, 0x01950194}, 739 - {0x0000a038, 0x038a0196}, 740 - {0x0000a03c, 0x038c038b}, 741 - {0x0000a040, 0x0390038d}, 742 - {0x0000a044, 0x03920391}, 743 - {0x0000a048, 0x03940393}, 744 - {0x0000a04c, 0x03960395}, 745 - {0x0000a050, 0x00000000}, 746 - {0x0000a054, 0x00000000}, 747 - {0x0000a058, 0x00000000}, 748 - {0x0000a05c, 0x00000000}, 749 - {0x0000a060, 0x00000000}, 750 - {0x0000a064, 0x00000000}, 751 - {0x0000a068, 0x00000000}, 752 - {0x0000a06c, 0x00000000}, 753 - {0x0000a070, 0x00000000}, 754 - {0x0000a074, 0x00000000}, 755 - {0x0000a078, 0x00000000}, 756 - {0x0000a07c, 0x00000000}, 757 - {0x0000a080, 0x22222229}, 758 - {0x0000a084, 0x1d1d1d1d}, 759 - {0x0000a088, 0x1d1d1d1d}, 760 - {0x0000a08c, 0x1d1d1d1d}, 761 - {0x0000a090, 0x171d1d1d}, 762 - {0x0000a094, 0x11111717}, 763 - {0x0000a098, 0x00030311}, 764 - {0x0000a09c, 0x00000000}, 765 - {0x0000a0a0, 0x00000000}, 766 - {0x0000a0a4, 0x00000000}, 767 - {0x0000a0a8, 0x00000000}, 768 - {0x0000a0ac, 0x00000000}, 769 - {0x0000a0b0, 0x00000000}, 770 - {0x0000a0b4, 0x00000000}, 771 - {0x0000a0b8, 0x00000000}, 772 - {0x0000a0bc, 0x00000000}, 773 - {0x0000a0c0, 0x001f0000}, 774 - {0x0000a0c4, 0x01000101}, 775 - {0x0000a0c8, 0x011e011f}, 776 - {0x0000a0cc, 0x011c011d}, 777 - {0x0000a0d0, 0x02030204}, 778 - {0x0000a0d4, 0x02010202}, 779 - {0x0000a0d8, 0x021f0200}, 780 - {0x0000a0dc, 0x0302021e}, 781 - {0x0000a0e0, 0x03000301}, 782 - {0x0000a0e4, 0x031e031f}, 783 - {0x0000a0e8, 0x0402031d}, 784 - {0x0000a0ec, 0x04000401}, 785 - {0x0000a0f0, 0x041e041f}, 786 - {0x0000a0f4, 0x0502041d}, 787 - {0x0000a0f8, 0x05000501}, 788 - {0x0000a0fc, 0x051e051f}, 789 - {0x0000a100, 0x06010602}, 790 - {0x0000a104, 0x061f0600}, 791 - {0x0000a108, 0x061d061e}, 792 - {0x0000a10c, 0x07020703}, 793 - {0x0000a110, 0x07000701}, 794 - {0x0000a114, 0x00000000}, 795 - {0x0000a118, 0x00000000}, 796 - {0x0000a11c, 0x00000000}, 797 - {0x0000a120, 0x00000000}, 798 - {0x0000a124, 0x00000000}, 799 - {0x0000a128, 0x00000000}, 800 - {0x0000a12c, 0x00000000}, 801 - {0x0000a130, 0x00000000}, 802 - {0x0000a134, 0x00000000}, 803 - {0x0000a138, 0x00000000}, 804 - {0x0000a13c, 0x00000000}, 805 - {0x0000a140, 0x001f0000}, 806 - {0x0000a144, 0x01000101}, 807 - {0x0000a148, 0x011e011f}, 808 - {0x0000a14c, 0x011c011d}, 809 - {0x0000a150, 0x02030204}, 810 - {0x0000a154, 0x02010202}, 811 - {0x0000a158, 0x021f0200}, 812 - {0x0000a15c, 0x0302021e}, 813 - {0x0000a160, 0x03000301}, 814 - {0x0000a164, 0x031e031f}, 815 - {0x0000a168, 0x0402031d}, 816 - {0x0000a16c, 0x04000401}, 817 - {0x0000a170, 0x041e041f}, 818 - {0x0000a174, 0x0502041d}, 819 - {0x0000a178, 0x05000501}, 820 - {0x0000a17c, 0x051e051f}, 821 - {0x0000a180, 0x06010602}, 822 - {0x0000a184, 0x061f0600}, 823 - {0x0000a188, 0x061d061e}, 824 - {0x0000a18c, 0x07020703}, 825 - {0x0000a190, 0x07000701}, 826 - {0x0000a194, 0x00000000}, 827 - {0x0000a198, 0x00000000}, 828 - {0x0000a19c, 0x00000000}, 829 - {0x0000a1a0, 0x00000000}, 830 - {0x0000a1a4, 0x00000000}, 831 - {0x0000a1a8, 0x00000000}, 832 - {0x0000a1ac, 0x00000000}, 833 - {0x0000a1b0, 0x00000000}, 834 - {0x0000a1b4, 0x00000000}, 835 - {0x0000a1b8, 0x00000000}, 836 - {0x0000a1bc, 0x00000000}, 837 - {0x0000a1c0, 0x00000000}, 838 - {0x0000a1c4, 0x00000000}, 839 - {0x0000a1c8, 0x00000000}, 840 - {0x0000a1cc, 0x00000000}, 841 - {0x0000a1d0, 0x00000000}, 842 - {0x0000a1d4, 0x00000000}, 843 - {0x0000a1d8, 0x00000000}, 844 - {0x0000a1dc, 0x00000000}, 845 - {0x0000a1e0, 0x00000000}, 846 - {0x0000a1e4, 0x00000000}, 847 - {0x0000a1e8, 0x00000000}, 848 - {0x0000a1ec, 0x00000000}, 849 - {0x0000a1f0, 0x00000396}, 850 - {0x0000a1f4, 0x00000396}, 851 - {0x0000a1f8, 0x00000396}, 852 - {0x0000a1fc, 0x00000196}, 853 - {0x0000b000, 0x00010000}, 854 - {0x0000b004, 0x00030002}, 855 - {0x0000b008, 0x00050004}, 856 - {0x0000b00c, 0x00810080}, 857 - {0x0000b010, 0x00830082}, 858 - {0x0000b014, 0x01810180}, 859 - {0x0000b018, 0x01830182}, 860 - {0x0000b01c, 0x01850184}, 861 - {0x0000b020, 0x02810280}, 862 - {0x0000b024, 0x02830282}, 863 - {0x0000b028, 0x02850284}, 864 - {0x0000b02c, 0x02890288}, 865 - {0x0000b030, 0x028b028a}, 866 - {0x0000b034, 0x0388028c}, 867 - {0x0000b038, 0x038a0389}, 868 - {0x0000b03c, 0x038c038b}, 869 - {0x0000b040, 0x0390038d}, 870 - {0x0000b044, 0x03920391}, 871 - {0x0000b048, 0x03940393}, 872 - {0x0000b04c, 0x03960395}, 873 - {0x0000b050, 0x00000000}, 874 - {0x0000b054, 0x00000000}, 875 - {0x0000b058, 0x00000000}, 876 - {0x0000b05c, 0x00000000}, 877 - {0x0000b060, 0x00000000}, 878 - {0x0000b064, 0x00000000}, 879 - {0x0000b068, 0x00000000}, 880 - {0x0000b06c, 0x00000000}, 881 - {0x0000b070, 0x00000000}, 882 - {0x0000b074, 0x00000000}, 883 - {0x0000b078, 0x00000000}, 884 - {0x0000b07c, 0x00000000}, 885 - {0x0000b080, 0x23232323}, 886 - {0x0000b084, 0x21232323}, 887 - {0x0000b088, 0x19191c1e}, 888 - {0x0000b08c, 0x12141417}, 889 - {0x0000b090, 0x07070e0e}, 890 - {0x0000b094, 0x03030305}, 891 - {0x0000b098, 0x00000003}, 892 - {0x0000b09c, 0x00000000}, 893 - {0x0000b0a0, 0x00000000}, 894 - {0x0000b0a4, 0x00000000}, 895 - {0x0000b0a8, 0x00000000}, 896 - {0x0000b0ac, 0x00000000}, 897 - {0x0000b0b0, 0x00000000}, 898 - {0x0000b0b4, 0x00000000}, 899 - {0x0000b0b8, 0x00000000}, 900 - {0x0000b0bc, 0x00000000}, 901 - {0x0000b0c0, 0x003f0020}, 902 - {0x0000b0c4, 0x00400041}, 903 - {0x0000b0c8, 0x0140005f}, 904 - {0x0000b0cc, 0x0160015f}, 905 - {0x0000b0d0, 0x017e017f}, 906 - {0x0000b0d4, 0x02410242}, 907 - {0x0000b0d8, 0x025f0240}, 908 - {0x0000b0dc, 0x027f0260}, 909 - {0x0000b0e0, 0x0341027e}, 910 - {0x0000b0e4, 0x035f0340}, 911 - {0x0000b0e8, 0x037f0360}, 912 - {0x0000b0ec, 0x04400441}, 913 - {0x0000b0f0, 0x0460045f}, 914 - {0x0000b0f4, 0x0541047f}, 915 - {0x0000b0f8, 0x055f0540}, 916 - {0x0000b0fc, 0x057f0560}, 917 - {0x0000b100, 0x06400641}, 918 - {0x0000b104, 0x0660065f}, 919 - {0x0000b108, 0x067e067f}, 920 - {0x0000b10c, 0x07410742}, 921 - {0x0000b110, 0x075f0740}, 922 - {0x0000b114, 0x077f0760}, 923 - {0x0000b118, 0x07800781}, 924 - {0x0000b11c, 0x07a0079f}, 925 - {0x0000b120, 0x07c107bf}, 926 - {0x0000b124, 0x000007c0}, 927 - {0x0000b128, 0x00000000}, 928 - {0x0000b12c, 0x00000000}, 929 - {0x0000b130, 0x00000000}, 930 - {0x0000b134, 0x00000000}, 931 - {0x0000b138, 0x00000000}, 932 - {0x0000b13c, 0x00000000}, 933 - {0x0000b140, 0x003f0020}, 934 - {0x0000b144, 0x00400041}, 935 - {0x0000b148, 0x0140005f}, 936 - {0x0000b14c, 0x0160015f}, 937 - {0x0000b150, 0x017e017f}, 938 - {0x0000b154, 0x02410242}, 939 - {0x0000b158, 0x025f0240}, 940 - {0x0000b15c, 0x027f0260}, 941 - {0x0000b160, 0x0341027e}, 942 - {0x0000b164, 0x035f0340}, 943 - {0x0000b168, 0x037f0360}, 944 - {0x0000b16c, 0x04400441}, 945 - {0x0000b170, 0x0460045f}, 946 - {0x0000b174, 0x0541047f}, 947 - {0x0000b178, 0x055f0540}, 948 - {0x0000b17c, 0x057f0560}, 949 - {0x0000b180, 0x06400641}, 950 - {0x0000b184, 0x0660065f}, 951 - {0x0000b188, 0x067e067f}, 952 - {0x0000b18c, 0x07410742}, 953 - {0x0000b190, 0x075f0740}, 954 - {0x0000b194, 0x077f0760}, 955 - {0x0000b198, 0x07800781}, 956 - {0x0000b19c, 0x07a0079f}, 957 - {0x0000b1a0, 0x07c107bf}, 958 - {0x0000b1a4, 0x000007c0}, 959 - {0x0000b1a8, 0x00000000}, 960 - {0x0000b1ac, 0x00000000}, 961 - {0x0000b1b0, 0x00000000}, 962 - {0x0000b1b4, 0x00000000}, 963 - {0x0000b1b8, 0x00000000}, 964 - {0x0000b1bc, 0x00000000}, 965 - {0x0000b1c0, 0x00000000}, 966 - {0x0000b1c4, 0x00000000}, 967 - {0x0000b1c8, 0x00000000}, 968 - {0x0000b1cc, 0x00000000}, 969 - {0x0000b1d0, 0x00000000}, 970 - {0x0000b1d4, 0x00000000}, 971 - {0x0000b1d8, 0x00000000}, 972 - {0x0000b1dc, 0x00000000}, 973 - {0x0000b1e0, 0x00000000}, 974 - {0x0000b1e4, 0x00000000}, 975 - {0x0000b1e8, 0x00000000}, 976 - {0x0000b1ec, 0x00000000}, 977 - {0x0000b1f0, 0x00000396}, 978 - {0x0000b1f4, 0x00000396}, 979 - {0x0000b1f8, 0x00000396}, 980 - {0x0000b1fc, 0x00000196}, 981 715 }; 982 716 983 717 static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { ··· 1183 1437 {0x000083d0, 0x000101ff}, 1184 1438 }; 1185 1439 1186 - #define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2 1187 - 1188 1440 static const u32 ar9340_1p0_soc_preamble[][2] = { 1189 1441 /* Addr allmodes */ 1190 1442 {0x00007008, 0x00000000}, 1191 1443 {0x00007020, 0x00000000}, 1192 1444 {0x00007034, 0x00000002}, 1193 1445 {0x00007038, 0x000004c2}, 1446 + }; 1447 + 1448 + static const u32 ar9340_cus227_tx_gain_table_1p0[][5] = { 1449 + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1450 + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 1451 + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 1452 + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 1453 + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1454 + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 1455 + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1456 + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, 1457 + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, 1458 + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, 1459 + {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, 1460 + {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400}, 1461 + {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402}, 1462 + {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, 1463 + {0x0000a520, 0x2c022220, 0x2c022220, 0x1b000603, 0x1b000603}, 1464 + {0x0000a524, 0x30022222, 0x30022222, 0x1f000a02, 0x1f000a02}, 1465 + {0x0000a528, 0x35022225, 0x35022225, 0x23000a04, 0x23000a04}, 1466 + {0x0000a52c, 0x3b02222a, 0x3b02222a, 0x26000a20, 0x26000a20}, 1467 + {0x0000a530, 0x3f02222c, 0x3f02222c, 0x2a000e20, 0x2a000e20}, 1468 + {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22}, 1469 + {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24}, 1470 + {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640}, 1471 + {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660}, 1472 + {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861}, 1473 + {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81}, 1474 + {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83}, 1475 + {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84}, 1476 + {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3}, 1477 + {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5}, 1478 + {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9}, 1479 + {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb}, 1480 + {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, 1481 + {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, 1482 + {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, 1483 + {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, 1484 + {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, 1485 + {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, 1486 + {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, 1487 + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, 1488 + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, 1489 + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, 1490 + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, 1491 + {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, 1492 + {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400}, 1493 + {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402}, 1494 + {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, 1495 + {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603}, 1496 + {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02}, 1497 + {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04}, 1498 + {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20}, 1499 + {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20}, 1500 + {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22}, 1501 + {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24}, 1502 + {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640}, 1503 + {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660}, 1504 + {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861}, 1505 + {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81}, 1506 + {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83}, 1507 + {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84}, 1508 + {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3}, 1509 + {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5}, 1510 + {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9}, 1511 + {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb}, 1512 + {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, 1513 + {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, 1514 + {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, 1515 + {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, 1516 + {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, 1517 + {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, 1518 + {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, 1519 + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1520 + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1521 + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1522 + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1523 + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1524 + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, 1525 + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, 1526 + {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, 1527 + {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, 1528 + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, 1529 + {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, 1530 + {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, 1531 + {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1532 + {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1533 + {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1534 + {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1535 + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 1536 + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 1537 + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 1538 + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1539 + {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, 1540 + {0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, 1541 + {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, 1542 + {0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000}, 1543 + {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, 1544 + {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, 1545 + {0x0000a3a4, 0x00000011, 0x00000011, 0x00000011, 0x00000011}, 1546 + {0x0000a3a8, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c}, 1547 + {0x0000a3ac, 0x30303030, 0x30303030, 0x30303030, 0x30303030}, 1194 1548 }; 1195 1549 1196 1550 #endif /* INITVALS_9340_H */
+9 -23
drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
··· 20 20 21 21 /* AR9462 2.0 */ 22 22 23 - static const u32 ar9462_modes_fast_clock_2p0[][3] = { 23 + static const u32 ar9462_2p0_modes_fast_clock[][3] = { 24 24 /* Addr 5G_HT20 5G_HT40 */ 25 25 {0x00001030, 0x00000268, 0x000004d0}, 26 26 {0x00001070, 0x0000018c, 0x00000318}, ··· 31 31 {0x00009e00, 0x0372131c, 0x0372131c}, 32 32 {0x0000a230, 0x0000400b, 0x00004016}, 33 33 {0x0000a254, 0x00000898, 0x00001130}, 34 - }; 35 - 36 - static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = { 37 - /* Addr allmodes */ 38 - {0x00018c00, 0x18253ede}, 39 - {0x00018c04, 0x000801d8}, 40 - {0x00018c08, 0x0003780c}, 41 34 }; 42 35 43 36 static const u32 ar9462_2p0_baseband_postamble[][5] = { ··· 92 99 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 93 100 }; 94 101 95 - static const u32 ar9462_common_rx_gain_table_2p0[][2] = { 102 + static const u32 ar9462_2p0_common_rx_gain[][2] = { 96 103 /* Addr allmodes */ 97 104 {0x0000a000, 0x00010000}, 98 105 {0x0000a004, 0x00030002}, ··· 352 359 {0x0000b1fc, 0x00000196}, 353 360 }; 354 361 355 - static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = { 362 + static const u32 ar9462_2p0_pciephy_clkreq_disable_L1[][2] = { 356 363 /* Addr allmodes */ 357 364 {0x00018c00, 0x18213ede}, 358 - {0x00018c04, 0x000801d8}, 359 - {0x00018c08, 0x0003780c}, 360 - }; 361 - 362 - static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = { 363 - /* Addr allmodes */ 364 - {0x00018c00, 0x18212ede}, 365 365 {0x00018c04, 0x000801d8}, 366 366 {0x00018c08, 0x0003780c}, 367 367 }; ··· 366 380 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 367 381 }; 368 382 369 - static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { 383 + static const u32 ar9462_2p0_common_wo_xlna_rx_gain[][2] = { 370 384 /* Addr allmodes */ 371 385 {0x0000a000, 0x00010000}, 372 386 {0x0000a004, 0x00030002}, ··· 633 647 {0x0000a3a0, 0xca9228ee}, 634 648 }; 635 649 636 - static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = { 650 + static const u32 ar9462_2p0_modes_low_ob_db_tx_gain[][5] = { 637 651 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 638 652 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 639 653 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, ··· 865 879 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 866 880 }; 867 881 868 - static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = { 882 + static const u32 ar9462_2p0_modes_mix_ob_db_tx_gain[][5] = { 869 883 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 870 884 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 871 885 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, ··· 928 942 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 929 943 }; 930 944 931 - static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { 945 + static const u32 ar9462_2p0_modes_high_ob_db_tx_gain[][5] = { 932 946 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 933 947 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 934 948 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, ··· 1238 1252 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, 1239 1253 }; 1240 1254 1241 - static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = { 1255 + static const u32 ar9462_2p0_common_mixed_rx_gain[][2] = { 1242 1256 /* Addr allmodes */ 1243 1257 {0x0000a000, 0x00010000}, 1244 1258 {0x0000a004, 0x00030002}, ··· 1503 1517 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, 1504 1518 }; 1505 1519 1506 - static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = { 1520 + static const u32 ar9462_2p0_common_5g_xlna_only_rxgain[][2] = { 1507 1521 /* Addr allmodes */ 1508 1522 {0x0000a000, 0x00010000}, 1509 1523 {0x0000a004, 0x00030002},
+38 -1521
drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
··· 20 20 21 21 /* AR9462 2.1 */ 22 22 23 + #define ar9462_2p1_mac_postamble ar9462_2p0_mac_postamble 24 + 25 + #define ar9462_2p1_baseband_core ar9462_2p0_baseband_core 26 + 27 + #define ar9462_2p1_radio_core ar9462_2p0_radio_core 28 + 29 + #define ar9462_2p1_radio_postamble ar9462_2p0_radio_postamble 30 + 31 + #define ar9462_2p1_soc_postamble ar9462_2p0_soc_postamble 32 + 33 + #define ar9462_2p1_radio_postamble_sys2ant ar9462_2p0_radio_postamble_sys2ant 34 + 35 + #define ar9462_2p1_common_rx_gain ar9462_2p0_common_rx_gain 36 + 37 + #define ar9462_2p1_common_mixed_rx_gain ar9462_2p0_common_mixed_rx_gain 38 + 39 + #define ar9462_2p1_common_5g_xlna_only_rxgain ar9462_2p0_common_5g_xlna_only_rxgain 40 + 41 + #define ar9462_2p1_baseband_core_mix_rxgain ar9462_2p0_baseband_core_mix_rxgain 42 + 43 + #define ar9462_2p1_baseband_postamble_mix_rxgain ar9462_2p0_baseband_postamble_mix_rxgain 44 + 45 + #define ar9462_2p1_baseband_postamble_5g_xlna ar9462_2p0_baseband_postamble_5g_xlna 46 + 47 + #define ar9462_2p1_common_wo_xlna_rx_gain ar9462_2p0_common_wo_xlna_rx_gain 48 + 49 + #define ar9462_2p1_modes_low_ob_db_tx_gain ar9462_2p0_modes_low_ob_db_tx_gain 50 + 51 + #define ar9462_2p1_modes_high_ob_db_tx_gain ar9462_2p0_modes_high_ob_db_tx_gain 52 + 53 + #define ar9462_2p1_modes_mix_ob_db_tx_gain ar9462_2p0_modes_mix_ob_db_tx_gain 54 + 55 + #define ar9462_2p1_modes_fast_clock ar9462_2p0_modes_fast_clock 56 + 57 + #define ar9462_2p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 58 + 59 + #define ar9462_2p1_pciephy_clkreq_disable_L1 ar9462_2p0_pciephy_clkreq_disable_L1 60 + 23 61 static const u32 ar9462_2p1_mac_core[][2] = { 24 62 /* Addr allmodes */ 25 63 {0x00000008, 0x00000000}, ··· 221 183 {0x000083d0, 0x000301ff}, 222 184 }; 223 185 224 - static const u32 ar9462_2p1_mac_postamble[][5] = { 225 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 226 - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, 227 - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, 228 - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, 229 - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, 230 - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, 231 - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, 232 - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, 233 - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, 234 - }; 235 - 236 - static const u32 ar9462_2p1_baseband_core[][2] = { 237 - /* Addr allmodes */ 238 - {0x00009800, 0xafe68e30}, 239 - {0x00009804, 0xfd14e000}, 240 - {0x00009808, 0x9c0a9f6b}, 241 - {0x0000980c, 0x04900000}, 242 - {0x00009814, 0x9280c00a}, 243 - {0x00009818, 0x00000000}, 244 - {0x0000981c, 0x00020028}, 245 - {0x00009834, 0x6400a290}, 246 - {0x00009838, 0x0108ecff}, 247 - {0x0000983c, 0x0d000600}, 248 - {0x00009880, 0x201fff00}, 249 - {0x00009884, 0x00001042}, 250 - {0x000098a4, 0x00200400}, 251 - {0x000098b0, 0x32440bbe}, 252 - {0x000098d0, 0x004b6a8e}, 253 - {0x000098d4, 0x00000820}, 254 - {0x000098dc, 0x00000000}, 255 - {0x000098e4, 0x01ffffff}, 256 - {0x000098e8, 0x01ffffff}, 257 - {0x000098ec, 0x01ffffff}, 258 - {0x000098f0, 0x00000000}, 259 - {0x000098f4, 0x00000000}, 260 - {0x00009bf0, 0x80000000}, 261 - {0x00009c04, 0xff55ff55}, 262 - {0x00009c08, 0x0320ff55}, 263 - {0x00009c0c, 0x00000000}, 264 - {0x00009c10, 0x00000000}, 265 - {0x00009c14, 0x00046384}, 266 - {0x00009c18, 0x05b6b440}, 267 - {0x00009c1c, 0x00b6b440}, 268 - {0x00009d00, 0xc080a333}, 269 - {0x00009d04, 0x40206c10}, 270 - {0x00009d08, 0x009c4060}, 271 - {0x00009d0c, 0x9883800a}, 272 - {0x00009d10, 0x01834061}, 273 - {0x00009d14, 0x00c0040b}, 274 - {0x00009d18, 0x00000000}, 275 - {0x00009e08, 0x0038230c}, 276 - {0x00009e24, 0x990bb515}, 277 - {0x00009e28, 0x0c6f0000}, 278 - {0x00009e30, 0x06336f77}, 279 - {0x00009e34, 0x6af6532f}, 280 - {0x00009e38, 0x0cc80c00}, 281 - {0x00009e40, 0x15262820}, 282 - {0x00009e4c, 0x00001004}, 283 - {0x00009e50, 0x00ff03f1}, 284 - {0x00009e54, 0xe4c555c2}, 285 - {0x00009e58, 0xfd857722}, 286 - {0x00009e5c, 0xe9198724}, 287 - {0x00009fc0, 0x803e4788}, 288 - {0x00009fc4, 0x0001efb5}, 289 - {0x00009fcc, 0x40000014}, 290 - {0x00009fd0, 0x0a193b93}, 291 - {0x0000a20c, 0x00000000}, 292 - {0x0000a220, 0x00000000}, 293 - {0x0000a224, 0x00000000}, 294 - {0x0000a228, 0x10002310}, 295 - {0x0000a23c, 0x00000000}, 296 - {0x0000a244, 0x0c000000}, 297 - {0x0000a2a0, 0x00000001}, 298 - {0x0000a2c0, 0x00000001}, 299 - {0x0000a2c8, 0x00000000}, 300 - {0x0000a2cc, 0x18c43433}, 301 - {0x0000a2d4, 0x00000000}, 302 - {0x0000a2ec, 0x00000000}, 303 - {0x0000a2f0, 0x00000000}, 304 - {0x0000a2f4, 0x00000000}, 305 - {0x0000a2f8, 0x00000000}, 306 - {0x0000a344, 0x00000000}, 307 - {0x0000a34c, 0x00000000}, 308 - {0x0000a350, 0x0000a000}, 309 - {0x0000a364, 0x00000000}, 310 - {0x0000a370, 0x00000000}, 311 - {0x0000a390, 0x00000001}, 312 - {0x0000a394, 0x00000444}, 313 - {0x0000a398, 0x001f0e0f}, 314 - {0x0000a39c, 0x0075393f}, 315 - {0x0000a3a0, 0xb79f6427}, 316 - {0x0000a3c0, 0x20202020}, 317 - {0x0000a3c4, 0x22222220}, 318 - {0x0000a3c8, 0x20200020}, 319 - {0x0000a3cc, 0x20202020}, 320 - {0x0000a3d0, 0x20202020}, 321 - {0x0000a3d4, 0x20202020}, 322 - {0x0000a3d8, 0x20202020}, 323 - {0x0000a3dc, 0x20202020}, 324 - {0x0000a3e0, 0x20202020}, 325 - {0x0000a3e4, 0x20202020}, 326 - {0x0000a3e8, 0x20202020}, 327 - {0x0000a3ec, 0x20202020}, 328 - {0x0000a3f0, 0x00000000}, 329 - {0x0000a3f4, 0x00000006}, 330 - {0x0000a3f8, 0x0c9bd380}, 331 - {0x0000a3fc, 0x000f0f01}, 332 - {0x0000a400, 0x8fa91f01}, 333 - {0x0000a404, 0x00000000}, 334 - {0x0000a408, 0x0e79e5c6}, 335 - {0x0000a40c, 0x00820820}, 336 - {0x0000a414, 0x1ce739ce}, 337 - {0x0000a418, 0x2d001dce}, 338 - {0x0000a434, 0x00000000}, 339 - {0x0000a438, 0x00001801}, 340 - {0x0000a43c, 0x00100000}, 341 - {0x0000a444, 0x00000000}, 342 - {0x0000a448, 0x05000080}, 343 - {0x0000a44c, 0x00000001}, 344 - {0x0000a450, 0x00010000}, 345 - {0x0000a454, 0x07000000}, 346 - {0x0000a644, 0xbfad9d74}, 347 - {0x0000a648, 0x0048060a}, 348 - {0x0000a64c, 0x00002037}, 349 - {0x0000a670, 0x03020100}, 350 - {0x0000a674, 0x09080504}, 351 - {0x0000a678, 0x0d0c0b0a}, 352 - {0x0000a67c, 0x13121110}, 353 - {0x0000a680, 0x31301514}, 354 - {0x0000a684, 0x35343332}, 355 - {0x0000a688, 0x00000036}, 356 - {0x0000a690, 0x00000838}, 357 - {0x0000a6b0, 0x0000000a}, 358 - {0x0000a6b4, 0x00512c01}, 359 - {0x0000a7c0, 0x00000000}, 360 - {0x0000a7c4, 0xfffffffc}, 361 - {0x0000a7c8, 0x00000000}, 362 - {0x0000a7cc, 0x00000000}, 363 - {0x0000a7d0, 0x00000000}, 364 - {0x0000a7d4, 0x00000004}, 365 - {0x0000a7dc, 0x00000000}, 366 - {0x0000a7f0, 0x80000000}, 367 - {0x0000a8d0, 0x004b6a8e}, 368 - {0x0000a8d4, 0x00000820}, 369 - {0x0000a8dc, 0x00000000}, 370 - {0x0000a8f0, 0x00000000}, 371 - {0x0000a8f4, 0x00000000}, 372 - {0x0000abf0, 0x80000000}, 373 - {0x0000b2d0, 0x00000080}, 374 - {0x0000b2d4, 0x00000000}, 375 - {0x0000b2ec, 0x00000000}, 376 - {0x0000b2f0, 0x00000000}, 377 - {0x0000b2f4, 0x00000000}, 378 - {0x0000b2f8, 0x00000000}, 379 - {0x0000b408, 0x0e79e5c0}, 380 - {0x0000b40c, 0x00820820}, 381 - {0x0000b420, 0x00000000}, 382 - {0x0000b6b0, 0x0000000a}, 383 - {0x0000b6b4, 0x00000001}, 384 - }; 385 - 386 186 static const u32 ar9462_2p1_baseband_postamble[][5] = { 387 187 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 388 188 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, ··· 280 404 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 281 405 }; 282 406 283 - static const u32 ar9462_2p1_radio_core[][2] = { 284 - /* Addr allmodes */ 285 - {0x00016000, 0x36db6db6}, 286 - {0x00016004, 0x6db6db40}, 287 - {0x00016008, 0x73f00000}, 288 - {0x0001600c, 0x00000000}, 289 - {0x00016010, 0x6d820001}, 290 - {0x00016040, 0x7f80fff8}, 291 - {0x0001604c, 0x2699e04f}, 292 - {0x00016050, 0x6db6db6c}, 293 - {0x00016058, 0x6c200000}, 294 - {0x00016080, 0x000c0000}, 295 - {0x00016084, 0x9a68048c}, 296 - {0x00016088, 0x54214514}, 297 - {0x0001608c, 0x1203040b}, 298 - {0x00016090, 0x24926490}, 299 - {0x00016098, 0xd2888888}, 300 - {0x000160a0, 0x0a108ffe}, 301 - {0x000160a4, 0x812fc491}, 302 - {0x000160a8, 0x423c8000}, 303 - {0x000160b4, 0x92000000}, 304 - {0x000160b8, 0x0285dddc}, 305 - {0x000160bc, 0x02908888}, 306 - {0x000160c0, 0x00adb6d0}, 307 - {0x000160c4, 0x6db6db60}, 308 - {0x000160c8, 0x6db6db6c}, 309 - {0x000160cc, 0x0de6c1b0}, 310 - {0x00016100, 0x3fffbe04}, 311 - {0x00016104, 0xfff80000}, 312 - {0x00016108, 0x00200400}, 313 - {0x00016110, 0x00000000}, 314 - {0x00016144, 0x02084080}, 315 - {0x00016148, 0x000080c0}, 316 - {0x00016280, 0x050a0001}, 317 - {0x00016284, 0x3d841418}, 318 - {0x00016288, 0x00000000}, 319 - {0x0001628c, 0xe3000000}, 320 - {0x00016290, 0xa1005080}, 321 - {0x00016294, 0x00000020}, 322 - {0x00016298, 0x54a82900}, 323 - {0x00016340, 0x121e4276}, 324 - {0x00016344, 0x00300000}, 325 - {0x00016400, 0x36db6db6}, 326 - {0x00016404, 0x6db6db40}, 327 - {0x00016408, 0x73f00000}, 328 - {0x0001640c, 0x00000000}, 329 - {0x00016410, 0x6c800001}, 330 - {0x00016440, 0x7f80fff8}, 331 - {0x0001644c, 0x4699e04f}, 332 - {0x00016450, 0x6db6db6c}, 333 - {0x00016500, 0x3fffbe04}, 334 - {0x00016504, 0xfff80000}, 335 - {0x00016508, 0x00200400}, 336 - {0x00016510, 0x00000000}, 337 - {0x00016544, 0x02084080}, 338 - {0x00016548, 0x000080c0}, 339 - }; 340 - 341 - static const u32 ar9462_2p1_radio_postamble[][5] = { 342 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 343 - {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, 344 - {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, 345 - {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 346 - {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 347 - }; 348 - 349 407 static const u32 ar9462_2p1_soc_preamble[][2] = { 350 408 /* Addr allmodes */ 351 409 {0x000040a4, 0x00a0c9c9}, 352 410 {0x00007020, 0x00000000}, 353 411 {0x00007034, 0x00000002}, 354 412 {0x00007038, 0x000004c2}, 355 - }; 356 - 357 - static const u32 ar9462_2p1_soc_postamble[][5] = { 358 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 359 - {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033}, 360 - }; 361 - 362 - static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = { 363 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 364 - {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 365 - {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 366 - {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 367 - }; 368 - 369 - static const u32 ar9462_2p1_common_rx_gain[][2] = { 370 - /* Addr allmodes */ 371 - {0x0000a000, 0x00010000}, 372 - {0x0000a004, 0x00030002}, 373 - {0x0000a008, 0x00050004}, 374 - {0x0000a00c, 0x00810080}, 375 - {0x0000a010, 0x00830082}, 376 - {0x0000a014, 0x01810180}, 377 - {0x0000a018, 0x01830182}, 378 - {0x0000a01c, 0x01850184}, 379 - {0x0000a020, 0x01890188}, 380 - {0x0000a024, 0x018b018a}, 381 - {0x0000a028, 0x018d018c}, 382 - {0x0000a02c, 0x01910190}, 383 - {0x0000a030, 0x01930192}, 384 - {0x0000a034, 0x01950194}, 385 - {0x0000a038, 0x038a0196}, 386 - {0x0000a03c, 0x038c038b}, 387 - {0x0000a040, 0x0390038d}, 388 - {0x0000a044, 0x03920391}, 389 - {0x0000a048, 0x03940393}, 390 - {0x0000a04c, 0x03960395}, 391 - {0x0000a050, 0x00000000}, 392 - {0x0000a054, 0x00000000}, 393 - {0x0000a058, 0x00000000}, 394 - {0x0000a05c, 0x00000000}, 395 - {0x0000a060, 0x00000000}, 396 - {0x0000a064, 0x00000000}, 397 - {0x0000a068, 0x00000000}, 398 - {0x0000a06c, 0x00000000}, 399 - {0x0000a070, 0x00000000}, 400 - {0x0000a074, 0x00000000}, 401 - {0x0000a078, 0x00000000}, 402 - {0x0000a07c, 0x00000000}, 403 - {0x0000a080, 0x22222229}, 404 - {0x0000a084, 0x1d1d1d1d}, 405 - {0x0000a088, 0x1d1d1d1d}, 406 - {0x0000a08c, 0x1d1d1d1d}, 407 - {0x0000a090, 0x171d1d1d}, 408 - {0x0000a094, 0x11111717}, 409 - {0x0000a098, 0x00030311}, 410 - {0x0000a09c, 0x00000000}, 411 - {0x0000a0a0, 0x00000000}, 412 - {0x0000a0a4, 0x00000000}, 413 - {0x0000a0a8, 0x00000000}, 414 - {0x0000a0ac, 0x00000000}, 415 - {0x0000a0b0, 0x00000000}, 416 - {0x0000a0b4, 0x00000000}, 417 - {0x0000a0b8, 0x00000000}, 418 - {0x0000a0bc, 0x00000000}, 419 - {0x0000a0c0, 0x001f0000}, 420 - {0x0000a0c4, 0x01000101}, 421 - {0x0000a0c8, 0x011e011f}, 422 - {0x0000a0cc, 0x011c011d}, 423 - {0x0000a0d0, 0x02030204}, 424 - {0x0000a0d4, 0x02010202}, 425 - {0x0000a0d8, 0x021f0200}, 426 - {0x0000a0dc, 0x0302021e}, 427 - {0x0000a0e0, 0x03000301}, 428 - {0x0000a0e4, 0x031e031f}, 429 - {0x0000a0e8, 0x0402031d}, 430 - {0x0000a0ec, 0x04000401}, 431 - {0x0000a0f0, 0x041e041f}, 432 - {0x0000a0f4, 0x0502041d}, 433 - {0x0000a0f8, 0x05000501}, 434 - {0x0000a0fc, 0x051e051f}, 435 - {0x0000a100, 0x06010602}, 436 - {0x0000a104, 0x061f0600}, 437 - {0x0000a108, 0x061d061e}, 438 - {0x0000a10c, 0x07020703}, 439 - {0x0000a110, 0x07000701}, 440 - {0x0000a114, 0x00000000}, 441 - {0x0000a118, 0x00000000}, 442 - {0x0000a11c, 0x00000000}, 443 - {0x0000a120, 0x00000000}, 444 - {0x0000a124, 0x00000000}, 445 - {0x0000a128, 0x00000000}, 446 - {0x0000a12c, 0x00000000}, 447 - {0x0000a130, 0x00000000}, 448 - {0x0000a134, 0x00000000}, 449 - {0x0000a138, 0x00000000}, 450 - {0x0000a13c, 0x00000000}, 451 - {0x0000a140, 0x001f0000}, 452 - {0x0000a144, 0x01000101}, 453 - {0x0000a148, 0x011e011f}, 454 - {0x0000a14c, 0x011c011d}, 455 - {0x0000a150, 0x02030204}, 456 - {0x0000a154, 0x02010202}, 457 - {0x0000a158, 0x021f0200}, 458 - {0x0000a15c, 0x0302021e}, 459 - {0x0000a160, 0x03000301}, 460 - {0x0000a164, 0x031e031f}, 461 - {0x0000a168, 0x0402031d}, 462 - {0x0000a16c, 0x04000401}, 463 - {0x0000a170, 0x041e041f}, 464 - {0x0000a174, 0x0502041d}, 465 - {0x0000a178, 0x05000501}, 466 - {0x0000a17c, 0x051e051f}, 467 - {0x0000a180, 0x06010602}, 468 - {0x0000a184, 0x061f0600}, 469 - {0x0000a188, 0x061d061e}, 470 - {0x0000a18c, 0x07020703}, 471 - {0x0000a190, 0x07000701}, 472 - {0x0000a194, 0x00000000}, 473 - {0x0000a198, 0x00000000}, 474 - {0x0000a19c, 0x00000000}, 475 - {0x0000a1a0, 0x00000000}, 476 - {0x0000a1a4, 0x00000000}, 477 - {0x0000a1a8, 0x00000000}, 478 - {0x0000a1ac, 0x00000000}, 479 - {0x0000a1b0, 0x00000000}, 480 - {0x0000a1b4, 0x00000000}, 481 - {0x0000a1b8, 0x00000000}, 482 - {0x0000a1bc, 0x00000000}, 483 - {0x0000a1c0, 0x00000000}, 484 - {0x0000a1c4, 0x00000000}, 485 - {0x0000a1c8, 0x00000000}, 486 - {0x0000a1cc, 0x00000000}, 487 - {0x0000a1d0, 0x00000000}, 488 - {0x0000a1d4, 0x00000000}, 489 - {0x0000a1d8, 0x00000000}, 490 - {0x0000a1dc, 0x00000000}, 491 - {0x0000a1e0, 0x00000000}, 492 - {0x0000a1e4, 0x00000000}, 493 - {0x0000a1e8, 0x00000000}, 494 - {0x0000a1ec, 0x00000000}, 495 - {0x0000a1f0, 0x00000396}, 496 - {0x0000a1f4, 0x00000396}, 497 - {0x0000a1f8, 0x00000396}, 498 - {0x0000a1fc, 0x00000196}, 499 - {0x0000b000, 0x00010000}, 500 - {0x0000b004, 0x00030002}, 501 - {0x0000b008, 0x00050004}, 502 - {0x0000b00c, 0x00810080}, 503 - {0x0000b010, 0x00830082}, 504 - {0x0000b014, 0x01810180}, 505 - {0x0000b018, 0x01830182}, 506 - {0x0000b01c, 0x01850184}, 507 - {0x0000b020, 0x02810280}, 508 - {0x0000b024, 0x02830282}, 509 - {0x0000b028, 0x02850284}, 510 - {0x0000b02c, 0x02890288}, 511 - {0x0000b030, 0x028b028a}, 512 - {0x0000b034, 0x0388028c}, 513 - {0x0000b038, 0x038a0389}, 514 - {0x0000b03c, 0x038c038b}, 515 - {0x0000b040, 0x0390038d}, 516 - {0x0000b044, 0x03920391}, 517 - {0x0000b048, 0x03940393}, 518 - {0x0000b04c, 0x03960395}, 519 - {0x0000b050, 0x00000000}, 520 - {0x0000b054, 0x00000000}, 521 - {0x0000b058, 0x00000000}, 522 - {0x0000b05c, 0x00000000}, 523 - {0x0000b060, 0x00000000}, 524 - {0x0000b064, 0x00000000}, 525 - {0x0000b068, 0x00000000}, 526 - {0x0000b06c, 0x00000000}, 527 - {0x0000b070, 0x00000000}, 528 - {0x0000b074, 0x00000000}, 529 - {0x0000b078, 0x00000000}, 530 - {0x0000b07c, 0x00000000}, 531 - {0x0000b080, 0x2a2d2f32}, 532 - {0x0000b084, 0x21232328}, 533 - {0x0000b088, 0x19191c1e}, 534 - {0x0000b08c, 0x12141417}, 535 - {0x0000b090, 0x07070e0e}, 536 - {0x0000b094, 0x03030305}, 537 - {0x0000b098, 0x00000003}, 538 - {0x0000b09c, 0x00000000}, 539 - {0x0000b0a0, 0x00000000}, 540 - {0x0000b0a4, 0x00000000}, 541 - {0x0000b0a8, 0x00000000}, 542 - {0x0000b0ac, 0x00000000}, 543 - {0x0000b0b0, 0x00000000}, 544 - {0x0000b0b4, 0x00000000}, 545 - {0x0000b0b8, 0x00000000}, 546 - {0x0000b0bc, 0x00000000}, 547 - {0x0000b0c0, 0x003f0020}, 548 - {0x0000b0c4, 0x00400041}, 549 - {0x0000b0c8, 0x0140005f}, 550 - {0x0000b0cc, 0x0160015f}, 551 - {0x0000b0d0, 0x017e017f}, 552 - {0x0000b0d4, 0x02410242}, 553 - {0x0000b0d8, 0x025f0240}, 554 - {0x0000b0dc, 0x027f0260}, 555 - {0x0000b0e0, 0x0341027e}, 556 - {0x0000b0e4, 0x035f0340}, 557 - {0x0000b0e8, 0x037f0360}, 558 - {0x0000b0ec, 0x04400441}, 559 - {0x0000b0f0, 0x0460045f}, 560 - {0x0000b0f4, 0x0541047f}, 561 - {0x0000b0f8, 0x055f0540}, 562 - {0x0000b0fc, 0x057f0560}, 563 - {0x0000b100, 0x06400641}, 564 - {0x0000b104, 0x0660065f}, 565 - {0x0000b108, 0x067e067f}, 566 - {0x0000b10c, 0x07410742}, 567 - {0x0000b110, 0x075f0740}, 568 - {0x0000b114, 0x077f0760}, 569 - {0x0000b118, 0x07800781}, 570 - {0x0000b11c, 0x07a0079f}, 571 - {0x0000b120, 0x07c107bf}, 572 - {0x0000b124, 0x000007c0}, 573 - {0x0000b128, 0x00000000}, 574 - {0x0000b12c, 0x00000000}, 575 - {0x0000b130, 0x00000000}, 576 - {0x0000b134, 0x00000000}, 577 - {0x0000b138, 0x00000000}, 578 - {0x0000b13c, 0x00000000}, 579 - {0x0000b140, 0x003f0020}, 580 - {0x0000b144, 0x00400041}, 581 - {0x0000b148, 0x0140005f}, 582 - {0x0000b14c, 0x0160015f}, 583 - {0x0000b150, 0x017e017f}, 584 - {0x0000b154, 0x02410242}, 585 - {0x0000b158, 0x025f0240}, 586 - {0x0000b15c, 0x027f0260}, 587 - {0x0000b160, 0x0341027e}, 588 - {0x0000b164, 0x035f0340}, 589 - {0x0000b168, 0x037f0360}, 590 - {0x0000b16c, 0x04400441}, 591 - {0x0000b170, 0x0460045f}, 592 - {0x0000b174, 0x0541047f}, 593 - {0x0000b178, 0x055f0540}, 594 - {0x0000b17c, 0x057f0560}, 595 - {0x0000b180, 0x06400641}, 596 - {0x0000b184, 0x0660065f}, 597 - {0x0000b188, 0x067e067f}, 598 - {0x0000b18c, 0x07410742}, 599 - {0x0000b190, 0x075f0740}, 600 - {0x0000b194, 0x077f0760}, 601 - {0x0000b198, 0x07800781}, 602 - {0x0000b19c, 0x07a0079f}, 603 - {0x0000b1a0, 0x07c107bf}, 604 - {0x0000b1a4, 0x000007c0}, 605 - {0x0000b1a8, 0x00000000}, 606 - {0x0000b1ac, 0x00000000}, 607 - {0x0000b1b0, 0x00000000}, 608 - {0x0000b1b4, 0x00000000}, 609 - {0x0000b1b8, 0x00000000}, 610 - {0x0000b1bc, 0x00000000}, 611 - {0x0000b1c0, 0x00000000}, 612 - {0x0000b1c4, 0x00000000}, 613 - {0x0000b1c8, 0x00000000}, 614 - {0x0000b1cc, 0x00000000}, 615 - {0x0000b1d0, 0x00000000}, 616 - {0x0000b1d4, 0x00000000}, 617 - {0x0000b1d8, 0x00000000}, 618 - {0x0000b1dc, 0x00000000}, 619 - {0x0000b1e0, 0x00000000}, 620 - {0x0000b1e4, 0x00000000}, 621 - {0x0000b1e8, 0x00000000}, 622 - {0x0000b1ec, 0x00000000}, 623 - {0x0000b1f0, 0x00000396}, 624 - {0x0000b1f4, 0x00000396}, 625 - {0x0000b1f8, 0x00000396}, 626 - {0x0000b1fc, 0x00000196}, 627 - }; 628 - 629 - static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = { 630 - /* Addr allmodes */ 631 - {0x0000a000, 0x00010000}, 632 - {0x0000a004, 0x00030002}, 633 - {0x0000a008, 0x00050004}, 634 - {0x0000a00c, 0x00810080}, 635 - {0x0000a010, 0x00830082}, 636 - {0x0000a014, 0x01810180}, 637 - {0x0000a018, 0x01830182}, 638 - {0x0000a01c, 0x01850184}, 639 - {0x0000a020, 0x01890188}, 640 - {0x0000a024, 0x018b018a}, 641 - {0x0000a028, 0x018d018c}, 642 - {0x0000a02c, 0x03820190}, 643 - {0x0000a030, 0x03840383}, 644 - {0x0000a034, 0x03880385}, 645 - {0x0000a038, 0x038a0389}, 646 - {0x0000a03c, 0x038c038b}, 647 - {0x0000a040, 0x0390038d}, 648 - {0x0000a044, 0x03920391}, 649 - {0x0000a048, 0x03940393}, 650 - {0x0000a04c, 0x03960395}, 651 - {0x0000a050, 0x00000000}, 652 - {0x0000a054, 0x00000000}, 653 - {0x0000a058, 0x00000000}, 654 - {0x0000a05c, 0x00000000}, 655 - {0x0000a060, 0x00000000}, 656 - {0x0000a064, 0x00000000}, 657 - {0x0000a068, 0x00000000}, 658 - {0x0000a06c, 0x00000000}, 659 - {0x0000a070, 0x00000000}, 660 - {0x0000a074, 0x00000000}, 661 - {0x0000a078, 0x00000000}, 662 - {0x0000a07c, 0x00000000}, 663 - {0x0000a080, 0x29292929}, 664 - {0x0000a084, 0x29292929}, 665 - {0x0000a088, 0x29292929}, 666 - {0x0000a08c, 0x29292929}, 667 - {0x0000a090, 0x22292929}, 668 - {0x0000a094, 0x1d1d2222}, 669 - {0x0000a098, 0x0c111117}, 670 - {0x0000a09c, 0x00030303}, 671 - {0x0000a0a0, 0x00000000}, 672 - {0x0000a0a4, 0x00000000}, 673 - {0x0000a0a8, 0x00000000}, 674 - {0x0000a0ac, 0x00000000}, 675 - {0x0000a0b0, 0x00000000}, 676 - {0x0000a0b4, 0x00000000}, 677 - {0x0000a0b8, 0x00000000}, 678 - {0x0000a0bc, 0x00000000}, 679 - {0x0000a0c0, 0x001f0000}, 680 - {0x0000a0c4, 0x01000101}, 681 - {0x0000a0c8, 0x011e011f}, 682 - {0x0000a0cc, 0x011c011d}, 683 - {0x0000a0d0, 0x02030204}, 684 - {0x0000a0d4, 0x02010202}, 685 - {0x0000a0d8, 0x021f0200}, 686 - {0x0000a0dc, 0x0302021e}, 687 - {0x0000a0e0, 0x03000301}, 688 - {0x0000a0e4, 0x031e031f}, 689 - {0x0000a0e8, 0x0402031d}, 690 - {0x0000a0ec, 0x04000401}, 691 - {0x0000a0f0, 0x041e041f}, 692 - {0x0000a0f4, 0x0502041d}, 693 - {0x0000a0f8, 0x05000501}, 694 - {0x0000a0fc, 0x051e051f}, 695 - {0x0000a100, 0x06010602}, 696 - {0x0000a104, 0x061f0600}, 697 - {0x0000a108, 0x061d061e}, 698 - {0x0000a10c, 0x07020703}, 699 - {0x0000a110, 0x07000701}, 700 - {0x0000a114, 0x00000000}, 701 - {0x0000a118, 0x00000000}, 702 - {0x0000a11c, 0x00000000}, 703 - {0x0000a120, 0x00000000}, 704 - {0x0000a124, 0x00000000}, 705 - {0x0000a128, 0x00000000}, 706 - {0x0000a12c, 0x00000000}, 707 - {0x0000a130, 0x00000000}, 708 - {0x0000a134, 0x00000000}, 709 - {0x0000a138, 0x00000000}, 710 - {0x0000a13c, 0x00000000}, 711 - {0x0000a140, 0x001f0000}, 712 - {0x0000a144, 0x01000101}, 713 - {0x0000a148, 0x011e011f}, 714 - {0x0000a14c, 0x011c011d}, 715 - {0x0000a150, 0x02030204}, 716 - {0x0000a154, 0x02010202}, 717 - {0x0000a158, 0x021f0200}, 718 - {0x0000a15c, 0x0302021e}, 719 - {0x0000a160, 0x03000301}, 720 - {0x0000a164, 0x031e031f}, 721 - {0x0000a168, 0x0402031d}, 722 - {0x0000a16c, 0x04000401}, 723 - {0x0000a170, 0x041e041f}, 724 - {0x0000a174, 0x0502041d}, 725 - {0x0000a178, 0x05000501}, 726 - {0x0000a17c, 0x051e051f}, 727 - {0x0000a180, 0x06010602}, 728 - {0x0000a184, 0x061f0600}, 729 - {0x0000a188, 0x061d061e}, 730 - {0x0000a18c, 0x07020703}, 731 - {0x0000a190, 0x07000701}, 732 - {0x0000a194, 0x00000000}, 733 - {0x0000a198, 0x00000000}, 734 - {0x0000a19c, 0x00000000}, 735 - {0x0000a1a0, 0x00000000}, 736 - {0x0000a1a4, 0x00000000}, 737 - {0x0000a1a8, 0x00000000}, 738 - {0x0000a1ac, 0x00000000}, 739 - {0x0000a1b0, 0x00000000}, 740 - {0x0000a1b4, 0x00000000}, 741 - {0x0000a1b8, 0x00000000}, 742 - {0x0000a1bc, 0x00000000}, 743 - {0x0000a1c0, 0x00000000}, 744 - {0x0000a1c4, 0x00000000}, 745 - {0x0000a1c8, 0x00000000}, 746 - {0x0000a1cc, 0x00000000}, 747 - {0x0000a1d0, 0x00000000}, 748 - {0x0000a1d4, 0x00000000}, 749 - {0x0000a1d8, 0x00000000}, 750 - {0x0000a1dc, 0x00000000}, 751 - {0x0000a1e0, 0x00000000}, 752 - {0x0000a1e4, 0x00000000}, 753 - {0x0000a1e8, 0x00000000}, 754 - {0x0000a1ec, 0x00000000}, 755 - {0x0000a1f0, 0x00000396}, 756 - {0x0000a1f4, 0x00000396}, 757 - {0x0000a1f8, 0x00000396}, 758 - {0x0000a1fc, 0x00000196}, 759 - {0x0000b000, 0x00010000}, 760 - {0x0000b004, 0x00030002}, 761 - {0x0000b008, 0x00050004}, 762 - {0x0000b00c, 0x00810080}, 763 - {0x0000b010, 0x00830082}, 764 - {0x0000b014, 0x01810180}, 765 - {0x0000b018, 0x01830182}, 766 - {0x0000b01c, 0x01850184}, 767 - {0x0000b020, 0x02810280}, 768 - {0x0000b024, 0x02830282}, 769 - {0x0000b028, 0x02850284}, 770 - {0x0000b02c, 0x02890288}, 771 - {0x0000b030, 0x028b028a}, 772 - {0x0000b034, 0x0388028c}, 773 - {0x0000b038, 0x038a0389}, 774 - {0x0000b03c, 0x038c038b}, 775 - {0x0000b040, 0x0390038d}, 776 - {0x0000b044, 0x03920391}, 777 - {0x0000b048, 0x03940393}, 778 - {0x0000b04c, 0x03960395}, 779 - {0x0000b050, 0x00000000}, 780 - {0x0000b054, 0x00000000}, 781 - {0x0000b058, 0x00000000}, 782 - {0x0000b05c, 0x00000000}, 783 - {0x0000b060, 0x00000000}, 784 - {0x0000b064, 0x00000000}, 785 - {0x0000b068, 0x00000000}, 786 - {0x0000b06c, 0x00000000}, 787 - {0x0000b070, 0x00000000}, 788 - {0x0000b074, 0x00000000}, 789 - {0x0000b078, 0x00000000}, 790 - {0x0000b07c, 0x00000000}, 791 - {0x0000b080, 0x2a2d2f32}, 792 - {0x0000b084, 0x21232328}, 793 - {0x0000b088, 0x19191c1e}, 794 - {0x0000b08c, 0x12141417}, 795 - {0x0000b090, 0x07070e0e}, 796 - {0x0000b094, 0x03030305}, 797 - {0x0000b098, 0x00000003}, 798 - {0x0000b09c, 0x00000000}, 799 - {0x0000b0a0, 0x00000000}, 800 - {0x0000b0a4, 0x00000000}, 801 - {0x0000b0a8, 0x00000000}, 802 - {0x0000b0ac, 0x00000000}, 803 - {0x0000b0b0, 0x00000000}, 804 - {0x0000b0b4, 0x00000000}, 805 - {0x0000b0b8, 0x00000000}, 806 - {0x0000b0bc, 0x00000000}, 807 - {0x0000b0c0, 0x003f0020}, 808 - {0x0000b0c4, 0x00400041}, 809 - {0x0000b0c8, 0x0140005f}, 810 - {0x0000b0cc, 0x0160015f}, 811 - {0x0000b0d0, 0x017e017f}, 812 - {0x0000b0d4, 0x02410242}, 813 - {0x0000b0d8, 0x025f0240}, 814 - {0x0000b0dc, 0x027f0260}, 815 - {0x0000b0e0, 0x0341027e}, 816 - {0x0000b0e4, 0x035f0340}, 817 - {0x0000b0e8, 0x037f0360}, 818 - {0x0000b0ec, 0x04400441}, 819 - {0x0000b0f0, 0x0460045f}, 820 - {0x0000b0f4, 0x0541047f}, 821 - {0x0000b0f8, 0x055f0540}, 822 - {0x0000b0fc, 0x057f0560}, 823 - {0x0000b100, 0x06400641}, 824 - {0x0000b104, 0x0660065f}, 825 - {0x0000b108, 0x067e067f}, 826 - {0x0000b10c, 0x07410742}, 827 - {0x0000b110, 0x075f0740}, 828 - {0x0000b114, 0x077f0760}, 829 - {0x0000b118, 0x07800781}, 830 - {0x0000b11c, 0x07a0079f}, 831 - {0x0000b120, 0x07c107bf}, 832 - {0x0000b124, 0x000007c0}, 833 - {0x0000b128, 0x00000000}, 834 - {0x0000b12c, 0x00000000}, 835 - {0x0000b130, 0x00000000}, 836 - {0x0000b134, 0x00000000}, 837 - {0x0000b138, 0x00000000}, 838 - {0x0000b13c, 0x00000000}, 839 - {0x0000b140, 0x003f0020}, 840 - {0x0000b144, 0x00400041}, 841 - {0x0000b148, 0x0140005f}, 842 - {0x0000b14c, 0x0160015f}, 843 - {0x0000b150, 0x017e017f}, 844 - {0x0000b154, 0x02410242}, 845 - {0x0000b158, 0x025f0240}, 846 - {0x0000b15c, 0x027f0260}, 847 - {0x0000b160, 0x0341027e}, 848 - {0x0000b164, 0x035f0340}, 849 - {0x0000b168, 0x037f0360}, 850 - {0x0000b16c, 0x04400441}, 851 - {0x0000b170, 0x0460045f}, 852 - {0x0000b174, 0x0541047f}, 853 - {0x0000b178, 0x055f0540}, 854 - {0x0000b17c, 0x057f0560}, 855 - {0x0000b180, 0x06400641}, 856 - {0x0000b184, 0x0660065f}, 857 - {0x0000b188, 0x067e067f}, 858 - {0x0000b18c, 0x07410742}, 859 - {0x0000b190, 0x075f0740}, 860 - {0x0000b194, 0x077f0760}, 861 - {0x0000b198, 0x07800781}, 862 - {0x0000b19c, 0x07a0079f}, 863 - {0x0000b1a0, 0x07c107bf}, 864 - {0x0000b1a4, 0x000007c0}, 865 - {0x0000b1a8, 0x00000000}, 866 - {0x0000b1ac, 0x00000000}, 867 - {0x0000b1b0, 0x00000000}, 868 - {0x0000b1b4, 0x00000000}, 869 - {0x0000b1b8, 0x00000000}, 870 - {0x0000b1bc, 0x00000000}, 871 - {0x0000b1c0, 0x00000000}, 872 - {0x0000b1c4, 0x00000000}, 873 - {0x0000b1c8, 0x00000000}, 874 - {0x0000b1cc, 0x00000000}, 875 - {0x0000b1d0, 0x00000000}, 876 - {0x0000b1d4, 0x00000000}, 877 - {0x0000b1d8, 0x00000000}, 878 - {0x0000b1dc, 0x00000000}, 879 - {0x0000b1e0, 0x00000000}, 880 - {0x0000b1e4, 0x00000000}, 881 - {0x0000b1e8, 0x00000000}, 882 - {0x0000b1ec, 0x00000000}, 883 - {0x0000b1f0, 0x00000396}, 884 - {0x0000b1f4, 0x00000396}, 885 - {0x0000b1f8, 0x00000396}, 886 - {0x0000b1fc, 0x00000196}, 887 - }; 888 - 889 - static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = { 890 - /* Addr allmodes */ 891 - {0x00009fd0, 0x0a2d6b93}, 892 - }; 893 - 894 - static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = { 895 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 896 - {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae}, 897 - {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da}, 898 - {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81}, 899 - {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8}, 900 - {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e}, 901 - {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e}, 902 - }; 903 - 904 - static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = { 905 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 906 - {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, 907 - }; 908 - 909 - static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = { 910 - /* Addr allmodes */ 911 - {0x0000a000, 0x00010000}, 912 - {0x0000a004, 0x00030002}, 913 - {0x0000a008, 0x00050004}, 914 - {0x0000a00c, 0x00810080}, 915 - {0x0000a010, 0x00830082}, 916 - {0x0000a014, 0x01810180}, 917 - {0x0000a018, 0x01830182}, 918 - {0x0000a01c, 0x01850184}, 919 - {0x0000a020, 0x01890188}, 920 - {0x0000a024, 0x018b018a}, 921 - {0x0000a028, 0x018d018c}, 922 - {0x0000a02c, 0x03820190}, 923 - {0x0000a030, 0x03840383}, 924 - {0x0000a034, 0x03880385}, 925 - {0x0000a038, 0x038a0389}, 926 - {0x0000a03c, 0x038c038b}, 927 - {0x0000a040, 0x0390038d}, 928 - {0x0000a044, 0x03920391}, 929 - {0x0000a048, 0x03940393}, 930 - {0x0000a04c, 0x03960395}, 931 - {0x0000a050, 0x00000000}, 932 - {0x0000a054, 0x00000000}, 933 - {0x0000a058, 0x00000000}, 934 - {0x0000a05c, 0x00000000}, 935 - {0x0000a060, 0x00000000}, 936 - {0x0000a064, 0x00000000}, 937 - {0x0000a068, 0x00000000}, 938 - {0x0000a06c, 0x00000000}, 939 - {0x0000a070, 0x00000000}, 940 - {0x0000a074, 0x00000000}, 941 - {0x0000a078, 0x00000000}, 942 - {0x0000a07c, 0x00000000}, 943 - {0x0000a080, 0x29292929}, 944 - {0x0000a084, 0x29292929}, 945 - {0x0000a088, 0x29292929}, 946 - {0x0000a08c, 0x29292929}, 947 - {0x0000a090, 0x22292929}, 948 - {0x0000a094, 0x1d1d2222}, 949 - {0x0000a098, 0x0c111117}, 950 - {0x0000a09c, 0x00030303}, 951 - {0x0000a0a0, 0x00000000}, 952 - {0x0000a0a4, 0x00000000}, 953 - {0x0000a0a8, 0x00000000}, 954 - {0x0000a0ac, 0x00000000}, 955 - {0x0000a0b0, 0x00000000}, 956 - {0x0000a0b4, 0x00000000}, 957 - {0x0000a0b8, 0x00000000}, 958 - {0x0000a0bc, 0x00000000}, 959 - {0x0000a0c0, 0x001f0000}, 960 - {0x0000a0c4, 0x01000101}, 961 - {0x0000a0c8, 0x011e011f}, 962 - {0x0000a0cc, 0x011c011d}, 963 - {0x0000a0d0, 0x02030204}, 964 - {0x0000a0d4, 0x02010202}, 965 - {0x0000a0d8, 0x021f0200}, 966 - {0x0000a0dc, 0x0302021e}, 967 - {0x0000a0e0, 0x03000301}, 968 - {0x0000a0e4, 0x031e031f}, 969 - {0x0000a0e8, 0x0402031d}, 970 - {0x0000a0ec, 0x04000401}, 971 - {0x0000a0f0, 0x041e041f}, 972 - {0x0000a0f4, 0x0502041d}, 973 - {0x0000a0f8, 0x05000501}, 974 - {0x0000a0fc, 0x051e051f}, 975 - {0x0000a100, 0x06010602}, 976 - {0x0000a104, 0x061f0600}, 977 - {0x0000a108, 0x061d061e}, 978 - {0x0000a10c, 0x07020703}, 979 - {0x0000a110, 0x07000701}, 980 - {0x0000a114, 0x00000000}, 981 - {0x0000a118, 0x00000000}, 982 - {0x0000a11c, 0x00000000}, 983 - {0x0000a120, 0x00000000}, 984 - {0x0000a124, 0x00000000}, 985 - {0x0000a128, 0x00000000}, 986 - {0x0000a12c, 0x00000000}, 987 - {0x0000a130, 0x00000000}, 988 - {0x0000a134, 0x00000000}, 989 - {0x0000a138, 0x00000000}, 990 - {0x0000a13c, 0x00000000}, 991 - {0x0000a140, 0x001f0000}, 992 - {0x0000a144, 0x01000101}, 993 - {0x0000a148, 0x011e011f}, 994 - {0x0000a14c, 0x011c011d}, 995 - {0x0000a150, 0x02030204}, 996 - {0x0000a154, 0x02010202}, 997 - {0x0000a158, 0x021f0200}, 998 - {0x0000a15c, 0x0302021e}, 999 - {0x0000a160, 0x03000301}, 1000 - {0x0000a164, 0x031e031f}, 1001 - {0x0000a168, 0x0402031d}, 1002 - {0x0000a16c, 0x04000401}, 1003 - {0x0000a170, 0x041e041f}, 1004 - {0x0000a174, 0x0502041d}, 1005 - {0x0000a178, 0x05000501}, 1006 - {0x0000a17c, 0x051e051f}, 1007 - {0x0000a180, 0x06010602}, 1008 - {0x0000a184, 0x061f0600}, 1009 - {0x0000a188, 0x061d061e}, 1010 - {0x0000a18c, 0x07020703}, 1011 - {0x0000a190, 0x07000701}, 1012 - {0x0000a194, 0x00000000}, 1013 - {0x0000a198, 0x00000000}, 1014 - {0x0000a19c, 0x00000000}, 1015 - {0x0000a1a0, 0x00000000}, 1016 - {0x0000a1a4, 0x00000000}, 1017 - {0x0000a1a8, 0x00000000}, 1018 - {0x0000a1ac, 0x00000000}, 1019 - {0x0000a1b0, 0x00000000}, 1020 - {0x0000a1b4, 0x00000000}, 1021 - {0x0000a1b8, 0x00000000}, 1022 - {0x0000a1bc, 0x00000000}, 1023 - {0x0000a1c0, 0x00000000}, 1024 - {0x0000a1c4, 0x00000000}, 1025 - {0x0000a1c8, 0x00000000}, 1026 - {0x0000a1cc, 0x00000000}, 1027 - {0x0000a1d0, 0x00000000}, 1028 - {0x0000a1d4, 0x00000000}, 1029 - {0x0000a1d8, 0x00000000}, 1030 - {0x0000a1dc, 0x00000000}, 1031 - {0x0000a1e0, 0x00000000}, 1032 - {0x0000a1e4, 0x00000000}, 1033 - {0x0000a1e8, 0x00000000}, 1034 - {0x0000a1ec, 0x00000000}, 1035 - {0x0000a1f0, 0x00000396}, 1036 - {0x0000a1f4, 0x00000396}, 1037 - {0x0000a1f8, 0x00000396}, 1038 - {0x0000a1fc, 0x00000196}, 1039 - {0x0000b000, 0x00010000}, 1040 - {0x0000b004, 0x00030002}, 1041 - {0x0000b008, 0x00050004}, 1042 - {0x0000b00c, 0x00810080}, 1043 - {0x0000b010, 0x00830082}, 1044 - {0x0000b014, 0x01810180}, 1045 - {0x0000b018, 0x01830182}, 1046 - {0x0000b01c, 0x01850184}, 1047 - {0x0000b020, 0x02810280}, 1048 - {0x0000b024, 0x02830282}, 1049 - {0x0000b028, 0x02850284}, 1050 - {0x0000b02c, 0x02890288}, 1051 - {0x0000b030, 0x028b028a}, 1052 - {0x0000b034, 0x0388028c}, 1053 - {0x0000b038, 0x038a0389}, 1054 - {0x0000b03c, 0x038c038b}, 1055 - {0x0000b040, 0x0390038d}, 1056 - {0x0000b044, 0x03920391}, 1057 - {0x0000b048, 0x03940393}, 1058 - {0x0000b04c, 0x03960395}, 1059 - {0x0000b050, 0x00000000}, 1060 - {0x0000b054, 0x00000000}, 1061 - {0x0000b058, 0x00000000}, 1062 - {0x0000b05c, 0x00000000}, 1063 - {0x0000b060, 0x00000000}, 1064 - {0x0000b064, 0x00000000}, 1065 - {0x0000b068, 0x00000000}, 1066 - {0x0000b06c, 0x00000000}, 1067 - {0x0000b070, 0x00000000}, 1068 - {0x0000b074, 0x00000000}, 1069 - {0x0000b078, 0x00000000}, 1070 - {0x0000b07c, 0x00000000}, 1071 - {0x0000b080, 0x32323232}, 1072 - {0x0000b084, 0x2f2f3232}, 1073 - {0x0000b088, 0x23282a2d}, 1074 - {0x0000b08c, 0x1c1e2123}, 1075 - {0x0000b090, 0x14171919}, 1076 - {0x0000b094, 0x0e0e1214}, 1077 - {0x0000b098, 0x03050707}, 1078 - {0x0000b09c, 0x00030303}, 1079 - {0x0000b0a0, 0x00000000}, 1080 - {0x0000b0a4, 0x00000000}, 1081 - {0x0000b0a8, 0x00000000}, 1082 - {0x0000b0ac, 0x00000000}, 1083 - {0x0000b0b0, 0x00000000}, 1084 - {0x0000b0b4, 0x00000000}, 1085 - {0x0000b0b8, 0x00000000}, 1086 - {0x0000b0bc, 0x00000000}, 1087 - {0x0000b0c0, 0x003f0020}, 1088 - {0x0000b0c4, 0x00400041}, 1089 - {0x0000b0c8, 0x0140005f}, 1090 - {0x0000b0cc, 0x0160015f}, 1091 - {0x0000b0d0, 0x017e017f}, 1092 - {0x0000b0d4, 0x02410242}, 1093 - {0x0000b0d8, 0x025f0240}, 1094 - {0x0000b0dc, 0x027f0260}, 1095 - {0x0000b0e0, 0x0341027e}, 1096 - {0x0000b0e4, 0x035f0340}, 1097 - {0x0000b0e8, 0x037f0360}, 1098 - {0x0000b0ec, 0x04400441}, 1099 - {0x0000b0f0, 0x0460045f}, 1100 - {0x0000b0f4, 0x0541047f}, 1101 - {0x0000b0f8, 0x055f0540}, 1102 - {0x0000b0fc, 0x057f0560}, 1103 - {0x0000b100, 0x06400641}, 1104 - {0x0000b104, 0x0660065f}, 1105 - {0x0000b108, 0x067e067f}, 1106 - {0x0000b10c, 0x07410742}, 1107 - {0x0000b110, 0x075f0740}, 1108 - {0x0000b114, 0x077f0760}, 1109 - {0x0000b118, 0x07800781}, 1110 - {0x0000b11c, 0x07a0079f}, 1111 - {0x0000b120, 0x07c107bf}, 1112 - {0x0000b124, 0x000007c0}, 1113 - {0x0000b128, 0x00000000}, 1114 - {0x0000b12c, 0x00000000}, 1115 - {0x0000b130, 0x00000000}, 1116 - {0x0000b134, 0x00000000}, 1117 - {0x0000b138, 0x00000000}, 1118 - {0x0000b13c, 0x00000000}, 1119 - {0x0000b140, 0x003f0020}, 1120 - {0x0000b144, 0x00400041}, 1121 - {0x0000b148, 0x0140005f}, 1122 - {0x0000b14c, 0x0160015f}, 1123 - {0x0000b150, 0x017e017f}, 1124 - {0x0000b154, 0x02410242}, 1125 - {0x0000b158, 0x025f0240}, 1126 - {0x0000b15c, 0x027f0260}, 1127 - {0x0000b160, 0x0341027e}, 1128 - {0x0000b164, 0x035f0340}, 1129 - {0x0000b168, 0x037f0360}, 1130 - {0x0000b16c, 0x04400441}, 1131 - {0x0000b170, 0x0460045f}, 1132 - {0x0000b174, 0x0541047f}, 1133 - {0x0000b178, 0x055f0540}, 1134 - {0x0000b17c, 0x057f0560}, 1135 - {0x0000b180, 0x06400641}, 1136 - {0x0000b184, 0x0660065f}, 1137 - {0x0000b188, 0x067e067f}, 1138 - {0x0000b18c, 0x07410742}, 1139 - {0x0000b190, 0x075f0740}, 1140 - {0x0000b194, 0x077f0760}, 1141 - {0x0000b198, 0x07800781}, 1142 - {0x0000b19c, 0x07a0079f}, 1143 - {0x0000b1a0, 0x07c107bf}, 1144 - {0x0000b1a4, 0x000007c0}, 1145 - {0x0000b1a8, 0x00000000}, 1146 - {0x0000b1ac, 0x00000000}, 1147 - {0x0000b1b0, 0x00000000}, 1148 - {0x0000b1b4, 0x00000000}, 1149 - {0x0000b1b8, 0x00000000}, 1150 - {0x0000b1bc, 0x00000000}, 1151 - {0x0000b1c0, 0x00000000}, 1152 - {0x0000b1c4, 0x00000000}, 1153 - {0x0000b1c8, 0x00000000}, 1154 - {0x0000b1cc, 0x00000000}, 1155 - {0x0000b1d0, 0x00000000}, 1156 - {0x0000b1d4, 0x00000000}, 1157 - {0x0000b1d8, 0x00000000}, 1158 - {0x0000b1dc, 0x00000000}, 1159 - {0x0000b1e0, 0x00000000}, 1160 - {0x0000b1e4, 0x00000000}, 1161 - {0x0000b1e8, 0x00000000}, 1162 - {0x0000b1ec, 0x00000000}, 1163 - {0x0000b1f0, 0x00000396}, 1164 - {0x0000b1f4, 0x00000396}, 1165 - {0x0000b1f8, 0x00000396}, 1166 - {0x0000b1fc, 0x00000196}, 1167 - }; 1168 - 1169 - static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = { 1170 - /* Addr allmodes */ 1171 - {0x0000a000, 0x00010000}, 1172 - {0x0000a004, 0x00030002}, 1173 - {0x0000a008, 0x00050004}, 1174 - {0x0000a00c, 0x00810080}, 1175 - {0x0000a010, 0x00830082}, 1176 - {0x0000a014, 0x01810180}, 1177 - {0x0000a018, 0x01830182}, 1178 - {0x0000a01c, 0x01850184}, 1179 - {0x0000a020, 0x01890188}, 1180 - {0x0000a024, 0x018b018a}, 1181 - {0x0000a028, 0x018d018c}, 1182 - {0x0000a02c, 0x03820190}, 1183 - {0x0000a030, 0x03840383}, 1184 - {0x0000a034, 0x03880385}, 1185 - {0x0000a038, 0x038a0389}, 1186 - {0x0000a03c, 0x038c038b}, 1187 - {0x0000a040, 0x0390038d}, 1188 - {0x0000a044, 0x03920391}, 1189 - {0x0000a048, 0x03940393}, 1190 - {0x0000a04c, 0x03960395}, 1191 - {0x0000a050, 0x00000000}, 1192 - {0x0000a054, 0x00000000}, 1193 - {0x0000a058, 0x00000000}, 1194 - {0x0000a05c, 0x00000000}, 1195 - {0x0000a060, 0x00000000}, 1196 - {0x0000a064, 0x00000000}, 1197 - {0x0000a068, 0x00000000}, 1198 - {0x0000a06c, 0x00000000}, 1199 - {0x0000a070, 0x00000000}, 1200 - {0x0000a074, 0x00000000}, 1201 - {0x0000a078, 0x00000000}, 1202 - {0x0000a07c, 0x00000000}, 1203 - {0x0000a080, 0x29292929}, 1204 - {0x0000a084, 0x29292929}, 1205 - {0x0000a088, 0x29292929}, 1206 - {0x0000a08c, 0x29292929}, 1207 - {0x0000a090, 0x22292929}, 1208 - {0x0000a094, 0x1d1d2222}, 1209 - {0x0000a098, 0x0c111117}, 1210 - {0x0000a09c, 0x00030303}, 1211 - {0x0000a0a0, 0x00000000}, 1212 - {0x0000a0a4, 0x00000000}, 1213 - {0x0000a0a8, 0x00000000}, 1214 - {0x0000a0ac, 0x00000000}, 1215 - {0x0000a0b0, 0x00000000}, 1216 - {0x0000a0b4, 0x00000000}, 1217 - {0x0000a0b8, 0x00000000}, 1218 - {0x0000a0bc, 0x00000000}, 1219 - {0x0000a0c0, 0x001f0000}, 1220 - {0x0000a0c4, 0x01000101}, 1221 - {0x0000a0c8, 0x011e011f}, 1222 - {0x0000a0cc, 0x011c011d}, 1223 - {0x0000a0d0, 0x02030204}, 1224 - {0x0000a0d4, 0x02010202}, 1225 - {0x0000a0d8, 0x021f0200}, 1226 - {0x0000a0dc, 0x0302021e}, 1227 - {0x0000a0e0, 0x03000301}, 1228 - {0x0000a0e4, 0x031e031f}, 1229 - {0x0000a0e8, 0x0402031d}, 1230 - {0x0000a0ec, 0x04000401}, 1231 - {0x0000a0f0, 0x041e041f}, 1232 - {0x0000a0f4, 0x0502041d}, 1233 - {0x0000a0f8, 0x05000501}, 1234 - {0x0000a0fc, 0x051e051f}, 1235 - {0x0000a100, 0x06010602}, 1236 - {0x0000a104, 0x061f0600}, 1237 - {0x0000a108, 0x061d061e}, 1238 - {0x0000a10c, 0x07020703}, 1239 - {0x0000a110, 0x07000701}, 1240 - {0x0000a114, 0x00000000}, 1241 - {0x0000a118, 0x00000000}, 1242 - {0x0000a11c, 0x00000000}, 1243 - {0x0000a120, 0x00000000}, 1244 - {0x0000a124, 0x00000000}, 1245 - {0x0000a128, 0x00000000}, 1246 - {0x0000a12c, 0x00000000}, 1247 - {0x0000a130, 0x00000000}, 1248 - {0x0000a134, 0x00000000}, 1249 - {0x0000a138, 0x00000000}, 1250 - {0x0000a13c, 0x00000000}, 1251 - {0x0000a140, 0x001f0000}, 1252 - {0x0000a144, 0x01000101}, 1253 - {0x0000a148, 0x011e011f}, 1254 - {0x0000a14c, 0x011c011d}, 1255 - {0x0000a150, 0x02030204}, 1256 - {0x0000a154, 0x02010202}, 1257 - {0x0000a158, 0x021f0200}, 1258 - {0x0000a15c, 0x0302021e}, 1259 - {0x0000a160, 0x03000301}, 1260 - {0x0000a164, 0x031e031f}, 1261 - {0x0000a168, 0x0402031d}, 1262 - {0x0000a16c, 0x04000401}, 1263 - {0x0000a170, 0x041e041f}, 1264 - {0x0000a174, 0x0502041d}, 1265 - {0x0000a178, 0x05000501}, 1266 - {0x0000a17c, 0x051e051f}, 1267 - {0x0000a180, 0x06010602}, 1268 - {0x0000a184, 0x061f0600}, 1269 - {0x0000a188, 0x061d061e}, 1270 - {0x0000a18c, 0x07020703}, 1271 - {0x0000a190, 0x07000701}, 1272 - {0x0000a194, 0x00000000}, 1273 - {0x0000a198, 0x00000000}, 1274 - {0x0000a19c, 0x00000000}, 1275 - {0x0000a1a0, 0x00000000}, 1276 - {0x0000a1a4, 0x00000000}, 1277 - {0x0000a1a8, 0x00000000}, 1278 - {0x0000a1ac, 0x00000000}, 1279 - {0x0000a1b0, 0x00000000}, 1280 - {0x0000a1b4, 0x00000000}, 1281 - {0x0000a1b8, 0x00000000}, 1282 - {0x0000a1bc, 0x00000000}, 1283 - {0x0000a1c0, 0x00000000}, 1284 - {0x0000a1c4, 0x00000000}, 1285 - {0x0000a1c8, 0x00000000}, 1286 - {0x0000a1cc, 0x00000000}, 1287 - {0x0000a1d0, 0x00000000}, 1288 - {0x0000a1d4, 0x00000000}, 1289 - {0x0000a1d8, 0x00000000}, 1290 - {0x0000a1dc, 0x00000000}, 1291 - {0x0000a1e0, 0x00000000}, 1292 - {0x0000a1e4, 0x00000000}, 1293 - {0x0000a1e8, 0x00000000}, 1294 - {0x0000a1ec, 0x00000000}, 1295 - {0x0000a1f0, 0x00000396}, 1296 - {0x0000a1f4, 0x00000396}, 1297 - {0x0000a1f8, 0x00000396}, 1298 - {0x0000a1fc, 0x00000196}, 1299 - {0x0000b000, 0x00010000}, 1300 - {0x0000b004, 0x00030002}, 1301 - {0x0000b008, 0x00050004}, 1302 - {0x0000b00c, 0x00810080}, 1303 - {0x0000b010, 0x00830082}, 1304 - {0x0000b014, 0x01810180}, 1305 - {0x0000b018, 0x01830182}, 1306 - {0x0000b01c, 0x01850184}, 1307 - {0x0000b020, 0x02810280}, 1308 - {0x0000b024, 0x02830282}, 1309 - {0x0000b028, 0x02850284}, 1310 - {0x0000b02c, 0x02890288}, 1311 - {0x0000b030, 0x028b028a}, 1312 - {0x0000b034, 0x0388028c}, 1313 - {0x0000b038, 0x038a0389}, 1314 - {0x0000b03c, 0x038c038b}, 1315 - {0x0000b040, 0x0390038d}, 1316 - {0x0000b044, 0x03920391}, 1317 - {0x0000b048, 0x03940393}, 1318 - {0x0000b04c, 0x03960395}, 1319 - {0x0000b050, 0x00000000}, 1320 - {0x0000b054, 0x00000000}, 1321 - {0x0000b058, 0x00000000}, 1322 - {0x0000b05c, 0x00000000}, 1323 - {0x0000b060, 0x00000000}, 1324 - {0x0000b064, 0x00000000}, 1325 - {0x0000b068, 0x00000000}, 1326 - {0x0000b06c, 0x00000000}, 1327 - {0x0000b070, 0x00000000}, 1328 - {0x0000b074, 0x00000000}, 1329 - {0x0000b078, 0x00000000}, 1330 - {0x0000b07c, 0x00000000}, 1331 - {0x0000b080, 0x2a2d2f32}, 1332 - {0x0000b084, 0x21232328}, 1333 - {0x0000b088, 0x19191c1e}, 1334 - {0x0000b08c, 0x12141417}, 1335 - {0x0000b090, 0x07070e0e}, 1336 - {0x0000b094, 0x03030305}, 1337 - {0x0000b098, 0x00000003}, 1338 - {0x0000b09c, 0x00000000}, 1339 - {0x0000b0a0, 0x00000000}, 1340 - {0x0000b0a4, 0x00000000}, 1341 - {0x0000b0a8, 0x00000000}, 1342 - {0x0000b0ac, 0x00000000}, 1343 - {0x0000b0b0, 0x00000000}, 1344 - {0x0000b0b4, 0x00000000}, 1345 - {0x0000b0b8, 0x00000000}, 1346 - {0x0000b0bc, 0x00000000}, 1347 - {0x0000b0c0, 0x003f0020}, 1348 - {0x0000b0c4, 0x00400041}, 1349 - {0x0000b0c8, 0x0140005f}, 1350 - {0x0000b0cc, 0x0160015f}, 1351 - {0x0000b0d0, 0x017e017f}, 1352 - {0x0000b0d4, 0x02410242}, 1353 - {0x0000b0d8, 0x025f0240}, 1354 - {0x0000b0dc, 0x027f0260}, 1355 - {0x0000b0e0, 0x0341027e}, 1356 - {0x0000b0e4, 0x035f0340}, 1357 - {0x0000b0e8, 0x037f0360}, 1358 - {0x0000b0ec, 0x04400441}, 1359 - {0x0000b0f0, 0x0460045f}, 1360 - {0x0000b0f4, 0x0541047f}, 1361 - {0x0000b0f8, 0x055f0540}, 1362 - {0x0000b0fc, 0x057f0560}, 1363 - {0x0000b100, 0x06400641}, 1364 - {0x0000b104, 0x0660065f}, 1365 - {0x0000b108, 0x067e067f}, 1366 - {0x0000b10c, 0x07410742}, 1367 - {0x0000b110, 0x075f0740}, 1368 - {0x0000b114, 0x077f0760}, 1369 - {0x0000b118, 0x07800781}, 1370 - {0x0000b11c, 0x07a0079f}, 1371 - {0x0000b120, 0x07c107bf}, 1372 - {0x0000b124, 0x000007c0}, 1373 - {0x0000b128, 0x00000000}, 1374 - {0x0000b12c, 0x00000000}, 1375 - {0x0000b130, 0x00000000}, 1376 - {0x0000b134, 0x00000000}, 1377 - {0x0000b138, 0x00000000}, 1378 - {0x0000b13c, 0x00000000}, 1379 - {0x0000b140, 0x003f0020}, 1380 - {0x0000b144, 0x00400041}, 1381 - {0x0000b148, 0x0140005f}, 1382 - {0x0000b14c, 0x0160015f}, 1383 - {0x0000b150, 0x017e017f}, 1384 - {0x0000b154, 0x02410242}, 1385 - {0x0000b158, 0x025f0240}, 1386 - {0x0000b15c, 0x027f0260}, 1387 - {0x0000b160, 0x0341027e}, 1388 - {0x0000b164, 0x035f0340}, 1389 - {0x0000b168, 0x037f0360}, 1390 - {0x0000b16c, 0x04400441}, 1391 - {0x0000b170, 0x0460045f}, 1392 - {0x0000b174, 0x0541047f}, 1393 - {0x0000b178, 0x055f0540}, 1394 - {0x0000b17c, 0x057f0560}, 1395 - {0x0000b180, 0x06400641}, 1396 - {0x0000b184, 0x0660065f}, 1397 - {0x0000b188, 0x067e067f}, 1398 - {0x0000b18c, 0x07410742}, 1399 - {0x0000b190, 0x075f0740}, 1400 - {0x0000b194, 0x077f0760}, 1401 - {0x0000b198, 0x07800781}, 1402 - {0x0000b19c, 0x07a0079f}, 1403 - {0x0000b1a0, 0x07c107bf}, 1404 - {0x0000b1a4, 0x000007c0}, 1405 - {0x0000b1a8, 0x00000000}, 1406 - {0x0000b1ac, 0x00000000}, 1407 - {0x0000b1b0, 0x00000000}, 1408 - {0x0000b1b4, 0x00000000}, 1409 - {0x0000b1b8, 0x00000000}, 1410 - {0x0000b1bc, 0x00000000}, 1411 - {0x0000b1c0, 0x00000000}, 1412 - {0x0000b1c4, 0x00000000}, 1413 - {0x0000b1c8, 0x00000000}, 1414 - {0x0000b1cc, 0x00000000}, 1415 - {0x0000b1d0, 0x00000000}, 1416 - {0x0000b1d4, 0x00000000}, 1417 - {0x0000b1d8, 0x00000000}, 1418 - {0x0000b1dc, 0x00000000}, 1419 - {0x0000b1e0, 0x00000000}, 1420 - {0x0000b1e4, 0x00000000}, 1421 - {0x0000b1e8, 0x00000000}, 1422 - {0x0000b1ec, 0x00000000}, 1423 - {0x0000b1f0, 0x00000396}, 1424 - {0x0000b1f4, 0x00000396}, 1425 - {0x0000b1f8, 0x00000396}, 1426 - {0x0000b1fc, 0x00000196}, 1427 - }; 1428 - 1429 - static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = { 1430 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1431 - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 1432 - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 1433 - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 1434 - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 1435 - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1436 - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 1437 - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1438 - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1439 - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, 1440 - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, 1441 - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, 1442 - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, 1443 - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, 1444 - {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, 1445 - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, 1446 - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, 1447 - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, 1448 - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, 1449 - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, 1450 - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, 1451 - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, 1452 - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, 1453 - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, 1454 - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, 1455 - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, 1456 - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, 1457 - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, 1458 - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, 1459 - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, 1460 - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, 1461 - {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, 1462 - {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, 1463 - {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, 1464 - {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, 1465 - {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, 1466 - {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, 1467 - {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, 1468 - {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, 1469 - {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, 1470 - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1471 - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1472 - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1473 - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1474 - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1475 - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, 1476 - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, 1477 - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, 1478 - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, 1479 - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, 1480 - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, 1481 - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, 1482 - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1483 - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1484 - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1485 - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 1486 - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 1487 - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 1488 - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 1489 - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1490 - {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, 1491 - {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060}, 1492 - {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, 1493 - {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, 1494 - {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000}, 1495 - {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, 1496 - }; 1497 - 1498 - static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = { 1499 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1500 - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 1501 - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 1502 - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 1503 - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 1504 - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1505 - {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de}, 1506 - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1507 - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 1508 - {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, 1509 - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, 1510 - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, 1511 - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, 1512 - {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, 1513 - {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, 1514 - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, 1515 - {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, 1516 - {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, 1517 - {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, 1518 - {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, 1519 - {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, 1520 - {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, 1521 - {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, 1522 - {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, 1523 - {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, 1524 - {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, 1525 - {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81}, 1526 - {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83}, 1527 - {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84}, 1528 - {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, 1529 - {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, 1530 - {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, 1531 - {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, 1532 - {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec}, 1533 - {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0}, 1534 - {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4}, 1535 - {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, 1536 - {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, 1537 - {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, 1538 - {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, 1539 - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1540 - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1541 - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1542 - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1543 - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, 1544 - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, 1545 - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, 1546 - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, 1547 - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, 1548 - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, 1549 - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, 1550 - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1551 - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1552 - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1553 - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1554 - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1555 - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 1556 - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 1557 - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 1558 - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1559 - {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, 1560 - {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, 1561 - {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, 1562 - {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, 1563 - {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, 1564 - {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, 1565 - }; 1566 - 1567 - static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = { 1568 - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1569 - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 1570 - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 1571 - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 1572 - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 1573 - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1574 - {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de}, 1575 - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1576 - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 1577 - {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, 1578 - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, 1579 - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, 1580 - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, 1581 - {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400}, 1582 - {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402}, 1583 - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, 1584 - {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603}, 1585 - {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02}, 1586 - {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04}, 1587 - {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20}, 1588 - {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20}, 1589 - {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22}, 1590 - {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24}, 1591 - {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640}, 1592 - {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660}, 1593 - {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861}, 1594 - {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81}, 1595 - {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83}, 1596 - {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84}, 1597 - {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3}, 1598 - {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5}, 1599 - {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9}, 1600 - {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb}, 1601 - {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec}, 1602 - {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0}, 1603 - {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4}, 1604 - {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, 1605 - {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, 1606 - {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, 1607 - {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, 1608 - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1609 - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1610 - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1611 - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1612 - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, 1613 - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, 1614 - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, 1615 - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, 1616 - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, 1617 - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, 1618 - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, 1619 - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1620 - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1621 - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1622 - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1623 - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 1624 - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 1625 - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 1626 - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 1627 - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 1628 - }; 1629 - 1630 - static const u32 ar9462_2p1_modes_fast_clock[][3] = { 1631 - /* Addr 5G_HT20 5G_HT40 */ 1632 - {0x00001030, 0x00000268, 0x000004d0}, 1633 - {0x00001070, 0x0000018c, 0x00000318}, 1634 - {0x000010b0, 0x00000fd0, 0x00001fa0}, 1635 - {0x00008014, 0x044c044c, 0x08980898}, 1636 - {0x0000801c, 0x148ec02b, 0x148ec057}, 1637 - {0x00008318, 0x000044c0, 0x00008980}, 1638 - {0x00009e00, 0x0372131c, 0x0372131c}, 1639 - {0x0000a230, 0x0000400b, 0x00004016}, 1640 - {0x0000a254, 0x00000898, 0x00001130}, 1641 - }; 1642 - 1643 - static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = { 1644 - /* Addr allmodes */ 1645 - {0x0000a398, 0x00000000}, 1646 - {0x0000a39c, 0x6f7f0301}, 1647 - {0x0000a3a0, 0xca9228ee}, 1648 413 }; 1649 414 1650 415 #endif /* INITVALS_9462_2P1_H */
+64
drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
··· 1 + /* 2 + * Copyright (c) 2010-2011 Atheros Communications Inc. 3 + * Copyright (c) 2011-2012 Qualcomm Atheros Inc. 4 + * 5 + * Permission to use, copy, modify, and/or distribute this software for any 6 + * purpose with or without fee is hereby granted, provided that the above 7 + * copyright notice and this permission notice appear in all copies. 8 + * 9 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 + */ 17 + 18 + #ifndef INITVALS_9565_1P1_H 19 + #define INITVALS_9565_1P1_H 20 + 21 + /* AR9565 1.1 */ 22 + 23 + #define ar9565_1p1_mac_core ar9565_1p0_mac_core 24 + 25 + #define ar9565_1p1_mac_postamble ar9565_1p0_mac_postamble 26 + 27 + #define ar9565_1p1_baseband_core ar9565_1p0_baseband_core 28 + 29 + #define ar9565_1p1_baseband_postamble ar9565_1p0_baseband_postamble 30 + 31 + #define ar9565_1p1_radio_core ar9565_1p0_radio_core 32 + 33 + #define ar9565_1p1_soc_preamble ar9565_1p0_soc_preamble 34 + 35 + #define ar9565_1p1_soc_postamble ar9565_1p0_soc_postamble 36 + 37 + #define ar9565_1p1_Common_rx_gain_table ar9565_1p0_Common_rx_gain_table 38 + 39 + #define ar9565_1p1_Modes_lowest_ob_db_tx_gain_table ar9565_1p0_Modes_lowest_ob_db_tx_gain_table 40 + 41 + #define ar9565_1p1_pciephy_clkreq_disable_L1 ar9565_1p0_pciephy_clkreq_disable_L1 42 + 43 + #define ar9565_1p1_modes_fast_clock ar9565_1p0_modes_fast_clock 44 + 45 + #define ar9565_1p1_common_wo_xlna_rx_gain_table ar9565_1p0_common_wo_xlna_rx_gain_table 46 + 47 + #define ar9565_1p1_modes_low_ob_db_tx_gain_table ar9565_1p0_modes_low_ob_db_tx_gain_table 48 + 49 + #define ar9565_1p1_modes_high_ob_db_tx_gain_table ar9565_1p0_modes_high_ob_db_tx_gain_table 50 + 51 + #define ar9565_1p1_modes_high_power_tx_gain_table ar9565_1p0_modes_high_power_tx_gain_table 52 + 53 + #define ar9565_1p1_baseband_core_txfir_coeff_japan_2484 ar9565_1p0_baseband_core_txfir_coeff_japan_2484 54 + 55 + static const u32 ar9565_1p1_radio_postamble[][5] = { 56 + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 57 + {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, 58 + {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 59 + {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, 60 + {0x0001610c, 0x40000000, 0x40000000, 0x40000000, 0x40000000}, 61 + {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 62 + }; 63 + 64 + #endif /* INITVALS_9565_1P1_H */
+386 -173
drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
··· 20 20 21 21 /* AR9580 1.0 */ 22 22 23 + #define ar9580_1p0_soc_preamble ar9300_2p2_soc_preamble 24 + 25 + #define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble 26 + 27 + #define ar9580_1p0_radio_core ar9300_2p2_radio_core 28 + 29 + #define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble 30 + 31 + #define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2 32 + 33 + #define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2 34 + 35 + #define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 36 + 23 37 #define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 38 + 39 + #define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484 24 40 25 41 static const u32 ar9580_1p0_radio_postamble[][5] = { 26 42 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 27 43 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, 28 44 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, 29 45 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, 30 - {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 46 + {0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000}, 31 47 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 32 - {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 48 + {0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000}, 33 49 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 34 - {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 50 + {0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000}, 35 51 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 36 52 }; 37 53 ··· 60 44 {0x00009814, 0x3280c00a}, 61 45 {0x00009818, 0x00000000}, 62 46 {0x0000981c, 0x00020028}, 63 - {0x00009834, 0x6400a290}, 47 + {0x00009834, 0x6400a190}, 64 48 {0x00009838, 0x0108ecff}, 65 - {0x0000983c, 0x0d000600}, 49 + {0x0000983c, 0x14000600}, 66 50 {0x00009880, 0x201fff00}, 67 51 {0x00009884, 0x00001042}, 68 52 {0x000098a4, 0x00200400}, ··· 83 67 {0x00009d04, 0x40206c10}, 84 68 {0x00009d08, 0x009c4060}, 85 69 {0x00009d0c, 0x9883800a}, 86 - {0x00009d10, 0x01834061}, 70 + {0x00009d10, 0x01884061}, 87 71 {0x00009d14, 0x00c0040b}, 88 72 {0x00009d18, 0x00000000}, 89 73 {0x00009e08, 0x0038230c}, ··· 214 198 {0x0000c420, 0x00000000}, 215 199 }; 216 200 217 - #define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble 218 - 219 201 static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { 220 202 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 221 203 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, ··· 320 306 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 321 307 }; 322 308 323 - #define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table 309 + static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = { 310 + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 311 + {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, 312 + {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, 313 + {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, 314 + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 315 + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 316 + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 317 + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, 318 + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, 319 + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, 320 + {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, 321 + {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, 322 + {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, 323 + {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, 324 + {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, 325 + {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, 326 + {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, 327 + {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, 328 + {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, 329 + {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, 330 + {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, 331 + {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, 332 + {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, 333 + {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, 334 + {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, 335 + {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83}, 336 + {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84}, 337 + {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, 338 + {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, 339 + {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, 340 + {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, 341 + {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, 342 + {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, 343 + {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, 344 + {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, 345 + {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, 346 + {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, 347 + {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, 348 + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, 349 + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, 350 + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, 351 + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, 352 + {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, 353 + {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, 354 + {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, 355 + {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, 356 + {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, 357 + {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, 358 + {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, 359 + {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, 360 + {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, 361 + {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, 362 + {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, 363 + {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, 364 + {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, 365 + {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, 366 + {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, 367 + {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, 368 + {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, 369 + {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, 370 + {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, 371 + {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, 372 + {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, 373 + {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, 374 + {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, 375 + {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, 376 + {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, 377 + {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, 378 + {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, 379 + {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, 380 + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 381 + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 382 + {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, 383 + {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, 384 + {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, 385 + {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, 386 + {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, 387 + {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, 388 + {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, 389 + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, 390 + {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, 391 + {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, 392 + {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, 393 + {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, 394 + {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, 395 + {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, 396 + {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, 397 + {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, 398 + {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, 399 + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 400 + {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, 401 + {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, 402 + {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, 403 + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 404 + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 405 + {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, 406 + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 407 + {0x00016288, 0x05a2040a, 0x05a2040a, 0x05a20408, 0x05a20408}, 408 + {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 409 + {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, 410 + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 411 + {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 412 + {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, 413 + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 414 + }; 324 415 325 416 static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { 326 417 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ··· 532 413 {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, 533 414 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 534 415 }; 535 - 536 - #define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 537 416 538 417 static const u32 ar9580_1p0_mac_core[][2] = { 539 418 /* Addr allmodes */ ··· 796 679 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 797 680 }; 798 681 799 - #define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2 800 - 801 - #define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble 802 - 803 - #define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 804 - 805 - #define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2 806 - 807 682 static const u32 ar9580_1p0_type6_tx_gain_table[][5] = { 808 683 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 809 684 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, ··· 870 761 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 871 762 }; 872 763 873 - static const u32 ar9580_1p0_soc_preamble[][2] = { 764 + static const u32 ar9580_1p0_rx_gain_table[][2] = { 874 765 /* Addr allmodes */ 875 - {0x000040a4, 0x00a0c1c9}, 876 - {0x00007008, 0x00000000}, 877 - {0x00007020, 0x00000000}, 878 - {0x00007034, 0x00000002}, 879 - {0x00007038, 0x000004c2}, 880 - {0x00007048, 0x00000008}, 881 - }; 882 - 883 - #define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0 884 - 885 - static const u32 ar9580_1p0_radio_core[][2] = { 886 - /* Addr allmodes */ 887 - {0x00016000, 0x36db6db6}, 888 - {0x00016004, 0x6db6db40}, 889 - {0x00016008, 0x73f00000}, 890 - {0x0001600c, 0x00000000}, 891 - {0x00016040, 0x7f80fff8}, 892 - {0x0001604c, 0x76d005b5}, 893 - {0x00016050, 0x556cf031}, 894 - {0x00016054, 0x13449440}, 895 - {0x00016058, 0x0c51c92c}, 896 - {0x0001605c, 0x3db7fffc}, 897 - {0x00016060, 0xfffffffc}, 898 - {0x00016064, 0x000f0278}, 899 - {0x0001606c, 0x6db60000}, 900 - {0x00016080, 0x00000000}, 901 - {0x00016084, 0x0e48048c}, 902 - {0x00016088, 0x54214514}, 903 - {0x0001608c, 0x119f481e}, 904 - {0x00016090, 0x24926490}, 905 - {0x00016098, 0xd2888888}, 906 - {0x000160a0, 0x0a108ffe}, 907 - {0x000160a4, 0x812fc370}, 908 - {0x000160a8, 0x423c8000}, 909 - {0x000160b4, 0x92480080}, 910 - {0x000160c0, 0x00adb6d0}, 911 - {0x000160c4, 0x6db6db60}, 912 - {0x000160c8, 0x6db6db6c}, 913 - {0x000160cc, 0x01e6c000}, 914 - {0x00016100, 0x3fffbe01}, 915 - {0x00016104, 0xfff80000}, 916 - {0x00016108, 0x00080010}, 917 - {0x00016144, 0x02084080}, 918 - {0x00016148, 0x00000000}, 919 - {0x00016280, 0x058a0001}, 920 - {0x00016284, 0x3d840208}, 921 - {0x00016288, 0x05a20408}, 922 - {0x0001628c, 0x00038c07}, 923 - {0x00016290, 0x00000004}, 924 - {0x00016294, 0x458aa14f}, 925 - {0x00016380, 0x00000000}, 926 - {0x00016384, 0x00000000}, 927 - {0x00016388, 0x00800700}, 928 - {0x0001638c, 0x00800700}, 929 - {0x00016390, 0x00800700}, 930 - {0x00016394, 0x00000000}, 931 - {0x00016398, 0x00000000}, 932 - {0x0001639c, 0x00000000}, 933 - {0x000163a0, 0x00000001}, 934 - {0x000163a4, 0x00000001}, 935 - {0x000163a8, 0x00000000}, 936 - {0x000163ac, 0x00000000}, 937 - {0x000163b0, 0x00000000}, 938 - {0x000163b4, 0x00000000}, 939 - {0x000163b8, 0x00000000}, 940 - {0x000163bc, 0x00000000}, 941 - {0x000163c0, 0x000000a0}, 942 - {0x000163c4, 0x000c0000}, 943 - {0x000163c8, 0x14021402}, 944 - {0x000163cc, 0x00001402}, 945 - {0x000163d0, 0x00000000}, 946 - {0x000163d4, 0x00000000}, 947 - {0x00016400, 0x36db6db6}, 948 - {0x00016404, 0x6db6db40}, 949 - {0x00016408, 0x73f00000}, 950 - {0x0001640c, 0x00000000}, 951 - {0x00016440, 0x7f80fff8}, 952 - {0x0001644c, 0x76d005b5}, 953 - {0x00016450, 0x556cf031}, 954 - {0x00016454, 0x13449440}, 955 - {0x00016458, 0x0c51c92c}, 956 - {0x0001645c, 0x3db7fffc}, 957 - {0x00016460, 0xfffffffc}, 958 - {0x00016464, 0x000f0278}, 959 - {0x0001646c, 0x6db60000}, 960 - {0x00016500, 0x3fffbe01}, 961 - {0x00016504, 0xfff80000}, 962 - {0x00016508, 0x00080010}, 963 - {0x00016544, 0x02084080}, 964 - {0x00016548, 0x00000000}, 965 - {0x00016780, 0x00000000}, 966 - {0x00016784, 0x00000000}, 967 - {0x00016788, 0x00800700}, 968 - {0x0001678c, 0x00800700}, 969 - {0x00016790, 0x00800700}, 970 - {0x00016794, 0x00000000}, 971 - {0x00016798, 0x00000000}, 972 - {0x0001679c, 0x00000000}, 973 - {0x000167a0, 0x00000001}, 974 - {0x000167a4, 0x00000001}, 975 - {0x000167a8, 0x00000000}, 976 - {0x000167ac, 0x00000000}, 977 - {0x000167b0, 0x00000000}, 978 - {0x000167b4, 0x00000000}, 979 - {0x000167b8, 0x00000000}, 980 - {0x000167bc, 0x00000000}, 981 - {0x000167c0, 0x000000a0}, 982 - {0x000167c4, 0x000c0000}, 983 - {0x000167c8, 0x14021402}, 984 - {0x000167cc, 0x00001402}, 985 - {0x000167d0, 0x00000000}, 986 - {0x000167d4, 0x00000000}, 987 - {0x00016800, 0x36db6db6}, 988 - {0x00016804, 0x6db6db40}, 989 - {0x00016808, 0x73f00000}, 990 - {0x0001680c, 0x00000000}, 991 - {0x00016840, 0x7f80fff8}, 992 - {0x0001684c, 0x76d005b5}, 993 - {0x00016850, 0x556cf031}, 994 - {0x00016854, 0x13449440}, 995 - {0x00016858, 0x0c51c92c}, 996 - {0x0001685c, 0x3db7fffc}, 997 - {0x00016860, 0xfffffffc}, 998 - {0x00016864, 0x000f0278}, 999 - {0x0001686c, 0x6db60000}, 1000 - {0x00016900, 0x3fffbe01}, 1001 - {0x00016904, 0xfff80000}, 1002 - {0x00016908, 0x00080010}, 1003 - {0x00016944, 0x02084080}, 1004 - {0x00016948, 0x00000000}, 1005 - {0x00016b80, 0x00000000}, 1006 - {0x00016b84, 0x00000000}, 1007 - {0x00016b88, 0x00800700}, 1008 - {0x00016b8c, 0x00800700}, 1009 - {0x00016b90, 0x00800700}, 1010 - {0x00016b94, 0x00000000}, 1011 - {0x00016b98, 0x00000000}, 1012 - {0x00016b9c, 0x00000000}, 1013 - {0x00016ba0, 0x00000001}, 1014 - {0x00016ba4, 0x00000001}, 1015 - {0x00016ba8, 0x00000000}, 1016 - {0x00016bac, 0x00000000}, 1017 - {0x00016bb0, 0x00000000}, 1018 - {0x00016bb4, 0x00000000}, 1019 - {0x00016bb8, 0x00000000}, 1020 - {0x00016bbc, 0x00000000}, 1021 - {0x00016bc0, 0x000000a0}, 1022 - {0x00016bc4, 0x000c0000}, 1023 - {0x00016bc8, 0x14021402}, 1024 - {0x00016bcc, 0x00001402}, 1025 - {0x00016bd0, 0x00000000}, 1026 - {0x00016bd4, 0x00000000}, 766 + {0x0000a000, 0x00010000}, 767 + {0x0000a004, 0x00030002}, 768 + {0x0000a008, 0x00050004}, 769 + {0x0000a00c, 0x00810080}, 770 + {0x0000a010, 0x00830082}, 771 + {0x0000a014, 0x01810180}, 772 + {0x0000a018, 0x01830182}, 773 + {0x0000a01c, 0x01850184}, 774 + {0x0000a020, 0x01890188}, 775 + {0x0000a024, 0x018b018a}, 776 + {0x0000a028, 0x018d018c}, 777 + {0x0000a02c, 0x01910190}, 778 + {0x0000a030, 0x01930192}, 779 + {0x0000a034, 0x01950194}, 780 + {0x0000a038, 0x038a0196}, 781 + {0x0000a03c, 0x038c038b}, 782 + {0x0000a040, 0x0390038d}, 783 + {0x0000a044, 0x03920391}, 784 + {0x0000a048, 0x03940393}, 785 + {0x0000a04c, 0x03960395}, 786 + {0x0000a050, 0x00000000}, 787 + {0x0000a054, 0x00000000}, 788 + {0x0000a058, 0x00000000}, 789 + {0x0000a05c, 0x00000000}, 790 + {0x0000a060, 0x00000000}, 791 + {0x0000a064, 0x00000000}, 792 + {0x0000a068, 0x00000000}, 793 + {0x0000a06c, 0x00000000}, 794 + {0x0000a070, 0x00000000}, 795 + {0x0000a074, 0x00000000}, 796 + {0x0000a078, 0x00000000}, 797 + {0x0000a07c, 0x00000000}, 798 + {0x0000a080, 0x22222229}, 799 + {0x0000a084, 0x1d1d1d1d}, 800 + {0x0000a088, 0x1d1d1d1d}, 801 + {0x0000a08c, 0x1d1d1d1d}, 802 + {0x0000a090, 0x171d1d1d}, 803 + {0x0000a094, 0x11111717}, 804 + {0x0000a098, 0x00030311}, 805 + {0x0000a09c, 0x00000000}, 806 + {0x0000a0a0, 0x00000000}, 807 + {0x0000a0a4, 0x00000000}, 808 + {0x0000a0a8, 0x00000000}, 809 + {0x0000a0ac, 0x00000000}, 810 + {0x0000a0b0, 0x00000000}, 811 + {0x0000a0b4, 0x00000000}, 812 + {0x0000a0b8, 0x00000000}, 813 + {0x0000a0bc, 0x00000000}, 814 + {0x0000a0c0, 0x001f0000}, 815 + {0x0000a0c4, 0x01000101}, 816 + {0x0000a0c8, 0x011e011f}, 817 + {0x0000a0cc, 0x011c011d}, 818 + {0x0000a0d0, 0x02030204}, 819 + {0x0000a0d4, 0x02010202}, 820 + {0x0000a0d8, 0x021f0200}, 821 + {0x0000a0dc, 0x0302021e}, 822 + {0x0000a0e0, 0x03000301}, 823 + {0x0000a0e4, 0x031e031f}, 824 + {0x0000a0e8, 0x0402031d}, 825 + {0x0000a0ec, 0x04000401}, 826 + {0x0000a0f0, 0x041e041f}, 827 + {0x0000a0f4, 0x0502041d}, 828 + {0x0000a0f8, 0x05000501}, 829 + {0x0000a0fc, 0x051e051f}, 830 + {0x0000a100, 0x06010602}, 831 + {0x0000a104, 0x061f0600}, 832 + {0x0000a108, 0x061d061e}, 833 + {0x0000a10c, 0x07020703}, 834 + {0x0000a110, 0x07000701}, 835 + {0x0000a114, 0x00000000}, 836 + {0x0000a118, 0x00000000}, 837 + {0x0000a11c, 0x00000000}, 838 + {0x0000a120, 0x00000000}, 839 + {0x0000a124, 0x00000000}, 840 + {0x0000a128, 0x00000000}, 841 + {0x0000a12c, 0x00000000}, 842 + {0x0000a130, 0x00000000}, 843 + {0x0000a134, 0x00000000}, 844 + {0x0000a138, 0x00000000}, 845 + {0x0000a13c, 0x00000000}, 846 + {0x0000a140, 0x001f0000}, 847 + {0x0000a144, 0x01000101}, 848 + {0x0000a148, 0x011e011f}, 849 + {0x0000a14c, 0x011c011d}, 850 + {0x0000a150, 0x02030204}, 851 + {0x0000a154, 0x02010202}, 852 + {0x0000a158, 0x021f0200}, 853 + {0x0000a15c, 0x0302021e}, 854 + {0x0000a160, 0x03000301}, 855 + {0x0000a164, 0x031e031f}, 856 + {0x0000a168, 0x0402031d}, 857 + {0x0000a16c, 0x04000401}, 858 + {0x0000a170, 0x041e041f}, 859 + {0x0000a174, 0x0502041d}, 860 + {0x0000a178, 0x05000501}, 861 + {0x0000a17c, 0x051e051f}, 862 + {0x0000a180, 0x06010602}, 863 + {0x0000a184, 0x061f0600}, 864 + {0x0000a188, 0x061d061e}, 865 + {0x0000a18c, 0x07020703}, 866 + {0x0000a190, 0x07000701}, 867 + {0x0000a194, 0x00000000}, 868 + {0x0000a198, 0x00000000}, 869 + {0x0000a19c, 0x00000000}, 870 + {0x0000a1a0, 0x00000000}, 871 + {0x0000a1a4, 0x00000000}, 872 + {0x0000a1a8, 0x00000000}, 873 + {0x0000a1ac, 0x00000000}, 874 + {0x0000a1b0, 0x00000000}, 875 + {0x0000a1b4, 0x00000000}, 876 + {0x0000a1b8, 0x00000000}, 877 + {0x0000a1bc, 0x00000000}, 878 + {0x0000a1c0, 0x00000000}, 879 + {0x0000a1c4, 0x00000000}, 880 + {0x0000a1c8, 0x00000000}, 881 + {0x0000a1cc, 0x00000000}, 882 + {0x0000a1d0, 0x00000000}, 883 + {0x0000a1d4, 0x00000000}, 884 + {0x0000a1d8, 0x00000000}, 885 + {0x0000a1dc, 0x00000000}, 886 + {0x0000a1e0, 0x00000000}, 887 + {0x0000a1e4, 0x00000000}, 888 + {0x0000a1e8, 0x00000000}, 889 + {0x0000a1ec, 0x00000000}, 890 + {0x0000a1f0, 0x00000396}, 891 + {0x0000a1f4, 0x00000396}, 892 + {0x0000a1f8, 0x00000396}, 893 + {0x0000a1fc, 0x00000196}, 894 + {0x0000b000, 0x00010000}, 895 + {0x0000b004, 0x00030002}, 896 + {0x0000b008, 0x00050004}, 897 + {0x0000b00c, 0x00810080}, 898 + {0x0000b010, 0x00830082}, 899 + {0x0000b014, 0x01810180}, 900 + {0x0000b018, 0x01830182}, 901 + {0x0000b01c, 0x01850184}, 902 + {0x0000b020, 0x02810280}, 903 + {0x0000b024, 0x02830282}, 904 + {0x0000b028, 0x02850284}, 905 + {0x0000b02c, 0x02890288}, 906 + {0x0000b030, 0x028b028a}, 907 + {0x0000b034, 0x0388028c}, 908 + {0x0000b038, 0x038a0389}, 909 + {0x0000b03c, 0x038c038b}, 910 + {0x0000b040, 0x0390038d}, 911 + {0x0000b044, 0x03920391}, 912 + {0x0000b048, 0x03940393}, 913 + {0x0000b04c, 0x03960395}, 914 + {0x0000b050, 0x00000000}, 915 + {0x0000b054, 0x00000000}, 916 + {0x0000b058, 0x00000000}, 917 + {0x0000b05c, 0x00000000}, 918 + {0x0000b060, 0x00000000}, 919 + {0x0000b064, 0x00000000}, 920 + {0x0000b068, 0x00000000}, 921 + {0x0000b06c, 0x00000000}, 922 + {0x0000b070, 0x00000000}, 923 + {0x0000b074, 0x00000000}, 924 + {0x0000b078, 0x00000000}, 925 + {0x0000b07c, 0x00000000}, 926 + {0x0000b080, 0x23232323}, 927 + {0x0000b084, 0x21232323}, 928 + {0x0000b088, 0x19191c1e}, 929 + {0x0000b08c, 0x12141417}, 930 + {0x0000b090, 0x07070e0e}, 931 + {0x0000b094, 0x03030305}, 932 + {0x0000b098, 0x00000003}, 933 + {0x0000b09c, 0x00000000}, 934 + {0x0000b0a0, 0x00000000}, 935 + {0x0000b0a4, 0x00000000}, 936 + {0x0000b0a8, 0x00000000}, 937 + {0x0000b0ac, 0x00000000}, 938 + {0x0000b0b0, 0x00000000}, 939 + {0x0000b0b4, 0x00000000}, 940 + {0x0000b0b8, 0x00000000}, 941 + {0x0000b0bc, 0x00000000}, 942 + {0x0000b0c0, 0x003f0020}, 943 + {0x0000b0c4, 0x00400041}, 944 + {0x0000b0c8, 0x0140005f}, 945 + {0x0000b0cc, 0x0160015f}, 946 + {0x0000b0d0, 0x017e017f}, 947 + {0x0000b0d4, 0x02410242}, 948 + {0x0000b0d8, 0x025f0240}, 949 + {0x0000b0dc, 0x027f0260}, 950 + {0x0000b0e0, 0x0341027e}, 951 + {0x0000b0e4, 0x035f0340}, 952 + {0x0000b0e8, 0x037f0360}, 953 + {0x0000b0ec, 0x04400441}, 954 + {0x0000b0f0, 0x0460045f}, 955 + {0x0000b0f4, 0x0541047f}, 956 + {0x0000b0f8, 0x055f0540}, 957 + {0x0000b0fc, 0x057f0560}, 958 + {0x0000b100, 0x06400641}, 959 + {0x0000b104, 0x0660065f}, 960 + {0x0000b108, 0x067e067f}, 961 + {0x0000b10c, 0x07410742}, 962 + {0x0000b110, 0x075f0740}, 963 + {0x0000b114, 0x077f0760}, 964 + {0x0000b118, 0x07800781}, 965 + {0x0000b11c, 0x07a0079f}, 966 + {0x0000b120, 0x07c107bf}, 967 + {0x0000b124, 0x000007c0}, 968 + {0x0000b128, 0x00000000}, 969 + {0x0000b12c, 0x00000000}, 970 + {0x0000b130, 0x00000000}, 971 + {0x0000b134, 0x00000000}, 972 + {0x0000b138, 0x00000000}, 973 + {0x0000b13c, 0x00000000}, 974 + {0x0000b140, 0x003f0020}, 975 + {0x0000b144, 0x00400041}, 976 + {0x0000b148, 0x0140005f}, 977 + {0x0000b14c, 0x0160015f}, 978 + {0x0000b150, 0x017e017f}, 979 + {0x0000b154, 0x02410242}, 980 + {0x0000b158, 0x025f0240}, 981 + {0x0000b15c, 0x027f0260}, 982 + {0x0000b160, 0x0341027e}, 983 + {0x0000b164, 0x035f0340}, 984 + {0x0000b168, 0x037f0360}, 985 + {0x0000b16c, 0x04400441}, 986 + {0x0000b170, 0x0460045f}, 987 + {0x0000b174, 0x0541047f}, 988 + {0x0000b178, 0x055f0540}, 989 + {0x0000b17c, 0x057f0560}, 990 + {0x0000b180, 0x06400641}, 991 + {0x0000b184, 0x0660065f}, 992 + {0x0000b188, 0x067e067f}, 993 + {0x0000b18c, 0x07410742}, 994 + {0x0000b190, 0x075f0740}, 995 + {0x0000b194, 0x077f0760}, 996 + {0x0000b198, 0x07800781}, 997 + {0x0000b19c, 0x07a0079f}, 998 + {0x0000b1a0, 0x07c107bf}, 999 + {0x0000b1a4, 0x000007c0}, 1000 + {0x0000b1a8, 0x00000000}, 1001 + {0x0000b1ac, 0x00000000}, 1002 + {0x0000b1b0, 0x00000000}, 1003 + {0x0000b1b4, 0x00000000}, 1004 + {0x0000b1b8, 0x00000000}, 1005 + {0x0000b1bc, 0x00000000}, 1006 + {0x0000b1c0, 0x00000000}, 1007 + {0x0000b1c4, 0x00000000}, 1008 + {0x0000b1c8, 0x00000000}, 1009 + {0x0000b1cc, 0x00000000}, 1010 + {0x0000b1d0, 0x00000000}, 1011 + {0x0000b1d4, 0x00000000}, 1012 + {0x0000b1d8, 0x00000000}, 1013 + {0x0000b1dc, 0x00000000}, 1014 + {0x0000b1e0, 0x00000000}, 1015 + {0x0000b1e4, 0x00000000}, 1016 + {0x0000b1e8, 0x00000000}, 1017 + {0x0000b1ec, 0x00000000}, 1018 + {0x0000b1f0, 0x00000396}, 1019 + {0x0000b1f4, 0x00000396}, 1020 + {0x0000b1f8, 0x00000396}, 1021 + {0x0000b1fc, 0x00000196}, 1027 1022 }; 1028 1023 1029 1024 static const u32 ar9580_1p0_baseband_postamble[][5] = { ··· 1169 956 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 1170 957 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 1171 958 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 1172 - {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, 959 + {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982}, 1173 960 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 1174 961 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1175 962 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+53 -3
drivers/net/wireless/ath/ath9k/ath9k.h
··· 459 459 int ath_update_survey_stats(struct ath_softc *sc); 460 460 void ath_update_survey_nf(struct ath_softc *sc, int channel); 461 461 void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); 462 + void ath_ps_full_sleep(unsigned long data); 462 463 463 464 /**********/ 464 465 /* BTCOEX */ ··· 571 570 } 572 571 #endif 573 572 573 + /************************/ 574 + /* Wake on Wireless LAN */ 575 + /************************/ 576 + 577 + #ifdef CONFIG_ATH9K_WOW 578 + void ath9k_init_wow(struct ieee80211_hw *hw); 579 + int ath9k_suspend(struct ieee80211_hw *hw, 580 + struct cfg80211_wowlan *wowlan); 581 + int ath9k_resume(struct ieee80211_hw *hw); 582 + void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled); 583 + #else 584 + static inline void ath9k_init_wow(struct ieee80211_hw *hw) 585 + { 586 + } 587 + static inline int ath9k_suspend(struct ieee80211_hw *hw, 588 + struct cfg80211_wowlan *wowlan) 589 + { 590 + return 0; 591 + } 592 + static inline int ath9k_resume(struct ieee80211_hw *hw) 593 + { 594 + return 0; 595 + } 596 + static inline void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) 597 + { 598 + } 599 + #endif /* CONFIG_ATH9K_WOW */ 600 + 574 601 /*******************************/ 575 602 /* Antenna diversity/combining */ 576 603 /*******************************/ ··· 671 642 #define ATH9K_PCI_AR9565_1ANT 0x0080 672 643 #define ATH9K_PCI_AR9565_2ANT 0x0100 673 644 #define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200 645 + #define ATH9K_PCI_KILLER 0x0400 674 646 675 647 /* 676 648 * Default cache line size, in bytes. ··· 754 724 struct work_struct hw_check_work; 755 725 struct work_struct hw_reset_work; 756 726 struct completion paprd_complete; 727 + wait_queue_head_t tx_wait; 757 728 758 729 unsigned int hw_busy_count; 759 730 unsigned long sc_flags; ··· 791 760 struct delayed_work tx_complete_work; 792 761 struct delayed_work hw_pll_work; 793 762 struct timer_list rx_poll_timer; 763 + struct timer_list sleep_timer; 794 764 795 765 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 796 766 struct ath_btcoex btcoex; ··· 816 784 bool tx99_state; 817 785 s16 tx99_power; 818 786 819 - #ifdef CONFIG_PM_SLEEP 787 + #ifdef CONFIG_ATH9K_WOW 820 788 atomic_t wow_got_bmiss_intr; 821 789 atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */ 822 790 u32 wow_intr_before_sleep; ··· 979 947 u8 data[SPECTRAL_HT20_40_NUM_BINS]; 980 948 } __packed; 981 949 982 - int ath9k_tx99_init(struct ath_softc *sc); 983 - void ath9k_tx99_deinit(struct ath_softc *sc); 950 + /********/ 951 + /* TX99 */ 952 + /********/ 953 + 954 + #ifdef CONFIG_ATH9K_TX99 955 + void ath9k_tx99_init_debug(struct ath_softc *sc); 984 956 int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, 985 957 struct ath_tx_control *txctl); 958 + #else 959 + static inline void ath9k_tx99_init_debug(struct ath_softc *sc) 960 + { 961 + } 962 + static inline int ath9k_tx99_send(struct ath_softc *sc, 963 + struct sk_buff *skb, 964 + struct ath_tx_control *txctl) 965 + { 966 + return 0; 967 + } 968 + #endif /* CONFIG_ATH9K_TX99 */ 986 969 987 970 void ath9k_tasklet(unsigned long data); 988 971 int ath_cabq_update(struct ath_softc *); ··· 1014 967 1015 968 u8 ath9k_parse_mpdudensity(u8 mpdudensity); 1016 969 irqreturn_t ath_isr(int irq, void *dev); 970 + int ath_reset(struct ath_softc *sc); 971 + void ath_cancel_work(struct ath_softc *sc); 972 + void ath_restart_work(struct ath_softc *sc); 1017 973 int ath9k_init_device(u16 devid, struct ath_softc *sc, 1018 974 const struct ath_bus_ops *bus_ops); 1019 975 void ath9k_deinit_device(struct ath_softc *sc);
+1 -114
drivers/net/wireless/ath/ath9k/debug.c
··· 1778 1778 } 1779 1779 } 1780 1780 1781 - static ssize_t read_file_tx99(struct file *file, char __user *user_buf, 1782 - size_t count, loff_t *ppos) 1783 - { 1784 - struct ath_softc *sc = file->private_data; 1785 - char buf[3]; 1786 - unsigned int len; 1787 - 1788 - len = sprintf(buf, "%d\n", sc->tx99_state); 1789 - return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1790 - } 1791 - 1792 - static ssize_t write_file_tx99(struct file *file, const char __user *user_buf, 1793 - size_t count, loff_t *ppos) 1794 - { 1795 - struct ath_softc *sc = file->private_data; 1796 - struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1797 - char buf[32]; 1798 - bool start; 1799 - ssize_t len; 1800 - int r; 1801 - 1802 - if (sc->nvifs > 1) 1803 - return -EOPNOTSUPP; 1804 - 1805 - len = min(count, sizeof(buf) - 1); 1806 - if (copy_from_user(buf, user_buf, len)) 1807 - return -EFAULT; 1808 - 1809 - if (strtobool(buf, &start)) 1810 - return -EINVAL; 1811 - 1812 - if (start == sc->tx99_state) { 1813 - if (!start) 1814 - return count; 1815 - ath_dbg(common, XMIT, "Resetting TX99\n"); 1816 - ath9k_tx99_deinit(sc); 1817 - } 1818 - 1819 - if (!start) { 1820 - ath9k_tx99_deinit(sc); 1821 - return count; 1822 - } 1823 - 1824 - r = ath9k_tx99_init(sc); 1825 - if (r) 1826 - return r; 1827 - 1828 - return count; 1829 - } 1830 - 1831 - static const struct file_operations fops_tx99 = { 1832 - .read = read_file_tx99, 1833 - .write = write_file_tx99, 1834 - .open = simple_open, 1835 - .owner = THIS_MODULE, 1836 - .llseek = default_llseek, 1837 - }; 1838 - 1839 - static ssize_t read_file_tx99_power(struct file *file, 1840 - char __user *user_buf, 1841 - size_t count, loff_t *ppos) 1842 - { 1843 - struct ath_softc *sc = file->private_data; 1844 - char buf[32]; 1845 - unsigned int len; 1846 - 1847 - len = sprintf(buf, "%d (%d dBm)\n", 1848 - sc->tx99_power, 1849 - sc->tx99_power / 2); 1850 - 1851 - return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1852 - } 1853 - 1854 - static ssize_t write_file_tx99_power(struct file *file, 1855 - const char __user *user_buf, 1856 - size_t count, loff_t *ppos) 1857 - { 1858 - struct ath_softc *sc = file->private_data; 1859 - int r; 1860 - u8 tx_power; 1861 - 1862 - r = kstrtou8_from_user(user_buf, count, 0, &tx_power); 1863 - if (r) 1864 - return r; 1865 - 1866 - if (tx_power > MAX_RATE_POWER) 1867 - return -EINVAL; 1868 - 1869 - sc->tx99_power = tx_power; 1870 - 1871 - ath9k_ps_wakeup(sc); 1872 - ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power); 1873 - ath9k_ps_restore(sc); 1874 - 1875 - return count; 1876 - } 1877 - 1878 - static const struct file_operations fops_tx99_power = { 1879 - .read = read_file_tx99_power, 1880 - .write = write_file_tx99_power, 1881 - .open = simple_open, 1882 - .owner = THIS_MODULE, 1883 - .llseek = default_llseek, 1884 - }; 1885 - 1886 1781 int ath9k_init_debug(struct ath_hw *ah) 1887 1782 { 1888 1783 struct ath_common *common = ath9k_hw_common(ah); ··· 1794 1899 #endif 1795 1900 1796 1901 ath9k_dfs_init_debug(sc); 1902 + ath9k_tx99_init_debug(sc); 1797 1903 1798 1904 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, 1799 1905 &fops_dma); ··· 1870 1974 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, 1871 1975 &fops_btcoex); 1872 1976 #endif 1873 - if (config_enabled(CONFIG_ATH9K_TX99) && 1874 - AR_SREV_9300_20_OR_LATER(ah)) { 1875 - debugfs_create_file("tx99", S_IRUSR | S_IWUSR, 1876 - sc->debug.debugfs_phy, sc, 1877 - &fops_tx99); 1878 - debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR, 1879 - sc->debug.debugfs_phy, sc, 1880 - &fops_tx99_power); 1881 - } 1882 1977 1883 1978 return 0; 1884 1979 }
+14 -10
drivers/net/wireless/ath/ath9k/hw.c
··· 17 17 #include <linux/io.h> 18 18 #include <linux/slab.h> 19 19 #include <linux/module.h> 20 + #include <linux/time.h> 20 21 #include <asm/unaligned.h> 21 22 22 23 #include "hw.h" ··· 454 453 } 455 454 456 455 ah->config.rx_intr_mitigation = true; 457 - ah->config.pcieSerDesWrite = true; 458 456 459 457 /* 460 458 * We need this for PCI devices only (Cardbus, PCI, miniPCI) ··· 1501 1501 int r; 1502 1502 1503 1503 if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) { 1504 - band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan); 1505 - mode_diff = (chan->channelFlags != ah->curchan->channelFlags); 1504 + u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags; 1505 + band_switch = !!(flags_diff & CHANNEL_5GHZ); 1506 + mode_diff = !!(flags_diff & ~CHANNEL_HT); 1506 1507 } 1507 1508 1508 1509 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { ··· 1815 1814 * If cross-band fcc is not supoprted, bail out if channelFlags differ. 1816 1815 */ 1817 1816 if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) && 1818 - chan->channelFlags != ah->curchan->channelFlags) 1817 + ((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT)) 1819 1818 goto fail; 1820 1819 1821 1820 if (!ath9k_hw_check_alive(ah)) ··· 1856 1855 struct ath9k_hw_cal_data *caldata, bool fastcc) 1857 1856 { 1858 1857 struct ath_common *common = ath9k_hw_common(ah); 1858 + struct timespec ts; 1859 1859 u32 saveLedState; 1860 1860 u32 saveDefAntenna; 1861 1861 u32 macStaId1; 1862 1862 u64 tsf = 0; 1863 + s64 usec = 0; 1863 1864 int r; 1864 1865 bool start_mci_reset = false; 1865 1866 bool save_fullsleep = ah->chip_fullsleep; ··· 1904 1901 1905 1902 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 1906 1903 1907 - /* For chips on which RTC reset is done, save TSF before it gets cleared */ 1908 - if (AR_SREV_9100(ah) || 1909 - (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) 1910 - tsf = ath9k_hw_gettsf64(ah); 1904 + /* Save TSF before chip reset, a cold reset clears it */ 1905 + tsf = ath9k_hw_gettsf64(ah); 1906 + getrawmonotonic(&ts); 1907 + usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000; 1911 1908 1912 1909 saveLedState = REG_READ(ah, AR_CFG_LED) & 1913 1910 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | ··· 1940 1937 } 1941 1938 1942 1939 /* Restore TSF */ 1943 - if (tsf) 1944 - ath9k_hw_settsf64(ah, tsf); 1940 + getrawmonotonic(&ts); 1941 + usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec; 1942 + ath9k_hw_settsf64(ah, tsf + usec); 1945 1943 1946 1944 if (AR_SREV_9280_20_OR_LATER(ah)) 1947 1945 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
+2 -3
drivers/net/wireless/ath/ath9k/hw.h
··· 283 283 int additional_swba_backoff; 284 284 int ack_6mb; 285 285 u32 cwm_ignore_extcca; 286 - bool pcieSerDesWrite; 287 286 u8 pcie_clock_req; 288 287 u32 pcie_waen; 289 288 u8 analog_shiftreg; ··· 920 921 /* Enterprise mode cap */ 921 922 u32 ent_mode; 922 923 923 - #ifdef CONFIG_PM_SLEEP 924 + #ifdef CONFIG_ATH9K_WOW 924 925 u32 wow_event_mask; 925 926 #endif 926 927 bool is_clk_25mhz; ··· 1126 1127 #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ 1127 1128 1128 1129 1129 - #ifdef CONFIG_PM_SLEEP 1130 + #ifdef CONFIG_ATH9K_WOW 1130 1131 const char *ath9k_hw_wow_event_to_string(u32 wow_event); 1131 1132 void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 1132 1133 u8 *user_mask, int pattern_count,
+7 -19
drivers/net/wireless/ath/ath9k/init.c
··· 589 589 if (sc->driver_data & ATH9K_PCI_AR9565_2ANT) 590 590 ath_info(common, "WB335 2-ANT card detected\n"); 591 591 592 + if (sc->driver_data & ATH9K_PCI_KILLER) 593 + ath_info(common, "Killer Wireless card detected\n"); 594 + 592 595 /* 593 596 * Some WB335 cards do not support antenna diversity. Since 594 597 * we use a hardcoded value for AR9565 instead of using the ··· 691 688 common = ath9k_hw_common(ah); 692 689 sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); 693 690 sc->tx99_power = MAX_RATE_POWER + 1; 691 + init_waitqueue_head(&sc->tx_wait); 694 692 695 693 if (!pdata) { 696 694 ah->ah_flags |= AH_USE_EEPROM; ··· 739 735 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, 740 736 (unsigned long)sc); 741 737 738 + setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); 742 739 INIT_WORK(&sc->hw_reset_work, ath_reset_work); 743 740 INIT_WORK(&sc->hw_check_work, ath_hw_check); 744 741 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); ··· 878 873 } 879 874 }; 880 875 881 - #ifdef CONFIG_PM 882 - static const struct wiphy_wowlan_support ath9k_wowlan_support = { 883 - .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, 884 - .n_patterns = MAX_NUM_USER_PATTERN, 885 - .pattern_min_len = 1, 886 - .pattern_max_len = MAX_PATTERN_SIZE, 887 - }; 888 - #endif 889 - 890 876 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) 891 877 { 892 878 struct ath_hw *ah = sc->sc_ah; ··· 927 931 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; 928 932 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; 929 933 930 - #ifdef CONFIG_PM_SLEEP 931 - if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 932 - (sc->driver_data & ATH9K_PCI_WOW) && 933 - device_can_wakeup(sc->dev)) 934 - hw->wiphy->wowlan = &ath9k_wowlan_support; 935 - 936 - atomic_set(&sc->wow_sleep_proc_intr, -1); 937 - atomic_set(&sc->wow_got_bmiss_intr, -1); 938 - #endif 939 - 940 934 hw->queues = 4; 941 935 hw->max_rates = 4; 942 936 hw->channel_change_time = 5000; ··· 952 966 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 953 967 &sc->sbands[IEEE80211_BAND_5GHZ]; 954 968 969 + ath9k_init_wow(hw); 955 970 ath9k_reload_chainmask_settings(sc); 956 971 957 972 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); ··· 1051 1064 if (ATH_TXQ_SETUP(sc, i)) 1052 1065 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 1053 1066 1067 + del_timer_sync(&sc->sleep_timer); 1054 1068 ath9k_hw_deinit(sc->sc_ah); 1055 1069 if (sc->dfs_detector != NULL) 1056 1070 sc->dfs_detector->exit(sc->dfs_detector);
+55 -486
drivers/net/wireless/ath/ath9k/main.c
··· 82 82 return ret; 83 83 } 84 84 85 + void ath_ps_full_sleep(unsigned long data) 86 + { 87 + struct ath_softc *sc = (struct ath_softc *) data; 88 + struct ath_common *common = ath9k_hw_common(sc->sc_ah); 89 + bool reset; 90 + 91 + spin_lock(&common->cc_lock); 92 + ath_hw_cycle_counters_update(common); 93 + spin_unlock(&common->cc_lock); 94 + 95 + ath9k_hw_setrxabort(sc->sc_ah, 1); 96 + ath9k_hw_stopdmarecv(sc->sc_ah, &reset); 97 + 98 + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); 99 + } 100 + 85 101 void ath9k_ps_wakeup(struct ath_softc *sc) 86 102 { 87 103 struct ath_common *common = ath9k_hw_common(sc->sc_ah); ··· 108 92 if (++sc->ps_usecount != 1) 109 93 goto unlock; 110 94 95 + del_timer_sync(&sc->sleep_timer); 111 96 power_mode = sc->sc_ah->power_mode; 112 97 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 113 98 ··· 134 117 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 135 118 enum ath9k_power_mode mode; 136 119 unsigned long flags; 137 - bool reset; 138 120 139 121 spin_lock_irqsave(&sc->sc_pm_lock, flags); 140 122 if (--sc->ps_usecount != 0) 141 123 goto unlock; 142 124 143 125 if (sc->ps_idle) { 144 - ath9k_hw_setrxabort(sc->sc_ah, 1); 145 - ath9k_hw_stopdmarecv(sc->sc_ah, &reset); 146 - mode = ATH9K_PM_FULL_SLEEP; 147 - } else if (sc->ps_enabled && 126 + mod_timer(&sc->sleep_timer, jiffies + HZ / 10); 127 + goto unlock; 128 + } 129 + 130 + if (sc->ps_enabled && 148 131 !(sc->ps_flags & (PS_WAIT_FOR_BEACON | 149 132 PS_WAIT_FOR_CAB | 150 133 PS_WAIT_FOR_PSPOLL_DATA | ··· 180 163 #endif 181 164 } 182 165 183 - static void ath_cancel_work(struct ath_softc *sc) 166 + void ath_cancel_work(struct ath_softc *sc) 184 167 { 185 168 __ath_cancel_work(sc); 186 169 cancel_work_sync(&sc->hw_reset_work); 187 170 } 188 171 189 - static void ath_restart_work(struct ath_softc *sc) 172 + void ath_restart_work(struct ath_softc *sc) 190 173 { 191 174 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 192 175 ··· 504 487 ath_tx_edma_tasklet(sc); 505 488 else 506 489 ath_tx_tasklet(sc); 490 + 491 + wake_up(&sc->tx_wait); 507 492 } 508 493 509 494 ath9k_btcoex_handle_interrupt(sc, status); ··· 598 579 599 580 goto chip_reset; 600 581 } 601 - #ifdef CONFIG_PM_SLEEP 582 + 583 + #ifdef CONFIG_ATH9K_WOW 602 584 if (status & ATH9K_INT_BMISS) { 603 585 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { 604 586 ath_dbg(common, ANY, "during WoW we got a BMISS\n"); ··· 608 588 } 609 589 } 610 590 #endif 591 + 592 + 611 593 if (status & ATH9K_INT_SWBA) 612 594 tasklet_schedule(&sc->bcon_tasklet); 613 595 ··· 649 627 #undef SCHED_INTR 650 628 } 651 629 652 - static int ath_reset(struct ath_softc *sc) 630 + int ath_reset(struct ath_softc *sc) 653 631 { 654 632 int r; 655 633 ··· 1839 1817 mutex_unlock(&sc->mutex); 1840 1818 } 1841 1819 1820 + static bool ath9k_has_tx_pending(struct ath_softc *sc) 1821 + { 1822 + int i, npend; 1823 + 1824 + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 1825 + if (!ATH_TXQ_SETUP(sc, i)) 1826 + continue; 1827 + 1828 + if (!sc->tx.txq[i].axq_depth) 1829 + continue; 1830 + 1831 + npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]); 1832 + if (npend) 1833 + break; 1834 + } 1835 + 1836 + return !!npend; 1837 + } 1838 + 1842 1839 static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1843 1840 { 1844 1841 struct ath_softc *sc = hw->priv; 1845 1842 struct ath_hw *ah = sc->sc_ah; 1846 1843 struct ath_common *common = ath9k_hw_common(ah); 1847 - int timeout = 200; /* ms */ 1848 - int i, j; 1844 + int timeout = HZ / 5; /* 200 ms */ 1849 1845 bool drain_txq; 1850 1846 1851 1847 mutex_lock(&sc->mutex); ··· 1881 1841 return; 1882 1842 } 1883 1843 1884 - for (j = 0; j < timeout; j++) { 1885 - bool npend = false; 1886 - 1887 - if (j) 1888 - usleep_range(1000, 2000); 1889 - 1890 - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 1891 - if (!ATH_TXQ_SETUP(sc, i)) 1892 - continue; 1893 - 1894 - npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]); 1895 - 1896 - if (npend) 1897 - break; 1898 - } 1899 - 1900 - if (!npend) 1901 - break; 1902 - } 1844 + if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc), 1845 + timeout) > 0) 1846 + drop = false; 1903 1847 1904 1848 if (drop) { 1905 1849 ath9k_ps_wakeup(sc); ··· 2045 2021 return 0; 2046 2022 } 2047 2023 2048 - #ifdef CONFIG_PM_SLEEP 2049 - 2050 - static void ath9k_wow_map_triggers(struct ath_softc *sc, 2051 - struct cfg80211_wowlan *wowlan, 2052 - u32 *wow_triggers) 2053 - { 2054 - if (wowlan->disconnect) 2055 - *wow_triggers |= AH_WOW_LINK_CHANGE | 2056 - AH_WOW_BEACON_MISS; 2057 - if (wowlan->magic_pkt) 2058 - *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN; 2059 - 2060 - if (wowlan->n_patterns) 2061 - *wow_triggers |= AH_WOW_USER_PATTERN_EN; 2062 - 2063 - sc->wow_enabled = *wow_triggers; 2064 - 2065 - } 2066 - 2067 - static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc) 2068 - { 2069 - struct ath_hw *ah = sc->sc_ah; 2070 - struct ath_common *common = ath9k_hw_common(ah); 2071 - int pattern_count = 0; 2072 - int i, byte_cnt; 2073 - u8 dis_deauth_pattern[MAX_PATTERN_SIZE]; 2074 - u8 dis_deauth_mask[MAX_PATTERN_SIZE]; 2075 - 2076 - memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE); 2077 - memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE); 2078 - 2079 - /* 2080 - * Create Dissassociate / Deauthenticate packet filter 2081 - * 2082 - * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes 2083 - * +--------------+----------+---------+--------+--------+---- 2084 - * + Frame Control+ Duration + DA + SA + BSSID + 2085 - * +--------------+----------+---------+--------+--------+---- 2086 - * 2087 - * The above is the management frame format for disassociate/ 2088 - * deauthenticate pattern, from this we need to match the first byte 2089 - * of 'Frame Control' and DA, SA, and BSSID fields 2090 - * (skipping 2nd byte of FC and Duration feild. 2091 - * 2092 - * Disassociate pattern 2093 - * -------------------- 2094 - * Frame control = 00 00 1010 2095 - * DA, SA, BSSID = x:x:x:x:x:x 2096 - * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x 2097 - * | x:x:x:x:x:x -- 22 bytes 2098 - * 2099 - * Deauthenticate pattern 2100 - * ---------------------- 2101 - * Frame control = 00 00 1100 2102 - * DA, SA, BSSID = x:x:x:x:x:x 2103 - * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x 2104 - * | x:x:x:x:x:x -- 22 bytes 2105 - */ 2106 - 2107 - /* Create Disassociate Pattern first */ 2108 - 2109 - byte_cnt = 0; 2110 - 2111 - /* Fill out the mask with all FF's */ 2112 - 2113 - for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++) 2114 - dis_deauth_mask[i] = 0xff; 2115 - 2116 - /* copy the first byte of frame control field */ 2117 - dis_deauth_pattern[byte_cnt] = 0xa0; 2118 - byte_cnt++; 2119 - 2120 - /* skip 2nd byte of frame control and Duration field */ 2121 - byte_cnt += 3; 2122 - 2123 - /* 2124 - * need not match the destination mac address, it can be a broadcast 2125 - * mac address or an unicast to this station 2126 - */ 2127 - byte_cnt += 6; 2128 - 2129 - /* copy the source mac address */ 2130 - memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN); 2131 - 2132 - byte_cnt += 6; 2133 - 2134 - /* copy the bssid, its same as the source mac address */ 2135 - 2136 - memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN); 2137 - 2138 - /* Create Disassociate pattern mask */ 2139 - 2140 - dis_deauth_mask[0] = 0xfe; 2141 - dis_deauth_mask[1] = 0x03; 2142 - dis_deauth_mask[2] = 0xc0; 2143 - 2144 - ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n"); 2145 - 2146 - ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, 2147 - pattern_count, byte_cnt); 2148 - 2149 - pattern_count++; 2150 - /* 2151 - * for de-authenticate pattern, only the first byte of the frame 2152 - * control field gets changed from 0xA0 to 0xC0 2153 - */ 2154 - dis_deauth_pattern[0] = 0xC0; 2155 - 2156 - ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, 2157 - pattern_count, byte_cnt); 2158 - 2159 - } 2160 - 2161 - static void ath9k_wow_add_pattern(struct ath_softc *sc, 2162 - struct cfg80211_wowlan *wowlan) 2163 - { 2164 - struct ath_hw *ah = sc->sc_ah; 2165 - struct ath9k_wow_pattern *wow_pattern = NULL; 2166 - struct cfg80211_pkt_pattern *patterns = wowlan->patterns; 2167 - int mask_len; 2168 - s8 i = 0; 2169 - 2170 - if (!wowlan->n_patterns) 2171 - return; 2172 - 2173 - /* 2174 - * Add the new user configured patterns 2175 - */ 2176 - for (i = 0; i < wowlan->n_patterns; i++) { 2177 - 2178 - wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL); 2179 - 2180 - if (!wow_pattern) 2181 - return; 2182 - 2183 - /* 2184 - * TODO: convert the generic user space pattern to 2185 - * appropriate chip specific/802.11 pattern. 2186 - */ 2187 - 2188 - mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); 2189 - memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE); 2190 - memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE); 2191 - memcpy(wow_pattern->pattern_bytes, patterns[i].pattern, 2192 - patterns[i].pattern_len); 2193 - memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len); 2194 - wow_pattern->pattern_len = patterns[i].pattern_len; 2195 - 2196 - /* 2197 - * just need to take care of deauth and disssoc pattern, 2198 - * make sure we don't overwrite them. 2199 - */ 2200 - 2201 - ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes, 2202 - wow_pattern->mask_bytes, 2203 - i + 2, 2204 - wow_pattern->pattern_len); 2205 - kfree(wow_pattern); 2206 - 2207 - } 2208 - 2209 - } 2210 - 2211 - static int ath9k_suspend(struct ieee80211_hw *hw, 2212 - struct cfg80211_wowlan *wowlan) 2213 - { 2214 - struct ath_softc *sc = hw->priv; 2215 - struct ath_hw *ah = sc->sc_ah; 2216 - struct ath_common *common = ath9k_hw_common(ah); 2217 - u32 wow_triggers_enabled = 0; 2218 - int ret = 0; 2219 - 2220 - mutex_lock(&sc->mutex); 2221 - 2222 - ath_cancel_work(sc); 2223 - ath_stop_ani(sc); 2224 - del_timer_sync(&sc->rx_poll_timer); 2225 - 2226 - if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { 2227 - ath_dbg(common, ANY, "Device not present\n"); 2228 - ret = -EINVAL; 2229 - goto fail_wow; 2230 - } 2231 - 2232 - if (WARN_ON(!wowlan)) { 2233 - ath_dbg(common, WOW, "None of the WoW triggers enabled\n"); 2234 - ret = -EINVAL; 2235 - goto fail_wow; 2236 - } 2237 - 2238 - if (!device_can_wakeup(sc->dev)) { 2239 - ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n"); 2240 - ret = 1; 2241 - goto fail_wow; 2242 - } 2243 - 2244 - /* 2245 - * none of the sta vifs are associated 2246 - * and we are not currently handling multivif 2247 - * cases, for instance we have to seperately 2248 - * configure 'keep alive frame' for each 2249 - * STA. 2250 - */ 2251 - 2252 - if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { 2253 - ath_dbg(common, WOW, "None of the STA vifs are associated\n"); 2254 - ret = 1; 2255 - goto fail_wow; 2256 - } 2257 - 2258 - if (sc->nvifs > 1) { 2259 - ath_dbg(common, WOW, "WoW for multivif is not yet supported\n"); 2260 - ret = 1; 2261 - goto fail_wow; 2262 - } 2263 - 2264 - ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled); 2265 - 2266 - ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n", 2267 - wow_triggers_enabled); 2268 - 2269 - ath9k_ps_wakeup(sc); 2270 - 2271 - ath9k_stop_btcoex(sc); 2272 - 2273 - /* 2274 - * Enable wake up on recieving disassoc/deauth 2275 - * frame by default. 2276 - */ 2277 - ath9k_wow_add_disassoc_deauth_pattern(sc); 2278 - 2279 - if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN) 2280 - ath9k_wow_add_pattern(sc, wowlan); 2281 - 2282 - spin_lock_bh(&sc->sc_pcu_lock); 2283 - /* 2284 - * To avoid false wake, we enable beacon miss interrupt only 2285 - * when we go to sleep. We save the current interrupt mask 2286 - * so we can restore it after the system wakes up 2287 - */ 2288 - sc->wow_intr_before_sleep = ah->imask; 2289 - ah->imask &= ~ATH9K_INT_GLOBAL; 2290 - ath9k_hw_disable_interrupts(ah); 2291 - ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL; 2292 - ath9k_hw_set_interrupts(ah); 2293 - ath9k_hw_enable_interrupts(ah); 2294 - 2295 - spin_unlock_bh(&sc->sc_pcu_lock); 2296 - 2297 - /* 2298 - * we can now sync irq and kill any running tasklets, since we already 2299 - * disabled interrupts and not holding a spin lock 2300 - */ 2301 - synchronize_irq(sc->irq); 2302 - tasklet_kill(&sc->intr_tq); 2303 - 2304 - ath9k_hw_wow_enable(ah, wow_triggers_enabled); 2305 - 2306 - ath9k_ps_restore(sc); 2307 - ath_dbg(common, ANY, "WoW enabled in ath9k\n"); 2308 - atomic_inc(&sc->wow_sleep_proc_intr); 2309 - 2310 - fail_wow: 2311 - mutex_unlock(&sc->mutex); 2312 - return ret; 2313 - } 2314 - 2315 - static int ath9k_resume(struct ieee80211_hw *hw) 2316 - { 2317 - struct ath_softc *sc = hw->priv; 2318 - struct ath_hw *ah = sc->sc_ah; 2319 - struct ath_common *common = ath9k_hw_common(ah); 2320 - u32 wow_status; 2321 - 2322 - mutex_lock(&sc->mutex); 2323 - 2324 - ath9k_ps_wakeup(sc); 2325 - 2326 - spin_lock_bh(&sc->sc_pcu_lock); 2327 - 2328 - ath9k_hw_disable_interrupts(ah); 2329 - ah->imask = sc->wow_intr_before_sleep; 2330 - ath9k_hw_set_interrupts(ah); 2331 - ath9k_hw_enable_interrupts(ah); 2332 - 2333 - spin_unlock_bh(&sc->sc_pcu_lock); 2334 - 2335 - wow_status = ath9k_hw_wow_wakeup(ah); 2336 - 2337 - if (atomic_read(&sc->wow_got_bmiss_intr) == 0) { 2338 - /* 2339 - * some devices may not pick beacon miss 2340 - * as the reason they woke up so we add 2341 - * that here for that shortcoming. 2342 - */ 2343 - wow_status |= AH_WOW_BEACON_MISS; 2344 - atomic_dec(&sc->wow_got_bmiss_intr); 2345 - ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n"); 2346 - } 2347 - 2348 - atomic_dec(&sc->wow_sleep_proc_intr); 2349 - 2350 - if (wow_status) { 2351 - ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n", 2352 - ath9k_hw_wow_event_to_string(wow_status), wow_status); 2353 - } 2354 - 2355 - ath_restart_work(sc); 2356 - ath9k_start_btcoex(sc); 2357 - 2358 - ath9k_ps_restore(sc); 2359 - mutex_unlock(&sc->mutex); 2360 - 2361 - return 0; 2362 - } 2363 - 2364 - static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) 2365 - { 2366 - struct ath_softc *sc = hw->priv; 2367 - 2368 - mutex_lock(&sc->mutex); 2369 - device_init_wakeup(sc->dev, 1); 2370 - device_set_wakeup_enable(sc->dev, enabled); 2371 - mutex_unlock(&sc->mutex); 2372 - } 2373 - 2374 - #endif 2375 2024 static void ath9k_sw_scan_start(struct ieee80211_hw *hw) 2376 2025 { 2377 2026 struct ath_softc *sc = hw->priv; ··· 2068 2371 return; 2069 2372 2070 2373 sc->csa_vif = vif; 2071 - } 2072 - 2073 - static void ath9k_tx99_stop(struct ath_softc *sc) 2074 - { 2075 - struct ath_hw *ah = sc->sc_ah; 2076 - struct ath_common *common = ath9k_hw_common(ah); 2077 - 2078 - ath_drain_all_txq(sc); 2079 - ath_startrecv(sc); 2080 - 2081 - ath9k_hw_set_interrupts(ah); 2082 - ath9k_hw_enable_interrupts(ah); 2083 - 2084 - ieee80211_wake_queues(sc->hw); 2085 - 2086 - kfree_skb(sc->tx99_skb); 2087 - sc->tx99_skb = NULL; 2088 - sc->tx99_state = false; 2089 - 2090 - ath9k_hw_tx99_stop(sc->sc_ah); 2091 - ath_dbg(common, XMIT, "TX99 stopped\n"); 2092 - } 2093 - 2094 - static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc) 2095 - { 2096 - static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24, 2097 - 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50, 2098 - 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1, 2099 - 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18, 2100 - 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8, 2101 - 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84, 2102 - 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3, 2103 - 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0}; 2104 - u32 len = 1200; 2105 - struct ieee80211_hw *hw = sc->hw; 2106 - struct ieee80211_hdr *hdr; 2107 - struct ieee80211_tx_info *tx_info; 2108 - struct sk_buff *skb; 2109 - 2110 - skb = alloc_skb(len, GFP_KERNEL); 2111 - if (!skb) 2112 - return NULL; 2113 - 2114 - skb_put(skb, len); 2115 - 2116 - memset(skb->data, 0, len); 2117 - 2118 - hdr = (struct ieee80211_hdr *)skb->data; 2119 - hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA); 2120 - hdr->duration_id = 0; 2121 - 2122 - memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); 2123 - memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); 2124 - memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); 2125 - 2126 - hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); 2127 - 2128 - tx_info = IEEE80211_SKB_CB(skb); 2129 - memset(tx_info, 0, sizeof(*tx_info)); 2130 - tx_info->band = hw->conf.chandef.chan->band; 2131 - tx_info->flags = IEEE80211_TX_CTL_NO_ACK; 2132 - tx_info->control.vif = sc->tx99_vif; 2133 - 2134 - memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data)); 2135 - 2136 - return skb; 2137 - } 2138 - 2139 - void ath9k_tx99_deinit(struct ath_softc *sc) 2140 - { 2141 - ath_reset(sc); 2142 - 2143 - ath9k_ps_wakeup(sc); 2144 - ath9k_tx99_stop(sc); 2145 - ath9k_ps_restore(sc); 2146 - } 2147 - 2148 - int ath9k_tx99_init(struct ath_softc *sc) 2149 - { 2150 - struct ieee80211_hw *hw = sc->hw; 2151 - struct ath_hw *ah = sc->sc_ah; 2152 - struct ath_common *common = ath9k_hw_common(ah); 2153 - struct ath_tx_control txctl; 2154 - int r; 2155 - 2156 - if (sc->sc_flags & SC_OP_INVALID) { 2157 - ath_err(common, 2158 - "driver is in invalid state unable to use TX99"); 2159 - return -EINVAL; 2160 - } 2161 - 2162 - sc->tx99_skb = ath9k_build_tx99_skb(sc); 2163 - if (!sc->tx99_skb) 2164 - return -ENOMEM; 2165 - 2166 - memset(&txctl, 0, sizeof(txctl)); 2167 - txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; 2168 - 2169 - ath_reset(sc); 2170 - 2171 - ath9k_ps_wakeup(sc); 2172 - 2173 - ath9k_hw_disable_interrupts(ah); 2174 - atomic_set(&ah->intr_ref_cnt, -1); 2175 - ath_drain_all_txq(sc); 2176 - ath_stoprecv(sc); 2177 - 2178 - sc->tx99_state = true; 2179 - 2180 - ieee80211_stop_queues(hw); 2181 - 2182 - if (sc->tx99_power == MAX_RATE_POWER + 1) 2183 - sc->tx99_power = MAX_RATE_POWER; 2184 - 2185 - ath9k_hw_tx99_set_txpower(ah, sc->tx99_power); 2186 - r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl); 2187 - if (r) { 2188 - ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n"); 2189 - return r; 2190 - } 2191 - 2192 - ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n", 2193 - sc->tx99_power, 2194 - sc->tx99_power / 2); 2195 - 2196 - /* We leave the harware awake as it will be chugging on */ 2197 - 2198 - return 0; 2199 2374 } 2200 2375 2201 2376 struct ieee80211_ops ath9k_ops = { ··· 2100 2531 .set_antenna = ath9k_set_antenna, 2101 2532 .get_antenna = ath9k_get_antenna, 2102 2533 2103 - #ifdef CONFIG_PM_SLEEP 2534 + #ifdef CONFIG_ATH9K_WOW 2104 2535 .suspend = ath9k_suspend, 2105 2536 .resume = ath9k_resume, 2106 2537 .set_wakeup = ath9k_set_wakeup,
+45
drivers/net/wireless/ath/ath9k/pci.c
··· 87 87 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ 88 88 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 89 89 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 90 + 91 + /* Killer Wireless (3x3) */ 92 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 93 + 0x0030, 94 + 0x1A56, 95 + 0x2000), 96 + .driver_data = ATH9K_PCI_KILLER }, 97 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 98 + 0x0030, 99 + 0x1A56, 100 + 0x2001), 101 + .driver_data = ATH9K_PCI_KILLER }, 102 + 90 103 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ 91 104 92 105 /* PCI-E CUS198 */ ··· 367 354 0x1783), 368 355 .driver_data = ATH9K_PCI_WOW }, 369 356 357 + /* Killer Wireless (2x2) */ 358 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 359 + 0x0030, 360 + 0x1A56, 361 + 0x2003), 362 + .driver_data = ATH9K_PCI_KILLER }, 363 + 370 364 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ 371 365 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ 372 366 ··· 468 448 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 469 449 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 470 450 0x0036, 451 + 0x11AD, /* LITEON */ 452 + 0x0682), 453 + .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 454 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 455 + 0x0036, 471 456 PCI_VENDOR_ID_AZWAVE, 472 457 0x213A), 473 458 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, ··· 483 458 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 484 459 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 485 460 0x0036, 461 + PCI_VENDOR_ID_LENOVO, 462 + 0x4026), 463 + .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 464 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 465 + 0x0036, 486 466 PCI_VENDOR_ID_HP, 487 467 0x18E3), 488 468 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, ··· 495 465 0x0036, 496 466 PCI_VENDOR_ID_HP, 497 467 0x217F), 468 + .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 469 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 470 + 0x0036, 471 + PCI_VENDOR_ID_HP, 472 + 0x2005), 498 473 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 499 474 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 500 475 0x0036, ··· 579 544 0x0036, 580 545 0x185F, /* WNC */ 581 546 0x3027), 547 + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 548 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 549 + 0x0036, 550 + 0x185F, /* WNC */ 551 + 0xA120), 552 + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 553 + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 554 + 0x0036, 555 + PCI_VENDOR_ID_FOXCONN, 556 + 0xE07F), 582 557 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 583 558 584 559 /* PCI-E AR9565 (WB335) */
+11 -1
drivers/net/wireless/ath/ath9k/reg.h
··· 809 809 #define AR_SREV_REVISION_9462_21 3 810 810 #define AR_SREV_VERSION_9565 0x2C0 811 811 #define AR_SREV_REVISION_9565_10 0 812 + #define AR_SREV_REVISION_9565_101 1 813 + #define AR_SREV_REVISION_9565_11 2 812 814 #define AR_SREV_VERSION_9550 0x400 813 815 814 816 #define AR_SREV_5416(_ah) \ ··· 929 927 930 928 #define AR_SREV_9565(_ah) \ 931 929 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) 932 - 933 930 #define AR_SREV_9565_10(_ah) \ 934 931 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ 935 932 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10)) 933 + #define AR_SREV_9565_101(_ah) \ 934 + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ 935 + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101)) 936 + #define AR_SREV_9565_11(_ah) \ 937 + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ 938 + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11)) 939 + #define AR_SREV_9565_11_OR_LATER(_ah) \ 940 + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ 941 + ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11)) 936 942 937 943 #define AR_SREV_9550(_ah) \ 938 944 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550))
+264
drivers/net/wireless/ath/ath9k/tx99.c
··· 1 + /* 2 + * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 + * 4 + * Permission to use, copy, modify, and/or distribute this software for any 5 + * purpose with or without fee is hereby granted, provided that the above 6 + * copyright notice and this permission notice appear in all copies. 7 + * 8 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + 17 + #include "ath9k.h" 18 + 19 + static void ath9k_tx99_stop(struct ath_softc *sc) 20 + { 21 + struct ath_hw *ah = sc->sc_ah; 22 + struct ath_common *common = ath9k_hw_common(ah); 23 + 24 + ath_drain_all_txq(sc); 25 + ath_startrecv(sc); 26 + 27 + ath9k_hw_set_interrupts(ah); 28 + ath9k_hw_enable_interrupts(ah); 29 + 30 + ieee80211_wake_queues(sc->hw); 31 + 32 + kfree_skb(sc->tx99_skb); 33 + sc->tx99_skb = NULL; 34 + sc->tx99_state = false; 35 + 36 + ath9k_hw_tx99_stop(sc->sc_ah); 37 + ath_dbg(common, XMIT, "TX99 stopped\n"); 38 + } 39 + 40 + static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc) 41 + { 42 + static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24, 43 + 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50, 44 + 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1, 45 + 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18, 46 + 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8, 47 + 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84, 48 + 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3, 49 + 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0}; 50 + u32 len = 1200; 51 + struct ieee80211_hw *hw = sc->hw; 52 + struct ieee80211_hdr *hdr; 53 + struct ieee80211_tx_info *tx_info; 54 + struct sk_buff *skb; 55 + 56 + skb = alloc_skb(len, GFP_KERNEL); 57 + if (!skb) 58 + return NULL; 59 + 60 + skb_put(skb, len); 61 + 62 + memset(skb->data, 0, len); 63 + 64 + hdr = (struct ieee80211_hdr *)skb->data; 65 + hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA); 66 + hdr->duration_id = 0; 67 + 68 + memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); 69 + memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); 70 + memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); 71 + 72 + hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); 73 + 74 + tx_info = IEEE80211_SKB_CB(skb); 75 + memset(tx_info, 0, sizeof(*tx_info)); 76 + tx_info->band = hw->conf.chandef.chan->band; 77 + tx_info->flags = IEEE80211_TX_CTL_NO_ACK; 78 + tx_info->control.vif = sc->tx99_vif; 79 + tx_info->control.rates[0].count = 1; 80 + 81 + memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data)); 82 + 83 + return skb; 84 + } 85 + 86 + static void ath9k_tx99_deinit(struct ath_softc *sc) 87 + { 88 + ath_reset(sc); 89 + 90 + ath9k_ps_wakeup(sc); 91 + ath9k_tx99_stop(sc); 92 + ath9k_ps_restore(sc); 93 + } 94 + 95 + static int ath9k_tx99_init(struct ath_softc *sc) 96 + { 97 + struct ieee80211_hw *hw = sc->hw; 98 + struct ath_hw *ah = sc->sc_ah; 99 + struct ath_common *common = ath9k_hw_common(ah); 100 + struct ath_tx_control txctl; 101 + int r; 102 + 103 + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { 104 + ath_err(common, 105 + "driver is in invalid state unable to use TX99"); 106 + return -EINVAL; 107 + } 108 + 109 + sc->tx99_skb = ath9k_build_tx99_skb(sc); 110 + if (!sc->tx99_skb) 111 + return -ENOMEM; 112 + 113 + memset(&txctl, 0, sizeof(txctl)); 114 + txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; 115 + 116 + ath_reset(sc); 117 + 118 + ath9k_ps_wakeup(sc); 119 + 120 + ath9k_hw_disable_interrupts(ah); 121 + atomic_set(&ah->intr_ref_cnt, -1); 122 + ath_drain_all_txq(sc); 123 + ath_stoprecv(sc); 124 + 125 + sc->tx99_state = true; 126 + 127 + ieee80211_stop_queues(hw); 128 + 129 + if (sc->tx99_power == MAX_RATE_POWER + 1) 130 + sc->tx99_power = MAX_RATE_POWER; 131 + 132 + ath9k_hw_tx99_set_txpower(ah, sc->tx99_power); 133 + r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl); 134 + if (r) { 135 + ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n"); 136 + return r; 137 + } 138 + 139 + ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n", 140 + sc->tx99_power, 141 + sc->tx99_power / 2); 142 + 143 + /* We leave the harware awake as it will be chugging on */ 144 + 145 + return 0; 146 + } 147 + 148 + static ssize_t read_file_tx99(struct file *file, char __user *user_buf, 149 + size_t count, loff_t *ppos) 150 + { 151 + struct ath_softc *sc = file->private_data; 152 + char buf[3]; 153 + unsigned int len; 154 + 155 + len = sprintf(buf, "%d\n", sc->tx99_state); 156 + return simple_read_from_buffer(user_buf, count, ppos, buf, len); 157 + } 158 + 159 + static ssize_t write_file_tx99(struct file *file, const char __user *user_buf, 160 + size_t count, loff_t *ppos) 161 + { 162 + struct ath_softc *sc = file->private_data; 163 + struct ath_common *common = ath9k_hw_common(sc->sc_ah); 164 + char buf[32]; 165 + bool start; 166 + ssize_t len; 167 + int r; 168 + 169 + if (sc->nvifs > 1) 170 + return -EOPNOTSUPP; 171 + 172 + len = min(count, sizeof(buf) - 1); 173 + if (copy_from_user(buf, user_buf, len)) 174 + return -EFAULT; 175 + 176 + if (strtobool(buf, &start)) 177 + return -EINVAL; 178 + 179 + if (start == sc->tx99_state) { 180 + if (!start) 181 + return count; 182 + ath_dbg(common, XMIT, "Resetting TX99\n"); 183 + ath9k_tx99_deinit(sc); 184 + } 185 + 186 + if (!start) { 187 + ath9k_tx99_deinit(sc); 188 + return count; 189 + } 190 + 191 + r = ath9k_tx99_init(sc); 192 + if (r) 193 + return r; 194 + 195 + return count; 196 + } 197 + 198 + static const struct file_operations fops_tx99 = { 199 + .read = read_file_tx99, 200 + .write = write_file_tx99, 201 + .open = simple_open, 202 + .owner = THIS_MODULE, 203 + .llseek = default_llseek, 204 + }; 205 + 206 + static ssize_t read_file_tx99_power(struct file *file, 207 + char __user *user_buf, 208 + size_t count, loff_t *ppos) 209 + { 210 + struct ath_softc *sc = file->private_data; 211 + char buf[32]; 212 + unsigned int len; 213 + 214 + len = sprintf(buf, "%d (%d dBm)\n", 215 + sc->tx99_power, 216 + sc->tx99_power / 2); 217 + 218 + return simple_read_from_buffer(user_buf, count, ppos, buf, len); 219 + } 220 + 221 + static ssize_t write_file_tx99_power(struct file *file, 222 + const char __user *user_buf, 223 + size_t count, loff_t *ppos) 224 + { 225 + struct ath_softc *sc = file->private_data; 226 + int r; 227 + u8 tx_power; 228 + 229 + r = kstrtou8_from_user(user_buf, count, 0, &tx_power); 230 + if (r) 231 + return r; 232 + 233 + if (tx_power > MAX_RATE_POWER) 234 + return -EINVAL; 235 + 236 + sc->tx99_power = tx_power; 237 + 238 + ath9k_ps_wakeup(sc); 239 + ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power); 240 + ath9k_ps_restore(sc); 241 + 242 + return count; 243 + } 244 + 245 + static const struct file_operations fops_tx99_power = { 246 + .read = read_file_tx99_power, 247 + .write = write_file_tx99_power, 248 + .open = simple_open, 249 + .owner = THIS_MODULE, 250 + .llseek = default_llseek, 251 + }; 252 + 253 + void ath9k_tx99_init_debug(struct ath_softc *sc) 254 + { 255 + if (!AR_SREV_9300_20_OR_LATER(sc->sc_ah)) 256 + return; 257 + 258 + debugfs_create_file("tx99", S_IRUSR | S_IWUSR, 259 + sc->debug.debugfs_phy, sc, 260 + &fops_tx99); 261 + debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR, 262 + sc->debug.debugfs_phy, sc, 263 + &fops_tx99_power); 264 + }
+323 -384
drivers/net/wireless/ath/ath9k/wow.c
··· 1 1 /* 2 - * Copyright (c) 2012 Qualcomm Atheros, Inc. 2 + * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 3 * 4 4 * Permission to use, copy, modify, and/or distribute this software for any 5 5 * purpose with or without fee is hereby granted, provided that the above ··· 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 16 17 - #include <linux/export.h> 18 17 #include "ath9k.h" 19 - #include "reg.h" 20 - #include "hw-ops.h" 21 18 22 - const char *ath9k_hw_wow_event_to_string(u32 wow_event) 19 + static const struct wiphy_wowlan_support ath9k_wowlan_support = { 20 + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, 21 + .n_patterns = MAX_NUM_USER_PATTERN, 22 + .pattern_min_len = 1, 23 + .pattern_max_len = MAX_PATTERN_SIZE, 24 + }; 25 + 26 + static void ath9k_wow_map_triggers(struct ath_softc *sc, 27 + struct cfg80211_wowlan *wowlan, 28 + u32 *wow_triggers) 23 29 { 24 - if (wow_event & AH_WOW_MAGIC_PATTERN_EN) 25 - return "Magic pattern"; 26 - if (wow_event & AH_WOW_USER_PATTERN_EN) 27 - return "User pattern"; 28 - if (wow_event & AH_WOW_LINK_CHANGE) 29 - return "Link change"; 30 - if (wow_event & AH_WOW_BEACON_MISS) 31 - return "Beacon miss"; 30 + if (wowlan->disconnect) 31 + *wow_triggers |= AH_WOW_LINK_CHANGE | 32 + AH_WOW_BEACON_MISS; 33 + if (wowlan->magic_pkt) 34 + *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN; 32 35 33 - return "unknown reason"; 36 + if (wowlan->n_patterns) 37 + *wow_triggers |= AH_WOW_USER_PATTERN_EN; 38 + 39 + sc->wow_enabled = *wow_triggers; 40 + 34 41 } 35 - EXPORT_SYMBOL(ath9k_hw_wow_event_to_string); 36 42 37 - static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 43 + static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc) 38 44 { 45 + struct ath_hw *ah = sc->sc_ah; 39 46 struct ath_common *common = ath9k_hw_common(ah); 47 + int pattern_count = 0; 48 + int i, byte_cnt; 49 + u8 dis_deauth_pattern[MAX_PATTERN_SIZE]; 50 + u8 dis_deauth_mask[MAX_PATTERN_SIZE]; 40 51 41 - REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 52 + memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE); 53 + memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE); 42 54 43 - /* set rx disable bit */ 44 - REG_WRITE(ah, AR_CR, AR_CR_RXD); 55 + /* 56 + * Create Dissassociate / Deauthenticate packet filter 57 + * 58 + * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes 59 + * +--------------+----------+---------+--------+--------+---- 60 + * + Frame Control+ Duration + DA + SA + BSSID + 61 + * +--------------+----------+---------+--------+--------+---- 62 + * 63 + * The above is the management frame format for disassociate/ 64 + * deauthenticate pattern, from this we need to match the first byte 65 + * of 'Frame Control' and DA, SA, and BSSID fields 66 + * (skipping 2nd byte of FC and Duration feild. 67 + * 68 + * Disassociate pattern 69 + * -------------------- 70 + * Frame control = 00 00 1010 71 + * DA, SA, BSSID = x:x:x:x:x:x 72 + * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x 73 + * | x:x:x:x:x:x -- 22 bytes 74 + * 75 + * Deauthenticate pattern 76 + * ---------------------- 77 + * Frame control = 00 00 1100 78 + * DA, SA, BSSID = x:x:x:x:x:x 79 + * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x 80 + * | x:x:x:x:x:x -- 22 bytes 81 + */ 45 82 46 - if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) { 47 - ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", 48 - REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); 83 + /* Create Disassociate Pattern first */ 84 + 85 + byte_cnt = 0; 86 + 87 + /* Fill out the mask with all FF's */ 88 + 89 + for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++) 90 + dis_deauth_mask[i] = 0xff; 91 + 92 + /* copy the first byte of frame control field */ 93 + dis_deauth_pattern[byte_cnt] = 0xa0; 94 + byte_cnt++; 95 + 96 + /* skip 2nd byte of frame control and Duration field */ 97 + byte_cnt += 3; 98 + 99 + /* 100 + * need not match the destination mac address, it can be a broadcast 101 + * mac address or an unicast to this station 102 + */ 103 + byte_cnt += 6; 104 + 105 + /* copy the source mac address */ 106 + memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN); 107 + 108 + byte_cnt += 6; 109 + 110 + /* copy the bssid, its same as the source mac address */ 111 + 112 + memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN); 113 + 114 + /* Create Disassociate pattern mask */ 115 + 116 + dis_deauth_mask[0] = 0xfe; 117 + dis_deauth_mask[1] = 0x03; 118 + dis_deauth_mask[2] = 0xc0; 119 + 120 + ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n"); 121 + 122 + ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, 123 + pattern_count, byte_cnt); 124 + 125 + pattern_count++; 126 + /* 127 + * for de-authenticate pattern, only the first byte of the frame 128 + * control field gets changed from 0xA0 to 0xC0 129 + */ 130 + dis_deauth_pattern[0] = 0xC0; 131 + 132 + ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, 133 + pattern_count, byte_cnt); 134 + 135 + } 136 + 137 + static void ath9k_wow_add_pattern(struct ath_softc *sc, 138 + struct cfg80211_wowlan *wowlan) 139 + { 140 + struct ath_hw *ah = sc->sc_ah; 141 + struct ath9k_wow_pattern *wow_pattern = NULL; 142 + struct cfg80211_pkt_pattern *patterns = wowlan->patterns; 143 + int mask_len; 144 + s8 i = 0; 145 + 146 + if (!wowlan->n_patterns) 49 147 return; 50 - } 51 - 52 - REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 53 - } 54 - 55 - static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) 56 - { 57 - struct ath_common *common = ath9k_hw_common(ah); 58 - u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN]; 59 - u32 ctl[13] = {0}; 60 - u32 data_word[KAL_NUM_DATA_WORDS]; 61 - u8 i; 62 - u32 wow_ka_data_word0; 63 - 64 - memcpy(sta_mac_addr, common->macaddr, ETH_ALEN); 65 - memcpy(ap_mac_addr, common->curbssid, ETH_ALEN); 66 - 67 - /* set the transmit buffer */ 68 - ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16)); 69 - ctl[1] = 0; 70 - ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */ 71 - ctl[4] = 0; 72 - ctl[7] = (ah->txchainmask) << 2; 73 - ctl[2] = 0xf << 16; /* tx_tries 0 */ 74 - 75 - for (i = 0; i < KAL_NUM_DESC_WORDS; i++) 76 - REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 77 - 78 - REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 79 - 80 - data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) | 81 - (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16); 82 - data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | 83 - (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); 84 - data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) | 85 - (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); 86 - data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) | 87 - (sta_mac_addr[3] << 8) | (sta_mac_addr[2]); 88 - data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | 89 - (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); 90 - data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); 91 - 92 - if (AR_SREV_9462_20(ah)) { 93 - /* AR9462 2.0 has an extra descriptor word (time based 94 - * discard) compared to other chips */ 95 - REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); 96 - wow_ka_data_word0 = AR_WOW_TXBUF(13); 97 - } else { 98 - wow_ka_data_word0 = AR_WOW_TXBUF(12); 99 - } 100 - 101 - for (i = 0; i < KAL_NUM_DATA_WORDS; i++) 102 - REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]); 103 - 104 - } 105 - 106 - void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 107 - u8 *user_mask, int pattern_count, 108 - int pattern_len) 109 - { 110 - int i; 111 - u32 pattern_val, mask_val; 112 - u32 set, clr; 113 - 114 - /* FIXME: should check count by querying the hardware capability */ 115 - if (pattern_count >= MAX_NUM_PATTERN) 116 - return; 117 - 118 - REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count)); 119 - 120 - /* set the registers for pattern */ 121 - for (i = 0; i < MAX_PATTERN_SIZE; i += 4) { 122 - memcpy(&pattern_val, user_pattern, 4); 123 - REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i), 124 - pattern_val); 125 - user_pattern += 4; 126 - } 127 - 128 - /* set the registers for mask */ 129 - for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) { 130 - memcpy(&mask_val, user_mask, 4); 131 - REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val); 132 - user_mask += 4; 133 - } 134 - 135 - /* set the pattern length to be matched 136 - * 137 - * AR_WOW_LENGTH1_REG1 138 - * bit 31:24 pattern 0 length 139 - * bit 23:16 pattern 1 length 140 - * bit 15:8 pattern 2 length 141 - * bit 7:0 pattern 3 length 142 - * 143 - * AR_WOW_LENGTH1_REG2 144 - * bit 31:24 pattern 4 length 145 - * bit 23:16 pattern 5 length 146 - * bit 15:8 pattern 6 length 147 - * bit 7:0 pattern 7 length 148 - * 149 - * the below logic writes out the new 150 - * pattern length for the corresponding 151 - * pattern_count, while masking out the 152 - * other fields 153 - */ 154 - 155 - ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 156 - 157 - if (pattern_count < 4) { 158 - /* Pattern 0-3 uses AR_WOW_LENGTH1 register */ 159 - set = (pattern_len & AR_WOW_LENGTH_MAX) << 160 - AR_WOW_LEN1_SHIFT(pattern_count); 161 - clr = AR_WOW_LENGTH1_MASK(pattern_count); 162 - REG_RMW(ah, AR_WOW_LENGTH1, set, clr); 163 - } else { 164 - /* Pattern 4-7 uses AR_WOW_LENGTH2 register */ 165 - set = (pattern_len & AR_WOW_LENGTH_MAX) << 166 - AR_WOW_LEN2_SHIFT(pattern_count); 167 - clr = AR_WOW_LENGTH2_MASK(pattern_count); 168 - REG_RMW(ah, AR_WOW_LENGTH2, set, clr); 169 - } 170 - 171 - } 172 - EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern); 173 - 174 - u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) 175 - { 176 - u32 wow_status = 0; 177 - u32 val = 0, rval; 178 148 179 149 /* 180 - * read the WoW status register to know 181 - * the wakeup reason 150 + * Add the new user configured patterns 182 151 */ 183 - rval = REG_READ(ah, AR_WOW_PATTERN); 184 - val = AR_WOW_STATUS(rval); 152 + for (i = 0; i < wowlan->n_patterns; i++) { 185 153 186 - /* 187 - * mask only the WoW events that we have enabled. Sometimes 188 - * we have spurious WoW events from the AR_WOW_PATTERN 189 - * register. This mask will clean it up. 190 - */ 154 + wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL); 191 155 192 - val &= ah->wow_event_mask; 156 + if (!wow_pattern) 157 + return; 193 158 194 - if (val) { 195 - if (val & AR_WOW_MAGIC_PAT_FOUND) 196 - wow_status |= AH_WOW_MAGIC_PATTERN_EN; 197 - if (AR_WOW_PATTERN_FOUND(val)) 198 - wow_status |= AH_WOW_USER_PATTERN_EN; 199 - if (val & AR_WOW_KEEP_ALIVE_FAIL) 200 - wow_status |= AH_WOW_LINK_CHANGE; 201 - if (val & AR_WOW_BEACON_FAIL) 202 - wow_status |= AH_WOW_BEACON_MISS; 203 - } 204 - 205 - /* 206 - * set and clear WOW_PME_CLEAR registers for the chip to 207 - * generate next wow signal. 208 - * disable D3 before accessing other registers ? 209 - */ 210 - 211 - /* do we need to check the bit value 0x01000000 (7-10) ?? */ 212 - REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR, 213 - AR_PMCTRL_PWR_STATE_D1D3); 214 - 215 - /* 216 - * clear all events 217 - */ 218 - REG_WRITE(ah, AR_WOW_PATTERN, 219 - AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); 220 - 221 - /* 222 - * restore the beacon threshold to init value 223 - */ 224 - REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 225 - 226 - /* 227 - * Restore the way the PCI-E reset, Power-On-Reset, external 228 - * PCIE_POR_SHORT pins are tied to its original value. 229 - * Previously just before WoW sleep, we untie the PCI-E 230 - * reset to our Chip's Power On Reset so that any PCI-E 231 - * reset from the bus will not reset our chip 232 - */ 233 - if (ah->is_pciexpress) 234 - ath9k_hw_configpcipowersave(ah, false); 235 - 236 - ah->wow_event_mask = 0; 237 - 238 - return wow_status; 239 - } 240 - EXPORT_SYMBOL(ath9k_hw_wow_wakeup); 241 - 242 - void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) 243 - { 244 - u32 wow_event_mask; 245 - u32 set, clr; 246 - 247 - /* 248 - * wow_event_mask is a mask to the AR_WOW_PATTERN register to 249 - * indicate which WoW events we have enabled. The WoW events 250 - * are from the 'pattern_enable' in this function and 251 - * 'pattern_count' of ath9k_hw_wow_apply_pattern() 252 - */ 253 - wow_event_mask = ah->wow_event_mask; 254 - 255 - /* 256 - * Untie Power-on-Reset from the PCI-E-Reset. When we are in 257 - * WOW sleep, we do want the Reset from the PCI-E to disturb 258 - * our hw state 259 - */ 260 - if (ah->is_pciexpress) { 261 159 /* 262 - * we need to untie the internal POR (power-on-reset) 263 - * to the external PCI-E reset. We also need to tie 264 - * the PCI-E Phy reset to the PCI-E reset. 160 + * TODO: convert the generic user space pattern to 161 + * appropriate chip specific/802.11 pattern. 265 162 */ 266 - set = AR_WA_RESET_EN | AR_WA_POR_SHORT; 267 - clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE; 268 - REG_RMW(ah, AR_WA, set, clr); 163 + 164 + mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); 165 + memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE); 166 + memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE); 167 + memcpy(wow_pattern->pattern_bytes, patterns[i].pattern, 168 + patterns[i].pattern_len); 169 + memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len); 170 + wow_pattern->pattern_len = patterns[i].pattern_len; 171 + 172 + /* 173 + * just need to take care of deauth and disssoc pattern, 174 + * make sure we don't overwrite them. 175 + */ 176 + 177 + ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes, 178 + wow_pattern->mask_bytes, 179 + i + 2, 180 + wow_pattern->pattern_len); 181 + kfree(wow_pattern); 182 + 269 183 } 270 184 271 - /* 272 - * set the power states appropriately and enable PME 273 - */ 274 - set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA | 275 - AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR; 276 - 277 - /* 278 - * set and clear WOW_PME_CLEAR registers for the chip 279 - * to generate next wow signal. 280 - */ 281 - REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 282 - clr = AR_PMCTRL_WOW_PME_CLR; 283 - REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); 284 - 285 - /* 286 - * Setup for: 287 - * - beacon misses 288 - * - magic pattern 289 - * - keep alive timeout 290 - * - pattern matching 291 - */ 292 - 293 - /* 294 - * Program default values for pattern backoff, aifs/slot/KAL count, 295 - * beacon miss timeout, KAL timeout, etc. 296 - */ 297 - set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF); 298 - REG_SET_BIT(ah, AR_WOW_PATTERN, set); 299 - 300 - set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) | 301 - AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) | 302 - AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT); 303 - REG_SET_BIT(ah, AR_WOW_COUNT, set); 304 - 305 - if (pattern_enable & AH_WOW_BEACON_MISS) 306 - set = AR_WOW_BEACON_TIMO; 307 - /* We are not using beacon miss, program a large value */ 308 - else 309 - set = AR_WOW_BEACON_TIMO_MAX; 310 - 311 - REG_WRITE(ah, AR_WOW_BCN_TIMO, set); 312 - 313 - /* 314 - * Keep alive timo in ms except AR9280 315 - */ 316 - if (!pattern_enable) 317 - set = AR_WOW_KEEP_ALIVE_NEVER; 318 - else 319 - set = KAL_TIMEOUT * 32; 320 - 321 - REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set); 322 - 323 - /* 324 - * Keep alive delay in us. based on 'power on clock', 325 - * therefore in usec 326 - */ 327 - set = KAL_DELAY * 1000; 328 - REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set); 329 - 330 - /* 331 - * Create keep alive pattern to respond to beacons 332 - */ 333 - ath9k_wow_create_keep_alive_pattern(ah); 334 - 335 - /* 336 - * Configure MAC WoW Registers 337 - */ 338 - set = 0; 339 - /* Send keep alive timeouts anyway */ 340 - clr = AR_WOW_KEEP_ALIVE_AUTO_DIS; 341 - 342 - if (pattern_enable & AH_WOW_LINK_CHANGE) 343 - wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL; 344 - else 345 - set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 346 - 347 - set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 348 - REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); 349 - 350 - /* 351 - * we are relying on a bmiss failure. ensure we have 352 - * enough threshold to prevent false positives 353 - */ 354 - REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, 355 - AR_WOW_BMISSTHRESHOLD); 356 - 357 - set = 0; 358 - clr = 0; 359 - 360 - if (pattern_enable & AH_WOW_BEACON_MISS) { 361 - set = AR_WOW_BEACON_FAIL_EN; 362 - wow_event_mask |= AR_WOW_BEACON_FAIL; 363 - } else { 364 - clr = AR_WOW_BEACON_FAIL_EN; 365 - } 366 - 367 - REG_RMW(ah, AR_WOW_BCN_EN, set, clr); 368 - 369 - set = 0; 370 - clr = 0; 371 - /* 372 - * Enable the magic packet registers 373 - */ 374 - if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) { 375 - set = AR_WOW_MAGIC_EN; 376 - wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND; 377 - } else { 378 - clr = AR_WOW_MAGIC_EN; 379 - } 380 - set |= AR_WOW_MAC_INTR_EN; 381 - REG_RMW(ah, AR_WOW_PATTERN, set, clr); 382 - 383 - REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B, 384 - AR_WOW_PATTERN_SUPPORTED); 385 - 386 - /* 387 - * Set the power states appropriately and enable PME 388 - */ 389 - clr = 0; 390 - set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN | 391 - AR_PMCTRL_PWR_PM_CTRL_ENA; 392 - 393 - clr = AR_PCIE_PM_CTRL_ENA; 394 - REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 395 - 396 - /* 397 - * this is needed to prevent the chip waking up 398 - * the host within 3-4 seconds with certain 399 - * platform/BIOS. The fix is to enable 400 - * D1 & D3 to match original definition and 401 - * also match the OTP value. Anyway this 402 - * is more related to SW WOW. 403 - */ 404 - clr = AR_PMCTRL_PWR_STATE_D1D3; 405 - REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); 406 - 407 - set = AR_PMCTRL_PWR_STATE_D1D3_REAL; 408 - REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 409 - 410 - REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 411 - 412 - /* to bring down WOW power low margin */ 413 - set = BIT(13); 414 - REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set); 415 - /* HW WoW */ 416 - clr = BIT(5); 417 - REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr); 418 - 419 - ath9k_hw_set_powermode_wow_sleep(ah); 420 - ah->wow_event_mask = wow_event_mask; 421 185 } 422 - EXPORT_SYMBOL(ath9k_hw_wow_enable); 186 + 187 + int ath9k_suspend(struct ieee80211_hw *hw, 188 + struct cfg80211_wowlan *wowlan) 189 + { 190 + struct ath_softc *sc = hw->priv; 191 + struct ath_hw *ah = sc->sc_ah; 192 + struct ath_common *common = ath9k_hw_common(ah); 193 + u32 wow_triggers_enabled = 0; 194 + int ret = 0; 195 + 196 + mutex_lock(&sc->mutex); 197 + 198 + ath_cancel_work(sc); 199 + ath_stop_ani(sc); 200 + del_timer_sync(&sc->rx_poll_timer); 201 + 202 + if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { 203 + ath_dbg(common, ANY, "Device not present\n"); 204 + ret = -EINVAL; 205 + goto fail_wow; 206 + } 207 + 208 + if (WARN_ON(!wowlan)) { 209 + ath_dbg(common, WOW, "None of the WoW triggers enabled\n"); 210 + ret = -EINVAL; 211 + goto fail_wow; 212 + } 213 + 214 + if (!device_can_wakeup(sc->dev)) { 215 + ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n"); 216 + ret = 1; 217 + goto fail_wow; 218 + } 219 + 220 + /* 221 + * none of the sta vifs are associated 222 + * and we are not currently handling multivif 223 + * cases, for instance we have to seperately 224 + * configure 'keep alive frame' for each 225 + * STA. 226 + */ 227 + 228 + if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { 229 + ath_dbg(common, WOW, "None of the STA vifs are associated\n"); 230 + ret = 1; 231 + goto fail_wow; 232 + } 233 + 234 + if (sc->nvifs > 1) { 235 + ath_dbg(common, WOW, "WoW for multivif is not yet supported\n"); 236 + ret = 1; 237 + goto fail_wow; 238 + } 239 + 240 + ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled); 241 + 242 + ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n", 243 + wow_triggers_enabled); 244 + 245 + ath9k_ps_wakeup(sc); 246 + 247 + ath9k_stop_btcoex(sc); 248 + 249 + /* 250 + * Enable wake up on recieving disassoc/deauth 251 + * frame by default. 252 + */ 253 + ath9k_wow_add_disassoc_deauth_pattern(sc); 254 + 255 + if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN) 256 + ath9k_wow_add_pattern(sc, wowlan); 257 + 258 + spin_lock_bh(&sc->sc_pcu_lock); 259 + /* 260 + * To avoid false wake, we enable beacon miss interrupt only 261 + * when we go to sleep. We save the current interrupt mask 262 + * so we can restore it after the system wakes up 263 + */ 264 + sc->wow_intr_before_sleep = ah->imask; 265 + ah->imask &= ~ATH9K_INT_GLOBAL; 266 + ath9k_hw_disable_interrupts(ah); 267 + ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL; 268 + ath9k_hw_set_interrupts(ah); 269 + ath9k_hw_enable_interrupts(ah); 270 + 271 + spin_unlock_bh(&sc->sc_pcu_lock); 272 + 273 + /* 274 + * we can now sync irq and kill any running tasklets, since we already 275 + * disabled interrupts and not holding a spin lock 276 + */ 277 + synchronize_irq(sc->irq); 278 + tasklet_kill(&sc->intr_tq); 279 + 280 + ath9k_hw_wow_enable(ah, wow_triggers_enabled); 281 + 282 + ath9k_ps_restore(sc); 283 + ath_dbg(common, ANY, "WoW enabled in ath9k\n"); 284 + atomic_inc(&sc->wow_sleep_proc_intr); 285 + 286 + fail_wow: 287 + mutex_unlock(&sc->mutex); 288 + return ret; 289 + } 290 + 291 + int ath9k_resume(struct ieee80211_hw *hw) 292 + { 293 + struct ath_softc *sc = hw->priv; 294 + struct ath_hw *ah = sc->sc_ah; 295 + struct ath_common *common = ath9k_hw_common(ah); 296 + u32 wow_status; 297 + 298 + mutex_lock(&sc->mutex); 299 + 300 + ath9k_ps_wakeup(sc); 301 + 302 + spin_lock_bh(&sc->sc_pcu_lock); 303 + 304 + ath9k_hw_disable_interrupts(ah); 305 + ah->imask = sc->wow_intr_before_sleep; 306 + ath9k_hw_set_interrupts(ah); 307 + ath9k_hw_enable_interrupts(ah); 308 + 309 + spin_unlock_bh(&sc->sc_pcu_lock); 310 + 311 + wow_status = ath9k_hw_wow_wakeup(ah); 312 + 313 + if (atomic_read(&sc->wow_got_bmiss_intr) == 0) { 314 + /* 315 + * some devices may not pick beacon miss 316 + * as the reason they woke up so we add 317 + * that here for that shortcoming. 318 + */ 319 + wow_status |= AH_WOW_BEACON_MISS; 320 + atomic_dec(&sc->wow_got_bmiss_intr); 321 + ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n"); 322 + } 323 + 324 + atomic_dec(&sc->wow_sleep_proc_intr); 325 + 326 + if (wow_status) { 327 + ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n", 328 + ath9k_hw_wow_event_to_string(wow_status), wow_status); 329 + } 330 + 331 + ath_restart_work(sc); 332 + ath9k_start_btcoex(sc); 333 + 334 + ath9k_ps_restore(sc); 335 + mutex_unlock(&sc->mutex); 336 + 337 + return 0; 338 + } 339 + 340 + void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) 341 + { 342 + struct ath_softc *sc = hw->priv; 343 + 344 + mutex_lock(&sc->mutex); 345 + device_init_wakeup(sc->dev, 1); 346 + device_set_wakeup_enable(sc->dev, enabled); 347 + mutex_unlock(&sc->mutex); 348 + } 349 + 350 + void ath9k_init_wow(struct ieee80211_hw *hw) 351 + { 352 + struct ath_softc *sc = hw->priv; 353 + 354 + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 355 + (sc->driver_data & ATH9K_PCI_WOW) && 356 + device_can_wakeup(sc->dev)) 357 + hw->wiphy->wowlan = &ath9k_wowlan_support; 358 + 359 + atomic_set(&sc->wow_sleep_proc_intr, -1); 360 + atomic_set(&sc->wow_got_bmiss_intr, -1); 361 + }
+7
drivers/net/wireless/ath/ath9k/xmit.c
··· 1786 1786 if (!ATH_TXQ_SETUP(sc, i)) 1787 1787 continue; 1788 1788 1789 + if (!sc->tx.txq[i].axq_depth) 1790 + continue; 1791 + 1789 1792 if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum)) 1790 1793 npend |= BIT(i); 1791 1794 } ··· 2752 2749 } 2753 2750 } 2754 2751 2752 + #ifdef CONFIG_ATH9K_TX99 2753 + 2755 2754 int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, 2756 2755 struct ath_tx_control *txctl) 2757 2756 { ··· 2796 2791 2797 2792 return 0; 2798 2793 } 2794 + 2795 + #endif /* CONFIG_ATH9K_TX99 */
+317 -293
drivers/net/wireless/ath/regd.c
··· 37 37 38 38 /* We enable active scan on these a case by case basis by regulatory domain */ 39 39 #define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 40 - NL80211_RRF_PASSIVE_SCAN) 40 + NL80211_RRF_NO_IR) 41 41 #define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ 42 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) 42 + NL80211_RRF_NO_IR | \ 43 + NL80211_RRF_NO_OFDM) 43 44 44 45 /* We allow IBSS on these on a case by case basis by regulatory domain */ 45 46 #define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ 46 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 47 + NL80211_RRF_NO_IR) 47 48 #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ 48 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 49 + NL80211_RRF_NO_IR) 49 50 #define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\ 50 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 51 + NL80211_RRF_NO_IR) 51 52 52 53 #define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \ 53 54 ATH9K_2GHZ_CH12_13, \ ··· 113 112 ATH9K_5GHZ_ALL, 114 113 } 115 114 }; 116 - 117 - static inline bool is_wwr_sku(u16 regd) 118 - { 119 - return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && 120 - (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || 121 - (regd == WORLD)); 122 - } 123 - 124 - static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) 125 - { 126 - return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; 127 - } 128 - 129 - bool ath_is_world_regd(struct ath_regulatory *reg) 130 - { 131 - return is_wwr_sku(ath_regd_get_eepromRD(reg)); 132 - } 133 - EXPORT_SYMBOL(ath_is_world_regd); 134 - 135 - static const struct ieee80211_regdomain *ath_default_world_regdomain(void) 136 - { 137 - /* this is the most restrictive */ 138 - return &ath_world_regdom_64; 139 - } 140 - 141 - static const struct 142 - ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) 143 - { 144 - switch (reg->regpair->regDmnEnum) { 145 - case 0x60: 146 - case 0x61: 147 - case 0x62: 148 - return &ath_world_regdom_60_61_62; 149 - case 0x63: 150 - case 0x65: 151 - return &ath_world_regdom_63_65; 152 - case 0x64: 153 - return &ath_world_regdom_64; 154 - case 0x66: 155 - case 0x69: 156 - return &ath_world_regdom_66_69; 157 - case 0x67: 158 - case 0x68: 159 - case 0x6A: 160 - case 0x6C: 161 - return &ath_world_regdom_67_68_6A_6C; 162 - default: 163 - WARN_ON(1); 164 - return ath_default_world_regdomain(); 165 - } 166 - } 167 - 168 - bool ath_is_49ghz_allowed(u16 regdomain) 169 - { 170 - /* possibly more */ 171 - return regdomain == MKK9_MKKC; 172 - } 173 - EXPORT_SYMBOL(ath_is_49ghz_allowed); 174 - 175 - /* Frequency is one where radar detection is required */ 176 - static bool ath_is_radar_freq(u16 center_freq) 177 - { 178 - return (center_freq >= 5260 && center_freq <= 5700); 179 - } 180 - 181 - /* 182 - * N.B: These exception rules do not apply radar freqs. 183 - * 184 - * - We enable adhoc (or beaconing) if allowed by 11d 185 - * - We enable active scan if the channel is allowed by 11d 186 - * - If no country IE has been processed and a we determine we have 187 - * received a beacon on a channel we can enable active scan and 188 - * adhoc (or beaconing). 189 - */ 190 - static void 191 - ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 192 - enum nl80211_reg_initiator initiator) 193 - { 194 - enum ieee80211_band band; 195 - struct ieee80211_supported_band *sband; 196 - const struct ieee80211_reg_rule *reg_rule; 197 - struct ieee80211_channel *ch; 198 - unsigned int i; 199 - 200 - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 201 - 202 - if (!wiphy->bands[band]) 203 - continue; 204 - 205 - sband = wiphy->bands[band]; 206 - 207 - for (i = 0; i < sband->n_channels; i++) { 208 - 209 - ch = &sband->channels[i]; 210 - 211 - if (ath_is_radar_freq(ch->center_freq) || 212 - (ch->flags & IEEE80211_CHAN_RADAR)) 213 - continue; 214 - 215 - if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 216 - reg_rule = freq_reg_info(wiphy, ch->center_freq); 217 - if (IS_ERR(reg_rule)) 218 - continue; 219 - /* 220 - * If 11d had a rule for this channel ensure 221 - * we enable adhoc/beaconing if it allows us to 222 - * use it. Note that we would have disabled it 223 - * by applying our static world regdomain by 224 - * default during init, prior to calling our 225 - * regulatory_hint(). 226 - */ 227 - if (!(reg_rule->flags & 228 - NL80211_RRF_NO_IBSS)) 229 - ch->flags &= 230 - ~IEEE80211_CHAN_NO_IBSS; 231 - if (!(reg_rule->flags & 232 - NL80211_RRF_PASSIVE_SCAN)) 233 - ch->flags &= 234 - ~IEEE80211_CHAN_PASSIVE_SCAN; 235 - } else { 236 - if (ch->beacon_found) 237 - ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 238 - IEEE80211_CHAN_PASSIVE_SCAN); 239 - } 240 - } 241 - } 242 - 243 - } 244 - 245 - /* Allows active scan scan on Ch 12 and 13 */ 246 - static void 247 - ath_reg_apply_active_scan_flags(struct wiphy *wiphy, 248 - enum nl80211_reg_initiator initiator) 249 - { 250 - struct ieee80211_supported_band *sband; 251 - struct ieee80211_channel *ch; 252 - const struct ieee80211_reg_rule *reg_rule; 253 - 254 - sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 255 - if (!sband) 256 - return; 257 - 258 - /* 259 - * If no country IE has been received always enable active scan 260 - * on these channels. This is only done for specific regulatory SKUs 261 - */ 262 - if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 263 - ch = &sband->channels[11]; /* CH 12 */ 264 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 265 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 266 - ch = &sband->channels[12]; /* CH 13 */ 267 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 268 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 269 - return; 270 - } 271 - 272 - /* 273 - * If a country IE has been received check its rule for this 274 - * channel first before enabling active scan. The passive scan 275 - * would have been enforced by the initial processing of our 276 - * custom regulatory domain. 277 - */ 278 - 279 - ch = &sband->channels[11]; /* CH 12 */ 280 - reg_rule = freq_reg_info(wiphy, ch->center_freq); 281 - if (!IS_ERR(reg_rule)) { 282 - if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 283 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 284 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 285 - } 286 - 287 - ch = &sband->channels[12]; /* CH 13 */ 288 - reg_rule = freq_reg_info(wiphy, ch->center_freq); 289 - if (!IS_ERR(reg_rule)) { 290 - if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 291 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 292 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 293 - } 294 - } 295 - 296 - /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ 297 - static void ath_reg_apply_radar_flags(struct wiphy *wiphy) 298 - { 299 - struct ieee80211_supported_band *sband; 300 - struct ieee80211_channel *ch; 301 - unsigned int i; 302 - 303 - if (!wiphy->bands[IEEE80211_BAND_5GHZ]) 304 - return; 305 - 306 - sband = wiphy->bands[IEEE80211_BAND_5GHZ]; 307 - 308 - for (i = 0; i < sband->n_channels; i++) { 309 - ch = &sband->channels[i]; 310 - if (!ath_is_radar_freq(ch->center_freq)) 311 - continue; 312 - /* We always enable radar detection/DFS on this 313 - * frequency range. Additionally we also apply on 314 - * this frequency range: 315 - * - If STA mode does not yet have DFS supports disable 316 - * active scanning 317 - * - If adhoc mode does not support DFS yet then 318 - * disable adhoc in the frequency. 319 - * - If AP mode does not yet support radar detection/DFS 320 - * do not allow AP mode 321 - */ 322 - if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 323 - ch->flags |= IEEE80211_CHAN_RADAR | 324 - IEEE80211_CHAN_NO_IBSS | 325 - IEEE80211_CHAN_PASSIVE_SCAN; 326 - } 327 - } 328 - 329 - static void ath_reg_apply_world_flags(struct wiphy *wiphy, 330 - enum nl80211_reg_initiator initiator, 331 - struct ath_regulatory *reg) 332 - { 333 - switch (reg->regpair->regDmnEnum) { 334 - case 0x60: 335 - case 0x63: 336 - case 0x66: 337 - case 0x67: 338 - case 0x6C: 339 - ath_reg_apply_beaconing_flags(wiphy, initiator); 340 - break; 341 - case 0x68: 342 - ath_reg_apply_beaconing_flags(wiphy, initiator); 343 - ath_reg_apply_active_scan_flags(wiphy, initiator); 344 - break; 345 - } 346 - } 347 - 348 - static u16 ath_regd_find_country_by_name(char *alpha2) 349 - { 350 - unsigned int i; 351 - 352 - for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 353 - if (!memcmp(allCountries[i].isoName, alpha2, 2)) 354 - return allCountries[i].countryCode; 355 - } 356 - 357 - return -1; 358 - } 359 - 360 - static int __ath_reg_dyn_country(struct wiphy *wiphy, 361 - struct ath_regulatory *reg, 362 - struct regulatory_request *request) 363 - { 364 - u16 country_code; 365 - 366 - if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 367 - !ath_is_world_regd(reg)) 368 - return -EINVAL; 369 - 370 - country_code = ath_regd_find_country_by_name(request->alpha2); 371 - if (country_code == (u16) -1) 372 - return -EINVAL; 373 - 374 - reg->current_rd = COUNTRY_ERD_FLAG; 375 - reg->current_rd |= country_code; 376 - 377 - __ath_regd_init(reg); 378 - 379 - ath_reg_apply_world_flags(wiphy, request->initiator, reg); 380 - 381 - return 0; 382 - } 383 - 384 - static void ath_reg_dyn_country(struct wiphy *wiphy, 385 - struct ath_regulatory *reg, 386 - struct regulatory_request *request) 387 - { 388 - if (__ath_reg_dyn_country(wiphy, reg, request)) 389 - return; 390 - 391 - printk(KERN_DEBUG "ath: regdomain 0x%0x " 392 - "dynamically updated by %s\n", 393 - reg->current_rd, 394 - reg_initiator_name(request->initiator)); 395 - } 396 115 397 116 static bool dynamic_country_user_possible(struct ath_regulatory *reg) 398 117 { ··· 186 465 return true; 187 466 } 188 467 189 - static void ath_reg_dyn_country_user(struct wiphy *wiphy, 190 - struct ath_regulatory *reg, 191 - struct regulatory_request *request) 468 + static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg) 192 469 { 193 470 if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS)) 194 - return; 471 + return false; 195 472 if (!dynamic_country_user_possible(reg)) 473 + return false; 474 + return true; 475 + } 476 + 477 + static inline bool is_wwr_sku(u16 regd) 478 + { 479 + return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && 480 + (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || 481 + (regd == WORLD)); 482 + } 483 + 484 + static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) 485 + { 486 + return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; 487 + } 488 + 489 + bool ath_is_world_regd(struct ath_regulatory *reg) 490 + { 491 + return is_wwr_sku(ath_regd_get_eepromRD(reg)); 492 + } 493 + EXPORT_SYMBOL(ath_is_world_regd); 494 + 495 + static const struct ieee80211_regdomain *ath_default_world_regdomain(void) 496 + { 497 + /* this is the most restrictive */ 498 + return &ath_world_regdom_64; 499 + } 500 + 501 + static const struct 502 + ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) 503 + { 504 + switch (reg->regpair->regDmnEnum) { 505 + case 0x60: 506 + case 0x61: 507 + case 0x62: 508 + return &ath_world_regdom_60_61_62; 509 + case 0x63: 510 + case 0x65: 511 + return &ath_world_regdom_63_65; 512 + case 0x64: 513 + return &ath_world_regdom_64; 514 + case 0x66: 515 + case 0x69: 516 + return &ath_world_regdom_66_69; 517 + case 0x67: 518 + case 0x68: 519 + case 0x6A: 520 + case 0x6C: 521 + return &ath_world_regdom_67_68_6A_6C; 522 + default: 523 + WARN_ON(1); 524 + return ath_default_world_regdomain(); 525 + } 526 + } 527 + 528 + bool ath_is_49ghz_allowed(u16 regdomain) 529 + { 530 + /* possibly more */ 531 + return regdomain == MKK9_MKKC; 532 + } 533 + EXPORT_SYMBOL(ath_is_49ghz_allowed); 534 + 535 + /* Frequency is one where radar detection is required */ 536 + static bool ath_is_radar_freq(u16 center_freq) 537 + { 538 + return (center_freq >= 5260 && center_freq <= 5700); 539 + } 540 + 541 + static void ath_force_clear_no_ir_chan(struct wiphy *wiphy, 542 + struct ieee80211_channel *ch) 543 + { 544 + const struct ieee80211_reg_rule *reg_rule; 545 + 546 + reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); 547 + if (IS_ERR(reg_rule)) 196 548 return; 197 - ath_reg_dyn_country(wiphy, reg, request); 549 + 550 + if (!(reg_rule->flags & NL80211_RRF_NO_IR)) 551 + if (ch->flags & IEEE80211_CHAN_NO_IR) 552 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 553 + } 554 + 555 + static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq) 556 + { 557 + struct ieee80211_channel *ch; 558 + 559 + ch = ieee80211_get_channel(wiphy, center_freq); 560 + if (!ch) 561 + return; 562 + 563 + ath_force_clear_no_ir_chan(wiphy, ch); 564 + } 565 + 566 + static void ath_force_no_ir_chan(struct ieee80211_channel *ch) 567 + { 568 + ch->flags |= IEEE80211_CHAN_NO_IR; 569 + } 570 + 571 + static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq) 572 + { 573 + struct ieee80211_channel *ch; 574 + 575 + ch = ieee80211_get_channel(wiphy, center_freq); 576 + if (!ch) 577 + return; 578 + 579 + ath_force_no_ir_chan(ch); 580 + } 581 + 582 + static void 583 + __ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 584 + struct ath_regulatory *reg, 585 + enum nl80211_reg_initiator initiator, 586 + struct ieee80211_channel *ch) 587 + { 588 + if (ath_is_radar_freq(ch->center_freq) || 589 + (ch->flags & IEEE80211_CHAN_RADAR)) 590 + return; 591 + 592 + switch (initiator) { 593 + case NL80211_REGDOM_SET_BY_COUNTRY_IE: 594 + ath_force_clear_no_ir_chan(wiphy, ch); 595 + break; 596 + case NL80211_REGDOM_SET_BY_USER: 597 + if (ath_reg_dyn_country_user_allow(reg)) 598 + ath_force_clear_no_ir_chan(wiphy, ch); 599 + break; 600 + default: 601 + if (ch->beacon_found) 602 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 603 + } 604 + } 605 + 606 + /* 607 + * These exception rules do not apply radar frequencies. 608 + * 609 + * - We enable initiating radiation if the country IE says its fine: 610 + * - If no country IE has been processed and a we determine we have 611 + * received a beacon on a channel we can enable initiating radiation. 612 + */ 613 + static void 614 + ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 615 + struct ath_regulatory *reg, 616 + enum nl80211_reg_initiator initiator) 617 + { 618 + enum ieee80211_band band; 619 + struct ieee80211_supported_band *sband; 620 + struct ieee80211_channel *ch; 621 + unsigned int i; 622 + 623 + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 624 + if (!wiphy->bands[band]) 625 + continue; 626 + sband = wiphy->bands[band]; 627 + for (i = 0; i < sband->n_channels; i++) { 628 + ch = &sband->channels[i]; 629 + __ath_reg_apply_beaconing_flags(wiphy, reg, 630 + initiator, ch); 631 + } 632 + } 633 + } 634 + 635 + /** 636 + * ath_reg_apply_ir_flags() 637 + * @wiphy: the wiphy to use 638 + * @initiator: the regulatory hint initiator 639 + * 640 + * If no country IE has been received always enable passive scan 641 + * and no-ibss on these channels. This is only done for specific 642 + * regulatory SKUs. 643 + * 644 + * If a country IE has been received check its rule for this 645 + * channel first before enabling active scan. The passive scan 646 + * would have been enforced by the initial processing of our 647 + * custom regulatory domain. 648 + */ 649 + static void 650 + ath_reg_apply_ir_flags(struct wiphy *wiphy, 651 + struct ath_regulatory *reg, 652 + enum nl80211_reg_initiator initiator) 653 + { 654 + struct ieee80211_supported_band *sband; 655 + 656 + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 657 + if (!sband) 658 + return; 659 + 660 + switch(initiator) { 661 + case NL80211_REGDOM_SET_BY_COUNTRY_IE: 662 + ath_force_clear_no_ir_freq(wiphy, 2467); 663 + ath_force_clear_no_ir_freq(wiphy, 2472); 664 + break; 665 + case NL80211_REGDOM_SET_BY_USER: 666 + if (!ath_reg_dyn_country_user_allow(reg)) 667 + break; 668 + ath_force_clear_no_ir_freq(wiphy, 2467); 669 + ath_force_clear_no_ir_freq(wiphy, 2472); 670 + break; 671 + default: 672 + ath_force_no_ir_freq(wiphy, 2467); 673 + ath_force_no_ir_freq(wiphy, 2472); 674 + } 675 + } 676 + 677 + /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ 678 + static void ath_reg_apply_radar_flags(struct wiphy *wiphy) 679 + { 680 + struct ieee80211_supported_band *sband; 681 + struct ieee80211_channel *ch; 682 + unsigned int i; 683 + 684 + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) 685 + return; 686 + 687 + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; 688 + 689 + for (i = 0; i < sband->n_channels; i++) { 690 + ch = &sband->channels[i]; 691 + if (!ath_is_radar_freq(ch->center_freq)) 692 + continue; 693 + /* We always enable radar detection/DFS on this 694 + * frequency range. Additionally we also apply on 695 + * this frequency range: 696 + * - If STA mode does not yet have DFS supports disable 697 + * active scanning 698 + * - If adhoc mode does not support DFS yet then 699 + * disable adhoc in the frequency. 700 + * - If AP mode does not yet support radar detection/DFS 701 + * do not allow AP mode 702 + */ 703 + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 704 + ch->flags |= IEEE80211_CHAN_RADAR | 705 + IEEE80211_CHAN_NO_IR; 706 + } 707 + } 708 + 709 + static void ath_reg_apply_world_flags(struct wiphy *wiphy, 710 + enum nl80211_reg_initiator initiator, 711 + struct ath_regulatory *reg) 712 + { 713 + switch (reg->regpair->regDmnEnum) { 714 + case 0x60: 715 + case 0x63: 716 + case 0x66: 717 + case 0x67: 718 + case 0x6C: 719 + ath_reg_apply_beaconing_flags(wiphy, reg, initiator); 720 + break; 721 + case 0x68: 722 + ath_reg_apply_beaconing_flags(wiphy, reg, initiator); 723 + ath_reg_apply_ir_flags(wiphy, reg, initiator); 724 + break; 725 + default: 726 + if (ath_reg_dyn_country_user_allow(reg)) 727 + ath_reg_apply_beaconing_flags(wiphy, reg, initiator); 728 + } 729 + } 730 + 731 + static u16 ath_regd_find_country_by_name(char *alpha2) 732 + { 733 + unsigned int i; 734 + 735 + for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 736 + if (!memcmp(allCountries[i].isoName, alpha2, 2)) 737 + return allCountries[i].countryCode; 738 + } 739 + 740 + return -1; 741 + } 742 + 743 + static int __ath_reg_dyn_country(struct wiphy *wiphy, 744 + struct ath_regulatory *reg, 745 + struct regulatory_request *request) 746 + { 747 + u16 country_code; 748 + 749 + if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 750 + !ath_is_world_regd(reg)) 751 + return -EINVAL; 752 + 753 + country_code = ath_regd_find_country_by_name(request->alpha2); 754 + if (country_code == (u16) -1) 755 + return -EINVAL; 756 + 757 + reg->current_rd = COUNTRY_ERD_FLAG; 758 + reg->current_rd |= country_code; 759 + 760 + __ath_regd_init(reg); 761 + 762 + ath_reg_apply_world_flags(wiphy, request->initiator, reg); 763 + 764 + return 0; 765 + } 766 + 767 + static void ath_reg_dyn_country(struct wiphy *wiphy, 768 + struct ath_regulatory *reg, 769 + struct regulatory_request *request) 770 + { 771 + if (__ath_reg_dyn_country(wiphy, reg, request)) 772 + return; 773 + 774 + printk(KERN_DEBUG "ath: regdomain 0x%0x " 775 + "dynamically updated by %s\n", 776 + reg->current_rd, 777 + reg_initiator_name(request->initiator)); 198 778 } 199 779 200 780 void ath_reg_notifier_apply(struct wiphy *wiphy, ··· 530 508 case NL80211_REGDOM_SET_BY_DRIVER: 531 509 break; 532 510 case NL80211_REGDOM_SET_BY_USER: 533 - ath_reg_dyn_country_user(wiphy, reg, request); 511 + if (ath_reg_dyn_country_user_allow(reg)) 512 + ath_reg_dyn_country(wiphy, reg, request); 534 513 break; 535 514 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 536 515 ath_reg_dyn_country(wiphy, reg, request); ··· 632 609 const struct ieee80211_regdomain *regd; 633 610 634 611 wiphy->reg_notifier = reg_notifier; 635 - wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 612 + wiphy->regulatory_flags |= REGULATORY_STRICT_REG; 636 613 637 614 if (ath_is_world_regd(reg)) { 638 615 /* ··· 640 617 * saved on the wiphy orig_* parameters 641 618 */ 642 619 regd = ath_world_regdomain(reg); 643 - wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 620 + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 621 + REGULATORY_COUNTRY_IE_FOLLOW_POWER; 644 622 } else { 645 623 /* 646 624 * This gets applied in the case of the absence of CRDA,
+1 -1
drivers/net/wireless/ath/wcn36xx/hal.h
··· 2644 2644 struct add_ba_info ba_info[STACFG_MAX_TC]; 2645 2645 } __packed; 2646 2646 2647 - struct wcn36xx_hal_trigget_ba_req_candidate { 2647 + struct wcn36xx_hal_trigger_ba_req_candidate { 2648 2648 u8 sta_index; 2649 2649 u8 tid_bitmap; 2650 2650 } __packed;
+2 -1
drivers/net/wireless/ath/wcn36xx/main.c
··· 641 641 dev_kfree_skb(skb); 642 642 } 643 643 644 - if (changed & BSS_CHANGED_BEACON_ENABLED) { 644 + if (changed & BSS_CHANGED_BEACON_ENABLED || 645 + changed & BSS_CHANGED_BEACON) { 645 646 wcn36xx_dbg(WCN36XX_DBG_MAC, 646 647 "mac bss changed beacon enabled %d\n", 647 648 bss_conf->enable_beacon);
+19 -2
drivers/net/wireless/ath/wcn36xx/smd.c
··· 115 115 } 116 116 } 117 117 118 + static void wcn36xx_smd_set_sta_default_ht_params( 119 + struct wcn36xx_hal_config_sta_params *sta_params) 120 + { 121 + sta_params->ht_capable = 1; 122 + sta_params->tx_channel_width_set = 1; 123 + sta_params->lsig_txop_protection = 1; 124 + sta_params->max_ampdu_size = 3; 125 + sta_params->max_ampdu_density = 5; 126 + sta_params->max_amsdu_size = 0; 127 + sta_params->sgi_20Mhz = 1; 128 + sta_params->sgi_40mhz = 1; 129 + sta_params->green_field_capable = 1; 130 + sta_params->delayed_ba_support = 0; 131 + sta_params->dsss_cck_mode_40mhz = 1; 132 + } 133 + 118 134 static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn, 119 135 struct ieee80211_vif *vif, 120 136 struct ieee80211_sta *sta, ··· 188 172 sizeof(priv_sta->supported_rates)); 189 173 } else { 190 174 wcn36xx_set_default_rates(&sta_params->supported_rates); 175 + wcn36xx_smd_set_sta_default_ht_params(sta_params); 191 176 } 192 177 } 193 178 ··· 1855 1838 int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) 1856 1839 { 1857 1840 struct wcn36xx_hal_trigger_ba_req_msg msg_body; 1858 - struct wcn36xx_hal_trigget_ba_req_candidate *candidate; 1841 + struct wcn36xx_hal_trigger_ba_req_candidate *candidate; 1859 1842 int ret = 0; 1860 1843 1861 1844 mutex_lock(&wcn->hal_mutex); ··· 1866 1849 msg_body.header.len += sizeof(*candidate); 1867 1850 PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 1868 1851 1869 - candidate = (struct wcn36xx_hal_trigget_ba_req_candidate *) 1852 + candidate = (struct wcn36xx_hal_trigger_ba_req_candidate *) 1870 1853 (wcn->hal_buf + sizeof(msg_body)); 1871 1854 candidate->sta_index = sta_index; 1872 1855 candidate->tid_bitmap = 1;
+1 -1
drivers/net/wireless/ath/wcn36xx/wcn36xx.h
··· 54 54 }; 55 55 56 56 #define wcn36xx_err(fmt, arg...) \ 57 - printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg); 57 + printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg) 58 58 59 59 #define wcn36xx_warn(fmt, arg...) \ 60 60 printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
+2 -3
drivers/net/wireless/brcm80211/Kconfig
··· 4 4 config BRCMSMAC 5 5 tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" 6 6 depends on MAC80211 7 - depends on BCMA 7 + depends on BCMA_POSSIBLE 8 + select BCMA 8 9 select NEW_LEDS if BCMA_DRIVER_GPIO 9 10 select LEDS_CLASS if BCMA_DRIVER_GPIO 10 11 select BRCMUTIL 11 12 select FW_LOADER 12 - select CRC_CCITT 13 - select CRC8 14 13 select CORDIC 15 14 ---help--- 16 15 This module adds support for PCIe wireless adapters based on Broadcom
+2 -1
drivers/net/wireless/brcm80211/brcmfmac/Makefile
··· 28 28 fweh.o \ 29 29 fwsignal.o \ 30 30 p2p.o \ 31 - dhd_cdc.o \ 31 + proto.o \ 32 + bcdc.o \ 32 33 dhd_common.o \ 33 34 dhd_linux.o \ 34 35 btcoex.o
+384
drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
··· 1 + /* 2 + * Copyright (c) 2010 Broadcom Corporation 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 ANY 11 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + 17 + /******************************************************************************* 18 + * Communicates with the dongle by using dcmd codes. 19 + * For certain dcmd codes, the dongle interprets string data from the host. 20 + ******************************************************************************/ 21 + 22 + #include <linux/types.h> 23 + #include <linux/netdevice.h> 24 + 25 + #include <brcmu_utils.h> 26 + #include <brcmu_wifi.h> 27 + 28 + #include "dhd.h" 29 + #include "dhd_bus.h" 30 + #include "fwsignal.h" 31 + #include "dhd_dbg.h" 32 + #include "tracepoint.h" 33 + #include "proto.h" 34 + #include "bcdc.h" 35 + 36 + struct brcmf_proto_bcdc_dcmd { 37 + __le32 cmd; /* dongle command value */ 38 + __le32 len; /* lower 16: output buflen; 39 + * upper 16: input buflen (excludes header) */ 40 + __le32 flags; /* flag defns given below */ 41 + __le32 status; /* status code returned from the device */ 42 + }; 43 + 44 + /* Max valid buffer size that can be sent to the dongle */ 45 + #define BCDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) 46 + 47 + /* BCDC flag definitions */ 48 + #define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */ 49 + #define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ 50 + #define BCDC_DCMD_IF_MASK 0xF000 /* I/F index */ 51 + #define BCDC_DCMD_IF_SHIFT 12 52 + #define BCDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */ 53 + #define BCDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */ 54 + #define BCDC_DCMD_ID(flags) \ 55 + (((flags) & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT) 56 + 57 + /* 58 + * BCDC header - Broadcom specific extension of CDC. 59 + * Used on data packets to convey priority across USB. 60 + */ 61 + #define BCDC_HEADER_LEN 4 62 + #define BCDC_PROTO_VER 2 /* Protocol version */ 63 + #define BCDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ 64 + #define BCDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ 65 + #define BCDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ 66 + #define BCDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ 67 + #define BCDC_PRIORITY_MASK 0x7 68 + #define BCDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ 69 + #define BCDC_FLAG2_IF_SHIFT 0 70 + 71 + #define BCDC_GET_IF_IDX(hdr) \ 72 + ((int)((((hdr)->flags2) & BCDC_FLAG2_IF_MASK) >> BCDC_FLAG2_IF_SHIFT)) 73 + #define BCDC_SET_IF_IDX(hdr, idx) \ 74 + ((hdr)->flags2 = (((hdr)->flags2 & ~BCDC_FLAG2_IF_MASK) | \ 75 + ((idx) << BCDC_FLAG2_IF_SHIFT))) 76 + 77 + /** 78 + * struct brcmf_proto_bcdc_header - BCDC header format 79 + * 80 + * @flags: flags contain protocol and checksum info. 81 + * @priority: 802.1d priority and USB flow control info (bit 4:7). 82 + * @flags2: additional flags containing dongle interface index. 83 + * @data_offset: start of packet data. header is following by firmware signals. 84 + */ 85 + struct brcmf_proto_bcdc_header { 86 + u8 flags; 87 + u8 priority; 88 + u8 flags2; 89 + u8 data_offset; 90 + }; 91 + 92 + /* 93 + * maximum length of firmware signal data between 94 + * the BCDC header and packet data in the tx path. 95 + */ 96 + #define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12 97 + 98 + #define RETRIES 2 /* # of retries to retrieve matching dcmd response */ 99 + #define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE 100 + * (amount of header tha might be added) 101 + * plus any space that might be needed 102 + * for bus alignment padding. 103 + */ 104 + #define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for 105 + * round off at the end of buffer 106 + * Currently is SDIO 107 + */ 108 + 109 + struct brcmf_bcdc { 110 + u16 reqid; 111 + u8 bus_header[BUS_HEADER_LEN]; 112 + struct brcmf_proto_bcdc_dcmd msg; 113 + unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; 114 + }; 115 + 116 + static int brcmf_proto_bcdc_msg(struct brcmf_pub *drvr) 117 + { 118 + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; 119 + int len = le32_to_cpu(bcdc->msg.len) + 120 + sizeof(struct brcmf_proto_bcdc_dcmd); 121 + 122 + brcmf_dbg(BCDC, "Enter\n"); 123 + 124 + /* NOTE : bcdc->msg.len holds the desired length of the buffer to be 125 + * returned. Only up to BCDC_MAX_MSG_SIZE of this buffer area 126 + * is actually sent to the dongle 127 + */ 128 + if (len > BCDC_MAX_MSG_SIZE) 129 + len = BCDC_MAX_MSG_SIZE; 130 + 131 + /* Send request */ 132 + return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); 133 + } 134 + 135 + static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) 136 + { 137 + int ret; 138 + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; 139 + 140 + brcmf_dbg(BCDC, "Enter\n"); 141 + len += sizeof(struct brcmf_proto_bcdc_dcmd); 142 + do { 143 + ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg, 144 + len); 145 + if (ret < 0) 146 + break; 147 + } while (BCDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id); 148 + 149 + return ret; 150 + } 151 + 152 + static int 153 + brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 154 + void *buf, uint len) 155 + { 156 + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; 157 + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; 158 + void *info; 159 + int ret = 0, retries = 0; 160 + u32 id, flags; 161 + 162 + brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); 163 + 164 + memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd)); 165 + 166 + msg->cmd = cpu_to_le32(cmd); 167 + msg->len = cpu_to_le32(len); 168 + flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT); 169 + flags = (flags & ~BCDC_DCMD_IF_MASK) | 170 + (ifidx << BCDC_DCMD_IF_SHIFT); 171 + msg->flags = cpu_to_le32(flags); 172 + 173 + if (buf) 174 + memcpy(bcdc->buf, buf, len); 175 + 176 + ret = brcmf_proto_bcdc_msg(drvr); 177 + if (ret < 0) { 178 + brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", 179 + ret); 180 + goto done; 181 + } 182 + 183 + retry: 184 + /* wait for interrupt and get first fragment */ 185 + ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len); 186 + if (ret < 0) 187 + goto done; 188 + 189 + flags = le32_to_cpu(msg->flags); 190 + id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT; 191 + 192 + if ((id < bcdc->reqid) && (++retries < RETRIES)) 193 + goto retry; 194 + if (id != bcdc->reqid) { 195 + brcmf_err("%s: unexpected request id %d (expected %d)\n", 196 + brcmf_ifname(drvr, ifidx), id, bcdc->reqid); 197 + ret = -EINVAL; 198 + goto done; 199 + } 200 + 201 + /* Check info buffer */ 202 + info = (void *)&msg[1]; 203 + 204 + /* Copy info buffer */ 205 + if (buf) { 206 + if (ret < (int)len) 207 + len = ret; 208 + memcpy(buf, info, len); 209 + } 210 + 211 + /* Check the ERROR flag */ 212 + if (flags & BCDC_DCMD_ERROR) 213 + ret = le32_to_cpu(msg->status); 214 + 215 + done: 216 + return ret; 217 + } 218 + 219 + static int 220 + brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 221 + void *buf, uint len) 222 + { 223 + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; 224 + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; 225 + int ret = 0; 226 + u32 flags, id; 227 + 228 + brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); 229 + 230 + memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd)); 231 + 232 + msg->cmd = cpu_to_le32(cmd); 233 + msg->len = cpu_to_le32(len); 234 + flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT) | BCDC_DCMD_SET; 235 + flags = (flags & ~BCDC_DCMD_IF_MASK) | 236 + (ifidx << BCDC_DCMD_IF_SHIFT); 237 + msg->flags = cpu_to_le32(flags); 238 + 239 + if (buf) 240 + memcpy(bcdc->buf, buf, len); 241 + 242 + ret = brcmf_proto_bcdc_msg(drvr); 243 + if (ret < 0) 244 + goto done; 245 + 246 + ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len); 247 + if (ret < 0) 248 + goto done; 249 + 250 + flags = le32_to_cpu(msg->flags); 251 + id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT; 252 + 253 + if (id != bcdc->reqid) { 254 + brcmf_err("%s: unexpected request id %d (expected %d)\n", 255 + brcmf_ifname(drvr, ifidx), id, bcdc->reqid); 256 + ret = -EINVAL; 257 + goto done; 258 + } 259 + 260 + /* Check the ERROR flag */ 261 + if (flags & BCDC_DCMD_ERROR) 262 + ret = le32_to_cpu(msg->status); 263 + 264 + done: 265 + return ret; 266 + } 267 + 268 + static void 269 + brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, 270 + struct sk_buff *pktbuf) 271 + { 272 + struct brcmf_proto_bcdc_header *h; 273 + 274 + brcmf_dbg(BCDC, "Enter\n"); 275 + 276 + /* Push BDC header used to convey priority for buses that don't */ 277 + skb_push(pktbuf, BCDC_HEADER_LEN); 278 + 279 + h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); 280 + 281 + h->flags = (BCDC_PROTO_VER << BCDC_FLAG_VER_SHIFT); 282 + if (pktbuf->ip_summed == CHECKSUM_PARTIAL) 283 + h->flags |= BCDC_FLAG_SUM_NEEDED; 284 + 285 + h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK); 286 + h->flags2 = 0; 287 + h->data_offset = offset; 288 + BCDC_SET_IF_IDX(h, ifidx); 289 + trace_brcmf_bcdchdr(pktbuf->data); 290 + } 291 + 292 + static int 293 + brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, 294 + struct sk_buff *pktbuf) 295 + { 296 + struct brcmf_proto_bcdc_header *h; 297 + 298 + brcmf_dbg(BCDC, "Enter\n"); 299 + 300 + /* Pop BCDC header used to convey priority for buses that don't */ 301 + if (pktbuf->len <= BCDC_HEADER_LEN) { 302 + brcmf_dbg(INFO, "rx data too short (%d <= %d)\n", 303 + pktbuf->len, BCDC_HEADER_LEN); 304 + return -EBADE; 305 + } 306 + 307 + trace_brcmf_bcdchdr(pktbuf->data); 308 + h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); 309 + 310 + *ifidx = BCDC_GET_IF_IDX(h); 311 + if (*ifidx >= BRCMF_MAX_IFS) { 312 + brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); 313 + return -EBADE; 314 + } 315 + /* The ifidx is the idx to map to matching netdev/ifp. When receiving 316 + * events this is easy because it contains the bssidx which maps 317 + * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. 318 + * bssidx 1 is used for p2p0 and no data can be received or 319 + * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 320 + */ 321 + if (*ifidx) 322 + (*ifidx)++; 323 + 324 + if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != 325 + BCDC_PROTO_VER) { 326 + brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", 327 + brcmf_ifname(drvr, *ifidx), h->flags); 328 + return -EBADE; 329 + } 330 + 331 + if (h->flags & BCDC_FLAG_SUM_GOOD) { 332 + brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n", 333 + brcmf_ifname(drvr, *ifidx), h->flags); 334 + pktbuf->ip_summed = CHECKSUM_UNNECESSARY; 335 + } 336 + 337 + pktbuf->priority = h->priority & BCDC_PRIORITY_MASK; 338 + 339 + skb_pull(pktbuf, BCDC_HEADER_LEN); 340 + if (do_fws) 341 + brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); 342 + else 343 + skb_pull(pktbuf, h->data_offset << 2); 344 + 345 + if (pktbuf->len == 0) 346 + return -ENODATA; 347 + return 0; 348 + } 349 + 350 + int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) 351 + { 352 + struct brcmf_bcdc *bcdc; 353 + 354 + bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC); 355 + if (!bcdc) 356 + goto fail; 357 + 358 + /* ensure that the msg buf directly follows the cdc msg struct */ 359 + if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) { 360 + brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n"); 361 + goto fail; 362 + } 363 + 364 + drvr->proto->hdrpush = brcmf_proto_bcdc_hdrpush; 365 + drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull; 366 + drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd; 367 + drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd; 368 + drvr->proto->pd = bcdc; 369 + 370 + drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; 371 + drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + 372 + sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN; 373 + return 0; 374 + 375 + fail: 376 + kfree(bcdc); 377 + return -ENOMEM; 378 + } 379 + 380 + void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) 381 + { 382 + kfree(drvr->proto->pd); 383 + drvr->proto->pd = NULL; 384 + }
+24
drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
··· 1 + /* 2 + * Copyright (c) 2013 Broadcom Corporation 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 ANY 11 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + #ifndef BRCMFMAC_BCDC_H 17 + #define BRCMFMAC_BCDC_H 18 + 19 + 20 + int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); 21 + void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); 22 + 23 + 24 + #endif /* BRCMFMAC_BCDC_H */
-3
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
··· 17 17 18 18 #include <linux/types.h> 19 19 #include <linux/netdevice.h> 20 - #include <linux/export.h> 21 20 #include <linux/pci.h> 22 21 #include <linux/pci_ids.h> 23 22 #include <linux/sched.h> ··· 773 774 774 775 return ret; 775 776 } 776 - EXPORT_SYMBOL(brcmf_sdio_probe); 777 777 778 778 int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) 779 779 { ··· 789 791 790 792 return 0; 791 793 } 792 - EXPORT_SYMBOL(brcmf_sdio_remove); 793 794 794 795 void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) 795 796 {
+32 -19
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
··· 158 158 } 159 159 } 160 160 161 - if (err_ret) 162 - brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", 163 - rw ? "write" : "read", func, regaddr, *byte, err_ret); 164 - 161 + if (err_ret) { 162 + /* 163 + * SleepCSR register access can fail when 164 + * waking up the device so reduce this noise 165 + * in the logs. 166 + */ 167 + if (regaddr != SBSDIO_FUNC1_SLEEPCSR) 168 + brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", 169 + rw ? "write" : "read", func, regaddr, *byte, 170 + err_ret); 171 + else 172 + brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", 173 + rw ? "write" : "read", func, regaddr, *byte, 174 + err_ret); 175 + } 165 176 return err_ret; 166 177 } 167 178 ··· 280 269 int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) 281 270 { 282 271 int err_ret = 0; 272 + struct mmc_host *host; 273 + struct sdio_func *func; 274 + uint max_blocks; 283 275 284 276 brcmf_dbg(SDIO, "\n"); 285 277 ··· 304 290 305 291 brcmf_sdioh_enablefuncs(sdiodev); 306 292 293 + /* 294 + * determine host related variables after brcmf_sdio_probe() 295 + * as func->cur_blksize is properly set and F2 init has been 296 + * completed successfully. 297 + */ 298 + func = sdiodev->func[2]; 299 + host = func->card->host; 300 + sdiodev->sg_support = host->max_segs > 1; 301 + max_blocks = min_t(uint, host->max_blk_count, 511u); 302 + sdiodev->max_request_size = min_t(uint, host->max_req_size, 303 + max_blocks * func->cur_blksize); 304 + sdiodev->max_segment_count = min_t(uint, host->max_segs, 305 + SG_MAX_SINGLE_ALLOC); 306 + sdiodev->max_segment_size = host->max_seg_size; 307 307 out: 308 308 sdio_release_host(sdiodev->func[1]); 309 309 brcmf_dbg(SDIO, "Done\n"); ··· 346 318 int err; 347 319 struct brcmf_sdio_dev *sdiodev; 348 320 struct brcmf_bus *bus_if; 349 - struct mmc_host *host; 350 - uint max_blocks; 351 321 352 322 brcmf_dbg(SDIO, "Enter\n"); 353 323 brcmf_dbg(SDIO, "Class=%x\n", func->class); ··· 393 367 goto fail; 394 368 } 395 369 396 - /* 397 - * determine host related variables after brcmf_sdio_probe() 398 - * as func->cur_blksize is properly set and F2 init has been 399 - * completed successfully. 400 - */ 401 - host = func->card->host; 402 - sdiodev->sg_support = host->max_segs > 1; 403 - max_blocks = min_t(uint, host->max_blk_count, 511u); 404 - sdiodev->max_request_size = min_t(uint, host->max_req_size, 405 - max_blocks * func->cur_blksize); 406 - sdiodev->max_segment_count = min_t(uint, host->max_segs, 407 - SG_MAX_SINGLE_ALLOC); 408 - sdiodev->max_segment_size = host->max_seg_size; 409 370 brcmf_dbg(SDIO, "F2 init completed...\n"); 410 371 return 0; 411 372
+8 -474
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
··· 25 25 26 26 #include "fweh.h" 27 27 28 - /******************************************************************************* 29 - * IO codes that are interpreted by dongle firmware 30 - ******************************************************************************/ 31 - #define BRCMF_C_GET_VERSION 1 32 - #define BRCMF_C_UP 2 33 - #define BRCMF_C_DOWN 3 34 - #define BRCMF_C_SET_PROMISC 10 35 - #define BRCMF_C_GET_RATE 12 36 - #define BRCMF_C_GET_INFRA 19 37 - #define BRCMF_C_SET_INFRA 20 38 - #define BRCMF_C_GET_AUTH 21 39 - #define BRCMF_C_SET_AUTH 22 40 - #define BRCMF_C_GET_BSSID 23 41 - #define BRCMF_C_GET_SSID 25 42 - #define BRCMF_C_SET_SSID 26 43 - #define BRCMF_C_TERMINATED 28 44 - #define BRCMF_C_GET_CHANNEL 29 45 - #define BRCMF_C_SET_CHANNEL 30 46 - #define BRCMF_C_GET_SRL 31 47 - #define BRCMF_C_SET_SRL 32 48 - #define BRCMF_C_GET_LRL 33 49 - #define BRCMF_C_SET_LRL 34 50 - #define BRCMF_C_GET_RADIO 37 51 - #define BRCMF_C_SET_RADIO 38 52 - #define BRCMF_C_GET_PHYTYPE 39 53 - #define BRCMF_C_SET_KEY 45 54 - #define BRCMF_C_SET_PASSIVE_SCAN 49 55 - #define BRCMF_C_SCAN 50 56 - #define BRCMF_C_SCAN_RESULTS 51 57 - #define BRCMF_C_DISASSOC 52 58 - #define BRCMF_C_REASSOC 53 59 - #define BRCMF_C_SET_ROAM_TRIGGER 55 60 - #define BRCMF_C_SET_ROAM_DELTA 57 61 - #define BRCMF_C_GET_BCNPRD 75 62 - #define BRCMF_C_SET_BCNPRD 76 63 - #define BRCMF_C_GET_DTIMPRD 77 64 - #define BRCMF_C_SET_DTIMPRD 78 65 - #define BRCMF_C_SET_COUNTRY 84 66 - #define BRCMF_C_GET_PM 85 67 - #define BRCMF_C_SET_PM 86 68 - #define BRCMF_C_GET_CURR_RATESET 114 69 - #define BRCMF_C_GET_AP 117 70 - #define BRCMF_C_SET_AP 118 71 - #define BRCMF_C_GET_RSSI 127 72 - #define BRCMF_C_GET_WSEC 133 73 - #define BRCMF_C_SET_WSEC 134 74 - #define BRCMF_C_GET_PHY_NOISE 135 75 - #define BRCMF_C_GET_BSS_INFO 136 76 - #define BRCMF_C_GET_BANDLIST 140 77 - #define BRCMF_C_SET_SCB_TIMEOUT 158 78 - #define BRCMF_C_GET_PHYLIST 180 79 - #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 80 - #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 81 - #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 82 - #define BRCMF_C_GET_VALID_CHANNELS 217 83 - #define BRCMF_C_GET_KEY_PRIMARY 235 84 - #define BRCMF_C_SET_KEY_PRIMARY 236 85 - #define BRCMF_C_SET_SCAN_PASSIVE_TIME 258 86 - #define BRCMF_C_GET_VAR 262 87 - #define BRCMF_C_SET_VAR 263 88 - 89 - /* phy types (returned by WLC_GET_PHYTPE) */ 90 - #define WLC_PHY_TYPE_A 0 91 - #define WLC_PHY_TYPE_B 1 92 - #define WLC_PHY_TYPE_G 2 93 - #define WLC_PHY_TYPE_N 4 94 - #define WLC_PHY_TYPE_LP 5 95 - #define WLC_PHY_TYPE_SSN 6 96 - #define WLC_PHY_TYPE_HT 7 97 - #define WLC_PHY_TYPE_LCN 8 98 - #define WLC_PHY_TYPE_NULL 0xf 99 - 100 28 #define TOE_TX_CSUM_OL 0x00000001 101 29 #define TOE_RX_CSUM_OL 0x00000002 102 - 103 - #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ 104 - 105 - /* size of brcmf_scan_params not including variable length array */ 106 - #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 107 - 108 - /* masks for channel and ssid count */ 109 - #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff 110 - #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 111 - 112 - /* primary (ie tx) key */ 113 - #define BRCMF_PRIMARY_KEY (1 << 1) 114 30 115 31 /* For supporting multiple interfaces */ 116 32 #define BRCMF_MAX_IFS 16 117 33 118 - #define DOT11_BSSTYPE_ANY 2 119 34 #define DOT11_MAX_DEFAULT_KEYS 4 120 - 121 - #define BRCMF_ESCAN_REQ_VERSION 1 122 - 123 - #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 124 - 125 - #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ 126 - #define BRCMF_STA_ASSOC 0x10 /* Associated */ 127 - 128 - #define BRCMF_E_STATUS_SUCCESS 0 129 - #define BRCMF_E_STATUS_FAIL 1 130 - #define BRCMF_E_STATUS_TIMEOUT 2 131 - #define BRCMF_E_STATUS_NO_NETWORKS 3 132 - #define BRCMF_E_STATUS_ABORT 4 133 - #define BRCMF_E_STATUS_NO_ACK 5 134 - #define BRCMF_E_STATUS_UNSOLICITED 6 135 - #define BRCMF_E_STATUS_ATTEMPT 7 136 - #define BRCMF_E_STATUS_PARTIAL 8 137 - #define BRCMF_E_STATUS_NEWSCAN 9 138 - #define BRCMF_E_STATUS_NEWASSOC 10 139 - #define BRCMF_E_STATUS_11HQUIET 11 140 - #define BRCMF_E_STATUS_SUPPRESS 12 141 - #define BRCMF_E_STATUS_NOCHANS 13 142 - #define BRCMF_E_STATUS_CS_ABORT 15 143 - #define BRCMF_E_STATUS_ERROR 16 144 - 145 - #define BRCMF_E_REASON_INITIAL_ASSOC 0 146 - #define BRCMF_E_REASON_LOW_RSSI 1 147 - #define BRCMF_E_REASON_DEAUTH 2 148 - #define BRCMF_E_REASON_DISASSOC 3 149 - #define BRCMF_E_REASON_BCNS_LOST 4 150 - #define BRCMF_E_REASON_MINTXRATE 9 151 - #define BRCMF_E_REASON_TXFAIL 10 152 - 153 - #define BRCMF_E_REASON_LINK_BSSCFG_DIS 4 154 - #define BRCMF_E_REASON_FAST_ROAM_FAILED 5 155 - #define BRCMF_E_REASON_DIRECTED_ROAM 6 156 - #define BRCMF_E_REASON_TSPEC_REJECTED 7 157 - #define BRCMF_E_REASON_BETTER_AP 8 158 - 159 - #define BRCMF_E_PRUNE_ENCR_MISMATCH 1 160 - #define BRCMF_E_PRUNE_BCAST_BSSID 2 161 - #define BRCMF_E_PRUNE_MAC_DENY 3 162 - #define BRCMF_E_PRUNE_MAC_NA 4 163 - #define BRCMF_E_PRUNE_REG_PASSV 5 164 - #define BRCMF_E_PRUNE_SPCT_MGMT 6 165 - #define BRCMF_E_PRUNE_RADAR 7 166 - #define BRCMF_E_RSN_MISMATCH 8 167 - #define BRCMF_E_PRUNE_NO_COMMON_RATES 9 168 - #define BRCMF_E_PRUNE_BASIC_RATES 10 169 - #define BRCMF_E_PRUNE_CIPHER_NA 12 170 - #define BRCMF_E_PRUNE_KNOWN_STA 13 171 - #define BRCMF_E_PRUNE_WDS_PEER 15 172 - #define BRCMF_E_PRUNE_QBSS_LOAD 16 173 - #define BRCMF_E_PRUNE_HOME_AP 17 174 - 175 - #define BRCMF_E_SUP_OTHER 0 176 - #define BRCMF_E_SUP_DECRYPT_KEY_DATA 1 177 - #define BRCMF_E_SUP_BAD_UCAST_WEP128 2 178 - #define BRCMF_E_SUP_BAD_UCAST_WEP40 3 179 - #define BRCMF_E_SUP_UNSUP_KEY_LEN 4 180 - #define BRCMF_E_SUP_PW_KEY_CIPHER 5 181 - #define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6 182 - #define BRCMF_E_SUP_MSG3_IE_MISMATCH 7 183 - #define BRCMF_E_SUP_NO_INSTALL_FLAG 8 184 - #define BRCMF_E_SUP_MSG3_NO_GTK 9 185 - #define BRCMF_E_SUP_GRP_KEY_CIPHER 10 186 - #define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11 187 - #define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12 188 - #define BRCMF_E_SUP_SEND_FAIL 13 189 - #define BRCMF_E_SUP_DEAUTH 14 190 - 191 - #define BRCMF_E_IF_ADD 1 192 - #define BRCMF_E_IF_DEL 2 193 - #define BRCMF_E_IF_CHANGE 3 194 - 195 - #define BRCMF_E_IF_FLAG_NOIF 1 196 - 197 - #define BRCMF_E_IF_ROLE_STA 0 198 - #define BRCMF_E_IF_ROLE_AP 1 199 - #define BRCMF_E_IF_ROLE_WDS 2 200 - 201 - #define BRCMF_E_LINK_BCN_LOSS 1 202 - #define BRCMF_E_LINK_DISASSOC 2 203 - #define BRCMF_E_LINK_ASSOC_REC 3 204 - #define BRCMF_E_LINK_BSSCFG_DIS 4 205 35 206 36 /* Small, medium and maximum buffer size for dcmd 207 37 */ ··· 41 211 42 212 #define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256 43 213 44 - /* Pattern matching filter. Specifies an offset within received packets to 45 - * start matching, the pattern to match, the size of the pattern, and a bitmask 46 - * that indicates which bits within the pattern should be matched. 214 + /* Length of firmware version string stored for 215 + * ethtool driver info which uses 32 bytes as well. 47 216 */ 48 - struct brcmf_pkt_filter_pattern_le { 49 - /* 50 - * Offset within received packet to start pattern matching. 51 - * Offset '0' is the first byte of the ethernet header. 52 - */ 53 - __le32 offset; 54 - /* Size of the pattern. Bitmask must be the same size.*/ 55 - __le32 size_bytes; 56 - /* 57 - * Variable length mask and pattern data. mask starts at offset 0. 58 - * Pattern immediately follows mask. 59 - */ 60 - u8 mask_and_pattern[1]; 61 - }; 62 - 63 - /* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ 64 - struct brcmf_pkt_filter_le { 65 - __le32 id; /* Unique filter id, specified by app. */ 66 - __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ 67 - __le32 negate_match; /* Negate the result of filter matches */ 68 - union { /* Filter definitions */ 69 - struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */ 70 - } u; 71 - }; 72 - 73 - /* IOVAR "pkt_filter_enable" parameter. */ 74 - struct brcmf_pkt_filter_enable_le { 75 - __le32 id; /* Unique filter id */ 76 - __le32 enable; /* Enable/disable bool */ 77 - }; 78 - 79 - /* BSS info structure 80 - * Applications MUST CHECK ie_offset field and length field to access IEs and 81 - * next bss_info structure in a vector (in struct brcmf_scan_results) 82 - */ 83 - struct brcmf_bss_info_le { 84 - __le32 version; /* version field */ 85 - __le32 length; /* byte length of data in this record, 86 - * starting at version and including IEs 87 - */ 88 - u8 BSSID[ETH_ALEN]; 89 - __le16 beacon_period; /* units are Kusec */ 90 - __le16 capability; /* Capability information */ 91 - u8 SSID_len; 92 - u8 SSID[32]; 93 - struct { 94 - __le32 count; /* # rates in this set */ 95 - u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ 96 - } rateset; /* supported rates */ 97 - __le16 chanspec; /* chanspec for bss */ 98 - __le16 atim_window; /* units are Kusec */ 99 - u8 dtim_period; /* DTIM period */ 100 - __le16 RSSI; /* receive signal strength (in dBm) */ 101 - s8 phy_noise; /* noise (in dBm) */ 102 - 103 - u8 n_cap; /* BSS is 802.11N Capable */ 104 - /* 802.11N BSS Capabilities (based on HT_CAP_*): */ 105 - __le32 nbss_cap; 106 - u8 ctl_ch; /* 802.11N BSS control channel number */ 107 - __le32 reserved32[1]; /* Reserved for expansion of BSS properties */ 108 - u8 flags; /* flags */ 109 - u8 reserved[3]; /* Reserved for expansion of BSS properties */ 110 - u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ 111 - 112 - __le16 ie_offset; /* offset at which IEs start, from beginning */ 113 - __le32 ie_length; /* byte length of Information Elements */ 114 - __le16 SNR; /* average SNR of during frame reception */ 115 - /* Add new fields here */ 116 - /* variable length Information Elements */ 117 - }; 118 - 119 - struct brcm_rateset_le { 120 - /* # rates in this set */ 121 - __le32 count; 122 - /* rates in 500kbps units w/hi bit set if basic */ 123 - u8 rates[BRCMF_MAXRATES_IN_SET]; 124 - }; 125 - 126 - struct brcmf_ssid { 127 - u32 SSID_len; 128 - unsigned char SSID[32]; 129 - }; 130 - 131 - struct brcmf_ssid_le { 132 - __le32 SSID_len; 133 - unsigned char SSID[32]; 134 - }; 135 - 136 - struct brcmf_scan_params_le { 137 - struct brcmf_ssid_le ssid_le; /* default: {0, ""} */ 138 - u8 bssid[ETH_ALEN]; /* default: bcast */ 139 - s8 bss_type; /* default: any, 140 - * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT 141 - */ 142 - u8 scan_type; /* flags, 0 use default */ 143 - __le32 nprobes; /* -1 use default, number of probes per channel */ 144 - __le32 active_time; /* -1 use default, dwell time per channel for 145 - * active scanning 146 - */ 147 - __le32 passive_time; /* -1 use default, dwell time per channel 148 - * for passive scanning 149 - */ 150 - __le32 home_time; /* -1 use default, dwell time for the 151 - * home channel between channel scans 152 - */ 153 - __le32 channel_num; /* count of channels and ssids that follow 154 - * 155 - * low half is count of channels in 156 - * channel_list, 0 means default (use all 157 - * available channels) 158 - * 159 - * high half is entries in struct brcmf_ssid 160 - * array that follows channel_list, aligned for 161 - * s32 (4 bytes) meaning an odd channel count 162 - * implies a 2-byte pad between end of 163 - * channel_list and first ssid 164 - * 165 - * if ssid count is zero, single ssid in the 166 - * fixed parameter portion is assumed, otherwise 167 - * ssid in the fixed portion is ignored 168 - */ 169 - __le16 channel_list[1]; /* list of chanspecs */ 170 - }; 171 - 172 - struct brcmf_scan_results { 173 - u32 buflen; 174 - u32 version; 175 - u32 count; 176 - struct brcmf_bss_info_le bss_info_le[]; 177 - }; 178 - 179 - struct brcmf_escan_params_le { 180 - __le32 version; 181 - __le16 action; 182 - __le16 sync_id; 183 - struct brcmf_scan_params_le params_le; 184 - }; 185 - 186 - struct brcmf_escan_result_le { 187 - __le32 buflen; 188 - __le32 version; 189 - __le16 sync_id; 190 - __le16 bss_count; 191 - struct brcmf_bss_info_le bss_info_le; 192 - }; 193 - 194 - #define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \ 195 - sizeof(struct brcmf_bss_info_le)) 196 - 197 - /* used for association with a specific BSSID and chanspec list */ 198 - struct brcmf_assoc_params_le { 199 - /* 00:00:00:00:00:00: broadcast scan */ 200 - u8 bssid[ETH_ALEN]; 201 - /* 0: all available channels, otherwise count of chanspecs in 202 - * chanspec_list */ 203 - __le32 chanspec_num; 204 - /* list of chanspecs */ 205 - __le16 chanspec_list[1]; 206 - }; 207 - 208 - /* used for join with or without a specific bssid and channel list */ 209 - struct brcmf_join_params { 210 - struct brcmf_ssid_le ssid_le; 211 - struct brcmf_assoc_params_le params_le; 212 - }; 213 - 214 - /* scan params for extended join */ 215 - struct brcmf_join_scan_params_le { 216 - u8 scan_type; /* 0 use default, active or passive scan */ 217 - __le32 nprobes; /* -1 use default, nr of probes per channel */ 218 - __le32 active_time; /* -1 use default, dwell time per channel for 219 - * active scanning 220 - */ 221 - __le32 passive_time; /* -1 use default, dwell time per channel 222 - * for passive scanning 223 - */ 224 - __le32 home_time; /* -1 use default, dwell time for the home 225 - * channel between channel scans 226 - */ 227 - }; 228 - 229 - /* extended join params */ 230 - struct brcmf_ext_join_params_le { 231 - struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */ 232 - struct brcmf_join_scan_params_le scan_le; 233 - struct brcmf_assoc_params_le assoc_le; 234 - }; 235 - 236 - struct brcmf_wsec_key { 237 - u32 index; /* key index */ 238 - u32 len; /* key length */ 239 - u8 data[WLAN_MAX_KEY_LEN]; /* key data */ 240 - u32 pad_1[18]; 241 - u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ 242 - u32 flags; /* misc flags */ 243 - u32 pad_2[3]; 244 - u32 iv_initialized; /* has IV been initialized already? */ 245 - u32 pad_3; 246 - /* Rx IV */ 247 - struct { 248 - u32 hi; /* upper 32 bits of IV */ 249 - u16 lo; /* lower 16 bits of IV */ 250 - } rxiv; 251 - u32 pad_4[2]; 252 - u8 ea[ETH_ALEN]; /* per station */ 253 - }; 254 - 255 - /* 256 - * dongle requires same struct as above but with fields in little endian order 257 - */ 258 - struct brcmf_wsec_key_le { 259 - __le32 index; /* key index */ 260 - __le32 len; /* key length */ 261 - u8 data[WLAN_MAX_KEY_LEN]; /* key data */ 262 - __le32 pad_1[18]; 263 - __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ 264 - __le32 flags; /* misc flags */ 265 - __le32 pad_2[3]; 266 - __le32 iv_initialized; /* has IV been initialized already? */ 267 - __le32 pad_3; 268 - /* Rx IV */ 269 - struct { 270 - __le32 hi; /* upper 32 bits of IV */ 271 - __le16 lo; /* lower 16 bits of IV */ 272 - } rxiv; 273 - __le32 pad_4[2]; 274 - u8 ea[ETH_ALEN]; /* per station */ 275 - }; 276 - 277 - /* Used to get specific STA parameters */ 278 - struct brcmf_scb_val_le { 279 - __le32 val; 280 - u8 ea[ETH_ALEN]; 281 - }; 282 - 283 - /* channel encoding */ 284 - struct brcmf_channel_info_le { 285 - __le32 hw_channel; 286 - __le32 target_channel; 287 - __le32 scan_channel; 288 - }; 289 - 290 - struct brcmf_sta_info_le { 291 - __le16 ver; /* version of this struct */ 292 - __le16 len; /* length in bytes of this structure */ 293 - __le16 cap; /* sta's advertised capabilities */ 294 - __le32 flags; /* flags defined below */ 295 - __le32 idle; /* time since data pkt rx'd from sta */ 296 - u8 ea[ETH_ALEN]; /* Station address */ 297 - __le32 count; /* # rates in this set */ 298 - u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ 299 - /* w/hi bit set if basic */ 300 - __le32 in; /* seconds elapsed since associated */ 301 - __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ 302 - __le32 tx_pkts; /* # of packets transmitted */ 303 - __le32 tx_failures; /* # of packets failed */ 304 - __le32 rx_ucast_pkts; /* # of unicast packets received */ 305 - __le32 rx_mcast_pkts; /* # of multicast packets received */ 306 - __le32 tx_rate; /* Rate of last successful tx frame */ 307 - __le32 rx_rate; /* Rate of last successful rx frame */ 308 - __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ 309 - __le32 rx_decrypt_failures; /* # of packet decrypted failed */ 310 - }; 311 - 312 - struct brcmf_chanspec_list { 313 - __le32 count; /* # of entries */ 314 - __le32 element[1]; /* variable length uint32 list */ 315 - }; 316 - 317 - /* 318 - * WLC_E_PROBRESP_MSG 319 - * WLC_E_P2P_PROBREQ_MSG 320 - * WLC_E_ACTION_FRAME_RX 321 - */ 322 - struct brcmf_rx_mgmt_data { 323 - __be16 version; 324 - __be16 chanspec; 325 - __be32 rssi; 326 - __be32 mactime; 327 - __be32 rate; 328 - }; 217 + #define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 329 218 330 219 /* Bus independent dongle command */ 331 220 struct brcmf_dcmd { ··· 84 535 struct brcmf_pub { 85 536 /* Linkage ponters */ 86 537 struct brcmf_bus *bus_if; 87 - struct brcmf_proto *prot; 538 + struct brcmf_proto *proto; 88 539 struct brcmf_cfg80211_info *config; 89 540 90 541 /* Internal brcmf items */ ··· 93 544 u8 wme_dp; /* wme discard priority */ 94 545 95 546 /* Dongle media info */ 96 - unsigned long drv_version; /* Version of dongle-resident driver */ 547 + char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN]; 97 548 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ 98 549 99 550 /* Multicast data packets sent to dongle */ ··· 113 564 #ifdef DEBUG 114 565 struct dentry *dbgfs_dir; 115 566 #endif 116 - }; 117 - 118 - struct brcmf_if_event { 119 - u8 ifidx; 120 - u8 action; 121 - u8 flags; 122 - u8 bssidx; 123 - u8 role; 124 567 }; 125 568 126 569 /* forward declarations */ ··· 176 635 /* Return pointer to interface name */ 177 636 char *brcmf_ifname(struct brcmf_pub *drvr, int idx); 178 637 179 - /* Query dongle */ 180 - int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 181 - void *buf, uint len); 182 - int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 183 - void *buf, uint len); 184 - 185 - /* Remove any protocol-specific data header. */ 186 - int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, 187 - struct sk_buff *rxp); 188 - 189 638 int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); 190 639 struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, 191 640 char *name, u8 *mac_addr); ··· 185 654 u32 brcmf_get_chip_info(struct brcmf_if *ifp); 186 655 void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, 187 656 bool success); 657 + 658 + /* Sets dongle media info (drv_version, mac address). */ 659 + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); 188 660 189 661 #endif /* _BRCMF_H_ */
+13 -2
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
··· 34 34 /** 35 35 * struct brcmf_bus_ops - bus callback operations. 36 36 * 37 + * @preinit: execute bus/device specific dongle init commands (optional). 37 38 * @init: prepare for communication with dongle. 38 39 * @stop: clear pending frames, disable data flow. 39 40 * @txdata: send a data frame to the dongle. When the data ··· 52 51 * indicated otherwise these callbacks are mandatory. 53 52 */ 54 53 struct brcmf_bus_ops { 54 + int (*preinit)(struct device *dev); 55 55 int (*init)(struct device *dev); 56 56 void (*stop)(struct device *dev); 57 57 int (*txdata)(struct device *dev, struct sk_buff *skb); ··· 87 85 unsigned long tx_realloc; 88 86 u32 chip; 89 87 u32 chiprev; 90 - struct list_head dcmd_list; 91 88 92 89 struct brcmf_bus_ops *ops; 93 90 }; ··· 94 93 /* 95 94 * callback wrappers 96 95 */ 96 + static inline int brcmf_bus_preinit(struct brcmf_bus *bus) 97 + { 98 + if (!bus->ops->preinit) 99 + return 0; 100 + return bus->ops->preinit(bus->dev); 101 + } 102 + 97 103 static inline int brcmf_bus_init(struct brcmf_bus *bus) 98 104 { 99 105 return bus->ops->init(bus->dev); ··· 147 139 void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); 148 140 149 141 /* Indication from bus module regarding presence/insertion of dongle. */ 150 - int brcmf_attach(uint bus_hdrlen, struct device *dev); 142 + int brcmf_attach(struct device *dev); 151 143 /* Indication from bus module regarding removal/absence of dongle */ 152 144 void brcmf_detach(struct device *dev); 153 145 /* Indication from bus module that dongle should be reset */ ··· 159 151 void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); 160 152 161 153 int brcmf_bus_start(struct device *dev); 154 + s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, 155 + u32 len); 156 + void brcmf_bus_add_txhdrlen(struct device *dev, uint len); 162 157 163 158 #ifdef CONFIG_BRCMFMAC_SDIO 164 159 void brcmf_sdio_exit(void);
-392
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
··· 1 - /* 2 - * Copyright (c) 2010 Broadcom Corporation 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 ANY 11 - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 - */ 16 - 17 - /******************************************************************************* 18 - * Communicates with the dongle by using dcmd codes. 19 - * For certain dcmd codes, the dongle interprets string data from the host. 20 - ******************************************************************************/ 21 - 22 - #include <linux/types.h> 23 - #include <linux/netdevice.h> 24 - 25 - #include <brcmu_utils.h> 26 - #include <brcmu_wifi.h> 27 - 28 - #include "dhd.h" 29 - #include "dhd_proto.h" 30 - #include "dhd_bus.h" 31 - #include "fwsignal.h" 32 - #include "dhd_dbg.h" 33 - #include "tracepoint.h" 34 - 35 - struct brcmf_proto_cdc_dcmd { 36 - __le32 cmd; /* dongle command value */ 37 - __le32 len; /* lower 16: output buflen; 38 - * upper 16: input buflen (excludes header) */ 39 - __le32 flags; /* flag defns given below */ 40 - __le32 status; /* status code returned from the device */ 41 - }; 42 - 43 - /* Max valid buffer size that can be sent to the dongle */ 44 - #define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) 45 - 46 - /* CDC flag definitions */ 47 - #define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */ 48 - #define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ 49 - #define CDC_DCMD_IF_MASK 0xF000 /* I/F index */ 50 - #define CDC_DCMD_IF_SHIFT 12 51 - #define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */ 52 - #define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */ 53 - #define CDC_DCMD_ID(flags) \ 54 - (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT) 55 - 56 - /* 57 - * BDC header - Broadcom specific extension of CDC. 58 - * Used on data packets to convey priority across USB. 59 - */ 60 - #define BDC_HEADER_LEN 4 61 - #define BDC_PROTO_VER 2 /* Protocol version */ 62 - #define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ 63 - #define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ 64 - #define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ 65 - #define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ 66 - #define BDC_PRIORITY_MASK 0x7 67 - #define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ 68 - #define BDC_FLAG2_IF_SHIFT 0 69 - 70 - #define BDC_GET_IF_IDX(hdr) \ 71 - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) 72 - #define BDC_SET_IF_IDX(hdr, idx) \ 73 - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ 74 - ((idx) << BDC_FLAG2_IF_SHIFT))) 75 - 76 - /** 77 - * struct brcmf_proto_bdc_header - BDC header format 78 - * 79 - * @flags: flags contain protocol and checksum info. 80 - * @priority: 802.1d priority and USB flow control info (bit 4:7). 81 - * @flags2: additional flags containing dongle interface index. 82 - * @data_offset: start of packet data. header is following by firmware signals. 83 - */ 84 - struct brcmf_proto_bdc_header { 85 - u8 flags; 86 - u8 priority; 87 - u8 flags2; 88 - u8 data_offset; 89 - }; 90 - 91 - /* 92 - * maximum length of firmware signal data between 93 - * the BDC header and packet data in the tx path. 94 - */ 95 - #define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12 96 - 97 - #define RETRIES 2 /* # of retries to retrieve matching dcmd response */ 98 - #define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE 99 - * (amount of header tha might be added) 100 - * plus any space that might be needed 101 - * for bus alignment padding. 102 - */ 103 - #define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for 104 - * round off at the end of buffer 105 - * Currently is SDIO 106 - */ 107 - 108 - struct brcmf_proto { 109 - u16 reqid; 110 - u8 bus_header[BUS_HEADER_LEN]; 111 - struct brcmf_proto_cdc_dcmd msg; 112 - unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; 113 - }; 114 - 115 - static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) 116 - { 117 - struct brcmf_proto *prot = drvr->prot; 118 - int len = le32_to_cpu(prot->msg.len) + 119 - sizeof(struct brcmf_proto_cdc_dcmd); 120 - 121 - brcmf_dbg(CDC, "Enter\n"); 122 - 123 - /* NOTE : cdc->msg.len holds the desired length of the buffer to be 124 - * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area 125 - * is actually sent to the dongle 126 - */ 127 - if (len > CDC_MAX_MSG_SIZE) 128 - len = CDC_MAX_MSG_SIZE; 129 - 130 - /* Send request */ 131 - return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len); 132 - } 133 - 134 - static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) 135 - { 136 - int ret; 137 - struct brcmf_proto *prot = drvr->prot; 138 - 139 - brcmf_dbg(CDC, "Enter\n"); 140 - len += sizeof(struct brcmf_proto_cdc_dcmd); 141 - do { 142 - ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg, 143 - len); 144 - if (ret < 0) 145 - break; 146 - } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id); 147 - 148 - return ret; 149 - } 150 - 151 - int 152 - brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 153 - void *buf, uint len) 154 - { 155 - struct brcmf_proto *prot = drvr->prot; 156 - struct brcmf_proto_cdc_dcmd *msg = &prot->msg; 157 - void *info; 158 - int ret = 0, retries = 0; 159 - u32 id, flags; 160 - 161 - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); 162 - 163 - memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); 164 - 165 - msg->cmd = cpu_to_le32(cmd); 166 - msg->len = cpu_to_le32(len); 167 - flags = (++prot->reqid << CDC_DCMD_ID_SHIFT); 168 - flags = (flags & ~CDC_DCMD_IF_MASK) | 169 - (ifidx << CDC_DCMD_IF_SHIFT); 170 - msg->flags = cpu_to_le32(flags); 171 - 172 - if (buf) 173 - memcpy(prot->buf, buf, len); 174 - 175 - ret = brcmf_proto_cdc_msg(drvr); 176 - if (ret < 0) { 177 - brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n", 178 - ret); 179 - goto done; 180 - } 181 - 182 - retry: 183 - /* wait for interrupt and get first fragment */ 184 - ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); 185 - if (ret < 0) 186 - goto done; 187 - 188 - flags = le32_to_cpu(msg->flags); 189 - id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; 190 - 191 - if ((id < prot->reqid) && (++retries < RETRIES)) 192 - goto retry; 193 - if (id != prot->reqid) { 194 - brcmf_err("%s: unexpected request id %d (expected %d)\n", 195 - brcmf_ifname(drvr, ifidx), id, prot->reqid); 196 - ret = -EINVAL; 197 - goto done; 198 - } 199 - 200 - /* Check info buffer */ 201 - info = (void *)&msg[1]; 202 - 203 - /* Copy info buffer */ 204 - if (buf) { 205 - if (ret < (int)len) 206 - len = ret; 207 - memcpy(buf, info, len); 208 - } 209 - 210 - /* Check the ERROR flag */ 211 - if (flags & CDC_DCMD_ERROR) 212 - ret = le32_to_cpu(msg->status); 213 - 214 - done: 215 - return ret; 216 - } 217 - 218 - int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 219 - void *buf, uint len) 220 - { 221 - struct brcmf_proto *prot = drvr->prot; 222 - struct brcmf_proto_cdc_dcmd *msg = &prot->msg; 223 - int ret = 0; 224 - u32 flags, id; 225 - 226 - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); 227 - 228 - memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); 229 - 230 - msg->cmd = cpu_to_le32(cmd); 231 - msg->len = cpu_to_le32(len); 232 - flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET; 233 - flags = (flags & ~CDC_DCMD_IF_MASK) | 234 - (ifidx << CDC_DCMD_IF_SHIFT); 235 - msg->flags = cpu_to_le32(flags); 236 - 237 - if (buf) 238 - memcpy(prot->buf, buf, len); 239 - 240 - ret = brcmf_proto_cdc_msg(drvr); 241 - if (ret < 0) 242 - goto done; 243 - 244 - ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); 245 - if (ret < 0) 246 - goto done; 247 - 248 - flags = le32_to_cpu(msg->flags); 249 - id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; 250 - 251 - if (id != prot->reqid) { 252 - brcmf_err("%s: unexpected request id %d (expected %d)\n", 253 - brcmf_ifname(drvr, ifidx), id, prot->reqid); 254 - ret = -EINVAL; 255 - goto done; 256 - } 257 - 258 - /* Check the ERROR flag */ 259 - if (flags & CDC_DCMD_ERROR) 260 - ret = le32_to_cpu(msg->status); 261 - 262 - done: 263 - return ret; 264 - } 265 - 266 - static bool pkt_sum_needed(struct sk_buff *skb) 267 - { 268 - return skb->ip_summed == CHECKSUM_PARTIAL; 269 - } 270 - 271 - static void pkt_set_sum_good(struct sk_buff *skb, bool x) 272 - { 273 - skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); 274 - } 275 - 276 - void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, 277 - struct sk_buff *pktbuf) 278 - { 279 - struct brcmf_proto_bdc_header *h; 280 - 281 - brcmf_dbg(CDC, "Enter\n"); 282 - 283 - /* Push BDC header used to convey priority for buses that don't */ 284 - skb_push(pktbuf, BDC_HEADER_LEN); 285 - 286 - h = (struct brcmf_proto_bdc_header *)(pktbuf->data); 287 - 288 - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); 289 - if (pkt_sum_needed(pktbuf)) 290 - h->flags |= BDC_FLAG_SUM_NEEDED; 291 - 292 - h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); 293 - h->flags2 = 0; 294 - h->data_offset = offset; 295 - BDC_SET_IF_IDX(h, ifidx); 296 - trace_brcmf_bdchdr(pktbuf->data); 297 - } 298 - 299 - int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, 300 - struct sk_buff *pktbuf) 301 - { 302 - struct brcmf_proto_bdc_header *h; 303 - 304 - brcmf_dbg(CDC, "Enter\n"); 305 - 306 - /* Pop BDC header used to convey priority for buses that don't */ 307 - 308 - if (pktbuf->len <= BDC_HEADER_LEN) { 309 - brcmf_dbg(INFO, "rx data too short (%d <= %d)\n", 310 - pktbuf->len, BDC_HEADER_LEN); 311 - return -EBADE; 312 - } 313 - 314 - trace_brcmf_bdchdr(pktbuf->data); 315 - h = (struct brcmf_proto_bdc_header *)(pktbuf->data); 316 - 317 - *ifidx = BDC_GET_IF_IDX(h); 318 - if (*ifidx >= BRCMF_MAX_IFS) { 319 - brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); 320 - return -EBADE; 321 - } 322 - /* The ifidx is the idx to map to matching netdev/ifp. When receiving 323 - * events this is easy because it contains the bssidx which maps 324 - * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. 325 - * bssidx 1 is used for p2p0 and no data can be received or 326 - * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 327 - */ 328 - if (*ifidx) 329 - (*ifidx)++; 330 - 331 - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != 332 - BDC_PROTO_VER) { 333 - brcmf_err("%s: non-BDC packet received, flags 0x%x\n", 334 - brcmf_ifname(drvr, *ifidx), h->flags); 335 - return -EBADE; 336 - } 337 - 338 - if (h->flags & BDC_FLAG_SUM_GOOD) { 339 - brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n", 340 - brcmf_ifname(drvr, *ifidx), h->flags); 341 - pkt_set_sum_good(pktbuf, true); 342 - } 343 - 344 - pktbuf->priority = h->priority & BDC_PRIORITY_MASK; 345 - 346 - skb_pull(pktbuf, BDC_HEADER_LEN); 347 - if (do_fws) 348 - brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); 349 - else 350 - skb_pull(pktbuf, h->data_offset << 2); 351 - 352 - if (pktbuf->len == 0) 353 - return -ENODATA; 354 - return 0; 355 - } 356 - 357 - int brcmf_proto_attach(struct brcmf_pub *drvr) 358 - { 359 - struct brcmf_proto *cdc; 360 - 361 - cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC); 362 - if (!cdc) 363 - goto fail; 364 - 365 - /* ensure that the msg buf directly follows the cdc msg struct */ 366 - if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) { 367 - brcmf_err("struct brcmf_proto is not correctly defined\n"); 368 - goto fail; 369 - } 370 - 371 - drvr->prot = cdc; 372 - drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; 373 - drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + 374 - sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; 375 - return 0; 376 - 377 - fail: 378 - kfree(cdc); 379 - return -ENOMEM; 380 - } 381 - 382 - /* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ 383 - void brcmf_proto_detach(struct brcmf_pub *drvr) 384 - { 385 - kfree(drvr->prot); 386 - drvr->prot = NULL; 387 - } 388 - 389 - void brcmf_proto_stop(struct brcmf_pub *drvr) 390 - { 391 - /* Nothing to do for CDC */ 392 - }
+8 -14
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
··· 21 21 #include <brcmu_utils.h> 22 22 #include "dhd.h" 23 23 #include "dhd_bus.h" 24 - #include "dhd_proto.h" 25 24 #include "dhd_dbg.h" 26 25 #include "fwil.h" 26 + #include "fwil_types.h" 27 27 #include "tracepoint.h" 28 28 29 29 #define PKTFILTER_BUF_SIZE 128 ··· 257 257 u8 buf[BRCMF_DCMD_SMLEN]; 258 258 char *ptr; 259 259 s32 err; 260 - struct brcmf_bus_dcmd *cmdlst; 261 - struct list_head *cur, *q; 262 260 263 261 /* retreive mac address */ 264 262 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, ··· 279 281 } 280 282 ptr = (char *)buf; 281 283 strsep(&ptr, "\n"); 284 + 282 285 /* Print fw version info */ 283 286 brcmf_err("Firmware version = %s\n", buf); 287 + 288 + /* locate firmware version number for ethtool */ 289 + ptr = strrchr(buf, ' ') + 1; 290 + strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); 284 291 285 292 /* 286 293 * Setup timeout if Beacons are lost and roam is off to report ··· 345 342 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, 346 343 0, true); 347 344 348 - /* set bus specific command if there is any */ 349 - list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) { 350 - cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list); 351 - if (cmdlst->name && cmdlst->param && cmdlst->param_len) { 352 - brcmf_fil_iovar_data_set(ifp, cmdlst->name, 353 - cmdlst->param, 354 - cmdlst->param_len); 355 - } 356 - list_del(cur); 357 - kfree(cmdlst); 358 - } 345 + /* do bus specific preinit here */ 346 + err = brcmf_bus_preinit(ifp->drvr->bus_if); 359 347 done: 360 348 return err; 361 349 }
+35 -1
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
··· 22 22 #include "dhd.h" 23 23 #include "dhd_bus.h" 24 24 #include "dhd_dbg.h" 25 - #include "tracepoint.h" 26 25 27 26 static struct dentry *root_folder; 28 27 ··· 41 42 root_folder = NULL; 42 43 } 43 44 45 + static 46 + ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data, 47 + size_t count, loff_t *ppos) 48 + { 49 + struct brcmf_pub *drvr = f->private_data; 50 + struct brcmf_bus *bus = drvr->bus_if; 51 + char buf[40]; 52 + int res; 53 + 54 + /* only allow read from start */ 55 + if (*ppos > 0) 56 + return 0; 57 + 58 + res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n", 59 + bus->chip, bus->chip, bus->chiprev); 60 + return simple_read_from_buffer(data, count, ppos, buf, res); 61 + } 62 + 63 + static const struct file_operations brcmf_debugfs_chipinfo_ops = { 64 + .owner = THIS_MODULE, 65 + .open = simple_open, 66 + .read = brcmf_debugfs_chipinfo_read 67 + }; 68 + 69 + static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr) 70 + { 71 + struct dentry *dentry = drvr->dbgfs_dir; 72 + 73 + if (!IS_ERR_OR_NULL(dentry)) 74 + debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr, 75 + &brcmf_debugfs_chipinfo_ops); 76 + return 0; 77 + } 78 + 44 79 int brcmf_debugfs_attach(struct brcmf_pub *drvr) 45 80 { 46 81 struct device *dev = drvr->bus_if->dev; ··· 83 50 return -ENODEV; 84 51 85 52 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); 53 + brcmf_debugfs_create_chipinfo(drvr); 86 54 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); 87 55 } 88 56
+1 -1
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
··· 33 33 #define BRCMF_USB_VAL 0x00002000 34 34 #define BRCMF_SCAN_VAL 0x00004000 35 35 #define BRCMF_CONN_VAL 0x00008000 36 - #define BRCMF_CDC_VAL 0x00010000 36 + #define BRCMF_BCDC_VAL 0x00010000 37 37 #define BRCMF_SDIO_VAL 0x00020000 38 38 39 39 /* set default print format */
+28 -166
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
··· 24 24 25 25 #include "dhd.h" 26 26 #include "dhd_bus.h" 27 - #include "dhd_proto.h" 28 27 #include "dhd_dbg.h" 29 28 #include "fwil_types.h" 30 29 #include "p2p.h" 31 30 #include "wl_cfg80211.h" 32 31 #include "fwil.h" 33 32 #include "fwsignal.h" 33 + #include "proto.h" 34 34 35 35 MODULE_AUTHOR("Broadcom Corporation"); 36 36 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); ··· 592 592 return &ifp->stats; 593 593 } 594 594 595 - /* 596 - * Set current toe component enables in toe_ol iovar, 597 - * and set toe global enable iovar 598 - */ 599 - static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol) 600 - { 601 - s32 err; 602 - 603 - err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol); 604 - if (err < 0) { 605 - brcmf_err("Setting toe_ol failed, %d\n", err); 606 - return err; 607 - } 608 - 609 - err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0)); 610 - if (err < 0) 611 - brcmf_err("Setting toe failed, %d\n", err); 612 - 613 - return err; 614 - 615 - } 616 - 617 595 static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, 618 596 struct ethtool_drvinfo *info) 619 597 { ··· 599 621 struct brcmf_pub *drvr = ifp->drvr; 600 622 601 623 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 602 - snprintf(info->version, sizeof(info->version), "%lu", 603 - drvr->drv_version); 624 + snprintf(info->version, sizeof(info->version), "n/a"); 625 + strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version)); 604 626 strlcpy(info->bus_info, dev_name(drvr->bus_if->dev), 605 627 sizeof(info->bus_info)); 606 628 } ··· 608 630 static const struct ethtool_ops brcmf_ethtool_ops = { 609 631 .get_drvinfo = brcmf_ethtool_get_drvinfo, 610 632 }; 611 - 612 - static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) 613 - { 614 - struct brcmf_pub *drvr = ifp->drvr; 615 - struct ethtool_drvinfo info; 616 - char drvname[sizeof(info.driver)]; 617 - u32 cmd; 618 - struct ethtool_value edata; 619 - u32 toe_cmpnt, csum_dir; 620 - int ret; 621 - 622 - brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); 623 - 624 - /* all ethtool calls start with a cmd word */ 625 - if (copy_from_user(&cmd, uaddr, sizeof(u32))) 626 - return -EFAULT; 627 - 628 - switch (cmd) { 629 - case ETHTOOL_GDRVINFO: 630 - /* Copy out any request driver name */ 631 - if (copy_from_user(&info, uaddr, sizeof(info))) 632 - return -EFAULT; 633 - strncpy(drvname, info.driver, sizeof(info.driver)); 634 - drvname[sizeof(info.driver) - 1] = '\0'; 635 - 636 - /* clear struct for return */ 637 - memset(&info, 0, sizeof(info)); 638 - info.cmd = cmd; 639 - 640 - /* if requested, identify ourselves */ 641 - if (strcmp(drvname, "?dhd") == 0) { 642 - sprintf(info.driver, "dhd"); 643 - strcpy(info.version, BRCMF_VERSION_STR); 644 - } 645 - /* report dongle driver type */ 646 - else 647 - sprintf(info.driver, "wl"); 648 - 649 - sprintf(info.version, "%lu", drvr->drv_version); 650 - if (copy_to_user(uaddr, &info, sizeof(info))) 651 - return -EFAULT; 652 - brcmf_dbg(TRACE, "given %*s, returning %s\n", 653 - (int)sizeof(drvname), drvname, info.driver); 654 - break; 655 - 656 - /* Get toe offload components from dongle */ 657 - case ETHTOOL_GRXCSUM: 658 - case ETHTOOL_GTXCSUM: 659 - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); 660 - if (ret < 0) 661 - return ret; 662 - 663 - csum_dir = 664 - (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; 665 - 666 - edata.cmd = cmd; 667 - edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; 668 - 669 - if (copy_to_user(uaddr, &edata, sizeof(edata))) 670 - return -EFAULT; 671 - break; 672 - 673 - /* Set toe offload components in dongle */ 674 - case ETHTOOL_SRXCSUM: 675 - case ETHTOOL_STXCSUM: 676 - if (copy_from_user(&edata, uaddr, sizeof(edata))) 677 - return -EFAULT; 678 - 679 - /* Read the current settings, update and write back */ 680 - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); 681 - if (ret < 0) 682 - return ret; 683 - 684 - csum_dir = 685 - (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; 686 - 687 - if (edata.data != 0) 688 - toe_cmpnt |= csum_dir; 689 - else 690 - toe_cmpnt &= ~csum_dir; 691 - 692 - ret = brcmf_toe_set(ifp, toe_cmpnt); 693 - if (ret < 0) 694 - return ret; 695 - 696 - /* If setting TX checksum mode, tell Linux the new mode */ 697 - if (cmd == ETHTOOL_STXCSUM) { 698 - if (edata.data) 699 - ifp->ndev->features |= NETIF_F_IP_CSUM; 700 - else 701 - ifp->ndev->features &= ~NETIF_F_IP_CSUM; 702 - } 703 - 704 - break; 705 - 706 - default: 707 - return -EOPNOTSUPP; 708 - } 709 - 710 - return 0; 711 - } 712 - 713 - static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, 714 - int cmd) 715 - { 716 - struct brcmf_if *ifp = netdev_priv(ndev); 717 - struct brcmf_pub *drvr = ifp->drvr; 718 - 719 - brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd); 720 - 721 - if (!drvr->iflist[ifp->bssidx]) 722 - return -1; 723 - 724 - if (cmd == SIOCETHTOOL) 725 - return brcmf_ethtool(ifp, ifr->ifr_data); 726 - 727 - return -EOPNOTSUPP; 728 - } 729 633 730 634 static int brcmf_netdev_stop(struct net_device *ndev) 731 635 { ··· 629 769 struct brcmf_pub *drvr = ifp->drvr; 630 770 struct brcmf_bus *bus_if = drvr->bus_if; 631 771 u32 toe_ol; 632 - s32 ret = 0; 633 772 634 773 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); 635 774 ··· 647 788 else 648 789 ndev->features &= ~NETIF_F_IP_CSUM; 649 790 650 - /* Allow transmit calls */ 651 - netif_start_queue(ndev); 652 791 if (brcmf_cfg80211_up(ndev)) { 653 792 brcmf_err("failed to bring up cfg80211\n"); 654 - return -1; 793 + return -EIO; 655 794 } 656 795 657 - return ret; 796 + /* Allow transmit calls */ 797 + netif_start_queue(ndev); 798 + return 0; 658 799 } 659 800 660 801 static const struct net_device_ops brcmf_netdev_ops_pri = { 661 802 .ndo_open = brcmf_netdev_open, 662 803 .ndo_stop = brcmf_netdev_stop, 663 804 .ndo_get_stats = brcmf_netdev_get_stats, 664 - .ndo_do_ioctl = brcmf_netdev_ioctl_entry, 665 805 .ndo_start_xmit = brcmf_netdev_start_xmit, 666 806 .ndo_set_mac_address = brcmf_netdev_set_mac_address, 667 807 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list ··· 726 868 return brcmf_cfg80211_down(ndev); 727 869 } 728 870 729 - static int brcmf_net_p2p_do_ioctl(struct net_device *ndev, 730 - struct ifreq *ifr, int cmd) 731 - { 732 - brcmf_dbg(TRACE, "Enter\n"); 733 - return 0; 734 - } 735 - 736 871 static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb, 737 872 struct net_device *ndev) 738 873 { ··· 738 887 static const struct net_device_ops brcmf_netdev_ops_p2p = { 739 888 .ndo_open = brcmf_net_p2p_open, 740 889 .ndo_stop = brcmf_net_p2p_stop, 741 - .ndo_do_ioctl = brcmf_net_p2p_do_ioctl, 742 890 .ndo_start_xmit = brcmf_net_p2p_start_xmit 743 891 }; 744 892 ··· 866 1016 } 867 1017 } 868 1018 869 - int brcmf_attach(uint bus_hdrlen, struct device *dev) 1019 + int brcmf_attach(struct device *dev) 870 1020 { 871 1021 struct brcmf_pub *drvr = NULL; 872 1022 int ret = 0; ··· 881 1031 mutex_init(&drvr->proto_block); 882 1032 883 1033 /* Link to bus module */ 884 - drvr->hdrlen = bus_hdrlen; 1034 + drvr->hdrlen = 0; 885 1035 drvr->bus_if = dev_get_drvdata(dev); 886 1036 drvr->bus_if->drvr = drvr; 887 1037 ··· 897 1047 898 1048 /* attach firmware event handler */ 899 1049 brcmf_fweh_attach(drvr); 900 - 901 - INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); 902 1050 903 1051 return ret; 904 1052 ··· 986 1138 return 0; 987 1139 } 988 1140 1141 + void brcmf_bus_add_txhdrlen(struct device *dev, uint len) 1142 + { 1143 + struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1144 + struct brcmf_pub *drvr = bus_if->drvr; 1145 + 1146 + if (drvr) { 1147 + drvr->hdrlen += len; 1148 + } 1149 + } 1150 + 989 1151 static void brcmf_bus_detach(struct brcmf_pub *drvr) 990 1152 { 991 1153 brcmf_dbg(TRACE, "Enter\n"); 992 1154 993 1155 if (drvr) { 994 - /* Stop the protocol module */ 995 - brcmf_proto_stop(drvr); 996 - 997 1156 /* Stop the bus module */ 998 1157 brcmf_bus_stop(drvr->bus_if); 999 1158 } ··· 1041 1186 1042 1187 brcmf_bus_detach(drvr); 1043 1188 1044 - if (drvr->prot) 1045 - brcmf_proto_detach(drvr); 1189 + brcmf_proto_detach(drvr); 1046 1190 1047 1191 brcmf_fws_deinit(drvr); 1048 1192 1049 1193 brcmf_debugfs_detach(drvr); 1050 1194 bus_if->drvr = NULL; 1051 1195 kfree(drvr); 1196 + } 1197 + 1198 + s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len) 1199 + { 1200 + struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1201 + struct brcmf_if *ifp = bus_if->drvr->iflist[0]; 1202 + 1203 + return brcmf_fil_iovar_data_set(ifp, name, data, len); 1052 1204 } 1053 1205 1054 1206 static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
-42
drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
··· 1 - /* 2 - * Copyright (c) 2010 Broadcom Corporation 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 ANY 11 - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 - */ 16 - 17 - #ifndef _BRCMF_PROTO_H_ 18 - #define _BRCMF_PROTO_H_ 19 - 20 - /* 21 - * Exported from the brcmf protocol module (brcmf_cdc) 22 - */ 23 - 24 - /* Linkage, sets prot link and updates hdrlen in pub */ 25 - int brcmf_proto_attach(struct brcmf_pub *drvr); 26 - 27 - /* Unlink, frees allocated protocol memory (including brcmf_proto) */ 28 - void brcmf_proto_detach(struct brcmf_pub *drvr); 29 - 30 - /* Stop protocol: sync w/dongle state. */ 31 - void brcmf_proto_stop(struct brcmf_pub *drvr); 32 - 33 - /* Add any protocol-specific data header. 34 - * Caller must reserve prot_hdrlen prepend space. 35 - */ 36 - void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, 37 - struct sk_buff *txp); 38 - 39 - /* Sets dongle media info (drv_version, mac address). */ 40 - int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); 41 - 42 - #endif /* _BRCMF_PROTO_H_ */
+295 -165
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
··· 32 32 #include <linux/debugfs.h> 33 33 #include <linux/vmalloc.h> 34 34 #include <linux/platform_data/brcmfmac-sdio.h> 35 + #include <linux/moduleparam.h> 35 36 #include <asm/unaligned.h> 36 37 #include <defs.h> 37 38 #include <brcmu_wifi.h> ··· 110 109 111 110 #define BRCMF_TXBOUND 20 /* Default for max tx frames in 112 111 one scheduling */ 112 + 113 + #define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */ 113 114 114 115 #define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ 115 116 ··· 363 360 u16 len_left; 364 361 u16 len_nxtfrm; 365 362 u8 dat_offset; 363 + bool lastfrm; 364 + u16 tail_pad; 366 365 }; 367 366 368 367 /* misc chip info needed by some of the routines */ ··· 389 384 u8 tx_seq; /* Transmit sequence number (next) */ 390 385 u8 tx_max; /* Maximum transmit sequence allowed */ 391 386 392 - u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; 387 + u8 *hdrbuf; /* buffer for handling rx frame */ 393 388 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ 394 389 u8 rx_seq; /* Receive sequence number (expected) */ 395 390 struct brcmf_sdio_hdrinfo cur_read; ··· 460 455 bool sleeping; /* SDIO bus sleeping */ 461 456 462 457 u8 tx_hdrlen; /* sdio bus header length for tx packet */ 458 + bool txglom; /* host tx glomming enable flag */ 459 + struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */ 460 + u16 head_align; /* buffer pointer alignment */ 461 + u16 sgentry_align; /* scatter-gather buffer alignment */ 463 462 }; 464 463 465 464 /* clkstate */ ··· 488 479 489 480 #define ALIGNMENT 4 490 481 482 + static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE; 483 + module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0); 484 + MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]"); 485 + 491 486 enum brcmf_sdio_frmtype { 492 487 BRCMF_SDIO_FT_NORMAL, 493 488 BRCMF_SDIO_FT_SUPER, ··· 512 499 #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" 513 500 #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" 514 501 #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" 502 + #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" 503 + #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" 515 504 516 505 MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME); 517 506 MODULE_FIRMWARE(BCM43143_NVRAM_NAME); ··· 529 514 MODULE_FIRMWARE(BCM4334_NVRAM_NAME); 530 515 MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); 531 516 MODULE_FIRMWARE(BCM4335_NVRAM_NAME); 517 + MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); 518 + MODULE_FIRMWARE(BCM4339_NVRAM_NAME); 532 519 533 520 struct brcmf_firmware_names { 534 521 u32 chipid; ··· 554 537 { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, 555 538 { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, 556 539 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, 557 - { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) } 540 + { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, 541 + { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) } 558 542 }; 559 543 560 544 ··· 1115 1097 * host and WiFi dongle which contains information needed for SDIO core and 1116 1098 * firmware 1117 1099 * 1118 - * It consists of 2 parts: hw header and software header 1100 + * It consists of 3 parts: hardware header, hardware extension header and 1101 + * software header 1119 1102 * hardware header (frame tag) - 4 bytes 1120 1103 * Byte 0~1: Frame length 1121 1104 * Byte 2~3: Checksum, bit-wise inverse of frame length 1105 + * hardware extension header - 8 bytes 1106 + * Tx glom mode only, N/A for Rx or normal Tx 1107 + * Byte 0~1: Packet length excluding hw frame tag 1108 + * Byte 2: Reserved 1109 + * Byte 3: Frame flags, bit 0: last frame indication 1110 + * Byte 4~5: Reserved 1111 + * Byte 6~7: Tail padding length 1122 1112 * software header - 8 bytes 1123 1113 * Byte 0: Rx/Tx sequence number 1124 1114 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag ··· 1137 1111 * Byte 6~7: Reserved 1138 1112 */ 1139 1113 #define SDPCM_HWHDR_LEN 4 1114 + #define SDPCM_HWEXT_LEN 8 1140 1115 #define SDPCM_SWHDR_LEN 8 1141 1116 #define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN) 1142 1117 /* software header */ ··· 1174 1147 u8 rx_seq, fc, tx_seq_max; 1175 1148 u32 swheader; 1176 1149 1177 - trace_brcmf_sdpcm_hdr(false, header); 1150 + trace_brcmf_sdpcm_hdr(SDPCM_RX, header); 1178 1151 1179 1152 /* hw header */ 1180 1153 len = get_unaligned_le16(header); ··· 1287 1260 static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header, 1288 1261 struct brcmf_sdio_hdrinfo *hd_info) 1289 1262 { 1290 - u32 sw_header; 1263 + u32 hdrval; 1264 + u8 hdr_offset; 1291 1265 1292 1266 brcmf_sdio_update_hwhdr(header, hd_info->len); 1267 + hdr_offset = SDPCM_HWHDR_LEN; 1293 1268 1294 - sw_header = bus->tx_seq; 1295 - sw_header |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) & 1296 - SDPCM_CHANNEL_MASK; 1297 - sw_header |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) & 1298 - SDPCM_DOFFSET_MASK; 1299 - *(((__le32 *)header) + 1) = cpu_to_le32(sw_header); 1300 - *(((__le32 *)header) + 2) = 0; 1301 - trace_brcmf_sdpcm_hdr(true, header); 1269 + if (bus->txglom) { 1270 + hdrval = (hd_info->len - hdr_offset) | (hd_info->lastfrm << 24); 1271 + *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval); 1272 + hdrval = (u16)hd_info->tail_pad << 16; 1273 + *(((__le32 *)(header + hdr_offset)) + 1) = cpu_to_le32(hdrval); 1274 + hdr_offset += SDPCM_HWEXT_LEN; 1275 + } 1276 + 1277 + hdrval = hd_info->seq_num; 1278 + hdrval |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) & 1279 + SDPCM_CHANNEL_MASK; 1280 + hdrval |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) & 1281 + SDPCM_DOFFSET_MASK; 1282 + *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval); 1283 + *(((__le32 *)(header + hdr_offset)) + 1) = 0; 1284 + trace_brcmf_sdpcm_hdr(SDPCM_TX + !!(bus->txglom), header); 1302 1285 } 1303 1286 1304 1287 static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) 1305 1288 { 1306 1289 u16 dlen, totlen; 1307 1290 u8 *dptr, num = 0; 1308 - u32 align = 0; 1309 1291 u16 sublen; 1310 1292 struct sk_buff *pfirst, *pnext; 1311 1293 ··· 1328 1292 1329 1293 brcmf_dbg(SDIO, "start: glomd %p glom %p\n", 1330 1294 bus->glomd, skb_peek(&bus->glom)); 1331 - 1332 - if (bus->sdiodev->pdata) 1333 - align = bus->sdiodev->pdata->sd_sgentry_align; 1334 - if (align < 4) 1335 - align = 4; 1336 1295 1337 1296 /* If there's a descriptor, generate the packet chain */ 1338 1297 if (bus->glomd) { ··· 1352 1321 pnext = NULL; 1353 1322 break; 1354 1323 } 1355 - if (sublen % align) { 1324 + if (sublen % bus->sgentry_align) { 1356 1325 brcmf_err("sublen %d not multiple of %d\n", 1357 - sublen, align); 1326 + sublen, bus->sgentry_align); 1358 1327 } 1359 1328 totlen += sublen; 1360 1329 ··· 1367 1336 } 1368 1337 1369 1338 /* Allocate/chain packet for next subframe */ 1370 - pnext = brcmu_pkt_buf_get_skb(sublen + align); 1339 + pnext = brcmu_pkt_buf_get_skb(sublen + bus->sgentry_align); 1371 1340 if (pnext == NULL) { 1372 1341 brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n", 1373 1342 num, sublen); ··· 1376 1345 skb_queue_tail(&bus->glom, pnext); 1377 1346 1378 1347 /* Adhere to start alignment requirements */ 1379 - pkt_align(pnext, sublen, align); 1348 + pkt_align(pnext, sublen, bus->sgentry_align); 1380 1349 } 1381 1350 1382 1351 /* If all allocations succeeded, save packet chain ··· 1580 1549 goto done; 1581 1550 1582 1551 rbuf = bus->rxbuf; 1583 - pad = ((unsigned long)rbuf % BRCMF_SDALIGN); 1552 + pad = ((unsigned long)rbuf % bus->head_align); 1584 1553 if (pad) 1585 - rbuf += (BRCMF_SDALIGN - pad); 1554 + rbuf += (bus->head_align - pad); 1586 1555 1587 1556 /* Copy the already-read portion over */ 1588 1557 memcpy(buf, hdr, BRCMF_FIRSTREAD); ··· 1596 1565 if ((pad <= bus->roundup) && (pad < bus->blocksize) && 1597 1566 ((len + pad) < bus->sdiodev->bus_if->maxctl)) 1598 1567 rdlen += pad; 1599 - } else if (rdlen % BRCMF_SDALIGN) { 1600 - rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); 1568 + } else if (rdlen % bus->head_align) { 1569 + rdlen += bus->head_align - (rdlen % bus->head_align); 1601 1570 } 1602 - 1603 - /* Satisfy length-alignment requirements */ 1604 - if (rdlen & (ALIGNMENT - 1)) 1605 - rdlen = roundup(rdlen, ALIGNMENT); 1606 1571 1607 1572 /* Drop if the read is too big or it exceeds our maximum */ 1608 1573 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { ··· 1664 1637 if (*pad <= bus->roundup && *pad < bus->blocksize && 1665 1638 *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ) 1666 1639 *rdlen += *pad; 1667 - } else if (*rdlen % BRCMF_SDALIGN) { 1668 - *rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN); 1640 + } else if (*rdlen % bus->head_align) { 1641 + *rdlen += bus->head_align - (*rdlen % bus->head_align); 1669 1642 } 1670 1643 } 1671 1644 ··· 1753 1726 brcmf_pad(bus, &pad, &rd->len_left); 1754 1727 1755 1728 pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read + 1756 - BRCMF_SDALIGN); 1729 + bus->head_align); 1757 1730 if (!pkt) { 1758 1731 /* Give up on data, request rtx of events */ 1759 1732 brcmf_err("brcmu_pkt_buf_get_skb failed\n"); ··· 1763 1736 continue; 1764 1737 } 1765 1738 skb_pull(pkt, head_read); 1766 - pkt_align(pkt, rd->len_left, BRCMF_SDALIGN); 1739 + pkt_align(pkt, rd->len_left, bus->head_align); 1767 1740 1768 1741 ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1769 1742 SDIO_FUNC_2, F2SYNC, pkt); ··· 1898 1871 return; 1899 1872 } 1900 1873 1874 + static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt) 1875 + { 1876 + u16 head_pad; 1877 + u8 *dat_buf; 1878 + 1879 + dat_buf = (u8 *)(pkt->data); 1880 + 1881 + /* Check head padding */ 1882 + head_pad = ((unsigned long)dat_buf % bus->head_align); 1883 + if (head_pad) { 1884 + if (skb_headroom(pkt) < head_pad) { 1885 + bus->sdiodev->bus_if->tx_realloc++; 1886 + head_pad = 0; 1887 + if (skb_cow(pkt, head_pad)) 1888 + return -ENOMEM; 1889 + } 1890 + skb_push(pkt, head_pad); 1891 + dat_buf = (u8 *)(pkt->data); 1892 + memset(dat_buf, 0, head_pad + bus->tx_hdrlen); 1893 + } 1894 + return head_pad; 1895 + } 1896 + 1901 1897 /** 1902 1898 * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for 1903 1899 * bus layer usage. ··· 1930 1880 /* bit mask of data length chopped from the previous packet */ 1931 1881 #define ALIGN_SKB_CHOP_LEN_MASK 0x7fff 1932 1882 1933 - static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev, 1883 + static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, 1934 1884 struct sk_buff_head *pktq, 1935 - struct sk_buff *pkt, uint chan) 1885 + struct sk_buff *pkt, u16 total_len) 1936 1886 { 1887 + struct brcmf_sdio_dev *sdiodev; 1937 1888 struct sk_buff *pkt_pad; 1938 - u16 tail_pad, tail_chop, sg_align; 1889 + u16 tail_pad, tail_chop, chain_pad; 1939 1890 unsigned int blksize; 1940 - u8 *dat_buf; 1941 - int ntail; 1891 + bool lastfrm; 1892 + int ntail, ret; 1942 1893 1894 + sdiodev = bus->sdiodev; 1943 1895 blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; 1944 - sg_align = 4; 1945 - if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4) 1946 - sg_align = sdiodev->pdata->sd_sgentry_align; 1947 1896 /* sg entry alignment should be a divisor of block size */ 1948 - WARN_ON(blksize % sg_align); 1897 + WARN_ON(blksize % bus->sgentry_align); 1949 1898 1950 1899 /* Check tail padding */ 1951 - pkt_pad = NULL; 1952 - tail_chop = pkt->len % sg_align; 1953 - tail_pad = sg_align - tail_chop; 1954 - tail_pad += blksize - (pkt->len + tail_pad) % blksize; 1900 + lastfrm = skb_queue_is_last(pktq, pkt); 1901 + tail_pad = 0; 1902 + tail_chop = pkt->len % bus->sgentry_align; 1903 + if (tail_chop) 1904 + tail_pad = bus->sgentry_align - tail_chop; 1905 + chain_pad = (total_len + tail_pad) % blksize; 1906 + if (lastfrm && chain_pad) 1907 + tail_pad += blksize - chain_pad; 1955 1908 if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { 1956 - pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop); 1909 + pkt_pad = bus->txglom_sgpad; 1910 + if (pkt_pad == NULL) 1911 + brcmu_pkt_buf_get_skb(tail_pad + tail_chop); 1957 1912 if (pkt_pad == NULL) 1958 1913 return -ENOMEM; 1914 + ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); 1915 + if (unlikely(ret < 0)) 1916 + return ret; 1959 1917 memcpy(pkt_pad->data, 1960 1918 pkt->data + pkt->len - tail_chop, 1961 1919 tail_chop); ··· 1978 1920 return -ENOMEM; 1979 1921 if (skb_linearize(pkt)) 1980 1922 return -ENOMEM; 1981 - dat_buf = (u8 *)(pkt->data); 1982 1923 __skb_put(pkt, tail_pad); 1983 1924 } 1984 1925 1985 - if (pkt_pad) 1986 - return pkt->len + tail_chop; 1987 - else 1988 - return pkt->len - tail_pad; 1926 + return tail_pad; 1989 1927 } 1990 1928 1991 1929 /** ··· 2000 1946 brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, 2001 1947 uint chan) 2002 1948 { 2003 - u16 head_pad, head_align; 1949 + u16 head_pad, total_len; 2004 1950 struct sk_buff *pkt_next; 2005 - u8 *dat_buf; 2006 - int err; 1951 + u8 txseq; 1952 + int ret; 2007 1953 struct brcmf_sdio_hdrinfo hd_info = {0}; 2008 1954 2009 - /* SDIO ADMA requires at least 32 bit alignment */ 2010 - head_align = 4; 2011 - if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4) 2012 - head_align = bus->sdiodev->pdata->sd_head_align; 1955 + txseq = bus->tx_seq; 1956 + total_len = 0; 1957 + skb_queue_walk(pktq, pkt_next) { 1958 + /* alignment packet inserted in previous 1959 + * loop cycle can be skipped as it is 1960 + * already properly aligned and does not 1961 + * need an sdpcm header. 1962 + */ 1963 + if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG) 1964 + continue; 2013 1965 2014 - pkt_next = pktq->next; 2015 - dat_buf = (u8 *)(pkt_next->data); 1966 + /* align packet data pointer */ 1967 + ret = brcmf_sdio_txpkt_hdalign(bus, pkt_next); 1968 + if (ret < 0) 1969 + return ret; 1970 + head_pad = (u16)ret; 1971 + if (head_pad) 1972 + memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen); 2016 1973 2017 - /* Check head padding */ 2018 - head_pad = ((unsigned long)dat_buf % head_align); 2019 - if (head_pad) { 2020 - if (skb_headroom(pkt_next) < head_pad) { 2021 - bus->sdiodev->bus_if->tx_realloc++; 2022 - head_pad = 0; 2023 - if (skb_cow(pkt_next, head_pad)) 2024 - return -ENOMEM; 2025 - } 2026 - skb_push(pkt_next, head_pad); 2027 - dat_buf = (u8 *)(pkt_next->data); 2028 - memset(dat_buf, 0, head_pad + bus->tx_hdrlen); 2029 - } 1974 + total_len += pkt_next->len; 2030 1975 2031 - if (bus->sdiodev->sg_support && pktq->qlen > 1) { 2032 - err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq, 2033 - pkt_next, chan); 2034 - if (err < 0) 2035 - return err; 2036 - hd_info.len = (u16)err; 2037 - } else { 2038 1976 hd_info.len = pkt_next->len; 1977 + hd_info.lastfrm = skb_queue_is_last(pktq, pkt_next); 1978 + if (bus->txglom && pktq->qlen > 1) { 1979 + ret = brcmf_sdio_txpkt_prep_sg(bus, pktq, 1980 + pkt_next, total_len); 1981 + if (ret < 0) 1982 + return ret; 1983 + hd_info.tail_pad = (u16)ret; 1984 + total_len += (u16)ret; 1985 + } 1986 + 1987 + hd_info.channel = chan; 1988 + hd_info.dat_offset = head_pad + bus->tx_hdrlen; 1989 + hd_info.seq_num = txseq++; 1990 + 1991 + /* Now fill the header */ 1992 + brcmf_sdio_hdpack(bus, pkt_next->data, &hd_info); 1993 + 1994 + if (BRCMF_BYTES_ON() && 1995 + ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || 1996 + (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) 1997 + brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, 1998 + "Tx Frame:\n"); 1999 + else if (BRCMF_HDRS_ON()) 2000 + brcmf_dbg_hex_dump(true, pkt_next, 2001 + head_pad + bus->tx_hdrlen, 2002 + "Tx Header:\n"); 2039 2003 } 2040 - 2041 - hd_info.channel = chan; 2042 - hd_info.dat_offset = head_pad + bus->tx_hdrlen; 2043 - 2044 - /* Now fill the header */ 2045 - brcmf_sdio_hdpack(bus, dat_buf, &hd_info); 2046 - 2047 - if (BRCMF_BYTES_ON() && 2048 - ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || 2049 - (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) 2050 - brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, "Tx Frame:\n"); 2051 - else if (BRCMF_HDRS_ON()) 2052 - brcmf_dbg_hex_dump(true, pkt_next, head_pad + bus->tx_hdrlen, 2053 - "Tx Header:\n"); 2054 - 2004 + /* Hardware length tag of the first packet should be total 2005 + * length of the chain (including padding) 2006 + */ 2007 + if (bus->txglom) 2008 + brcmf_sdio_update_hwhdr(pktq->next->data, total_len); 2055 2009 return 0; 2056 2010 } 2057 2011 ··· 2077 2015 { 2078 2016 u8 *hdr; 2079 2017 u32 dat_offset; 2018 + u16 tail_pad; 2080 2019 u32 dummy_flags, chop_len; 2081 2020 struct sk_buff *pkt_next, *tmp, *pkt_prev; 2082 2021 ··· 2087 2024 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; 2088 2025 if (chop_len) { 2089 2026 pkt_prev = pkt_next->prev; 2090 - memcpy(pkt_prev->data + pkt_prev->len, 2091 - pkt_next->data, chop_len); 2092 2027 skb_put(pkt_prev, chop_len); 2093 2028 } 2094 2029 __skb_unlink(pkt_next, pktq); 2095 2030 brcmu_pkt_buf_free_skb(pkt_next); 2096 2031 } else { 2097 - hdr = pkt_next->data + SDPCM_HWHDR_LEN; 2032 + hdr = pkt_next->data + bus->tx_hdrlen - SDPCM_SWHDR_LEN; 2098 2033 dat_offset = le32_to_cpu(*(__le32 *)hdr); 2099 2034 dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >> 2100 2035 SDPCM_DOFFSET_SHIFT; 2101 2036 skb_pull(pkt_next, dat_offset); 2037 + if (bus->txglom) { 2038 + tail_pad = le16_to_cpu(*(__le16 *)(hdr - 2)); 2039 + skb_trim(pkt_next, pkt_next->len - tail_pad); 2040 + } 2102 2041 } 2103 2042 } 2104 2043 } 2105 2044 2106 2045 /* Writes a HW/SW header into the packet and sends it. */ 2107 2046 /* Assumes: (a) header space already there, (b) caller holds lock */ 2108 - static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, 2047 + static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, 2109 2048 uint chan) 2110 2049 { 2111 2050 int ret; 2112 2051 int i; 2113 - struct sk_buff_head localq; 2052 + struct sk_buff *pkt_next, *tmp; 2114 2053 2115 2054 brcmf_dbg(TRACE, "Enter\n"); 2116 2055 2117 - __skb_queue_head_init(&localq); 2118 - __skb_queue_tail(&localq, pkt); 2119 - ret = brcmf_sdio_txpkt_prep(bus, &localq, chan); 2056 + ret = brcmf_sdio_txpkt_prep(bus, pktq, chan); 2120 2057 if (ret) 2121 2058 goto done; 2122 2059 2123 2060 sdio_claim_host(bus->sdiodev->func[1]); 2124 2061 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, 2125 - SDIO_FUNC_2, F2SYNC, &localq); 2062 + SDIO_FUNC_2, F2SYNC, pktq); 2126 2063 bus->sdcnt.f2txdata++; 2127 2064 2128 2065 if (ret < 0) { ··· 2146 2083 if ((hi == 0) && (lo == 0)) 2147 2084 break; 2148 2085 } 2149 - 2150 2086 } 2151 2087 sdio_release_host(bus->sdiodev->func[1]); 2152 - if (ret == 0) 2153 - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; 2154 2088 2155 2089 done: 2156 - brcmf_sdio_txpkt_postp(bus, &localq); 2157 - __skb_dequeue_tail(&localq); 2158 - brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0); 2090 + brcmf_sdio_txpkt_postp(bus, pktq); 2091 + if (ret == 0) 2092 + bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP; 2093 + skb_queue_walk_safe(pktq, pkt_next, tmp) { 2094 + __skb_unlink(pkt_next, pktq); 2095 + brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0); 2096 + } 2159 2097 return ret; 2160 2098 } 2161 2099 2162 2100 static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) 2163 2101 { 2164 2102 struct sk_buff *pkt; 2103 + struct sk_buff_head pktq; 2165 2104 u32 intstatus = 0; 2166 - int ret = 0, prec_out; 2105 + int ret = 0, prec_out, i; 2167 2106 uint cnt = 0; 2168 - u8 tx_prec_map; 2107 + u8 tx_prec_map, pkt_num; 2169 2108 2170 2109 brcmf_dbg(TRACE, "Enter\n"); 2171 2110 2172 2111 tx_prec_map = ~bus->flowcontrol; 2173 2112 2174 2113 /* Send frames until the limit or some other event */ 2175 - for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) { 2114 + for (cnt = 0; (cnt < maxframes) && data_ok(bus);) { 2115 + pkt_num = 1; 2116 + __skb_queue_head_init(&pktq); 2117 + if (bus->txglom) 2118 + pkt_num = min_t(u8, bus->tx_max - bus->tx_seq, 2119 + brcmf_sdio_txglomsz); 2120 + pkt_num = min_t(u32, pkt_num, 2121 + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)); 2176 2122 spin_lock_bh(&bus->txqlock); 2177 - pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); 2178 - if (pkt == NULL) { 2179 - spin_unlock_bh(&bus->txqlock); 2180 - break; 2123 + for (i = 0; i < pkt_num; i++) { 2124 + pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, 2125 + &prec_out); 2126 + if (pkt == NULL) 2127 + break; 2128 + __skb_queue_tail(&pktq, pkt); 2181 2129 } 2182 2130 spin_unlock_bh(&bus->txqlock); 2131 + if (i == 0) 2132 + break; 2183 2133 2184 - ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL); 2134 + ret = brcmf_sdbrcm_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL); 2135 + cnt += i; 2185 2136 2186 2137 /* In poll mode, need to check for other events */ 2187 2138 if (!bus->intr && cnt) { ··· 2742 2665 brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) 2743 2666 { 2744 2667 u8 *frame; 2745 - u16 len; 2668 + u16 len, pad; 2746 2669 uint retries = 0; 2747 2670 u8 doff = 0; 2748 2671 int ret = -1; ··· 2758 2681 len = (msglen += bus->tx_hdrlen); 2759 2682 2760 2683 /* Add alignment padding (optional for ctl frames) */ 2761 - doff = ((unsigned long)frame % BRCMF_SDALIGN); 2684 + doff = ((unsigned long)frame % bus->head_align); 2762 2685 if (doff) { 2763 2686 frame -= doff; 2764 2687 len += doff; 2765 2688 msglen += doff; 2766 2689 memset(frame, 0, doff + bus->tx_hdrlen); 2767 2690 } 2768 - /* precondition: doff < BRCMF_SDALIGN */ 2691 + /* precondition: doff < bus->head_align */ 2769 2692 doff += bus->tx_hdrlen; 2770 2693 2771 2694 /* Round send length to next SDIO block */ 2695 + pad = 0; 2772 2696 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { 2773 - u16 pad = bus->blocksize - (len % bus->blocksize); 2774 - if ((pad <= bus->roundup) && (pad < bus->blocksize)) 2775 - len += pad; 2776 - } else if (len % BRCMF_SDALIGN) { 2777 - len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); 2697 + pad = bus->blocksize - (len % bus->blocksize); 2698 + if ((pad > bus->roundup) || (pad >= bus->blocksize)) 2699 + pad = 0; 2700 + } else if (len % bus->head_align) { 2701 + pad = bus->head_align - (len % bus->head_align); 2778 2702 } 2779 - 2780 - /* Satisfy length-alignment requirements */ 2781 - if (len & (ALIGNMENT - 1)) 2782 - len = roundup(len, ALIGNMENT); 2703 + len += pad; 2783 2704 2784 2705 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ 2785 2706 ··· 2789 2714 hd_info.len = (u16)msglen; 2790 2715 hd_info.channel = SDPCM_CONTROL_CHANNEL; 2791 2716 hd_info.dat_offset = doff; 2717 + hd_info.seq_num = bus->tx_seq; 2718 + hd_info.lastfrm = true; 2719 + hd_info.tail_pad = pad; 2792 2720 brcmf_sdio_hdpack(bus, frame, &hd_info); 2721 + 2722 + if (bus->txglom) 2723 + brcmf_sdio_update_hwhdr(frame, len); 2793 2724 2794 2725 if (!data_ok(bus)) { 2795 2726 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", ··· 3506 3425 return ret; 3507 3426 } 3508 3427 3428 + static int brcmf_sdbrcm_bus_preinit(struct device *dev) 3429 + { 3430 + struct brcmf_bus *bus_if = dev_get_drvdata(dev); 3431 + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 3432 + struct brcmf_sdio *bus = sdiodev->bus; 3433 + uint pad_size; 3434 + u32 value; 3435 + u8 idx; 3436 + int err; 3437 + 3438 + /* the commands below use the terms tx and rx from 3439 + * a device perspective, ie. bus:txglom affects the 3440 + * bus transfers from device to host. 3441 + */ 3442 + idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 3443 + if (bus->ci->c_inf[idx].rev < 12) { 3444 + /* for sdio core rev < 12, disable txgloming */ 3445 + value = 0; 3446 + err = brcmf_iovar_data_set(dev, "bus:txglom", &value, 3447 + sizeof(u32)); 3448 + } else { 3449 + /* otherwise, set txglomalign */ 3450 + value = 4; 3451 + if (sdiodev->pdata) 3452 + value = sdiodev->pdata->sd_sgentry_align; 3453 + /* SDIO ADMA requires at least 32 bit alignment */ 3454 + value = max_t(u32, value, 4); 3455 + err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, 3456 + sizeof(u32)); 3457 + } 3458 + 3459 + if (err < 0) 3460 + goto done; 3461 + 3462 + bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; 3463 + if (sdiodev->sg_support) { 3464 + bus->txglom = false; 3465 + value = 1; 3466 + pad_size = bus->sdiodev->func[2]->cur_blksize << 1; 3467 + bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size); 3468 + if (!bus->txglom_sgpad) 3469 + brcmf_err("allocating txglom padding skb failed, reduced performance\n"); 3470 + 3471 + err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", 3472 + &value, sizeof(u32)); 3473 + if (err < 0) { 3474 + /* bus:rxglom is allowed to fail */ 3475 + err = 0; 3476 + } else { 3477 + bus->txglom = true; 3478 + bus->tx_hdrlen += SDPCM_HWEXT_LEN; 3479 + } 3480 + } 3481 + brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen); 3482 + 3483 + done: 3484 + return err; 3485 + } 3486 + 3509 3487 static int brcmf_sdbrcm_bus_init(struct device *dev) 3510 3488 { 3511 3489 struct brcmf_bus *bus_if = dev_get_drvdata(dev); ··· 3813 3673 if (bus->sdiodev->bus_if->maxctl) { 3814 3674 bus->rxblen = 3815 3675 roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), 3816 - ALIGNMENT) + BRCMF_SDALIGN; 3676 + ALIGNMENT) + bus->head_align; 3817 3677 bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); 3818 3678 if (!(bus->rxbuf)) 3819 3679 return false; ··· 3914 3774 3915 3775 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3916 3776 3777 + /* allocate header buffer */ 3778 + bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL); 3779 + if (!bus->hdrbuf) 3780 + return false; 3917 3781 /* Locate an appropriately-aligned portion of hdrbuf */ 3918 3782 bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], 3919 - BRCMF_SDALIGN); 3783 + bus->head_align); 3920 3784 3921 3785 /* Set the poll and/or interrupt flags */ 3922 3786 bus->intr = true; ··· 4039 3895 brcmf_sdbrcm_release_dongle(bus); 4040 3896 } 4041 3897 3898 + brcmu_pkt_buf_free_skb(bus->txglom_sgpad); 4042 3899 brcmf_sdbrcm_release_malloc(bus); 4043 - 3900 + kfree(bus->hdrbuf); 4044 3901 kfree(bus); 4045 3902 } 4046 3903 ··· 4050 3905 4051 3906 static struct brcmf_bus_ops brcmf_sdio_bus_ops = { 4052 3907 .stop = brcmf_sdbrcm_bus_stop, 3908 + .preinit = brcmf_sdbrcm_bus_preinit, 4053 3909 .init = brcmf_sdbrcm_bus_init, 4054 3910 .txdata = brcmf_sdbrcm_bus_txdata, 4055 3911 .txctl = brcmf_sdbrcm_bus_txctl, ··· 4062 3916 { 4063 3917 int ret; 4064 3918 struct brcmf_sdio *bus; 4065 - struct brcmf_bus_dcmd *dlst; 4066 - u32 dngl_txglom; 4067 - u32 txglomalign = 0; 4068 - u8 idx; 4069 3919 4070 3920 brcmf_dbg(TRACE, "Enter\n"); 4071 3921 ··· 4080 3938 bus->rxbound = BRCMF_RXBOUND; 4081 3939 bus->txminmax = BRCMF_TXMINMAX; 4082 3940 bus->tx_seq = SDPCM_SEQ_WRAP - 1; 3941 + 3942 + /* platform specific configuration: 3943 + * alignments must be at least 4 bytes for ADMA 3944 + */ 3945 + bus->head_align = ALIGNMENT; 3946 + bus->sgentry_align = ALIGNMENT; 3947 + if (sdiodev->pdata) { 3948 + if (sdiodev->pdata->sd_head_align > ALIGNMENT) 3949 + bus->head_align = sdiodev->pdata->sd_head_align; 3950 + if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) 3951 + bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; 3952 + } 4083 3953 4084 3954 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); 4085 3955 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); ··· 4137 3983 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; 4138 3984 4139 3985 /* Attach to the common layer, reserve hdr space */ 4140 - ret = brcmf_attach(bus->tx_hdrlen, bus->sdiodev->dev); 3986 + ret = brcmf_attach(bus->sdiodev->dev); 4141 3987 if (ret != 0) { 4142 3988 brcmf_err("brcmf_attach failed\n"); 4143 3989 goto fail; ··· 4156 4002 4157 4003 brcmf_sdio_debugfs_create(bus); 4158 4004 brcmf_dbg(INFO, "completed!!\n"); 4159 - 4160 - /* sdio bus core specific dcmd */ 4161 - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 4162 - dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL); 4163 - if (dlst) { 4164 - if (bus->ci->c_inf[idx].rev < 12) { 4165 - /* for sdio core rev < 12, disable txgloming */ 4166 - dngl_txglom = 0; 4167 - dlst->name = "bus:txglom"; 4168 - dlst->param = (char *)&dngl_txglom; 4169 - dlst->param_len = sizeof(u32); 4170 - } else { 4171 - /* otherwise, set txglomalign */ 4172 - if (sdiodev->pdata) 4173 - txglomalign = sdiodev->pdata->sd_sgentry_align; 4174 - /* SDIO ADMA requires at least 32 bit alignment */ 4175 - if (txglomalign < 4) 4176 - txglomalign = 4; 4177 - dlst->name = "bus:txglomalign"; 4178 - dlst->param = (char *)&txglomalign; 4179 - dlst->param_len = sizeof(u32); 4180 - } 4181 - list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list); 4182 - } 4183 4005 4184 4006 /* if firmware path present try to download and bring up bus */ 4185 4007 ret = brcmf_bus_start(bus->sdiodev->dev);
+54
drivers/net/wireless/brcm80211/brcmfmac/fweh.h
··· 122 122 #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 123 123 #define BRCMF_EVENT_MSG_GROUP 0x04 124 124 125 + /* status field values in struct brcmf_event_msg */ 126 + #define BRCMF_E_STATUS_SUCCESS 0 127 + #define BRCMF_E_STATUS_FAIL 1 128 + #define BRCMF_E_STATUS_TIMEOUT 2 129 + #define BRCMF_E_STATUS_NO_NETWORKS 3 130 + #define BRCMF_E_STATUS_ABORT 4 131 + #define BRCMF_E_STATUS_NO_ACK 5 132 + #define BRCMF_E_STATUS_UNSOLICITED 6 133 + #define BRCMF_E_STATUS_ATTEMPT 7 134 + #define BRCMF_E_STATUS_PARTIAL 8 135 + #define BRCMF_E_STATUS_NEWSCAN 9 136 + #define BRCMF_E_STATUS_NEWASSOC 10 137 + #define BRCMF_E_STATUS_11HQUIET 11 138 + #define BRCMF_E_STATUS_SUPPRESS 12 139 + #define BRCMF_E_STATUS_NOCHANS 13 140 + #define BRCMF_E_STATUS_CS_ABORT 15 141 + #define BRCMF_E_STATUS_ERROR 16 142 + 143 + /* reason field values in struct brcmf_event_msg */ 144 + #define BRCMF_E_REASON_INITIAL_ASSOC 0 145 + #define BRCMF_E_REASON_LOW_RSSI 1 146 + #define BRCMF_E_REASON_DEAUTH 2 147 + #define BRCMF_E_REASON_DISASSOC 3 148 + #define BRCMF_E_REASON_BCNS_LOST 4 149 + #define BRCMF_E_REASON_MINTXRATE 9 150 + #define BRCMF_E_REASON_TXFAIL 10 151 + 152 + #define BRCMF_E_REASON_LINK_BSSCFG_DIS 4 153 + #define BRCMF_E_REASON_FAST_ROAM_FAILED 5 154 + #define BRCMF_E_REASON_DIRECTED_ROAM 6 155 + #define BRCMF_E_REASON_TSPEC_REJECTED 7 156 + #define BRCMF_E_REASON_BETTER_AP 8 157 + 158 + /* action field values for brcmf_ifevent */ 159 + #define BRCMF_E_IF_ADD 1 160 + #define BRCMF_E_IF_DEL 2 161 + #define BRCMF_E_IF_CHANGE 3 162 + 163 + /* flag field values for brcmf_ifevent */ 164 + #define BRCMF_E_IF_FLAG_NOIF 1 165 + 166 + /* role field values for brcmf_ifevent */ 167 + #define BRCMF_E_IF_ROLE_STA 0 168 + #define BRCMF_E_IF_ROLE_AP 1 169 + #define BRCMF_E_IF_ROLE_WDS 2 170 + 125 171 /** 126 172 * definitions for event packet validation. 127 173 */ ··· 204 158 char ifname[IFNAMSIZ]; 205 159 u8 ifidx; 206 160 u8 bsscfgidx; 161 + }; 162 + 163 + struct brcmf_if_event { 164 + u8 ifidx; 165 + u8 action; 166 + u8 flags; 167 + u8 bssidx; 168 + u8 role; 207 169 }; 208 170 209 171 typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
+3 -4
drivers/net/wireless/brcm80211/brcmfmac/fwil.c
··· 27 27 #include "dhd_dbg.h" 28 28 #include "tracepoint.h" 29 29 #include "fwil.h" 30 + #include "proto.h" 30 31 31 32 32 33 #define MAX_HEX_DUMP_LEN 64 ··· 47 46 if (data != NULL) 48 47 len = min_t(uint, len, BRCMF_DCMD_MAXLEN); 49 48 if (set) 50 - err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data, 51 - len); 49 + err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len); 52 50 else 53 - err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data, 54 - len); 51 + err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); 55 52 56 53 if (err >= 0) 57 54 err = 0;
+61
drivers/net/wireless/brcm80211/brcmfmac/fwil.h
··· 17 17 #ifndef _fwil_h_ 18 18 #define _fwil_h_ 19 19 20 + /******************************************************************************* 21 + * Dongle command codes that are interpreted by firmware 22 + ******************************************************************************/ 23 + #define BRCMF_C_GET_VERSION 1 24 + #define BRCMF_C_UP 2 25 + #define BRCMF_C_DOWN 3 26 + #define BRCMF_C_SET_PROMISC 10 27 + #define BRCMF_C_GET_RATE 12 28 + #define BRCMF_C_GET_INFRA 19 29 + #define BRCMF_C_SET_INFRA 20 30 + #define BRCMF_C_GET_AUTH 21 31 + #define BRCMF_C_SET_AUTH 22 32 + #define BRCMF_C_GET_BSSID 23 33 + #define BRCMF_C_GET_SSID 25 34 + #define BRCMF_C_SET_SSID 26 35 + #define BRCMF_C_TERMINATED 28 36 + #define BRCMF_C_GET_CHANNEL 29 37 + #define BRCMF_C_SET_CHANNEL 30 38 + #define BRCMF_C_GET_SRL 31 39 + #define BRCMF_C_SET_SRL 32 40 + #define BRCMF_C_GET_LRL 33 41 + #define BRCMF_C_SET_LRL 34 42 + #define BRCMF_C_GET_RADIO 37 43 + #define BRCMF_C_SET_RADIO 38 44 + #define BRCMF_C_GET_PHYTYPE 39 45 + #define BRCMF_C_SET_KEY 45 46 + #define BRCMF_C_SET_PASSIVE_SCAN 49 47 + #define BRCMF_C_SCAN 50 48 + #define BRCMF_C_SCAN_RESULTS 51 49 + #define BRCMF_C_DISASSOC 52 50 + #define BRCMF_C_REASSOC 53 51 + #define BRCMF_C_SET_ROAM_TRIGGER 55 52 + #define BRCMF_C_SET_ROAM_DELTA 57 53 + #define BRCMF_C_GET_BCNPRD 75 54 + #define BRCMF_C_SET_BCNPRD 76 55 + #define BRCMF_C_GET_DTIMPRD 77 56 + #define BRCMF_C_SET_DTIMPRD 78 57 + #define BRCMF_C_SET_COUNTRY 84 58 + #define BRCMF_C_GET_PM 85 59 + #define BRCMF_C_SET_PM 86 60 + #define BRCMF_C_GET_CURR_RATESET 114 61 + #define BRCMF_C_GET_AP 117 62 + #define BRCMF_C_SET_AP 118 63 + #define BRCMF_C_GET_RSSI 127 64 + #define BRCMF_C_GET_WSEC 133 65 + #define BRCMF_C_SET_WSEC 134 66 + #define BRCMF_C_GET_PHY_NOISE 135 67 + #define BRCMF_C_GET_BSS_INFO 136 68 + #define BRCMF_C_GET_BANDLIST 140 69 + #define BRCMF_C_SET_SCB_TIMEOUT 158 70 + #define BRCMF_C_GET_PHYLIST 180 71 + #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 72 + #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 73 + #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 74 + #define BRCMF_C_GET_VALID_CHANNELS 217 75 + #define BRCMF_C_GET_KEY_PRIMARY 235 76 + #define BRCMF_C_SET_KEY_PRIMARY 236 77 + #define BRCMF_C_SET_SCAN_PASSIVE_TIME 258 78 + #define BRCMF_C_GET_VAR 262 79 + #define BRCMF_C_SET_VAR 263 80 + 20 81 s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); 21 82 s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); 22 83 s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
+304
drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
··· 29 29 #define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004 30 30 #define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 31 31 32 + #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ 33 + #define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 34 + 35 + #define BRCMF_STA_ASSOC 0x10 /* Associated */ 36 + 37 + /* size of brcmf_scan_params not including variable length array */ 38 + #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 39 + 40 + /* masks for channel and ssid count */ 41 + #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff 42 + #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 43 + 44 + /* primary (ie tx) key */ 45 + #define BRCMF_PRIMARY_KEY (1 << 1) 46 + #define DOT11_BSSTYPE_ANY 2 47 + #define BRCMF_ESCAN_REQ_VERSION 1 48 + 49 + #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ 32 50 33 51 enum brcmf_fil_p2p_if_types { 34 52 BRCMF_FIL_P2P_IF_CLIENT, ··· 106 88 BRCMF_TDLS_MANUAL_EP_CREATE = 1, 107 89 BRCMF_TDLS_MANUAL_EP_DELETE = 3, 108 90 BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6 91 + }; 92 + 93 + /* Pattern matching filter. Specifies an offset within received packets to 94 + * start matching, the pattern to match, the size of the pattern, and a bitmask 95 + * that indicates which bits within the pattern should be matched. 96 + */ 97 + struct brcmf_pkt_filter_pattern_le { 98 + /* 99 + * Offset within received packet to start pattern matching. 100 + * Offset '0' is the first byte of the ethernet header. 101 + */ 102 + __le32 offset; 103 + /* Size of the pattern. Bitmask must be the same size.*/ 104 + __le32 size_bytes; 105 + /* 106 + * Variable length mask and pattern data. mask starts at offset 0. 107 + * Pattern immediately follows mask. 108 + */ 109 + u8 mask_and_pattern[1]; 110 + }; 111 + 112 + /* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ 113 + struct brcmf_pkt_filter_le { 114 + __le32 id; /* Unique filter id, specified by app. */ 115 + __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ 116 + __le32 negate_match; /* Negate the result of filter matches */ 117 + union { /* Filter definitions */ 118 + struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */ 119 + } u; 120 + }; 121 + 122 + /* IOVAR "pkt_filter_enable" parameter. */ 123 + struct brcmf_pkt_filter_enable_le { 124 + __le32 id; /* Unique filter id */ 125 + __le32 enable; /* Enable/disable bool */ 126 + }; 127 + 128 + /* BSS info structure 129 + * Applications MUST CHECK ie_offset field and length field to access IEs and 130 + * next bss_info structure in a vector (in struct brcmf_scan_results) 131 + */ 132 + struct brcmf_bss_info_le { 133 + __le32 version; /* version field */ 134 + __le32 length; /* byte length of data in this record, 135 + * starting at version and including IEs 136 + */ 137 + u8 BSSID[ETH_ALEN]; 138 + __le16 beacon_period; /* units are Kusec */ 139 + __le16 capability; /* Capability information */ 140 + u8 SSID_len; 141 + u8 SSID[32]; 142 + struct { 143 + __le32 count; /* # rates in this set */ 144 + u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ 145 + } rateset; /* supported rates */ 146 + __le16 chanspec; /* chanspec for bss */ 147 + __le16 atim_window; /* units are Kusec */ 148 + u8 dtim_period; /* DTIM period */ 149 + __le16 RSSI; /* receive signal strength (in dBm) */ 150 + s8 phy_noise; /* noise (in dBm) */ 151 + 152 + u8 n_cap; /* BSS is 802.11N Capable */ 153 + /* 802.11N BSS Capabilities (based on HT_CAP_*): */ 154 + __le32 nbss_cap; 155 + u8 ctl_ch; /* 802.11N BSS control channel number */ 156 + __le32 reserved32[1]; /* Reserved for expansion of BSS properties */ 157 + u8 flags; /* flags */ 158 + u8 reserved[3]; /* Reserved for expansion of BSS properties */ 159 + u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ 160 + 161 + __le16 ie_offset; /* offset at which IEs start, from beginning */ 162 + __le32 ie_length; /* byte length of Information Elements */ 163 + __le16 SNR; /* average SNR of during frame reception */ 164 + /* Add new fields here */ 165 + /* variable length Information Elements */ 166 + }; 167 + 168 + struct brcm_rateset_le { 169 + /* # rates in this set */ 170 + __le32 count; 171 + /* rates in 500kbps units w/hi bit set if basic */ 172 + u8 rates[BRCMF_MAXRATES_IN_SET]; 173 + }; 174 + 175 + struct brcmf_ssid { 176 + u32 SSID_len; 177 + unsigned char SSID[32]; 178 + }; 179 + 180 + struct brcmf_ssid_le { 181 + __le32 SSID_len; 182 + unsigned char SSID[32]; 183 + }; 184 + 185 + struct brcmf_scan_params_le { 186 + struct brcmf_ssid_le ssid_le; /* default: {0, ""} */ 187 + u8 bssid[ETH_ALEN]; /* default: bcast */ 188 + s8 bss_type; /* default: any, 189 + * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT 190 + */ 191 + u8 scan_type; /* flags, 0 use default */ 192 + __le32 nprobes; /* -1 use default, number of probes per channel */ 193 + __le32 active_time; /* -1 use default, dwell time per channel for 194 + * active scanning 195 + */ 196 + __le32 passive_time; /* -1 use default, dwell time per channel 197 + * for passive scanning 198 + */ 199 + __le32 home_time; /* -1 use default, dwell time for the 200 + * home channel between channel scans 201 + */ 202 + __le32 channel_num; /* count of channels and ssids that follow 203 + * 204 + * low half is count of channels in 205 + * channel_list, 0 means default (use all 206 + * available channels) 207 + * 208 + * high half is entries in struct brcmf_ssid 209 + * array that follows channel_list, aligned for 210 + * s32 (4 bytes) meaning an odd channel count 211 + * implies a 2-byte pad between end of 212 + * channel_list and first ssid 213 + * 214 + * if ssid count is zero, single ssid in the 215 + * fixed parameter portion is assumed, otherwise 216 + * ssid in the fixed portion is ignored 217 + */ 218 + __le16 channel_list[1]; /* list of chanspecs */ 219 + }; 220 + 221 + struct brcmf_scan_results { 222 + u32 buflen; 223 + u32 version; 224 + u32 count; 225 + struct brcmf_bss_info_le bss_info_le[]; 226 + }; 227 + 228 + struct brcmf_escan_params_le { 229 + __le32 version; 230 + __le16 action; 231 + __le16 sync_id; 232 + struct brcmf_scan_params_le params_le; 233 + }; 234 + 235 + struct brcmf_escan_result_le { 236 + __le32 buflen; 237 + __le32 version; 238 + __le16 sync_id; 239 + __le16 bss_count; 240 + struct brcmf_bss_info_le bss_info_le; 241 + }; 242 + 243 + #define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \ 244 + sizeof(struct brcmf_bss_info_le)) 245 + 246 + /* used for association with a specific BSSID and chanspec list */ 247 + struct brcmf_assoc_params_le { 248 + /* 00:00:00:00:00:00: broadcast scan */ 249 + u8 bssid[ETH_ALEN]; 250 + /* 0: all available channels, otherwise count of chanspecs in 251 + * chanspec_list */ 252 + __le32 chanspec_num; 253 + /* list of chanspecs */ 254 + __le16 chanspec_list[1]; 255 + }; 256 + 257 + /* used for join with or without a specific bssid and channel list */ 258 + struct brcmf_join_params { 259 + struct brcmf_ssid_le ssid_le; 260 + struct brcmf_assoc_params_le params_le; 261 + }; 262 + 263 + /* scan params for extended join */ 264 + struct brcmf_join_scan_params_le { 265 + u8 scan_type; /* 0 use default, active or passive scan */ 266 + __le32 nprobes; /* -1 use default, nr of probes per channel */ 267 + __le32 active_time; /* -1 use default, dwell time per channel for 268 + * active scanning 269 + */ 270 + __le32 passive_time; /* -1 use default, dwell time per channel 271 + * for passive scanning 272 + */ 273 + __le32 home_time; /* -1 use default, dwell time for the home 274 + * channel between channel scans 275 + */ 276 + }; 277 + 278 + /* extended join params */ 279 + struct brcmf_ext_join_params_le { 280 + struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */ 281 + struct brcmf_join_scan_params_le scan_le; 282 + struct brcmf_assoc_params_le assoc_le; 283 + }; 284 + 285 + struct brcmf_wsec_key { 286 + u32 index; /* key index */ 287 + u32 len; /* key length */ 288 + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ 289 + u32 pad_1[18]; 290 + u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ 291 + u32 flags; /* misc flags */ 292 + u32 pad_2[3]; 293 + u32 iv_initialized; /* has IV been initialized already? */ 294 + u32 pad_3; 295 + /* Rx IV */ 296 + struct { 297 + u32 hi; /* upper 32 bits of IV */ 298 + u16 lo; /* lower 16 bits of IV */ 299 + } rxiv; 300 + u32 pad_4[2]; 301 + u8 ea[ETH_ALEN]; /* per station */ 302 + }; 303 + 304 + /* 305 + * dongle requires same struct as above but with fields in little endian order 306 + */ 307 + struct brcmf_wsec_key_le { 308 + __le32 index; /* key index */ 309 + __le32 len; /* key length */ 310 + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ 311 + __le32 pad_1[18]; 312 + __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ 313 + __le32 flags; /* misc flags */ 314 + __le32 pad_2[3]; 315 + __le32 iv_initialized; /* has IV been initialized already? */ 316 + __le32 pad_3; 317 + /* Rx IV */ 318 + struct { 319 + __le32 hi; /* upper 32 bits of IV */ 320 + __le16 lo; /* lower 16 bits of IV */ 321 + } rxiv; 322 + __le32 pad_4[2]; 323 + u8 ea[ETH_ALEN]; /* per station */ 324 + }; 325 + 326 + /* Used to get specific STA parameters */ 327 + struct brcmf_scb_val_le { 328 + __le32 val; 329 + u8 ea[ETH_ALEN]; 330 + }; 331 + 332 + /* channel encoding */ 333 + struct brcmf_channel_info_le { 334 + __le32 hw_channel; 335 + __le32 target_channel; 336 + __le32 scan_channel; 337 + }; 338 + 339 + struct brcmf_sta_info_le { 340 + __le16 ver; /* version of this struct */ 341 + __le16 len; /* length in bytes of this structure */ 342 + __le16 cap; /* sta's advertised capabilities */ 343 + __le32 flags; /* flags defined below */ 344 + __le32 idle; /* time since data pkt rx'd from sta */ 345 + u8 ea[ETH_ALEN]; /* Station address */ 346 + __le32 count; /* # rates in this set */ 347 + u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ 348 + /* w/hi bit set if basic */ 349 + __le32 in; /* seconds elapsed since associated */ 350 + __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ 351 + __le32 tx_pkts; /* # of packets transmitted */ 352 + __le32 tx_failures; /* # of packets failed */ 353 + __le32 rx_ucast_pkts; /* # of unicast packets received */ 354 + __le32 rx_mcast_pkts; /* # of multicast packets received */ 355 + __le32 tx_rate; /* Rate of last successful tx frame */ 356 + __le32 rx_rate; /* Rate of last successful rx frame */ 357 + __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ 358 + __le32 rx_decrypt_failures; /* # of packet decrypted failed */ 359 + }; 360 + 361 + struct brcmf_chanspec_list { 362 + __le32 count; /* # of entries */ 363 + __le32 element[1]; /* variable length uint32 list */ 364 + }; 365 + 366 + /* 367 + * WLC_E_PROBRESP_MSG 368 + * WLC_E_P2P_PROBREQ_MSG 369 + * WLC_E_ACTION_FRAME_RX 370 + */ 371 + struct brcmf_rx_mgmt_data { 372 + __be16 version; 373 + __be16 chanspec; 374 + __be32 rssi; 375 + __be32 mactime; 376 + __be32 rate; 109 377 }; 110 378 111 379 #endif /* FWIL_TYPES_H_ */
+151 -22
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
··· 27 27 #include <brcmu_utils.h> 28 28 #include <brcmu_wifi.h> 29 29 #include "dhd.h" 30 - #include "dhd_proto.h" 31 30 #include "dhd_dbg.h" 32 31 #include "dhd_bus.h" 33 32 #include "fwil.h" ··· 35 36 #include "fwsignal.h" 36 37 #include "p2p.h" 37 38 #include "wl_cfg80211.h" 39 + #include "proto.h" 38 40 39 41 /** 40 42 * DOC: Firmware Signalling ··· 105 105 }; 106 106 #undef BRCMF_FWS_TLV_DEF 107 107 108 + 108 109 static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) 109 110 { 110 111 int i; ··· 122 121 return "NODEBUG"; 123 122 } 124 123 #endif /* DEBUG */ 124 + 125 + /* 126 + * The PKTTAG tlv has additional bytes when firmware-signalling 127 + * mode has REUSESEQ flag set. 128 + */ 129 + #define BRCMF_FWS_TYPE_SEQ_LEN 2 125 130 126 131 /* 127 132 * flags used to enable tlv signalling from firmware. ··· 154 147 #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 155 148 #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 156 149 157 - #define BRCMF_FWS_RET_OK_NOSCHEDULE 0 158 - #define BRCMF_FWS_RET_OK_SCHEDULE 1 150 + #define BRCMF_FWS_RET_OK_NOSCHEDULE 0 151 + #define BRCMF_FWS_RET_OK_SCHEDULE 1 152 + 153 + #define BRCMF_FWS_MODE_REUSESEQ_SHIFT 3 /* seq reuse */ 154 + #define BRCMF_FWS_MODE_SET_REUSESEQ(x, val) ((x) = \ 155 + ((x) & ~(1 << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) | \ 156 + (((val) & 1) << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) 157 + #define BRCMF_FWS_MODE_GET_REUSESEQ(x) \ 158 + (((x) >> BRCMF_FWS_MODE_REUSESEQ_SHIFT) & 1) 159 159 160 160 /** 161 161 * enum brcmf_fws_skb_state - indicates processing state of skb. ··· 185 171 * @bus_flags: 2 bytes reserved for bus specific parameters 186 172 * @if_flags: holds interface index and packet related flags. 187 173 * @htod: host to device packet identifier (used in PKTTAG tlv). 174 + * @htod_seq: this 16-bit is original seq number for every suppress packet. 188 175 * @state: transmit state of the packet. 189 176 * @mac: descriptor related to destination for this packet. 190 177 * ··· 196 181 u16 bus_flags; 197 182 u16 if_flags; 198 183 u32 htod; 184 + u16 htod_seq; 199 185 enum brcmf_fws_skb_state state; 200 186 struct brcmf_fws_mac_descriptor *mac; 201 187 }; ··· 273 257 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ 274 258 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT) 275 259 260 + #define BRCMF_SKB_HTOD_SEQ_FROMFW_MASK 0x2000 261 + #define BRCMF_SKB_HTOD_SEQ_FROMFW_SHIFT 13 262 + #define BRCMF_SKB_HTOD_SEQ_FROMDRV_MASK 0x1000 263 + #define BRCMF_SKB_HTOD_SEQ_FROMDRV_SHIFT 12 264 + #define BRCMF_SKB_HTOD_SEQ_NR_MASK 0x0fff 265 + #define BRCMF_SKB_HTOD_SEQ_NR_SHIFT 0 266 + 267 + #define brcmf_skb_htod_seq_set_field(skb, field, value) \ 268 + brcmu_maskset16(&(brcmf_skbcb(skb)->htod_seq), \ 269 + BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \ 270 + BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT, (value)) 271 + #define brcmf_skb_htod_seq_get_field(skb, field) \ 272 + brcmu_maskget16(brcmf_skbcb(skb)->htod_seq, \ 273 + BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \ 274 + BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT) 275 + 276 276 #define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000 277 277 #define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31 278 278 #define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000 ··· 297 265 #define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24 298 266 #define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00 299 267 #define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8 300 - #define BRCMF_FWS_TXSTAT_PKTID_MASK 0x00FFFFFF 301 - #define BRCMF_FWS_TXSTAT_PKTID_SHIFT 0 268 + #define BRCMF_FWS_TXSTAT_FREERUN_MASK 0x000000FF 269 + #define BRCMF_FWS_TXSTAT_FREERUN_SHIFT 0 302 270 303 271 #define brcmf_txstatus_get_field(txs, field) \ 304 272 brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \ ··· 475 443 unsigned long borrow_defer_timestamp; 476 444 bool bus_flow_blocked; 477 445 bool creditmap_received; 446 + u8 mode; 478 447 }; 479 448 480 449 /* ··· 845 812 u16 data_offset = 0; 846 813 u8 fillers; 847 814 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); 815 + __le16 pktseq = cpu_to_le16(brcmf_skbcb(skb)->htod_seq); 848 816 849 - brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n", 817 + brcmf_dbg(TRACE, "enter: %s, idx=%d hslot=%d htod %X seq %X\n", 850 818 entry->name, brcmf_skb_if_flags_get_field(skb, INDEX), 851 - le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); 819 + (le32_to_cpu(pkttag) >> 8) & 0xffff, 820 + brcmf_skbcb(skb)->htod, brcmf_skbcb(skb)->htod_seq); 852 821 if (entry->send_tim_signal) 853 822 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; 854 - 823 + if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) 824 + data_offset += BRCMF_FWS_TYPE_SEQ_LEN; 855 825 /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ 856 826 data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN; 857 827 fillers = round_up(data_offset, 4) - data_offset; ··· 866 830 wlh[0] = BRCMF_FWS_TYPE_PKTTAG; 867 831 wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN; 868 832 memcpy(&wlh[2], &pkttag, sizeof(pkttag)); 869 - wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2; 833 + if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) { 834 + wlh[1] += BRCMF_FWS_TYPE_SEQ_LEN; 835 + memcpy(&wlh[2 + BRCMF_FWS_TYPE_PKTTAG_LEN], &pktseq, 836 + sizeof(pktseq)); 837 + } 838 + wlh += wlh[1] + 2; 870 839 871 840 if (entry->send_tim_signal) { 872 841 entry->send_tim_signal = 0; ··· 916 875 /* create a dummy packet and sent that. The traffic */ 917 876 /* bitmap info will automatically be attached to that packet */ 918 877 len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 + 878 + BRCMF_FWS_TYPE_SEQ_LEN + 919 879 BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 + 920 880 4 + fws->drvr->hdrlen; 921 881 skb = brcmu_pkt_buf_get_skb(len); ··· 926 884 skcb = brcmf_skbcb(skb); 927 885 skcb->mac = entry; 928 886 skcb->state = BRCMF_FWS_SKBSTATE_TIM; 887 + skcb->htod = 0; 888 + skcb->htod_seq = 0; 929 889 bus = fws->drvr->bus_if; 930 890 err = brcmf_fws_hdrpush(fws, skb); 931 891 if (err == 0) { ··· 1216 1172 { 1217 1173 int prec = 2 * fifo; 1218 1174 u32 *qfull_stat = &fws->stats.delayq_full_error; 1219 - 1220 1175 struct brcmf_fws_mac_descriptor *entry; 1176 + struct pktq *pq; 1177 + struct sk_buff_head *queue; 1178 + struct sk_buff *p_head; 1179 + struct sk_buff *p_tail; 1180 + u32 fr_new; 1181 + u32 fr_compare; 1221 1182 1222 1183 entry = brcmf_skbcb(p)->mac; 1223 1184 if (entry == NULL) { ··· 1234 1185 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) { 1235 1186 prec += 1; 1236 1187 qfull_stat = &fws->stats.supprq_full_error; 1237 - } 1238 1188 1239 - if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) { 1189 + /* Fix out of order delivery of frames. Dont assume frame */ 1190 + /* can be inserted at the end, but look for correct position */ 1191 + pq = &entry->psq; 1192 + if (pktq_full(pq) || pktq_pfull(pq, prec)) { 1193 + *qfull_stat += 1; 1194 + return -ENFILE; 1195 + } 1196 + queue = &pq->q[prec].skblist; 1197 + 1198 + p_head = skb_peek(queue); 1199 + p_tail = skb_peek_tail(queue); 1200 + fr_new = brcmf_skb_htod_tag_get_field(p, FREERUN); 1201 + 1202 + while (p_head != p_tail) { 1203 + fr_compare = brcmf_skb_htod_tag_get_field(p_tail, 1204 + FREERUN); 1205 + /* be sure to handle wrap of 256 */ 1206 + if (((fr_new > fr_compare) && 1207 + ((fr_new - fr_compare) < 128)) || 1208 + ((fr_new < fr_compare) && 1209 + ((fr_compare - fr_new) > 128))) 1210 + break; 1211 + p_tail = skb_queue_prev(queue, p_tail); 1212 + } 1213 + /* Position found. Determine what to do */ 1214 + if (p_tail == NULL) { 1215 + /* empty list */ 1216 + __skb_queue_tail(queue, p); 1217 + } else { 1218 + fr_compare = brcmf_skb_htod_tag_get_field(p_tail, 1219 + FREERUN); 1220 + if (((fr_new > fr_compare) && 1221 + ((fr_new - fr_compare) < 128)) || 1222 + ((fr_new < fr_compare) && 1223 + ((fr_compare - fr_new) > 128))) { 1224 + /* After tail */ 1225 + __skb_queue_after(queue, p_tail, p); 1226 + } else { 1227 + /* Before tail */ 1228 + __skb_insert(p, p_tail->prev, p_tail, queue); 1229 + } 1230 + } 1231 + 1232 + /* Complete the counters and statistics */ 1233 + pq->len++; 1234 + if (pq->hi_prec < prec) 1235 + pq->hi_prec = (u8) prec; 1236 + } else if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) { 1240 1237 *qfull_stat += 1; 1241 1238 return -ENFILE; 1242 1239 } ··· 1372 1277 } 1373 1278 1374 1279 static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, 1375 - struct sk_buff *skb, u32 genbit) 1280 + struct sk_buff *skb, u32 genbit, 1281 + u16 seq) 1376 1282 { 1377 1283 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; 1378 1284 u32 hslot; ··· 1394 1298 1395 1299 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); 1396 1300 if (ret == 0) 1301 + brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit); 1302 + brcmf_skbcb(skb)->htod_seq = seq; 1303 + if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) { 1304 + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1); 1305 + brcmf_skb_htod_seq_set_field(skb, FROMFW, 0); 1306 + } else { 1307 + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0); 1308 + } 1397 1309 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, 1398 1310 skb); 1399 1311 if (ret != 0) { ··· 1421 1317 1422 1318 static int 1423 1319 brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, 1424 - u32 genbit) 1320 + u32 genbit, u16 seq) 1425 1321 { 1426 1322 u32 fifo; 1427 1323 int ret; ··· 1464 1360 if (entry->suppressed && entry->suppr_transit_count) 1465 1361 entry->suppr_transit_count--; 1466 1362 1467 - brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags, 1468 - skcb->htod); 1363 + brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags, 1364 + skcb->htod, seq); 1469 1365 1470 1366 /* pick up the implicit credit from this packet */ 1471 1367 fifo = brcmf_skb_htod_tag_get_field(skb, FIFO); ··· 1478 1374 brcmf_fws_macdesc_return_req_credit(skb); 1479 1375 1480 1376 if (!remove_from_hanger) 1481 - ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit); 1377 + ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit, 1378 + seq); 1482 1379 1483 1380 if (remove_from_hanger || ret) 1484 1381 brcmf_txfinalize(fws->drvr, skb, true); ··· 1511 1406 static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) 1512 1407 { 1513 1408 __le32 status_le; 1409 + __le16 seq_le; 1514 1410 u32 status; 1515 1411 u32 hslot; 1516 1412 u32 genbit; 1517 1413 u8 flags; 1414 + u16 seq; 1518 1415 1519 1416 fws->stats.txs_indicate++; 1520 1417 memcpy(&status_le, data, sizeof(status_le)); ··· 1524 1417 flags = brcmf_txstatus_get_field(status, FLAGS); 1525 1418 hslot = brcmf_txstatus_get_field(status, HSLOT); 1526 1419 genbit = brcmf_txstatus_get_field(status, GENERATION); 1420 + if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) { 1421 + memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN], 1422 + sizeof(seq_le)); 1423 + seq = le16_to_cpu(seq_le); 1424 + } else { 1425 + seq = 0; 1426 + } 1527 1427 1528 1428 brcmf_fws_lock(fws); 1529 - brcmf_fws_txs_process(fws, flags, hslot, genbit); 1429 + brcmf_fws_txs_process(fws, flags, hslot, genbit, seq); 1530 1430 brcmf_fws_unlock(fws); 1531 1431 return BRCMF_FWS_RET_OK_NOSCHEDULE; 1532 1432 } ··· 1724 1610 struct brcmf_fws_mac_descriptor *entry = skcb->mac; 1725 1611 u8 flags; 1726 1612 1727 - brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); 1728 - brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); 1613 + if (skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED) 1614 + brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); 1729 1615 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; 1730 1616 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { 1731 1617 /* ··· 1766 1652 fws->stats.rollback_failed++; 1767 1653 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1768 1654 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, 1769 - hslot, 0); 1655 + hslot, 0, 0); 1770 1656 } else { 1771 1657 fws->stats.rollback_success++; 1772 1658 brcmf_fws_return_credits(fws, fifo, 1); ··· 1846 1732 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); 1847 1733 int rc, hslot; 1848 1734 1735 + skcb->htod = 0; 1736 + skcb->htod_seq = 0; 1849 1737 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger); 1850 1738 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot); 1851 1739 brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]); ··· 2024 1908 struct brcmf_fws_info *fws; 2025 1909 u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS; 2026 1910 int rc; 1911 + u32 mode; 2027 1912 2028 1913 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL); 2029 1914 if (!drvr->fws) { ··· 2083 1966 if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1)) 2084 1967 brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n"); 2085 1968 1969 + /* Enable seq number reuse, if supported */ 1970 + if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) { 1971 + if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) { 1972 + mode = 0; 1973 + BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1); 1974 + if (brcmf_fil_iovar_int_set(drvr->iflist[0], 1975 + "wlfc_mode", mode) == 0) { 1976 + BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1); 1977 + } 1978 + } 1979 + } 1980 + 2086 1981 brcmf_fws_hanger_init(&fws->hanger); 2087 1982 brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0); 2088 1983 brcmf_fws_macdesc_set_name(fws, &fws->desc.other); ··· 2151 2022 } 2152 2023 brcmf_fws_lock(fws); 2153 2024 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 2154 - brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0); 2025 + brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0); 2155 2026 brcmf_fws_unlock(fws); 2156 2027 } 2157 2028
+1 -1
drivers/net/wireless/brcm80211/brcmfmac/p2p.c
··· 812 812 struct ieee80211_channel *chan = request->channels[i]; 813 813 814 814 if (chan->flags & (IEEE80211_CHAN_RADAR | 815 - IEEE80211_CHAN_PASSIVE_SCAN)) 815 + IEEE80211_CHAN_NO_IR)) 816 816 continue; 817 817 818 818 chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf,
+62
drivers/net/wireless/brcm80211/brcmfmac/proto.c
··· 1 + /* 2 + * Copyright (c) 2013 Broadcom Corporation 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 ANY 11 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + 17 + 18 + #include <linux/types.h> 19 + #include <linux/slab.h> 20 + #include <linux/netdevice.h> 21 + 22 + #include <brcmu_wifi.h> 23 + #include "dhd.h" 24 + #include "dhd_dbg.h" 25 + #include "proto.h" 26 + #include "bcdc.h" 27 + 28 + 29 + int brcmf_proto_attach(struct brcmf_pub *drvr) 30 + { 31 + struct brcmf_proto *proto; 32 + 33 + proto = kzalloc(sizeof(*proto), GFP_ATOMIC); 34 + if (!proto) 35 + goto fail; 36 + 37 + drvr->proto = proto; 38 + /* BCDC protocol is only protocol supported for the moment */ 39 + if (brcmf_proto_bcdc_attach(drvr)) 40 + goto fail; 41 + 42 + if ((proto->hdrpush == NULL) || (proto->hdrpull == NULL) || 43 + (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) { 44 + brcmf_err("Not all proto handlers have been installed\n"); 45 + goto fail; 46 + } 47 + return 0; 48 + 49 + fail: 50 + kfree(proto); 51 + drvr->proto = NULL; 52 + return -ENOMEM; 53 + } 54 + 55 + void brcmf_proto_detach(struct brcmf_pub *drvr) 56 + { 57 + if (drvr->proto) { 58 + brcmf_proto_bcdc_detach(drvr); 59 + kfree(drvr->proto); 60 + drvr->proto = NULL; 61 + } 62 + }
+57
drivers/net/wireless/brcm80211/brcmfmac/proto.h
··· 1 + /* 2 + * Copyright (c) 2013 Broadcom Corporation 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 ANY 11 + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + #ifndef BRCMFMAC_PROTO_H 17 + #define BRCMFMAC_PROTO_H 18 + 19 + struct brcmf_proto { 20 + void (*hdrpush)(struct brcmf_pub *drvr, int ifidx, u8 offset, 21 + struct sk_buff *skb); 22 + int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, 23 + struct sk_buff *skb); 24 + int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, 25 + void *buf, uint len); 26 + int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, 27 + uint len); 28 + void *pd; 29 + }; 30 + 31 + 32 + int brcmf_proto_attach(struct brcmf_pub *drvr); 33 + void brcmf_proto_detach(struct brcmf_pub *drvr); 34 + 35 + static inline void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, 36 + u8 offset, struct sk_buff *skb) 37 + { 38 + drvr->proto->hdrpush(drvr, ifidx, offset, skb); 39 + } 40 + static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, 41 + u8 *ifidx, struct sk_buff *skb) 42 + { 43 + return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb); 44 + } 45 + static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx, 46 + uint cmd, void *buf, uint len) 47 + { 48 + return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len); 49 + } 50 + static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx, 51 + uint cmd, void *buf, uint len) 52 + { 53 + return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); 54 + } 55 + 56 + 57 + #endif /* BRCMFMAC_PROTO_H */
+22 -11
drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
··· 89 89 TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len) 90 90 ); 91 91 92 - TRACE_EVENT(brcmf_bdchdr, 92 + TRACE_EVENT(brcmf_bcdchdr, 93 93 TP_PROTO(void *data), 94 94 TP_ARGS(data), 95 95 TP_STRUCT__entry( ··· 107 107 memcpy(__get_dynamic_array(signal), 108 108 (u8 *)data + 4, __entry->siglen); 109 109 ), 110 - TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) 110 + TP_printk("bcdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) 111 111 ); 112 112 113 + #ifndef SDPCM_RX 114 + #define SDPCM_RX 0 115 + #endif 116 + #ifndef SDPCM_TX 117 + #define SDPCM_TX 1 118 + #endif 119 + #ifndef SDPCM_GLOM 120 + #define SDPCM_GLOM 2 121 + #endif 122 + 113 123 TRACE_EVENT(brcmf_sdpcm_hdr, 114 - TP_PROTO(bool tx, void *data), 115 - TP_ARGS(tx, data), 124 + TP_PROTO(u8 dir, void *data), 125 + TP_ARGS(dir, data), 116 126 TP_STRUCT__entry( 117 - __field(u8, tx) 127 + __field(u8, dir) 118 128 __field(u16, len) 119 - __array(u8, hdr, 12) 129 + __dynamic_array(u8, hdr, dir == SDPCM_GLOM ? 20 : 12) 120 130 ), 121 131 TP_fast_assign( 122 - memcpy(__entry->hdr, data, 12); 123 - __entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8); 124 - __entry->tx = tx ? 1 : 0; 132 + memcpy(__get_dynamic_array(hdr), data, dir == SDPCM_GLOM ? 20 : 12); 133 + __entry->len = *(u8 *)data | (*((u8 *)data + 1) << 8); 134 + __entry->dir = dir; 125 135 ), 126 - TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX", 127 - __entry->len, __entry->hdr[4]) 136 + TP_printk("sdpcm: %s len %u, seq %d", 137 + __entry->dir == SDPCM_RX ? "RX" : "TX", 138 + __entry->len, ((u8 *)__get_dynamic_array(hdr))[4]) 128 139 ); 129 140 130 141 #ifdef CONFIG_BRCM_TRACING
+2 -2
drivers/net/wireless/brcm80211/brcmfmac/usb.c
··· 1255 1255 bus->chiprev = bus_pub->chiprev; 1256 1256 1257 1257 /* Attach to the common driver interface */ 1258 - ret = brcmf_attach(0, dev); 1258 + ret = brcmf_attach(dev); 1259 1259 if (ret) { 1260 1260 brcmf_err("brcmf_attach failed\n"); 1261 1261 goto fail; ··· 1454 1454 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1455 1455 1456 1456 brcmf_dbg(USB, "Enter\n"); 1457 - if (!brcmf_attach(0, devinfo->dev)) 1457 + if (!brcmf_attach(devinfo->dev)) 1458 1458 return brcmf_bus_start(&usb->dev); 1459 1459 1460 1460 return 0;
+15 -14
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
··· 202 202 203 203 /* This is to override regulatory domains defined in cfg80211 module (reg.c) 204 204 * By default world regulatory domain defined in reg.c puts the flags 205 - * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for 206 - * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't 207 - * start p2p operations on 5GHz channels. All the changes in world regulatory 205 + * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165). 206 + * With respect to these flags, wpa_supplicant doesn't * start p2p 207 + * operations on 5GHz channels. All the changes in world regulatory 208 208 * domain are to be done here. 209 209 */ 210 210 static const struct ieee80211_regdomain brcmf_regdom = { ··· 2556 2556 ch_bss.band == ch_bss_info_le.band && 2557 2557 bss_info_le->SSID_len == bss->SSID_len && 2558 2558 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) { 2559 - if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == 2560 - (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) { 2559 + if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 2560 + (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) { 2561 2561 s16 bss_rssi = le16_to_cpu(bss->RSSI); 2562 2562 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI); 2563 2563 ··· 2566 2566 */ 2567 2567 if (bss_info_rssi > bss_rssi) 2568 2568 bss->RSSI = bss_info_le->RSSI; 2569 - } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) && 2570 - (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) { 2569 + } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) && 2570 + (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) { 2571 2571 /* preserve the on-channel rssi measurement 2572 2572 * if the new measurement is off channel 2573 2573 */ 2574 2574 bss->RSSI = bss_info_le->RSSI; 2575 - bss->flags |= WLC_BSS_RSSI_ON_CHANNEL; 2575 + bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL; 2576 2576 } 2577 2577 return 1; 2578 2578 } ··· 3973 3973 3974 3974 static int 3975 3975 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3976 - struct ieee80211_channel *chan, bool offchan, 3977 - unsigned int wait, const u8 *buf, size_t len, 3978 - bool no_cck, bool dont_wait_for_ack, u64 *cookie) 3976 + struct cfg80211_mgmt_tx_params *params, u64 *cookie) 3979 3977 { 3980 3978 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3979 + struct ieee80211_channel *chan = params->chan; 3980 + const u8 *buf = params->buf; 3981 + size_t len = params->len; 3981 3982 const struct ieee80211_mgmt *mgmt; 3982 3983 struct brcmf_cfg80211_vif *vif; 3983 3984 s32 err = 0; ··· 4342 4341 wiphy->max_remain_on_channel_duration = 5000; 4343 4342 brcmf_wiphy_pno_params(wiphy); 4344 4343 brcmf_dbg(INFO, "Registering custom regulatory\n"); 4345 - wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 4344 + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 4346 4345 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); 4347 4346 err = wiphy_register(wiphy); 4348 4347 if (err < 0) { ··· 5198 5197 if (channel & WL_CHAN_RADAR) 5199 5198 band_chan_arr[index].flags |= 5200 5199 (IEEE80211_CHAN_RADAR | 5201 - IEEE80211_CHAN_NO_IBSS); 5200 + IEEE80211_CHAN_NO_IR); 5202 5201 if (channel & WL_CHAN_PASSIVE) 5203 5202 band_chan_arr[index].flags |= 5204 - IEEE80211_CHAN_PASSIVE_SCAN; 5203 + IEEE80211_CHAN_NO_IR; 5205 5204 } 5206 5205 } 5207 5206 if (!update)
+15 -23
drivers/net/wireless/brcm80211/brcmsmac/channel.c
··· 59 59 60 60 #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) 61 61 #define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ 62 - NL80211_RRF_PASSIVE_SCAN | \ 63 - NL80211_RRF_NO_IBSS) 62 + NL80211_RRF_NO_IR) 64 63 65 64 #define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ 66 - NL80211_RRF_PASSIVE_SCAN | \ 67 - NL80211_RRF_NO_IBSS) 65 + NL80211_RRF_NO_IR) 68 66 #define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ 69 - NL80211_RRF_PASSIVE_SCAN | \ 70 67 NL80211_RRF_DFS | \ 71 - NL80211_RRF_NO_IBSS) 68 + NL80211_RRF_NO_IR) 72 69 #define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ 73 - NL80211_RRF_PASSIVE_SCAN | \ 74 70 NL80211_RRF_DFS | \ 75 - NL80211_RRF_NO_IBSS) 71 + NL80211_RRF_NO_IR) 76 72 #define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ 77 - NL80211_RRF_PASSIVE_SCAN | \ 78 - NL80211_RRF_NO_IBSS) 73 + NL80211_RRF_NO_IR) 79 74 80 75 static const struct ieee80211_regdomain brcms_regdom_x2 = { 81 76 .n_reg_rules = 6, ··· 390 395 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); 391 396 392 397 brcms_b_set_chanspec(wlc->hw, chanspec, 393 - !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN), 398 + !!(ch->flags & IEEE80211_CHAN_NO_IR), 394 399 &txpwr); 395 400 } 396 401 ··· 652 657 */ 653 658 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 654 659 ch->flags |= IEEE80211_CHAN_RADAR | 655 - IEEE80211_CHAN_NO_IBSS | 656 - IEEE80211_CHAN_PASSIVE_SCAN; 660 + IEEE80211_CHAN_NO_IR | 661 + IEEE80211_CHAN_NO_IR; 657 662 } 658 663 } 659 664 ··· 679 684 continue; 680 685 681 686 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 682 - rule = freq_reg_info(wiphy, ch->center_freq); 687 + rule = freq_reg_info(wiphy, 688 + MHZ_TO_KHZ(ch->center_freq)); 683 689 if (IS_ERR(rule)) 684 690 continue; 685 691 686 - if (!(rule->flags & NL80211_RRF_NO_IBSS)) 687 - ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 688 - if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN)) 689 - ch->flags &= 690 - ~IEEE80211_CHAN_PASSIVE_SCAN; 692 + if (!(rule->flags & NL80211_RRF_NO_IR)) 693 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 691 694 } else if (ch->beacon_found) { 692 - ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 693 - IEEE80211_CHAN_PASSIVE_SCAN); 695 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 694 696 } 695 697 } 696 698 } ··· 767 775 } 768 776 769 777 wlc->wiphy->reg_notifier = brcms_reg_notifier; 770 - wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 771 - WIPHY_FLAG_STRICT_REGULATORY; 778 + wlc->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 779 + REGULATORY_STRICT_REG; 772 780 wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain); 773 781 brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER); 774 782 }
+33 -33
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
··· 125 125 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), 126 126 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), 127 127 CHAN2GHZ(12, 2467, 128 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 128 + IEEE80211_CHAN_NO_IR | 129 129 IEEE80211_CHAN_NO_HT40PLUS), 130 130 CHAN2GHZ(13, 2472, 131 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 131 + IEEE80211_CHAN_NO_IR | 132 132 IEEE80211_CHAN_NO_HT40PLUS), 133 133 CHAN2GHZ(14, 2484, 134 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 134 + IEEE80211_CHAN_NO_IR | 135 135 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS | 136 136 IEEE80211_CHAN_NO_OFDM) 137 137 }; ··· 144 144 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), 145 145 /* UNII-2 */ 146 146 CHAN5GHZ(52, 147 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 148 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 147 + IEEE80211_CHAN_RADAR | 148 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), 149 149 CHAN5GHZ(56, 150 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 151 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 150 + IEEE80211_CHAN_RADAR | 151 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), 152 152 CHAN5GHZ(60, 153 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 154 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 153 + IEEE80211_CHAN_RADAR | 154 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), 155 155 CHAN5GHZ(64, 156 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 157 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 156 + IEEE80211_CHAN_RADAR | 157 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), 158 158 /* MID */ 159 159 CHAN5GHZ(100, 160 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 161 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 160 + IEEE80211_CHAN_RADAR | 161 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), 162 162 CHAN5GHZ(104, 163 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 164 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 163 + IEEE80211_CHAN_RADAR | 164 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), 165 165 CHAN5GHZ(108, 166 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 167 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 166 + IEEE80211_CHAN_RADAR | 167 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), 168 168 CHAN5GHZ(112, 169 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 170 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 169 + IEEE80211_CHAN_RADAR | 170 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), 171 171 CHAN5GHZ(116, 172 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 173 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 172 + IEEE80211_CHAN_RADAR | 173 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), 174 174 CHAN5GHZ(120, 175 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 176 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 175 + IEEE80211_CHAN_RADAR | 176 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), 177 177 CHAN5GHZ(124, 178 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 179 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 178 + IEEE80211_CHAN_RADAR | 179 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), 180 180 CHAN5GHZ(128, 181 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 182 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 181 + IEEE80211_CHAN_RADAR | 182 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), 183 183 CHAN5GHZ(132, 184 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 185 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 184 + IEEE80211_CHAN_RADAR | 185 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), 186 186 CHAN5GHZ(136, 187 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 188 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 187 + IEEE80211_CHAN_RADAR | 188 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), 189 189 CHAN5GHZ(140, 190 - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 191 - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | 190 + IEEE80211_CHAN_RADAR | 191 + IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS | 192 192 IEEE80211_CHAN_NO_HT40MINUS), 193 193 /* UNII-3 */ 194 194 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
+2 -2
drivers/net/wireless/cw1200/cw1200_sdio.c
··· 108 108 struct hwbus_priv *self = dev_id; 109 109 110 110 if (self->core) { 111 - sdio_claim_host(self->func); 111 + cw1200_sdio_lock(self); 112 112 cw1200_irq_handler(self->core); 113 - sdio_release_host(self->func); 113 + cw1200_sdio_unlock(self); 114 114 return IRQ_HANDLED; 115 115 } else { 116 116 return IRQ_NONE;
+8 -7
drivers/net/wireless/cw1200/scan.c
··· 173 173 cw1200_set_pm(priv, &priv->powersave_mode); 174 174 175 175 if (priv->scan.status < 0) 176 - wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n", 177 - priv->scan.status); 176 + wiphy_warn(priv->hw->wiphy, 177 + "[SCAN] Scan failed (%d).\n", 178 + priv->scan.status); 178 179 else if (priv->scan.req) 179 180 wiphy_dbg(priv->hw->wiphy, 180 181 "[SCAN] Scan completed.\n"); ··· 198 197 if ((*it)->band != first->band) 199 198 break; 200 199 if (((*it)->flags ^ first->flags) & 201 - IEEE80211_CHAN_PASSIVE_SCAN) 200 + IEEE80211_CHAN_NO_IR) 202 201 break; 203 - if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 202 + if (!(first->flags & IEEE80211_CHAN_NO_IR) && 204 203 (*it)->max_power != first->max_power) 205 204 break; 206 205 } ··· 211 210 else 212 211 scan.max_tx_rate = WSM_TRANSMIT_RATE_1; 213 212 scan.num_probes = 214 - (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2; 213 + (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2; 215 214 scan.num_ssids = priv->scan.n_ssids; 216 215 scan.ssids = &priv->scan.ssids[0]; 217 216 scan.num_channels = it - priv->scan.curr; ··· 234 233 } 235 234 for (i = 0; i < scan.num_channels; ++i) { 236 235 scan.ch[i].number = priv->scan.curr[i]->hw_value; 237 - if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) { 236 + if (priv->scan.curr[i]->flags & IEEE80211_CHAN_NO_IR) { 238 237 scan.ch[i].min_chan_time = 50; 239 238 scan.ch[i].max_chan_time = 100; 240 239 } else { ··· 242 241 scan.ch[i].max_chan_time = 25; 243 242 } 244 243 } 245 - if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 244 + if (!(first->flags & IEEE80211_CHAN_NO_IR) && 246 245 priv->scan.output_power != first->max_power) { 247 246 priv->scan.output_power = first->max_power; 248 247 wsm_set_output_power(priv,
+2 -3
drivers/net/wireless/ipw2x00/ipw2100.c
··· 1930 1930 bg_band->channels[i].max_power = geo->bg[i].max_power; 1931 1931 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) 1932 1932 bg_band->channels[i].flags |= 1933 - IEEE80211_CHAN_PASSIVE_SCAN; 1933 + IEEE80211_CHAN_NO_IR; 1934 1934 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) 1935 1935 bg_band->channels[i].flags |= 1936 - IEEE80211_CHAN_NO_IBSS; 1936 + IEEE80211_CHAN_NO_IR; 1937 1937 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) 1938 1938 bg_band->channels[i].flags |= 1939 1939 IEEE80211_CHAN_RADAR; ··· 6362 6362 &ipw2100_attribute_group); 6363 6363 6364 6364 free_libipw(dev, 0); 6365 - pci_set_drvdata(pci_dev, NULL); 6366 6365 } 6367 6366 6368 6367 pci_iounmap(pci_dev, ioaddr);
+4 -4
drivers/net/wireless/ipw2x00/ipw2200.c
··· 11472 11472 bg_band->channels[i].max_power = geo->bg[i].max_power; 11473 11473 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) 11474 11474 bg_band->channels[i].flags |= 11475 - IEEE80211_CHAN_PASSIVE_SCAN; 11475 + IEEE80211_CHAN_NO_IR; 11476 11476 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) 11477 11477 bg_band->channels[i].flags |= 11478 - IEEE80211_CHAN_NO_IBSS; 11478 + IEEE80211_CHAN_NO_IR; 11479 11479 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) 11480 11480 bg_band->channels[i].flags |= 11481 11481 IEEE80211_CHAN_RADAR; ··· 11511 11511 a_band->channels[i].max_power = geo->a[i].max_power; 11512 11512 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) 11513 11513 a_band->channels[i].flags |= 11514 - IEEE80211_CHAN_PASSIVE_SCAN; 11514 + IEEE80211_CHAN_NO_IR; 11515 11515 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) 11516 11516 a_band->channels[i].flags |= 11517 - IEEE80211_CHAN_NO_IBSS; 11517 + IEEE80211_CHAN_NO_IR; 11518 11518 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) 11519 11519 a_band->channels[i].flags |= 11520 11520 IEEE80211_CHAN_RADAR;
+5 -6
drivers/net/wireless/iwlegacy/3945-mac.c
··· 1595 1595 * and use long active_dwell time. 1596 1596 */ 1597 1597 if (!is_active || il_is_channel_passive(ch_info) || 1598 - (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { 1598 + (chan->flags & IEEE80211_CHAN_NO_IR)) { 1599 1599 scan_ch->type = 0; /* passive */ 1600 1600 if (IL_UCODE_API(il->ucode_ver) == 1) 1601 1601 scan_ch->active_dwell = ··· 2396 2396 clear_bit(S_RFKILL, &il->status); 2397 2397 else { 2398 2398 set_bit(S_RFKILL, &il->status); 2399 - IL_WARN("Radio disabled by HW RF Kill switch\n"); 2400 - return -ENODEV; 2399 + return -ERFKILL; 2401 2400 } 2402 2401 2403 2402 _il_wr(il, CSR_INT, 0xFFFFFFFF); ··· 3574 3575 hw->wiphy->interface_modes = 3575 3576 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 3576 3577 3577 - hw->wiphy->flags |= 3578 - WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | 3579 - WIPHY_FLAG_IBSS_RSN; 3578 + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 3579 + hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 3580 + REGULATORY_DISABLE_BEACON_HINTS; 3580 3581 3581 3582 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 3582 3583
+4 -4
drivers/net/wireless/iwlegacy/4965-mac.c
··· 805 805 } 806 806 807 807 if (!is_active || il_is_channel_passive(ch_info) || 808 - (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) 808 + (chan->flags & IEEE80211_CHAN_NO_IR)) 809 809 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; 810 810 else 811 811 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; ··· 5778 5778 hw->wiphy->interface_modes = 5779 5779 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 5780 5780 5781 - hw->wiphy->flags |= 5782 - WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | 5783 - WIPHY_FLAG_IBSS_RSN; 5781 + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 5782 + hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 5783 + REGULATORY_DISABLE_BEACON_HINTS; 5784 5784 5785 5785 /* 5786 5786 * For now, disable PS by default because it affects
+2 -2
drivers/net/wireless/iwlegacy/common.c
··· 3445 3445 3446 3446 if (il_is_channel_valid(ch)) { 3447 3447 if (!(ch->flags & EEPROM_CHANNEL_IBSS)) 3448 - geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; 3448 + geo_ch->flags |= IEEE80211_CHAN_NO_IR; 3449 3449 3450 3450 if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) 3451 - geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 3451 + geo_ch->flags |= IEEE80211_CHAN_NO_IR; 3452 3452 3453 3453 if (ch->flags & EEPROM_CHANNEL_RADAR) 3454 3454 geo_ch->flags |= IEEE80211_CHAN_RADAR;
+4 -4
drivers/net/wireless/iwlegacy/debug.c
··· 567 567 flags & IEEE80211_CHAN_RADAR ? 568 568 " (IEEE 802.11h required)" : "", 569 569 ((channels[i]. 570 - flags & IEEE80211_CHAN_NO_IBSS) || 570 + flags & IEEE80211_CHAN_NO_IR) || 571 571 (channels[i]. 572 572 flags & IEEE80211_CHAN_RADAR)) ? "" : 573 573 ", IBSS", 574 574 channels[i]. 575 - flags & IEEE80211_CHAN_PASSIVE_SCAN ? 575 + flags & IEEE80211_CHAN_NO_IR ? 576 576 "passive only" : "active/passive"); 577 577 } 578 578 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ); ··· 594 594 flags & IEEE80211_CHAN_RADAR ? 595 595 " (IEEE 802.11h required)" : "", 596 596 ((channels[i]. 597 - flags & IEEE80211_CHAN_NO_IBSS) || 597 + flags & IEEE80211_CHAN_NO_IR) || 598 598 (channels[i]. 599 599 flags & IEEE80211_CHAN_RADAR)) ? "" : 600 600 ", IBSS", 601 601 channels[i]. 602 - flags & IEEE80211_CHAN_PASSIVE_SCAN ? 602 + flags & IEEE80211_CHAN_NO_IR ? 603 603 "passive only" : "active/passive"); 604 604 } 605 605 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+4 -4
drivers/net/wireless/iwlwifi/dvm/debugfs.c
··· 352 352 channels[i].max_power, 353 353 channels[i].flags & IEEE80211_CHAN_RADAR ? 354 354 " (IEEE 802.11h required)" : "", 355 - ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 355 + ((channels[i].flags & IEEE80211_CHAN_NO_IR) 356 356 || (channels[i].flags & 357 357 IEEE80211_CHAN_RADAR)) ? "" : 358 358 ", IBSS", 359 359 channels[i].flags & 360 - IEEE80211_CHAN_PASSIVE_SCAN ? 360 + IEEE80211_CHAN_NO_IR ? 361 361 "passive only" : "active/passive"); 362 362 } 363 363 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); ··· 375 375 channels[i].max_power, 376 376 channels[i].flags & IEEE80211_CHAN_RADAR ? 377 377 " (IEEE 802.11h required)" : "", 378 - ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 378 + ((channels[i].flags & IEEE80211_CHAN_NO_IR) 379 379 || (channels[i].flags & 380 380 IEEE80211_CHAN_RADAR)) ? "" : 381 381 ", IBSS", 382 382 channels[i].flags & 383 - IEEE80211_CHAN_PASSIVE_SCAN ? 383 + IEEE80211_CHAN_NO_IR ? 384 384 "passive only" : "active/passive"); 385 385 } 386 386 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+3 -3
drivers/net/wireless/iwlwifi/dvm/mac80211.c
··· 155 155 ARRAY_SIZE(iwlagn_iface_combinations_dualmode); 156 156 } 157 157 158 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 159 - WIPHY_FLAG_DISABLE_BEACON_HINTS | 160 - WIPHY_FLAG_IBSS_RSN; 158 + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 159 + hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 160 + REGULATORY_DISABLE_BEACON_HINTS; 161 161 162 162 #ifdef CONFIG_PM_SLEEP 163 163 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
+1 -1
drivers/net/wireless/iwlwifi/dvm/scan.c
··· 544 544 channel = chan->hw_value; 545 545 scan_ch->channel = cpu_to_le16(channel); 546 546 547 - if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) 547 + if (!is_active || (chan->flags & IEEE80211_CHAN_NO_IR)) 548 548 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; 549 549 else 550 550 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
+2 -2
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
··· 614 614 channel->flags = IEEE80211_CHAN_NO_HT40; 615 615 616 616 if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS)) 617 - channel->flags |= IEEE80211_CHAN_NO_IBSS; 617 + channel->flags |= IEEE80211_CHAN_NO_IR; 618 618 619 619 if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE)) 620 - channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 620 + channel->flags |= IEEE80211_CHAN_NO_IR; 621 621 622 622 if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR) 623 623 channel->flags |= IEEE80211_CHAN_RADAR;
+2 -2
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
··· 223 223 channel->flags |= IEEE80211_CHAN_NO_160MHZ; 224 224 225 225 if (!(ch_flags & NVM_CHANNEL_IBSS)) 226 - channel->flags |= IEEE80211_CHAN_NO_IBSS; 226 + channel->flags |= IEEE80211_CHAN_NO_IR; 227 227 228 228 if (!(ch_flags & NVM_CHANNEL_ACTIVE)) 229 - channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 229 + channel->flags |= IEEE80211_CHAN_NO_IR; 230 230 231 231 if (ch_flags & NVM_CHANNEL_RADAR) 232 232 channel->flags |= IEEE80211_CHAN_RADAR;
+3 -3
drivers/net/wireless/iwlwifi/mvm/mac80211.c
··· 199 199 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8) 200 200 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); 201 201 202 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 203 - WIPHY_FLAG_DISABLE_BEACON_HINTS | 204 - WIPHY_FLAG_IBSS_RSN; 202 + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 203 + hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 204 + REGULATORY_DISABLE_BEACON_HINTS; 205 205 206 206 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations; 207 207 hw->wiphy->n_iface_combinations =
+2 -2
drivers/net/wireless/iwlwifi/mvm/scan.c
··· 192 192 for (i = 0; i < cmd->channel_count; i++) { 193 193 chan->channel = cpu_to_le16(req->channels[i]->hw_value); 194 194 chan->type = cpu_to_le32(type); 195 - if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) 195 + if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) 196 196 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); 197 197 chan->active_dwell = cpu_to_le16(active_dwell); 198 198 chan->passive_dwell = cpu_to_le16(passive_dwell); ··· 642 642 channels->iter_count[index] = cpu_to_le16(1); 643 643 channels->iter_interval[index] = 0; 644 644 645 - if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) 645 + if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR)) 646 646 channels->type[index] |= 647 647 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); 648 648
+3 -3
drivers/net/wireless/libertas/if_sdio.c
··· 849 849 card->started = true; 850 850 /* Tell PM core that we don't need the card to be 851 851 * powered now */ 852 - pm_runtime_put_noidle(&func->dev); 852 + pm_runtime_put(&func->dev); 853 853 } 854 854 } 855 855 ··· 907 907 sdio_release_host(func); 908 908 ret = if_sdio_prog_firmware(card); 909 909 if (ret) { 910 - sdio_disable_func(func); 911 - return ret; 910 + sdio_claim_host(func); 911 + goto disable; 912 912 } 913 913 914 914 return 0;
-1
drivers/net/wireless/libertas/if_spi.c
··· 93 93 list_del(&packet->list); 94 94 kfree(packet); 95 95 } 96 - spi_set_drvdata(card->spi, NULL); 97 96 kfree(card); 98 97 } 99 98
+69 -32
drivers/net/wireless/mac80211_hwsim.c
··· 159 159 .reg_rules = { 160 160 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0), 161 161 REG_RULE(5725-10, 5850+10, 40, 0, 30, 162 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 162 + NL80211_RRF_NO_IR), 163 163 } 164 164 }; 165 165 ··· 353 353 } ps; 354 354 bool ps_poll_pending; 355 355 struct dentry *debugfs; 356 - struct dentry *debugfs_ps; 357 356 358 357 struct sk_buff_head pending; /* packets pending */ 359 358 /* ··· 361 362 * radio can be in more then one group. 362 363 */ 363 364 u64 group; 364 - struct dentry *debugfs_group; 365 365 366 366 int power_level; 367 367 ··· 1491 1493 req->channels[hwsim->scan_chan_idx]->center_freq); 1492 1494 1493 1495 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; 1494 - if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || 1496 + if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR || 1495 1497 !req->n_ssids) { 1496 1498 dwell = 120; 1497 1499 } else { ··· 1740 1742 spin_unlock_bh(&hwsim_radio_lock); 1741 1743 1742 1744 list_for_each_entry_safe(data, tmpdata, &tmplist, list) { 1743 - debugfs_remove(data->debugfs_group); 1744 - debugfs_remove(data->debugfs_ps); 1745 - debugfs_remove(data->debugfs); 1745 + debugfs_remove_recursive(data->debugfs); 1746 1746 ieee80211_unregister_hw(data->hw); 1747 1747 device_release_driver(data->dev); 1748 1748 device_unregister(data->dev); ··· 1897 1901 DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write, 1898 1902 "%llu\n"); 1899 1903 1904 + static int hwsim_write_simulate_radar(void *dat, u64 val) 1905 + { 1906 + struct mac80211_hwsim_data *data = dat; 1907 + 1908 + ieee80211_radar_detected(data->hw); 1909 + 1910 + return 0; 1911 + } 1912 + 1913 + DEFINE_SIMPLE_ATTRIBUTE(hwsim_simulate_radar, NULL, 1914 + hwsim_write_simulate_radar, "%llu\n"); 1900 1915 1901 1916 static int hwsim_fops_group_read(void *dat, u64 *val) 1902 1917 { ··· 2208 2201 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, 2209 2202 }; 2210 2203 2211 - static struct ieee80211_iface_combination hwsim_if_comb = { 2212 - .limits = hwsim_if_limits, 2213 - .n_limits = ARRAY_SIZE(hwsim_if_limits), 2214 - .max_interfaces = 2048, 2215 - .num_different_channels = 1, 2204 + static const struct ieee80211_iface_limit hwsim_if_dfs_limits[] = { 2205 + { .max = 8, .types = BIT(NL80211_IFTYPE_AP) }, 2206 + }; 2207 + 2208 + static struct ieee80211_iface_combination hwsim_if_comb[] = { 2209 + { 2210 + .limits = hwsim_if_limits, 2211 + .n_limits = ARRAY_SIZE(hwsim_if_limits), 2212 + .max_interfaces = 2048, 2213 + .num_different_channels = 1, 2214 + }, 2215 + { 2216 + .limits = hwsim_if_dfs_limits, 2217 + .n_limits = ARRAY_SIZE(hwsim_if_dfs_limits), 2218 + .max_interfaces = 8, 2219 + .num_different_channels = 1, 2220 + .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 2221 + BIT(NL80211_CHAN_WIDTH_20) | 2222 + BIT(NL80211_CHAN_WIDTH_40) | 2223 + BIT(NL80211_CHAN_WIDTH_80) | 2224 + BIT(NL80211_CHAN_WIDTH_160), 2225 + } 2216 2226 }; 2217 2227 2218 2228 static int __init init_mac80211_hwsim(void) ··· 2247 2223 return -EINVAL; 2248 2224 2249 2225 if (channels > 1) { 2250 - hwsim_if_comb.num_different_channels = channels; 2226 + hwsim_if_comb[0].num_different_channels = channels; 2251 2227 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; 2252 2228 mac80211_hwsim_ops.cancel_hw_scan = 2253 2229 mac80211_hwsim_cancel_hw_scan; ··· 2327 2303 hw->wiphy->n_addresses = 2; 2328 2304 hw->wiphy->addresses = data->addresses; 2329 2305 2330 - hw->wiphy->iface_combinations = &hwsim_if_comb; 2331 - hw->wiphy->n_iface_combinations = 1; 2306 + hw->wiphy->iface_combinations = hwsim_if_comb; 2307 + hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb); 2332 2308 2333 2309 if (channels > 1) { 2334 2310 hw->wiphy->max_scan_ssids = 255; 2335 2311 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 2336 2312 hw->wiphy->max_remain_on_channel_duration = 1000; 2313 + /* For channels > 1 DFS is not allowed */ 2314 + hw->wiphy->n_iface_combinations = 1; 2337 2315 } 2338 2316 2339 2317 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done); ··· 2359 2333 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 2360 2334 IEEE80211_HW_AMPDU_AGGREGATION | 2361 2335 IEEE80211_HW_WANT_MONITOR_VIF | 2362 - IEEE80211_HW_QUEUE_CONTROL; 2336 + IEEE80211_HW_QUEUE_CONTROL | 2337 + IEEE80211_HW_SUPPORTS_HT_CCK_RATES; 2363 2338 if (rctbl) 2364 2339 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE; 2365 2340 ··· 2420 2393 sband->vht_cap.cap = 2421 2394 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | 2422 2395 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | 2396 + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ | 2423 2397 IEEE80211_VHT_CAP_RXLDPC | 2424 2398 IEEE80211_VHT_CAP_SHORT_GI_80 | 2425 2399 IEEE80211_VHT_CAP_SHORT_GI_160 | ··· 2463 2435 break; 2464 2436 case HWSIM_REGTEST_WORLD_ROAM: 2465 2437 if (i == 0) { 2466 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2438 + hw->wiphy->regulatory_flags |= 2439 + REGULATORY_CUSTOM_REG; 2467 2440 wiphy_apply_custom_regulatory(hw->wiphy, 2468 2441 &hwsim_world_regdom_custom_01); 2469 2442 } 2470 2443 break; 2471 2444 case HWSIM_REGTEST_CUSTOM_WORLD: 2472 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2445 + hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 2473 2446 wiphy_apply_custom_regulatory(hw->wiphy, 2474 2447 &hwsim_world_regdom_custom_01); 2475 2448 break; 2476 2449 case HWSIM_REGTEST_CUSTOM_WORLD_2: 2477 2450 if (i == 0) { 2478 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2451 + hw->wiphy->regulatory_flags |= 2452 + REGULATORY_CUSTOM_REG; 2479 2453 wiphy_apply_custom_regulatory(hw->wiphy, 2480 2454 &hwsim_world_regdom_custom_01); 2481 2455 } else if (i == 1) { 2482 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2456 + hw->wiphy->regulatory_flags |= 2457 + REGULATORY_CUSTOM_REG; 2483 2458 wiphy_apply_custom_regulatory(hw->wiphy, 2484 2459 &hwsim_world_regdom_custom_02); 2485 2460 } 2486 2461 break; 2487 2462 case HWSIM_REGTEST_STRICT_ALL: 2488 - hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 2463 + hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG; 2489 2464 break; 2490 2465 case HWSIM_REGTEST_STRICT_FOLLOW: 2491 2466 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG: 2492 2467 if (i == 0) 2493 - hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 2468 + hw->wiphy->regulatory_flags |= 2469 + REGULATORY_STRICT_REG; 2494 2470 break; 2495 2471 case HWSIM_REGTEST_ALL: 2496 2472 if (i == 0) { 2497 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2473 + hw->wiphy->regulatory_flags |= 2474 + REGULATORY_CUSTOM_REG; 2498 2475 wiphy_apply_custom_regulatory(hw->wiphy, 2499 2476 &hwsim_world_regdom_custom_01); 2500 2477 } else if (i == 1) { 2501 - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2478 + hw->wiphy->regulatory_flags |= 2479 + REGULATORY_CUSTOM_REG; 2502 2480 wiphy_apply_custom_regulatory(hw->wiphy, 2503 2481 &hwsim_world_regdom_custom_02); 2504 2482 } else if (i == 4) 2505 - hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 2483 + hw->wiphy->regulatory_flags |= 2484 + REGULATORY_STRICT_REG; 2506 2485 break; 2507 2486 default: 2508 2487 break; ··· 2576 2541 2577 2542 data->debugfs = debugfs_create_dir("hwsim", 2578 2543 hw->wiphy->debugfsdir); 2579 - data->debugfs_ps = debugfs_create_file("ps", 0666, 2580 - data->debugfs, data, 2581 - &hwsim_fops_ps); 2582 - data->debugfs_group = debugfs_create_file("group", 0666, 2583 - data->debugfs, data, 2584 - &hwsim_fops_group); 2544 + debugfs_create_file("ps", 0666, data->debugfs, data, 2545 + &hwsim_fops_ps); 2546 + debugfs_create_file("group", 0666, data->debugfs, data, 2547 + &hwsim_fops_group); 2548 + if (channels == 1) 2549 + debugfs_create_file("dfs_simulate_radar", 0222, 2550 + data->debugfs, 2551 + data, &hwsim_simulate_radar); 2585 2552 2586 2553 tasklet_hrtimer_init(&data->beacon_timer, 2587 2554 mac80211_hwsim_beacon, 2588 - CLOCK_REALTIME, HRTIMER_MODE_ABS); 2555 + CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS); 2589 2556 2590 2557 list_add_tail(&data->list, &hwsim_radios); 2591 2558 }
+13 -12
drivers/net/wireless/mwifiex/cfg80211.c
··· 50 50 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0), 51 51 /* Channel 12 - 13 */ 52 52 REG_RULE(2467-10, 2472+10, 20, 3, 20, 53 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 53 + NL80211_RRF_NO_IR), 54 54 /* Channel 14 */ 55 55 REG_RULE(2484-10, 2484+10, 20, 3, 20, 56 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 56 + NL80211_RRF_NO_IR | 57 57 NL80211_RRF_NO_OFDM), 58 58 /* Channel 36 - 48 */ 59 59 REG_RULE(5180-10, 5240+10, 40, 3, 20, 60 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 60 + NL80211_RRF_NO_IR), 61 61 /* Channel 149 - 165 */ 62 62 REG_RULE(5745-10, 5825+10, 40, 3, 20, 63 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 63 + NL80211_RRF_NO_IR), 64 64 /* Channel 52 - 64 */ 65 65 REG_RULE(5260-10, 5320+10, 40, 3, 30, 66 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 66 + NL80211_RRF_NO_IR | 67 67 NL80211_RRF_DFS), 68 68 /* Channel 100 - 140 */ 69 69 REG_RULE(5500-10, 5700+10, 40, 3, 30, 70 - NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 70 + NL80211_RRF_NO_IR | 71 71 NL80211_RRF_DFS), 72 72 } 73 73 }; ··· 184 184 */ 185 185 static int 186 186 mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 187 - struct ieee80211_channel *chan, bool offchan, 188 - unsigned int wait, const u8 *buf, size_t len, 189 - bool no_cck, bool dont_wait_for_ack, u64 *cookie) 187 + struct cfg80211_mgmt_tx_params *params, u64 *cookie) 190 188 { 189 + const u8 *buf = params->buf; 190 + size_t len = params->len; 191 191 struct sk_buff *skb; 192 192 u16 pkt_len; 193 193 const struct ieee80211_mgmt *mgmt; ··· 1968 1968 user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1969 1969 user_scan_cfg->chan_list[i].radio_type = chan->band; 1970 1970 1971 - if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 1971 + if (chan->flags & IEEE80211_CHAN_NO_IR) 1972 1972 user_scan_cfg->chan_list[i].scan_type = 1973 1973 MWIFIEX_SCAN_TYPE_PASSIVE; 1974 1974 else ··· 2702 2702 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 2703 2703 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 2704 2704 WIPHY_FLAG_AP_UAPSD | 2705 - WIPHY_FLAG_CUSTOM_REGULATORY | 2706 - WIPHY_FLAG_STRICT_REGULATORY | 2707 2705 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 2706 + wiphy->regulatory_flags |= 2707 + REGULATORY_CUSTOM_REG | 2708 + REGULATORY_STRICT_REG; 2708 2709 2709 2710 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); 2710 2711
+2 -2
drivers/net/wireless/mwifiex/scan.c
··· 515 515 scan_chan_list[chan_idx].max_scan_time = 516 516 cpu_to_le16((u16) user_scan_in-> 517 517 chan_list[0].scan_time); 518 - else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 518 + else if (ch->flags & IEEE80211_CHAN_NO_IR) 519 519 scan_chan_list[chan_idx].max_scan_time = 520 520 cpu_to_le16(adapter->passive_scan_time); 521 521 else 522 522 scan_chan_list[chan_idx].max_scan_time = 523 523 cpu_to_le16(adapter->active_scan_time); 524 524 525 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 525 + if (ch->flags & IEEE80211_CHAN_NO_IR) 526 526 scan_chan_list[chan_idx].chan_scan_mode_bitmap 527 527 |= MWIFIEX_PASSIVE_SCAN; 528 528 else
+16 -19
drivers/net/wireless/mwifiex/sta_cmdresp.c
··· 338 338 if (!data_buf) 339 339 return -1; 340 340 341 - pg_tlv_hdr = (struct mwifiex_types_power_group *) 342 - ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg)); 341 + pg_tlv_hdr = (struct mwifiex_types_power_group *)((u8 *)data_buf); 343 342 pg = (struct mwifiex_power_group *) 344 343 ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); 345 344 length = le16_to_cpu(pg_tlv_hdr->length); ··· 382 383 struct mwifiex_types_power_group *pg_tlv_hdr; 383 384 struct mwifiex_power_group *pg; 384 385 u16 action = le16_to_cpu(txp_cfg->action); 386 + u16 tlv_buf_left; 387 + 388 + pg_tlv_hdr = (struct mwifiex_types_power_group *) 389 + ((u8 *)txp_cfg + 390 + sizeof(struct host_cmd_ds_txpwr_cfg)); 391 + 392 + pg = (struct mwifiex_power_group *) 393 + ((u8 *)pg_tlv_hdr + 394 + sizeof(struct mwifiex_types_power_group)); 395 + 396 + tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg); 397 + if (tlv_buf_left < 398 + le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr)) 399 + return 0; 385 400 386 401 switch (action) { 387 402 case HostCmd_ACT_GEN_GET: 388 - pg_tlv_hdr = (struct mwifiex_types_power_group *) 389 - ((u8 *) txp_cfg + 390 - sizeof(struct host_cmd_ds_txpwr_cfg)); 391 - 392 - pg = (struct mwifiex_power_group *) 393 - ((u8 *) pg_tlv_hdr + 394 - sizeof(struct mwifiex_types_power_group)); 395 - 396 403 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 397 - mwifiex_get_power_level(priv, txp_cfg); 404 + mwifiex_get_power_level(priv, pg_tlv_hdr); 398 405 399 406 priv->tx_power_level = (u16) pg->power_min; 400 407 break; ··· 408 403 case HostCmd_ACT_GEN_SET: 409 404 if (!le32_to_cpu(txp_cfg->mode)) 410 405 break; 411 - 412 - pg_tlv_hdr = (struct mwifiex_types_power_group *) 413 - ((u8 *) txp_cfg + 414 - sizeof(struct host_cmd_ds_txpwr_cfg)); 415 - 416 - pg = (struct mwifiex_power_group *) 417 - ((u8 *) pg_tlv_hdr + 418 - sizeof(struct mwifiex_types_power_group)); 419 406 420 407 if (pg->power_max == pg->power_min) 421 408 priv->tx_power_level = (u16) pg->power_min;
-1
drivers/net/wireless/prism54/islpci_dev.c
··· 914 914 do_islpci_free_memory: 915 915 islpci_free_memory(priv); 916 916 do_free_netdev: 917 - pci_set_drvdata(pdev, NULL); 918 917 free_netdev(ndev); 919 918 priv = NULL; 920 919 return NULL;
-2
drivers/net/wireless/prism54/islpci_hotplug.c
··· 199 199 do_unregister_netdev: 200 200 unregister_netdev(ndev); 201 201 islpci_free_memory(priv); 202 - pci_set_drvdata(pdev, NULL); 203 202 free_netdev(ndev); 204 203 priv = NULL; 205 204 do_pci_clear_mwi: ··· 246 247 /* free the PCI memory and unmap the remapped page */ 247 248 islpci_free_memory(priv); 248 249 249 - pci_set_drvdata(pdev, NULL); 250 250 free_netdev(ndev); 251 251 priv = NULL; 252 252
+22 -15
drivers/net/wireless/rt2x00/rt2800lib.c
··· 5462 5462 5463 5463 rt2800_bbp_write(rt2x00dev, 68, 0x0b); 5464 5464 5465 - rt2800_bbp_write(rt2x00dev, 69, 0x12); 5465 + rt2800_bbp_write(rt2x00dev, 69, 0x0d); 5466 + rt2800_bbp_write(rt2x00dev, 70, 0x06); 5466 5467 rt2800_bbp_write(rt2x00dev, 73, 0x13); 5467 5468 rt2800_bbp_write(rt2x00dev, 75, 0x46); 5468 5469 rt2800_bbp_write(rt2x00dev, 76, 0x28); 5469 5470 5470 5471 rt2800_bbp_write(rt2x00dev, 77, 0x59); 5471 - 5472 - rt2800_bbp_write(rt2x00dev, 70, 0x0a); 5473 5472 5474 5473 rt2800_bbp_write(rt2x00dev, 79, 0x13); 5475 5474 rt2800_bbp_write(rt2x00dev, 80, 0x05); ··· 5512 5513 if (rt2x00_rt(rt2x00dev, RT5392)) { 5513 5514 rt2800_bbp_write(rt2x00dev, 134, 0xd0); 5514 5515 rt2800_bbp_write(rt2x00dev, 135, 0xf6); 5516 + rt2800_bbp_write(rt2x00dev, 148, 0x84); 5515 5517 } 5516 5518 5517 5519 rt2800_disable_unused_dac_adc(rt2x00dev); ··· 6453 6453 rt2800_rfcsr_write(rt2x00dev, 7, 0x00); 6454 6454 rt2800_rfcsr_write(rt2x00dev, 10, 0x53); 6455 6455 rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); 6456 - rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); 6456 + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); 6457 6457 rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); 6458 6458 rt2800_rfcsr_write(rt2x00dev, 14, 0x00); 6459 6459 rt2800_rfcsr_write(rt2x00dev, 15, 0x00); ··· 6466 6466 rt2800_rfcsr_write(rt2x00dev, 22, 0x20); 6467 6467 rt2800_rfcsr_write(rt2x00dev, 23, 0x00); 6468 6468 rt2800_rfcsr_write(rt2x00dev, 24, 0x00); 6469 - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6469 + if (rt2x00_is_usb(rt2x00dev) && 6470 + rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6470 6471 rt2800_rfcsr_write(rt2x00dev, 25, 0x80); 6471 6472 else 6472 6473 rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); ··· 6487 6486 rt2800_rfcsr_write(rt2x00dev, 38, 0x85); 6488 6487 rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); 6489 6488 6490 - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6491 - rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); 6492 - else 6493 - rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); 6489 + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); 6494 6490 rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); 6495 6491 rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); 6496 6492 rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); ··· 6508 6510 rt2800_rfcsr_write(rt2x00dev, 53, 0x84); 6509 6511 rt2800_rfcsr_write(rt2x00dev, 54, 0x78); 6510 6512 rt2800_rfcsr_write(rt2x00dev, 55, 0x44); 6511 - rt2800_rfcsr_write(rt2x00dev, 56, 0x22); 6513 + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6514 + rt2800_rfcsr_write(rt2x00dev, 56, 0x42); 6515 + else 6516 + rt2800_rfcsr_write(rt2x00dev, 56, 0x22); 6512 6517 rt2800_rfcsr_write(rt2x00dev, 57, 0x80); 6513 6518 rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); 6514 6519 rt2800_rfcsr_write(rt2x00dev, 59, 0x8f); 6515 6520 6516 6521 rt2800_rfcsr_write(rt2x00dev, 60, 0x45); 6517 - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6518 - rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); 6519 - else 6520 - rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); 6522 + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { 6523 + if (rt2x00_is_usb(rt2x00dev)) 6524 + rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); 6525 + else 6526 + rt2800_rfcsr_write(rt2x00dev, 61, 0xd5); 6527 + } else { 6528 + if (rt2x00_is_usb(rt2x00dev)) 6529 + rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); 6530 + else 6531 + rt2800_rfcsr_write(rt2x00dev, 61, 0xb5); 6532 + } 6521 6533 rt2800_rfcsr_write(rt2x00dev, 62, 0x00); 6522 6534 rt2800_rfcsr_write(rt2x00dev, 63, 0x00); 6523 6535 ··· 6609 6601 rt2800_rf_init_calibration(rt2x00dev, 30); 6610 6602 6611 6603 rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); 6612 - rt2800_rfcsr_write(rt2x00dev, 3, 0x08); 6613 6604 rt2800_rfcsr_write(rt2x00dev, 3, 0x08); 6614 6605 rt2800_rfcsr_write(rt2x00dev, 5, 0x10); 6615 6606 rt2800_rfcsr_write(rt2x00dev, 6, 0xE4);
-3
drivers/net/wireless/rt2x00/rt2x00pci.c
··· 156 156 exit_disable_device: 157 157 pci_disable_device(pci_dev); 158 158 159 - pci_set_drvdata(pci_dev, NULL); 160 - 161 159 return retval; 162 160 } 163 161 EXPORT_SYMBOL_GPL(rt2x00pci_probe); ··· 175 177 /* 176 178 * Free the PCI device data. 177 179 */ 178 - pci_set_drvdata(pci_dev, NULL); 179 180 pci_disable_device(pci_dev); 180 181 pci_release_regions(pci_dev); 181 182 }
+1 -1
drivers/net/wireless/rtl818x/rtl8187/dev.c
··· 416 416 struct rtl8187_rx_info *info; 417 417 int ret = 0; 418 418 419 - while (skb_queue_len(&priv->rx_queue) < 16) { 419 + while (skb_queue_len(&priv->rx_queue) < 32) { 420 420 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); 421 421 if (!skb) { 422 422 ret = -ENOMEM;
+2 -1
drivers/net/wireless/rtlwifi/base.c
··· 1437 1437 /* if we can't recv beacon for 6s, we should 1438 1438 * reconnect this AP 1439 1439 */ 1440 - if (rtlpriv->link_info.roam_times >= 3) { 1440 + if ((rtlpriv->link_info.roam_times >= 3) && 1441 + !is_zero_ether_addr(rtlpriv->mac80211.bssid)) { 1441 1442 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1442 1443 "AP off, try to reconnect now\n"); 1443 1444 rtlpriv->link_info.roam_times = 0;
+11
drivers/net/wireless/rtlwifi/core.c
··· 46 46 "Firmware callback routine entered!\n"); 47 47 complete(&rtlpriv->firmware_loading_complete); 48 48 if (!firmware) { 49 + if (rtlpriv->cfg->alt_fw_name) { 50 + err = request_firmware(&firmware, 51 + rtlpriv->cfg->alt_fw_name, 52 + rtlpriv->io.dev); 53 + pr_info("Loading alternative firmware %s\n", 54 + rtlpriv->cfg->alt_fw_name); 55 + if (!err) 56 + goto found_alt; 57 + } 49 58 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); 50 59 rtlpriv->max_fw_size = 0; 51 60 return; 52 61 } 62 + found_alt: 53 63 if (firmware->size > rtlpriv->max_fw_size) { 54 64 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 55 65 "Firmware is too big!\n"); ··· 194 184 rtlpriv->cfg->maps 195 185 [RTL_IBSS_INT_MASKS]); 196 186 } 187 + mac->link_state = MAC80211_LINKED; 197 188 break; 198 189 case NL80211_IFTYPE_ADHOC: 199 190 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-2
drivers/net/wireless/rtlwifi/pci.c
··· 688 688 rtlpriv->stats.rxbytesunicast += skb->len; 689 689 } 690 690 691 - rtl_is_special_data(hw, skb, false); 692 - 693 691 if (ieee80211_is_data(fc)) { 694 692 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 695 693
+26 -35
drivers/net/wireless/rtlwifi/regd.c
··· 59 59 */ 60 60 #define RTL819x_2GHZ_CH12_13 \ 61 61 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 62 - NL80211_RRF_PASSIVE_SCAN) 62 + NL80211_RRF_NO_IR) 63 63 64 64 #define RTL819x_2GHZ_CH14 \ 65 65 REG_RULE(2484-10, 2484+10, 40, 0, 20, \ 66 - NL80211_RRF_PASSIVE_SCAN | \ 67 - NL80211_RRF_NO_OFDM) 66 + NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM) 68 67 69 68 /* 5G chan 36 - chan 64*/ 70 69 #define RTL819x_5GHZ_5150_5350 \ 71 70 REG_RULE(5150-10, 5350+10, 40, 0, 30, \ 72 - NL80211_RRF_PASSIVE_SCAN | \ 73 - NL80211_RRF_NO_IBSS) 71 + NL80211_RRF_NO_IR) 74 72 75 73 /* 5G chan 100 - chan 165*/ 76 74 #define RTL819x_5GHZ_5470_5850 \ 77 75 REG_RULE(5470-10, 5850+10, 40, 0, 30, \ 78 - NL80211_RRF_PASSIVE_SCAN | \ 79 - NL80211_RRF_NO_IBSS) 76 + NL80211_RRF_NO_IR) 80 77 81 78 /* 5G chan 149 - chan 165*/ 82 79 #define RTL819x_5GHZ_5725_5850 \ 83 80 REG_RULE(5725-10, 5850+10, 40, 0, 30, \ 84 - NL80211_RRF_PASSIVE_SCAN | \ 85 - NL80211_RRF_NO_IBSS) 81 + NL80211_RRF_NO_IR) 86 82 87 83 #define RTL819x_5GHZ_ALL \ 88 84 (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) ··· 168 172 (ch->flags & IEEE80211_CHAN_RADAR)) 169 173 continue; 170 174 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 171 - reg_rule = freq_reg_info(wiphy, ch->center_freq); 175 + reg_rule = freq_reg_info(wiphy, 176 + MHZ_TO_KHZ(ch->center_freq)); 172 177 if (IS_ERR(reg_rule)) 173 178 continue; 174 179 ··· 182 185 *regulatory_hint(). 183 186 */ 184 187 185 - if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) 186 - ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 187 - if (!(reg_rule-> 188 - flags & NL80211_RRF_PASSIVE_SCAN)) 189 - ch->flags &= 190 - ~IEEE80211_CHAN_PASSIVE_SCAN; 188 + if (!(reg_rule->flags & NL80211_RRF_NO_IR)) 189 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 191 190 } else { 192 191 if (ch->beacon_found) 193 - ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 194 - IEEE80211_CHAN_PASSIVE_SCAN); 192 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 195 193 } 196 194 } 197 195 } ··· 211 219 */ 212 220 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 213 221 ch = &sband->channels[11]; /* CH 12 */ 214 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 215 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 222 + if (ch->flags & IEEE80211_CHAN_NO_IR) 223 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 216 224 ch = &sband->channels[12]; /* CH 13 */ 217 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 218 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 225 + if (ch->flags & IEEE80211_CHAN_NO_IR) 226 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 219 227 return; 220 228 } 221 229 ··· 227 235 */ 228 236 229 237 ch = &sband->channels[11]; /* CH 12 */ 230 - reg_rule = freq_reg_info(wiphy, ch->center_freq); 238 + reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); 231 239 if (!IS_ERR(reg_rule)) { 232 - if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 233 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 234 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 240 + if (!(reg_rule->flags & NL80211_RRF_NO_IR)) 241 + if (ch->flags & IEEE80211_CHAN_NO_IR) 242 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 235 243 } 236 244 237 245 ch = &sband->channels[12]; /* CH 13 */ 238 - reg_rule = freq_reg_info(wiphy, ch->center_freq); 246 + reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); 239 247 if (!IS_ERR(reg_rule)) { 240 - if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 241 - if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 242 - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 248 + if (!(reg_rule->flags & NL80211_RRF_NO_IR)) 249 + if (ch->flags & IEEE80211_CHAN_NO_IR) 250 + ch->flags &= ~IEEE80211_CHAN_NO_IR; 243 251 } 244 252 } 245 253 ··· 276 284 */ 277 285 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 278 286 ch->flags |= IEEE80211_CHAN_RADAR | 279 - IEEE80211_CHAN_NO_IBSS | 280 - IEEE80211_CHAN_PASSIVE_SCAN; 287 + IEEE80211_CHAN_NO_IR; 281 288 } 282 289 } 283 290 ··· 345 354 346 355 wiphy->reg_notifier = reg_notifier; 347 356 348 - wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 349 - wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; 350 - wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; 357 + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 358 + wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; 359 + wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; 351 360 352 361 regd = _rtl_regdomain_select(reg); 353 362 wiphy_apply_custom_regulatory(wiphy, regd);
+1 -1
drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
··· 1078 1078 rtldm->swing_flag_ofdm = true; 1079 1079 } 1080 1080 1081 - if (rtldm->swing_idx_cck != rtldm->swing_idx_cck) { 1081 + if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) { 1082 1082 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck; 1083 1083 rtldm->swing_flag_cck = true; 1084 1084 }
+229 -98
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
··· 158 158 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} 159 159 }; 160 160 161 + static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; 162 + 163 + void dm_restorepowerindex(struct ieee80211_hw *hw) 164 + { 165 + struct rtl_priv *rtlpriv = rtl_priv(hw); 166 + u8 index; 167 + 168 + for (index = 0; index < 6; index++) 169 + rtl_write_byte(rtlpriv, power_index_reg[index], 170 + rtlpriv->dm.powerindex_backup[index]); 171 + } 172 + EXPORT_SYMBOL_GPL(dm_restorepowerindex); 173 + 174 + void dm_writepowerindex(struct ieee80211_hw *hw, u8 value) 175 + { 176 + struct rtl_priv *rtlpriv = rtl_priv(hw); 177 + u8 index; 178 + 179 + for (index = 0; index < 6; index++) 180 + rtl_write_byte(rtlpriv, power_index_reg[index], value); 181 + } 182 + EXPORT_SYMBOL_GPL(dm_writepowerindex); 183 + 184 + void dm_savepowerindex(struct ieee80211_hw *hw) 185 + { 186 + struct rtl_priv *rtlpriv = rtl_priv(hw); 187 + u8 index; 188 + u8 tmp; 189 + 190 + for (index = 0; index < 6; index++) { 191 + tmp = rtl_read_byte(rtlpriv, power_index_reg[index]); 192 + rtlpriv->dm.powerindex_backup[index] = tmp; 193 + } 194 + } 195 + EXPORT_SYMBOL_GPL(dm_savepowerindex); 196 + 161 197 static void rtl92c_dm_diginit(struct ieee80211_hw *hw) 162 198 { 163 199 struct rtl_priv *rtlpriv = rtl_priv(hw); ··· 216 180 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; 217 181 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; 218 182 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; 219 - dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; 183 + dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LowRssi; 184 + 185 + dm_digtable->forbidden_igi = DM_DIG_MIN; 186 + dm_digtable->large_fa_hit = 0; 187 + dm_digtable->recover_cnt = 0; 188 + dm_digtable->dig_dynamic_min = 0x25; 220 189 } 221 190 222 191 static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) ··· 247 206 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; 248 207 } 249 208 250 - return (u8) rssi_val_min; 209 + if (rssi_val_min > 100) 210 + rssi_val_min = 100; 211 + return (u8)rssi_val_min; 251 212 } 252 213 253 214 static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) ··· 267 224 268 225 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); 269 226 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); 227 + 228 + ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD); 229 + falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff); 230 + falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); 231 + 270 232 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + 271 - falsealm_cnt->cnt_rate_illegal + 272 - falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; 233 + falsealm_cnt->cnt_rate_illegal + 234 + falsealm_cnt->cnt_crc8_fail + 235 + falsealm_cnt->cnt_mcs_fail + 236 + falsealm_cnt->cnt_fast_fsync_fail + 237 + falsealm_cnt->cnt_sb_search_fail; 273 238 274 239 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); 275 240 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); ··· 322 271 value_igi++; 323 272 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) 324 273 value_igi += 2; 274 + 325 275 if (value_igi > DM_DIG_FA_UPPER) 326 276 value_igi = DM_DIG_FA_UPPER; 327 277 else if (value_igi < DM_DIG_FA_LOWER) 328 278 value_igi = DM_DIG_FA_LOWER; 279 + 329 280 if (rtlpriv->falsealm_cnt.cnt_all > 10000) 330 - value_igi = 0x32; 281 + value_igi = DM_DIG_FA_UPPER; 331 282 332 283 dm_digtable->cur_igvalue = value_igi; 333 284 rtl92c_dm_write_dig(hw); ··· 339 286 { 340 287 struct rtl_priv *rtlpriv = rtl_priv(hw); 341 288 struct dig_t *digtable = &rtlpriv->dm_digtable; 289 + u32 isbt; 342 290 343 - if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) { 344 - if ((digtable->back_val - 2) < digtable->back_range_min) 345 - digtable->back_val = digtable->back_range_min; 346 - else 347 - digtable->back_val -= 2; 348 - } else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) { 349 - if ((digtable->back_val + 2) > digtable->back_range_max) 350 - digtable->back_val = digtable->back_range_max; 351 - else 352 - digtable->back_val += 2; 291 + /* modify DIG lower bound, deal with abnorally large false alarm */ 292 + if (rtlpriv->falsealm_cnt.cnt_all > 10000) { 293 + digtable->large_fa_hit++; 294 + if (digtable->forbidden_igi < digtable->cur_igvalue) { 295 + digtable->forbidden_igi = digtable->cur_igvalue; 296 + digtable->large_fa_hit = 1; 297 + } 298 + 299 + if (digtable->large_fa_hit >= 3) { 300 + if ((digtable->forbidden_igi + 1) > 301 + digtable->rx_gain_max) 302 + digtable->rx_gain_min = digtable->rx_gain_max; 303 + else 304 + digtable->rx_gain_min = (digtable->forbidden_igi + 1); 305 + digtable->recover_cnt = 3600; /* 3600=2hr */ 306 + } 307 + } else { 308 + /* Recovery mechanism for IGI lower bound */ 309 + if (digtable->recover_cnt != 0) { 310 + digtable->recover_cnt--; 311 + } else { 312 + if (digtable->large_fa_hit == 0) { 313 + if ((digtable->forbidden_igi-1) < DM_DIG_MIN) { 314 + digtable->forbidden_igi = DM_DIG_MIN; 315 + digtable->rx_gain_min = DM_DIG_MIN; 316 + } else { 317 + digtable->forbidden_igi--; 318 + digtable->rx_gain_min = digtable->forbidden_igi + 1; 319 + } 320 + } else if (digtable->large_fa_hit == 3) { 321 + digtable->large_fa_hit = 0; 322 + } 323 + } 324 + } 325 + if (rtlpriv->falsealm_cnt.cnt_all < 250) { 326 + isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01; 327 + 328 + if (!isbt) { 329 + if (rtlpriv->falsealm_cnt.cnt_all > 330 + digtable->fa_lowthresh) { 331 + if ((digtable->back_val - 2) < 332 + digtable->back_range_min) 333 + digtable->back_val = digtable->back_range_min; 334 + else 335 + digtable->back_val -= 2; 336 + } else if (rtlpriv->falsealm_cnt.cnt_all < 337 + digtable->fa_lowthresh) { 338 + if ((digtable->back_val + 2) > 339 + digtable->back_range_max) 340 + digtable->back_val = digtable->back_range_max; 341 + else 342 + digtable->back_val += 2; 343 + } 344 + } else { 345 + digtable->back_val = DM_DIG_BACKOFF_DEFAULT; 346 + } 347 + } else { 348 + /* Adjust initial gain by false alarm */ 349 + if (rtlpriv->falsealm_cnt.cnt_all > 1000) 350 + digtable->cur_igvalue = digtable->pre_igvalue + 2; 351 + else if (rtlpriv->falsealm_cnt.cnt_all > 750) 352 + digtable->cur_igvalue = digtable->pre_igvalue + 1; 353 + else if (rtlpriv->falsealm_cnt.cnt_all < 500) 354 + digtable->cur_igvalue = digtable->pre_igvalue - 1; 353 355 } 354 356 355 - if ((digtable->rssi_val_min + 10 - digtable->back_val) > 356 - digtable->rx_gain_max) 357 + /* Check initial gain by upper/lower bound */ 358 + if (digtable->cur_igvalue > digtable->rx_gain_max) 357 359 digtable->cur_igvalue = digtable->rx_gain_max; 358 - else if ((digtable->rssi_val_min + 10 - 359 - digtable->back_val) < digtable->rx_gain_min) 360 - digtable->cur_igvalue = digtable->rx_gain_min; 361 - else 362 - digtable->cur_igvalue = digtable->rssi_val_min + 10 - 363 - digtable->back_val; 364 360 365 - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, 366 - "rssi_val_min = %x back_val %x\n", 367 - digtable->rssi_val_min, digtable->back_val); 361 + if (digtable->cur_igvalue < digtable->rx_gain_min) 362 + digtable->cur_igvalue = digtable->rx_gain_min; 368 363 369 364 rtl92c_dm_write_dig(hw); 370 365 } ··· 430 329 multi_sta = true; 431 330 432 331 if (!multi_sta || 433 - dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { 332 + dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) { 434 333 initialized = false; 435 334 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; 436 335 return; ··· 476 375 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, 477 376 "presta_cstate = %x, cursta_cstate = %x\n", 478 377 dm_digtable->presta_cstate, dm_digtable->cursta_cstate); 479 - 480 378 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || 481 379 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || 482 380 dm_digtable->cursta_cstate == DIG_STA_CONNECT) { ··· 483 383 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { 484 384 dm_digtable->rssi_val_min = 485 385 rtl92c_dm_initial_gain_min_pwdb(hw); 386 + if (dm_digtable->rssi_val_min > 100) 387 + dm_digtable->rssi_val_min = 100; 486 388 rtl92c_dm_ctrl_initgain_by_rssi(hw); 487 389 } 488 390 } else { ··· 500 398 static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 501 399 { 502 400 struct rtl_priv *rtlpriv = rtl_priv(hw); 503 - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 504 401 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 505 402 506 403 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 507 404 dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); 405 + if (dm_digtable->rssi_val_min > 100) 406 + dm_digtable->rssi_val_min = 100; 508 407 509 408 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { 510 409 if (dm_digtable->rssi_val_min <= 25) ··· 527 424 } 528 425 529 426 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { 530 - if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { 531 - if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) 532 - dm_digtable->cur_cck_fa_state = 533 - CCK_FA_STAGE_High; 534 - else 535 - dm_digtable->cur_cck_fa_state = CCK_FA_STAGE_Low; 536 - 537 - if (dm_digtable->pre_cck_fa_state != 538 - dm_digtable->cur_cck_fa_state) { 539 - if (dm_digtable->cur_cck_fa_state == 540 - CCK_FA_STAGE_Low) 541 - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 542 - 0x83); 543 - else 544 - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 545 - 0xcd); 546 - 547 - dm_digtable->pre_cck_fa_state = 548 - dm_digtable->cur_cck_fa_state; 549 - } 550 - 551 - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); 552 - 553 - if (IS_92C_SERIAL(rtlhal->version)) 554 - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 555 - MASKBYTE2, 0xd7); 556 - } else { 427 + if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) || 428 + (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX)) 429 + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83); 430 + else 557 431 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 558 - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); 559 432 560 - if (IS_92C_SERIAL(rtlhal->version)) 561 - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 562 - MASKBYTE2, 0xd3); 563 - } 564 433 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; 565 434 } 566 - 567 - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n", 568 - dm_digtable->cur_cck_pd_state); 569 - 570 - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n", 571 - IS_92C_SERIAL(rtlhal->version)); 572 435 } 573 436 574 437 static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) ··· 551 482 else 552 483 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; 553 484 485 + dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; 486 + 554 487 rtl92c_dm_initial_gain_sta(hw); 555 488 rtl92c_dm_initial_gain_multi_sta(hw); 556 489 rtl92c_dm_cck_packet_detection_thresh(hw); ··· 564 493 static void rtl92c_dm_dig(struct ieee80211_hw *hw) 565 494 { 566 495 struct rtl_priv *rtlpriv = rtl_priv(hw); 567 - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 568 496 569 497 if (rtlpriv->dm.dm_initialgain_enable == false) 570 498 return; 571 - if (dm_digtable->dig_enable_flag == false) 499 + if (!rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG) 572 500 return; 573 501 574 502 rtl92c_dm_ctrl_initgain_by_twoport(hw); 575 - 576 503 } 577 504 578 505 static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) 579 506 { 580 507 struct rtl_priv *rtlpriv = rtl_priv(hw); 581 508 582 - rtlpriv->dm.dynamic_txpower_enable = false; 583 - 509 + if (rtlpriv->rtlhal.interface == INTF_USB && 510 + rtlpriv->rtlhal.board_type & 0x1) { 511 + dm_savepowerindex(hw); 512 + rtlpriv->dm.dynamic_txpower_enable = true; 513 + } else { 514 + rtlpriv->dm.dynamic_txpower_enable = false; 515 + } 584 516 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; 585 517 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; 586 518 } ··· 598 524 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, 599 525 dm_digtable->back_val); 600 526 601 - dm_digtable->cur_igvalue += 2; 602 - if (dm_digtable->cur_igvalue > 0x3f) 603 - dm_digtable->cur_igvalue = 0x3f; 527 + if (rtlpriv->rtlhal.interface == INTF_USB && 528 + !dm_digtable->dig_enable_flag) { 529 + dm_digtable->pre_igvalue = 0x17; 530 + return; 531 + } 532 + dm_digtable->cur_igvalue -= 1; 533 + if (dm_digtable->cur_igvalue < DM_DIG_MIN) 534 + dm_digtable->cur_igvalue = DM_DIG_MIN; 604 535 605 536 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { 606 537 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, ··· 615 536 616 537 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; 617 538 } 539 + RT_TRACE(rtlpriv, COMP_DIG, DBG_WARNING, 540 + "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 541 + dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, 542 + dm_digtable->rssi_val_min, dm_digtable->back_val, 543 + dm_digtable->rx_gain_max, dm_digtable->rx_gain_min, 544 + dm_digtable->large_fa_hit, dm_digtable->forbidden_igi); 618 545 } 619 546 EXPORT_SYMBOL(rtl92c_dm_write_dig); 620 547 621 548 static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) 622 549 { 550 + struct rtl_priv *rtlpriv = rtl_priv(hw); 551 + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 552 + long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; 553 + 554 + if (mac->link_state != MAC80211_LINKED) 555 + return; 556 + 557 + if (mac->opmode == NL80211_IFTYPE_ADHOC || 558 + mac->opmode == NL80211_IFTYPE_AP) { 559 + /* TODO: Handle ADHOC and AP Mode */ 560 + } 561 + 562 + if (tmpentry_max_pwdb != 0) 563 + rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb; 564 + else 565 + rtlpriv->dm.entry_max_undec_sm_pwdb = 0; 566 + 567 + if (tmpentry_min_pwdb != 0xff) 568 + rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb; 569 + else 570 + rtlpriv->dm.entry_min_undec_sm_pwdb = 0; 571 + 572 + /* TODO: 573 + * if (mac->opmode == NL80211_IFTYPE_STATION) { 574 + * if (rtlpriv->rtlhal.fw_ready) { 575 + * u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16); 576 + * rtl8192c_set_rssi_cmd(hw, param); 577 + * } 578 + * } 579 + */ 623 580 } 624 581 625 582 void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) ··· 865 750 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; 866 751 rtlpriv->dm.cck_index = cck_index_old; 867 752 } 753 + /* Handle USB High PA boards */ 868 754 869 755 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? 870 756 (thermalvalue - rtlpriv->dm.thermalvalue) : ··· 1256 1140 { 1257 1141 struct rtl_priv *rtlpriv = rtl_priv(hw); 1258 1142 struct ps_t *dm_pstable = &rtlpriv->dm_pstable; 1259 - static u8 initialize; 1260 - static u32 reg_874, reg_c70, reg_85c, reg_a74; 1261 1143 1262 - if (initialize == 0) { 1263 - reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 1264 - MASKDWORD) & 0x1CC000) >> 14; 1144 + if (!rtlpriv->reg_init) { 1145 + rtlpriv->reg_874 = (rtl_get_bbreg(hw, 1146 + RFPGA0_XCD_RFINTERFACESW, 1147 + MASKDWORD) & 0x1CC000) >> 14; 1265 1148 1266 - reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, 1267 - MASKDWORD) & BIT(3)) >> 3; 1149 + rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, 1150 + MASKDWORD) & BIT(3)) >> 3; 1268 1151 1269 - reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 1270 - MASKDWORD) & 0xFF000000) >> 24; 1152 + rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 1153 + MASKDWORD) & 0xFF000000) >> 24; 1271 1154 1272 - reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; 1155 + rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 1156 + 0xF000) >> 12; 1273 1157 1274 - initialize = 1; 1158 + rtlpriv->reg_init = true; 1275 1159 } 1276 1160 1277 1161 if (!bforce_in_normal) { ··· 1308 1192 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); 1309 1193 } else { 1310 1194 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 1311 - 0x1CC000, reg_874); 1195 + 0x1CC000, rtlpriv->reg_874); 1312 1196 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 1313 - reg_c70); 1197 + rtlpriv->reg_c70); 1314 1198 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, 1315 - reg_85c); 1316 - rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); 1199 + rtlpriv->reg_85c); 1200 + rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74); 1317 1201 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); 1318 1202 } 1319 1203 ··· 1329 1213 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1330 1214 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1331 1215 1216 + /* Determine the minimum RSSI */ 1332 1217 if (((mac->link_state == MAC80211_NOLINK)) && 1333 1218 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 1334 1219 dm_pstable->rssi_val_min = 0; ··· 1358 1241 dm_pstable->rssi_val_min); 1359 1242 } 1360 1243 1244 + /* Power Saving for 92C */ 1361 1245 if (IS_92C_SERIAL(rtlhal->version)) 1362 1246 ;/* rtl92c_dm_1r_cca(hw); */ 1363 1247 else ··· 1370 1252 struct rtl_priv *rtlpriv = rtl_priv(hw); 1371 1253 1372 1254 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 1255 + rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG; 1256 + rtlpriv->dm.undec_sm_pwdb = -1; 1257 + rtlpriv->dm.undec_sm_cck = -1; 1258 + rtlpriv->dm.dm_initialgain_enable = true; 1373 1259 rtl92c_dm_diginit(hw); 1260 + 1261 + rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE; 1374 1262 rtl92c_dm_init_dynamic_txpower(hw); 1263 + 1375 1264 rtl92c_dm_init_edca_turbo(hw); 1376 1265 rtl92c_dm_init_rate_adaptive_mask(hw); 1266 + rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS; 1377 1267 rtl92c_dm_initialize_txpower_tracking(hw); 1378 1268 rtl92c_dm_init_dynamic_bb_powersaving(hw); 1269 + 1270 + rtlpriv->dm.ofdm_pkt_cnt = 0; 1271 + rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT; 1379 1272 } 1380 1273 EXPORT_SYMBOL(rtl92c_dm_init); 1381 1274 ··· 1437 1308 } 1438 1309 1439 1310 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { 1440 - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; 1311 + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; 1441 1312 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 1442 1313 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); 1443 1314 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && ··· 1457 1328 "PHY_SetTxPowerLevel8192S() Channel = %d\n", 1458 1329 rtlphy->current_channel); 1459 1330 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 1331 + if (rtlpriv->dm.dynamic_txhighpower_lvl == 1332 + TXHIGHPWRLEVEL_NORMAL) 1333 + dm_restorepowerindex(hw); 1334 + else if (rtlpriv->dm.dynamic_txhighpower_lvl == 1335 + TXHIGHPWRLEVEL_LEVEL1) 1336 + dm_writepowerindex(hw, 0x14); 1337 + else if (rtlpriv->dm.dynamic_txhighpower_lvl == 1338 + TXHIGHPWRLEVEL_LEVEL2) 1339 + dm_writepowerindex(hw, 0x10); 1460 1340 } 1461 - 1462 1341 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; 1463 1342 } 1464 1343 ··· 1536 1399 curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; 1537 1400 else 1538 1401 curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); 1539 - 1540 - /* Set Tx Power according to BT status. */ 1541 - if (undec_sm_pwdb >= 30) 1542 - curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW; 1543 - else if (undec_sm_pwdb < 25) 1544 - curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); 1545 1402 1546 1403 /* Check BT state related to BT_Idle in B/G mode. */ 1547 1404 if (undec_sm_pwdb < 15)
+14
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
··· 91 91 #define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 92 92 #define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 93 93 94 + #define DYNAMIC_FUNC_DISABLE 0x0 95 + #define DYNAMIC_FUNC_DIG BIT(0) 96 + #define DYNAMIC_FUNC_HP BIT(1) 97 + #define DYNAMIC_FUNC_SS BIT(2) /*Tx Power Tracking*/ 98 + #define DYNAMIC_FUNC_BT BIT(3) 99 + #define DYNAMIC_FUNC_ANT_DIV BIT(4) 100 + 101 + #define RSSI_CCK 0 102 + #define RSSI_OFDM 1 103 + #define RSSI_DEFAULT 2 104 + 94 105 struct swat_t { 95 106 u8 failure_cnt; 96 107 u8 try_flag; ··· 178 167 void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); 179 168 void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); 180 169 void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); 170 + void dm_savepowerindex(struct ieee80211_hw *hw); 171 + void dm_writepowerindex(struct ieee80211_hw *hw, u8 value); 172 + void dm_restorepowerindex(struct ieee80211_hw *hw); 181 173 182 174 #endif
+28 -11
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
··· 1147 1147 0x522, 0x550, 0x551, 0x040 1148 1148 }; 1149 1149 1150 + u32 iqk_bb_reg_92C[9] = { 1151 + 0xc04, 0xc08, 0x874, 0xb68, 1152 + 0xb6c, 0x870, 0x860, 0x864, 1153 + 0x800 1154 + }; 1155 + 1150 1156 const u32 retrycount = 2; 1151 1157 1152 1158 if (t == 0) { ··· 1163 1157 rtlphy->adda_backup, 16); 1164 1158 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, 1165 1159 rtlphy->iqk_mac_backup); 1160 + _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg_92C, 1161 + rtlphy->iqk_bb_backup, 9); 1166 1162 } 1167 1163 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); 1168 1164 if (t == 0) { ··· 1175 1167 1176 1168 if (!rtlphy->rfpi_enable) 1177 1169 _rtl92c_phy_pi_mode_switch(hw, true); 1178 - if (t == 0) { 1179 - rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); 1180 - rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); 1181 - rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); 1182 - } 1170 + 1171 + rtl_set_bbreg(hw, 0x800, BIT(24), 0x0); 1172 + 1183 1173 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); 1184 1174 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); 1185 1175 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); 1176 + 1177 + rtl_set_bbreg(hw, 0x870, BIT(10), 0x1); 1178 + rtl_set_bbreg(hw, 0x870, BIT(26), 0x1); 1179 + rtl_set_bbreg(hw, 0x860, BIT(10), 0x0); 1180 + rtl_set_bbreg(hw, 0x864, BIT(10), 0x0); 1181 + 1186 1182 if (is2t) { 1187 1183 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 1188 1184 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); ··· 1251 1239 0x3FF0000) >> 16; 1252 1240 } 1253 1241 } 1254 - rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); 1255 - rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); 1256 - rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); 1242 + 1257 1243 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); 1258 - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); 1259 - if (is2t) 1260 - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); 1244 + 1261 1245 if (t != 0) { 1262 1246 if (!rtlphy->rfpi_enable) 1263 1247 _rtl92c_phy_pi_mode_switch(hw, false); ··· 1261 1253 rtlphy->adda_backup, 16); 1262 1254 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, 1263 1255 rtlphy->iqk_mac_backup); 1256 + _rtl92c_phy_reload_adda_registers(hw, iqk_bb_reg_92C, 1257 + rtlphy->iqk_bb_backup, 9); 1258 + 1259 + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); 1260 + if (is2t) 1261 + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); 1262 + 1263 + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); 1264 + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00); 1264 1265 } 1265 1266 } 1266 1267
+9
drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
··· 101 101 "PHY_SetTxPowerLevel8192S() Channel = %d\n", 102 102 rtlphy->current_channel); 103 103 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 104 + if (rtlpriv->dm.dynamic_txhighpower_lvl == 105 + TXHIGHPWRLEVEL_NORMAL) 106 + dm_restorepowerindex(hw); 107 + else if (rtlpriv->dm.dynamic_txhighpower_lvl == 108 + TXHIGHPWRLEVEL_LEVEL1) 109 + dm_writepowerindex(hw, 0x14); 110 + else if (rtlpriv->dm.dynamic_txhighpower_lvl == 111 + TXHIGHPWRLEVEL_LEVEL2) 112 + dm_writepowerindex(hw, 0x10); 104 113 } 105 114 106 115 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
+3
drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
··· 30 30 #include "../rtl8192ce/dm.h" 31 31 32 32 void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw); 33 + void dm_savepowerindex(struct ieee80211_hw *hw); 34 + void dm_writepowerindex(struct ieee80211_hw *hw, u8 value); 35 + void dm_restorepowerindex(struct ieee80211_hw *hw);
+1 -1
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
··· 1022 1022 if (ppsc->rfpwr_state == ERFON) { 1023 1023 rtl92c_phy_set_rfpath_switch(hw, 1); 1024 1024 if (iqk_initialized) { 1025 - rtl92c_phy_iq_calibrate(hw, false); 1025 + rtl92c_phy_iq_calibrate(hw, true); 1026 1026 } else { 1027 1027 rtl92c_phy_iq_calibrate(hw, false); 1028 1028 iqk_initialized = true;
+5 -1
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
··· 120 120 struct rtl_priv *rtlpriv = rtl_priv(hw); 121 121 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 122 122 u16 regval; 123 + u32 regval32; 123 124 u8 b_reg_hwparafile = 1; 124 125 125 126 _rtl92c_phy_init_bb_rf_register_definition(hw); ··· 136 135 } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) { 137 136 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | 138 137 FEN_BB_GLB_RSTn | FEN_BBRSTB); 139 - rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); 140 138 } 139 + regval32 = rtl_read_dword(rtlpriv, 0x87c); 140 + rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31))); 141 + if (IS_HARDWARE_TYPE_8192CU(rtlhal)) 142 + rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); 141 143 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); 142 144 if (b_reg_hwparafile == 1) 143 145 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
+16 -13
drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
··· 85 85 if (mac->act_scanning) { 86 86 tx_agc[RF90_PATH_A] = 0x3f3f3f3f; 87 87 tx_agc[RF90_PATH_B] = 0x3f3f3f3f; 88 - if (turbo_scanoff) { 89 - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { 90 - tx_agc[idx1] = ppowerlevel[idx1] | 91 - (ppowerlevel[idx1] << 8) | 92 - (ppowerlevel[idx1] << 16) | 93 - (ppowerlevel[idx1] << 24); 94 - if (rtlhal->interface == INTF_USB) { 95 - if (tx_agc[idx1] > 0x20 && 96 - rtlefuse->external_pa) 97 - tx_agc[idx1] = 0x20; 98 - } 88 + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { 89 + tx_agc[idx1] = ppowerlevel[idx1] | 90 + (ppowerlevel[idx1] << 8) | 91 + (ppowerlevel[idx1] << 16) | 92 + (ppowerlevel[idx1] << 24); 93 + if (rtlhal->interface == INTF_USB) { 94 + if (tx_agc[idx1] > 0x20 && 95 + rtlefuse->external_pa) 96 + tx_agc[idx1] = 0x20; 99 97 } 100 98 } 101 99 } else { ··· 105 107 TXHIGHPWRLEVEL_LEVEL2) { 106 108 tx_agc[RF90_PATH_A] = 0x00000000; 107 109 tx_agc[RF90_PATH_B] = 0x00000000; 108 - } else{ 110 + } else { 109 111 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { 110 112 tx_agc[idx1] = ppowerlevel[idx1] | 111 113 (ppowerlevel[idx1] << 8) | ··· 371 373 regoffset == RTXAGC_B_MCS07_MCS04) 372 374 regoffset = 0xc98; 373 375 for (i = 0; i < 3; i++) { 374 - writeVal = (writeVal > 6) ? (writeVal - 6) : 0; 376 + if (i != 2) 377 + writeVal = (writeVal > 8) ? 378 + (writeVal - 8) : 0; 379 + else 380 + writeVal = (writeVal > 6) ? 381 + (writeVal - 6) : 0; 375 382 rtl_write_byte(rtlpriv, (u32)(regoffset + i), 376 383 (u8)writeVal); 377 384 }
+13 -3
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
··· 50 50 MODULE_LICENSE("GPL"); 51 51 MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless"); 52 52 MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); 53 + MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin"); 54 + MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin"); 55 + MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin"); 53 56 54 57 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) 55 58 { ··· 72 69 "Can't alloc buffer for fw\n"); 73 70 return 1; 74 71 } 75 - 72 + if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) && 73 + !IS_92C_SERIAL(rtlpriv->rtlhal.version)) { 74 + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_A.bin"; 75 + } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) { 76 + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_B.bin"; 77 + } else { 78 + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; 79 + } 80 + /* provide name of alternative file */ 81 + rtlpriv->cfg->alt_fw_name = "rtlwifi/rtl8192cufw.bin"; 76 82 pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); 77 83 rtlpriv->max_fw_size = 0x4000; 78 84 err = request_firmware_nowait(THIS_MODULE, 1, 79 85 rtlpriv->cfg->fw_name, rtlpriv->io.dev, 80 86 GFP_KERNEL, hw, rtl_fw_cb); 81 - 82 - 83 87 return err; 84 88 } 85 89
+20 -20
drivers/net/wireless/rtlwifi/rtl8192cu/table.c
··· 36 36 0x804, 0x00000003, 37 37 0x808, 0x0000fc00, 38 38 0x80c, 0x0000000a, 39 - 0x810, 0x10005388, 39 + 0x810, 0x10000330, 40 40 0x814, 0x020c3d10, 41 41 0x818, 0x02200385, 42 42 0x81c, 0x00000000, ··· 110 110 0xc44, 0x000100b7, 111 111 0xc48, 0xec020107, 112 112 0xc4c, 0x007f037f, 113 - 0xc50, 0x6954341e, 113 + 0xc50, 0x69543420, 114 114 0xc54, 0x43bc0094, 115 - 0xc58, 0x6954341e, 115 + 0xc58, 0x69543420, 116 116 0xc5c, 0x433c0094, 117 117 0xc60, 0x00000000, 118 118 0xc64, 0x5116848b, 119 119 0xc68, 0x47c00bff, 120 120 0xc6c, 0x00000036, 121 121 0xc70, 0x2c7f000d, 122 - 0xc74, 0x0186115b, 122 + 0xc74, 0x2186115b, 123 123 0xc78, 0x0000001f, 124 124 0xc7c, 0x00b99612, 125 125 0xc80, 0x40000100, 126 126 0xc84, 0x20f60000, 127 127 0xc88, 0x40000100, 128 - 0xc8c, 0x20200000, 128 + 0xc8c, 0xa0e40000, 129 129 0xc90, 0x00121820, 130 130 0xc94, 0x00000000, 131 131 0xc98, 0x00121820, ··· 226 226 0x804, 0x00000001, 227 227 0x808, 0x0000fc00, 228 228 0x80c, 0x0000000a, 229 - 0x810, 0x10005388, 229 + 0x810, 0x10000330, 230 230 0x814, 0x020c3d10, 231 231 0x818, 0x02200385, 232 232 0x81c, 0x00000000, ··· 300 300 0xc44, 0x000100b7, 301 301 0xc48, 0xec020107, 302 302 0xc4c, 0x007f037f, 303 - 0xc50, 0x6954341e, 303 + 0xc50, 0x69543420, 304 304 0xc54, 0x43bc0094, 305 - 0xc58, 0x6954341e, 305 + 0xc58, 0x69543420, 306 306 0xc5c, 0x433c0094, 307 307 0xc60, 0x00000000, 308 308 0xc64, 0x5116848b, ··· 340 340 0xce4, 0x00000000, 341 341 0xce8, 0x37644302, 342 342 0xcec, 0x2f97d40c, 343 - 0xd00, 0x00080740, 343 + 0xd00, 0x00000740, 344 344 0xd04, 0x00020401, 345 345 0xd08, 0x0000907f, 346 346 0xd0c, 0x20010201, ··· 633 633 0x012, 0x00071000, 634 634 0x012, 0x000b0000, 635 635 0x012, 0x000fc000, 636 - 0x013, 0x000287af, 636 + 0x013, 0x000287b3, 637 637 0x013, 0x000244b7, 638 638 0x013, 0x000204ab, 639 639 0x013, 0x0001c49f, 640 640 0x013, 0x00018493, 641 - 0x013, 0x00014297, 642 - 0x013, 0x00010295, 643 - 0x013, 0x0000c298, 644 - 0x013, 0x0000819c, 645 - 0x013, 0x000040a8, 646 - 0x013, 0x0000001c, 641 + 0x013, 0x0001429b, 642 + 0x013, 0x00010299, 643 + 0x013, 0x0000c29c, 644 + 0x013, 0x000081a0, 645 + 0x013, 0x000040ac, 646 + 0x013, 0x00000020, 647 647 0x014, 0x0001944c, 648 648 0x014, 0x00059444, 649 649 0x014, 0x0009944c, ··· 932 932 0x608, 0x0000000e, 933 933 0x609, 0x0000002a, 934 934 0x652, 0x00000020, 935 - 0x63c, 0x0000000a, 936 - 0x63d, 0x0000000e, 937 - 0x63e, 0x0000000a, 938 - 0x63f, 0x0000000e, 935 + 0x63c, 0x00000008, 936 + 0x63d, 0x00000008, 937 + 0x63e, 0x0000000c, 938 + 0x63f, 0x0000000c, 939 939 0x66e, 0x00000005, 940 940 0x700, 0x00000021, 941 941 0x701, 0x00000043,
+14
drivers/net/wireless/rtlwifi/stats.c
··· 176 176 struct rtl_sta_info *drv_priv = NULL; 177 177 struct ieee80211_sta *sta = NULL; 178 178 long undec_sm_pwdb; 179 + long undec_sm_cck; 179 180 180 181 rcu_read_lock(); 181 182 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) ··· 186 185 if (sta) { 187 186 drv_priv = (struct rtl_sta_info *) sta->drv_priv; 188 187 undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; 188 + undec_sm_cck = drv_priv->rssi_stat.undec_sm_cck; 189 189 } else { 190 190 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; 191 + undec_sm_cck = rtlpriv->dm.undec_sm_cck; 191 192 } 192 193 193 194 if (undec_sm_pwdb < 0) 194 195 undec_sm_pwdb = pstatus->rx_pwdb_all; 196 + if (undec_sm_cck < 0) 197 + undec_sm_cck = pstatus->rx_pwdb_all; 195 198 if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) { 196 199 undec_sm_pwdb = (((undec_sm_pwdb) * 197 200 (RX_SMOOTH_FACTOR - 1)) + ··· 203 198 undec_sm_pwdb = undec_sm_pwdb + 1; 204 199 } else { 205 200 undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) + 201 + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 202 + } 203 + if (pstatus->rx_pwdb_all > (u32) undec_sm_cck) { 204 + undec_sm_cck = (((undec_sm_pwdb) * 205 + (RX_SMOOTH_FACTOR - 1)) + 206 + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 207 + undec_sm_cck = undec_sm_cck + 1; 208 + } else { 209 + undec_sm_pwdb = (((undec_sm_cck) * (RX_SMOOTH_FACTOR - 1)) + 206 210 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 207 211 } 208 212
+3 -5
drivers/net/wireless/rtlwifi/usb.c
··· 475 475 rtlpriv->stats.rxbytesunicast += skb->len; 476 476 } 477 477 478 - rtl_is_special_data(hw, skb, false); 479 - 480 478 if (ieee80211_is_data(fc)) { 481 479 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 482 480 483 481 if (unicast) 484 482 rtlpriv->link_info.num_rx_inperiod++; 485 483 } 484 + /* static bcn for roaming */ 485 + rtl_beacon_statistic(hw, skb); 486 486 } 487 487 } 488 488 ··· 516 516 unicast = true; 517 517 rtlpriv->stats.rxbytesunicast += skb->len; 518 518 } 519 - 520 - rtl_is_special_data(hw, skb, false); 521 519 522 520 if (ieee80211_is_data(fc)) { 523 521 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); ··· 551 553 } 552 554 } 553 555 554 - #define __RX_SKB_MAX_QUEUED 32 556 + #define __RX_SKB_MAX_QUEUED 64 555 557 556 558 static void _rtl_rx_work(unsigned long param) 557 559 {
+17 -16
drivers/net/wireless/rtlwifi/wifi.h
··· 1033 1033 1034 1034 struct rssi_sta { 1035 1035 long undec_sm_pwdb; 1036 + long undec_sm_cck; 1036 1037 }; 1037 1038 1038 1039 struct rtl_tid_data { ··· 1324 1323 struct rtl_dm { 1325 1324 /*PHY status for Dynamic Management */ 1326 1325 long entry_min_undec_sm_pwdb; 1326 + long undec_sm_cck; 1327 1327 long undec_sm_pwdb; /*out dm */ 1328 1328 long entry_max_undec_sm_pwdb; 1329 + s32 ofdm_pkt_cnt; 1329 1330 bool dm_initialgain_enable; 1330 1331 bool dynamic_txpower_enable; 1331 1332 bool current_turbo_edca; ··· 1342 1339 bool inform_fw_driverctrldm; 1343 1340 bool current_mrc_switch; 1344 1341 u8 txpowercount; 1342 + u8 powerindex_backup[6]; 1345 1343 1346 1344 u8 thermalvalue_rxgain; 1347 1345 u8 thermalvalue_iqk; ··· 1354 1350 bool done_txpower; 1355 1351 u8 dynamic_txhighpower_lvl; /*Tx high power level */ 1356 1352 u8 dm_flag; /*Indicate each dynamic mechanism's status. */ 1353 + u8 dm_flag_tmp; 1357 1354 u8 dm_type; 1355 + u8 dm_rssi_sel; 1358 1356 u8 txpower_track_control; 1359 1357 bool interrupt_migration; 1360 1358 bool disable_tx_int; ··· 1810 1804 bool write_readback; 1811 1805 char *name; 1812 1806 char *fw_name; 1807 + char *alt_fw_name; 1813 1808 struct rtl_hal_ops *ops; 1814 1809 struct rtl_mod_params *mod_params; 1815 1810 struct rtl_hal_usbint_cfg *usb_interface_cfg; ··· 1955 1948 u8 pre_ccastate; 1956 1949 u8 cur_ccasate; 1957 1950 u8 large_fa_hit; 1951 + u8 dig_dynamic_min; 1958 1952 u8 forbidden_igi; 1959 1953 u8 dig_state; 1960 1954 u8 dig_highpwrstate; ··· 2036 2028 struct dig_t dm_digtable; 2037 2029 struct ps_t dm_pstable; 2038 2030 2039 - /* section shared by individual drivers */ 2040 - union { 2041 - struct { /* data buffer pointer for USB reads */ 2042 - __le32 *usb_data; 2043 - int usb_data_index; 2044 - bool initialized; 2045 - }; 2046 - struct { /* section for 8723ae */ 2047 - bool reg_init; /* true if regs saved */ 2048 - u32 reg_874; 2049 - u32 reg_c70; 2050 - u32 reg_85c; 2051 - u32 reg_a74; 2052 - bool bt_operation_on; 2053 - }; 2054 - }; 2031 + u32 reg_874; 2032 + u32 reg_c70; 2033 + u32 reg_85c; 2034 + u32 reg_a74; 2035 + bool reg_init; /* true if regs saved */ 2036 + bool bt_operation_on; 2037 + __le32 *usb_data; 2038 + int usb_data_index; 2039 + bool initialized; 2055 2040 bool enter_ps; /* true when entering PS */ 2056 2041 u8 rate_mask[5]; 2057 2042
+68 -141
drivers/net/wireless/ti/wl1251/acx.c
··· 18 18 wl1251_debug(DEBUG_ACX, "acx frame rates"); 19 19 20 20 rates = kzalloc(sizeof(*rates), GFP_KERNEL); 21 - if (!rates) { 22 - ret = -ENOMEM; 23 - goto out; 24 - } 21 + if (!rates) 22 + return -ENOMEM; 25 23 26 24 rates->tx_ctrl_frame_rate = ctrl_rate; 27 25 rates->tx_ctrl_frame_mod = ctrl_mod; ··· 47 49 wl1251_debug(DEBUG_ACX, "acx dot11_station_id"); 48 50 49 51 mac = kzalloc(sizeof(*mac), GFP_KERNEL); 50 - if (!mac) { 51 - ret = -ENOMEM; 52 - goto out; 53 - } 52 + if (!mac) 53 + return -ENOMEM; 54 54 55 55 for (i = 0; i < ETH_ALEN; i++) 56 56 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; ··· 70 74 wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); 71 75 72 76 default_key = kzalloc(sizeof(*default_key), GFP_KERNEL); 73 - if (!default_key) { 74 - ret = -ENOMEM; 75 - goto out; 76 - } 77 + if (!default_key) 78 + return -ENOMEM; 77 79 78 80 default_key->id = key_id; 79 81 ··· 98 104 wl1251_debug(DEBUG_ACX, "acx wake up conditions"); 99 105 100 106 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); 101 - if (!wake_up) { 102 - ret = -ENOMEM; 103 - goto out; 104 - } 107 + if (!wake_up) 108 + return -ENOMEM; 105 109 106 110 wake_up->wake_up_event = wake_up_event; 107 111 wake_up->listen_interval = listen_interval; ··· 124 132 wl1251_debug(DEBUG_ACX, "acx sleep auth"); 125 133 126 134 auth = kzalloc(sizeof(*auth), GFP_KERNEL); 127 - if (!auth) { 128 - ret = -ENOMEM; 129 - goto out; 130 - } 135 + if (!auth) 136 + return -ENOMEM; 131 137 132 138 auth->sleep_auth = sleep_auth; 133 139 134 140 ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); 135 141 136 - out: 137 142 kfree(auth); 138 143 return ret; 139 144 } ··· 143 154 wl1251_debug(DEBUG_ACX, "acx fw rev"); 144 155 145 156 rev = kzalloc(sizeof(*rev), GFP_KERNEL); 146 - if (!rev) { 147 - ret = -ENOMEM; 148 - goto out; 149 - } 157 + if (!rev) 158 + return -ENOMEM; 150 159 151 160 ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev)); 152 161 if (ret < 0) { ··· 178 191 return -EINVAL; 179 192 180 193 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 181 - if (!acx) { 182 - ret = -ENOMEM; 183 - goto out; 184 - } 194 + if (!acx) 195 + return -ENOMEM; 185 196 186 197 acx->current_tx_power = power * 10; 187 198 ··· 202 217 wl1251_debug(DEBUG_ACX, "acx feature cfg"); 203 218 204 219 feature = kzalloc(sizeof(*feature), GFP_KERNEL); 205 - if (!feature) { 206 - ret = -ENOMEM; 207 - goto out; 208 - } 220 + if (!feature) 221 + return -ENOMEM; 209 222 210 223 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ 211 224 feature->data_flow_options = 0; ··· 244 261 wl1251_debug(DEBUG_ACX, "acx data path params"); 245 262 246 263 params = kzalloc(sizeof(*params), GFP_KERNEL); 247 - if (!params) { 248 - ret = -ENOMEM; 249 - goto out; 250 - } 264 + if (!params) 265 + return -ENOMEM; 251 266 252 267 params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE; 253 268 params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE; ··· 290 309 wl1251_debug(DEBUG_ACX, "acx rx msdu life time"); 291 310 292 311 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 293 - if (!acx) { 294 - ret = -ENOMEM; 295 - goto out; 296 - } 312 + if (!acx) 313 + return -ENOMEM; 297 314 298 315 acx->lifetime = life_time; 299 316 ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, ··· 314 335 wl1251_debug(DEBUG_ACX, "acx rx config"); 315 336 316 337 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); 317 - if (!rx_config) { 318 - ret = -ENOMEM; 319 - goto out; 320 - } 338 + if (!rx_config) 339 + return -ENOMEM; 321 340 322 341 rx_config->config_options = config; 323 342 rx_config->filter_options = filter; ··· 340 363 wl1251_debug(DEBUG_ACX, "acx data pd threshold"); 341 364 342 365 pd = kzalloc(sizeof(*pd), GFP_KERNEL); 343 - if (!pd) { 344 - ret = -ENOMEM; 345 - goto out; 346 - } 366 + if (!pd) 367 + return -ENOMEM; 347 368 348 369 /* FIXME: threshold value not set */ 349 370 ··· 364 389 wl1251_debug(DEBUG_ACX, "acx slot"); 365 390 366 391 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 367 - if (!slot) { 368 - ret = -ENOMEM; 369 - goto out; 370 - } 392 + if (!slot) 393 + return -ENOMEM; 371 394 372 395 slot->wone_index = STATION_WONE_INDEX; 373 396 slot->slot_time = slot_time; ··· 389 416 wl1251_debug(DEBUG_ACX, "acx group address tbl"); 390 417 391 418 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 392 - if (!acx) { 393 - ret = -ENOMEM; 394 - goto out; 395 - } 419 + if (!acx) 420 + return -ENOMEM; 396 421 397 422 /* MAC filtering */ 398 423 acx->enabled = 0; ··· 415 444 int ret; 416 445 417 446 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); 418 - if (!rx_timeout) { 419 - ret = -ENOMEM; 420 - goto out; 421 - } 447 + if (!rx_timeout) 448 + return -ENOMEM; 422 449 423 450 wl1251_debug(DEBUG_ACX, "acx service period timeout"); 424 451 ··· 444 475 wl1251_debug(DEBUG_ACX, "acx rts threshold"); 445 476 446 477 rts = kzalloc(sizeof(*rts), GFP_KERNEL); 447 - if (!rts) { 448 - ret = -ENOMEM; 449 - goto out; 450 - } 478 + if (!rts) 479 + return -ENOMEM; 451 480 452 481 rts->threshold = rts_threshold; 453 482 ··· 468 501 wl1251_debug(DEBUG_ACX, "acx beacon filter opt"); 469 502 470 503 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); 471 - if (!beacon_filter) { 472 - ret = -ENOMEM; 473 - goto out; 474 - } 504 + if (!beacon_filter) 505 + return -ENOMEM; 475 506 476 507 beacon_filter->enable = enable_filter; 477 508 beacon_filter->max_num_beacons = 0; ··· 495 530 wl1251_debug(DEBUG_ACX, "acx beacon filter table"); 496 531 497 532 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); 498 - if (!ie_table) { 499 - ret = -ENOMEM; 500 - goto out; 501 - } 533 + if (!ie_table) 534 + return -ENOMEM; 502 535 503 536 /* configure default beacon pass-through rules */ 504 537 ie_table->num_ie = 1; ··· 523 560 wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); 524 561 525 562 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 526 - if (!acx) { 527 - ret = -ENOMEM; 528 - goto out; 529 - } 563 + if (!acx) 564 + return -ENOMEM; 530 565 531 566 acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD; 532 567 acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT; ··· 550 589 wl1251_debug(DEBUG_ACX, "acx sg enable"); 551 590 552 591 pta = kzalloc(sizeof(*pta), GFP_KERNEL); 553 - if (!pta) { 554 - ret = -ENOMEM; 555 - goto out; 556 - } 592 + if (!pta) 593 + return -ENOMEM; 557 594 558 595 pta->enable = SG_ENABLE; 559 596 ··· 574 615 wl1251_debug(DEBUG_ACX, "acx sg cfg"); 575 616 576 617 param = kzalloc(sizeof(*param), GFP_KERNEL); 577 - if (!param) { 578 - ret = -ENOMEM; 579 - goto out; 580 - } 618 + if (!param) 619 + return -ENOMEM; 581 620 582 621 /* BT-WLAN coext parameters */ 583 622 param->min_rate = RATE_INDEX_24MBPS; ··· 626 669 wl1251_debug(DEBUG_ACX, "acx cca threshold"); 627 670 628 671 detection = kzalloc(sizeof(*detection), GFP_KERNEL); 629 - if (!detection) { 630 - ret = -ENOMEM; 631 - goto out; 632 - } 672 + if (!detection) 673 + return -ENOMEM; 633 674 634 675 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; 635 676 detection->tx_energy_detection = 0; ··· 637 682 if (ret < 0) 638 683 wl1251_warning("failed to set cca threshold: %d", ret); 639 684 640 - out: 641 685 kfree(detection); 642 686 return ret; 643 687 } ··· 649 695 wl1251_debug(DEBUG_ACX, "acx bcn dtim options"); 650 696 651 697 bb = kzalloc(sizeof(*bb), GFP_KERNEL); 652 - if (!bb) { 653 - ret = -ENOMEM; 654 - goto out; 655 - } 698 + if (!bb) 699 + return -ENOMEM; 656 700 657 701 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; 658 702 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; ··· 676 724 wl1251_debug(DEBUG_ACX, "acx aid"); 677 725 678 726 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); 679 - if (!acx_aid) { 680 - ret = -ENOMEM; 681 - goto out; 682 - } 727 + if (!acx_aid) 728 + return -ENOMEM; 683 729 684 730 acx_aid->aid = aid; 685 731 ··· 700 750 wl1251_debug(DEBUG_ACX, "acx event mbox mask"); 701 751 702 752 mask = kzalloc(sizeof(*mask), GFP_KERNEL); 703 - if (!mask) { 704 - ret = -ENOMEM; 705 - goto out; 706 - } 753 + if (!mask) 754 + return -ENOMEM; 707 755 708 756 /* high event mask is unused */ 709 757 mask->high_event_mask = 0xffffffff; ··· 753 805 wl1251_debug(DEBUG_ACX, "acx_set_preamble"); 754 806 755 807 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 756 - if (!acx) { 757 - ret = -ENOMEM; 758 - goto out; 759 - } 808 + if (!acx) 809 + return -ENOMEM; 760 810 761 811 acx->preamble = preamble; 762 812 ··· 778 832 wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect"); 779 833 780 834 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 781 - if (!acx) { 782 - ret = -ENOMEM; 783 - goto out; 784 - } 835 + if (!acx) 836 + return -ENOMEM; 785 837 786 838 acx->ctsprotect = ctsprotect; 787 839 ··· 800 856 int ret; 801 857 802 858 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); 803 - if (!tsf_info) { 804 - ret = -ENOMEM; 805 - goto out; 806 - } 859 + if (!tsf_info) 860 + return -ENOMEM; 807 861 808 862 ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO, 809 863 tsf_info, sizeof(*tsf_info)); ··· 842 900 wl1251_debug(DEBUG_ACX, "acx rate policies"); 843 901 844 902 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 845 - 846 - if (!acx) { 847 - ret = -ENOMEM; 848 - goto out; 849 - } 903 + if (!acx) 904 + return -ENOMEM; 850 905 851 906 /* configure one default (one-size-fits-all) rate class */ 852 907 acx->rate_class_cnt = 1; ··· 871 932 wl1251_debug(DEBUG_ACX, "acx mem cfg"); 872 933 873 934 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); 874 - if (!mem_conf) { 875 - ret = -ENOMEM; 876 - goto out; 877 - } 935 + if (!mem_conf) 936 + return -ENOMEM; 878 937 879 938 /* memory config */ 880 939 mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS); ··· 916 979 wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); 917 980 918 981 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 919 - if (!acx) { 920 - ret = -ENOMEM; 921 - goto out; 922 - } 982 + if (!acx) 983 + return -ENOMEM; 923 984 924 985 acx->tbtt = tbtt; 925 986 acx->dtim = dtim; ··· 943 1008 wl1251_debug(DEBUG_ACX, "acx bet enable"); 944 1009 945 1010 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 946 - if (!acx) { 947 - ret = -ENOMEM; 948 - goto out; 949 - } 1011 + if (!acx) 1012 + return -ENOMEM; 950 1013 951 1014 acx->enable = mode; 952 1015 acx->max_consecutive = max_consecutive; ··· 970 1037 "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop); 971 1038 972 1039 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 973 - 974 - if (!acx) { 975 - ret = -ENOMEM; 976 - goto out; 977 - } 1040 + if (!acx) 1041 + return -ENOMEM; 978 1042 979 1043 acx->ac = ac; 980 1044 acx->cw_min = cw_min; ··· 1003 1073 ps_scheme, ack_policy); 1004 1074 1005 1075 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1006 - 1007 - if (!acx) { 1008 - ret = -ENOMEM; 1009 - goto out; 1010 - } 1076 + if (!acx) 1077 + return -ENOMEM; 1011 1078 1012 1079 acx->queue = queue; 1013 1080 acx->type = type;
+1 -1
drivers/net/wireless/ti/wl12xx/scan.c
··· 47 47 * In active scans, we only scan channels not 48 48 * marked as passive. 49 49 */ 50 - (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { 50 + (passive || !(flags & IEEE80211_CHAN_NO_IR))) { 51 51 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", 52 52 req->channels[i]->band, 53 53 req->channels[i]->center_freq);
+1 -1
drivers/net/wireless/ti/wlcore/cmd.c
··· 1688 1688 1689 1689 if (channel->flags & (IEEE80211_CHAN_DISABLED | 1690 1690 IEEE80211_CHAN_RADAR | 1691 - IEEE80211_CHAN_PASSIVE_SCAN)) 1691 + IEEE80211_CHAN_NO_IR)) 1692 1692 continue; 1693 1693 1694 1694 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch);
+1 -2
drivers/net/wireless/ti/wlcore/main.c
··· 91 91 continue; 92 92 93 93 if (ch->flags & IEEE80211_CHAN_RADAR) 94 - ch->flags |= IEEE80211_CHAN_NO_IBSS | 95 - IEEE80211_CHAN_PASSIVE_SCAN; 94 + ch->flags |= IEEE80211_CHAN_NO_IR; 96 95 97 96 } 98 97
+5 -7
drivers/net/wireless/ti/wlcore/scan.c
··· 188 188 flags = req_channels[i]->flags; 189 189 190 190 if (force_passive) 191 - flags |= IEEE80211_CHAN_PASSIVE_SCAN; 191 + flags |= IEEE80211_CHAN_NO_IR; 192 192 193 193 if ((req_channels[i]->band == band) && 194 194 !(flags & IEEE80211_CHAN_DISABLED) && 195 195 (!!(flags & IEEE80211_CHAN_RADAR) == radar) && 196 196 /* if radar is set, we ignore the passive flag */ 197 197 (radar || 198 - !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { 199 - 200 - 198 + !!(flags & IEEE80211_CHAN_NO_IR) == passive)) { 201 199 if (flags & IEEE80211_CHAN_RADAR) { 202 200 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 203 201 ··· 218 220 (band == IEEE80211_BAND_2GHZ) && 219 221 (channels[j].channel >= 12) && 220 222 (channels[j].channel <= 14) && 221 - (flags & IEEE80211_CHAN_PASSIVE_SCAN) && 223 + (flags & IEEE80211_CHAN_NO_IR) && 222 224 !force_passive) { 223 225 /* pactive channels treated as DFS */ 224 226 channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; ··· 241 243 max_dwell_time_active, 242 244 flags & IEEE80211_CHAN_RADAR ? 243 245 ", DFS" : "", 244 - flags & IEEE80211_CHAN_PASSIVE_SCAN ? 245 - ", PASSIVE" : ""); 246 + flags & IEEE80211_CHAN_NO_IR ? 247 + ", NO-IR" : ""); 246 248 j++; 247 249 } 248 250 }
+6 -2
include/linux/ieee80211.h
··· 1411 1411 #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 1412 1412 #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 1413 1413 #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 1414 - #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX 0x0000e000 1415 - #define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00070000 1414 + #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13 1415 + #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK \ 1416 + (7 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT) 1417 + #define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16 1418 + #define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK \ 1419 + (7 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT) 1416 1420 #define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 1417 1421 #define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 1418 1422 #define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
+42 -34
include/net/cfg80211.h
··· 91 91 * Channel flags set by the regulatory control code. 92 92 * 93 93 * @IEEE80211_CHAN_DISABLED: This channel is disabled. 94 - * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted 95 - * on this channel. 96 - * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. 94 + * @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes 95 + * sending probe requests or beaconing. 97 96 * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. 98 97 * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel 99 98 * is not permitted. ··· 112 113 */ 113 114 enum ieee80211_channel_flags { 114 115 IEEE80211_CHAN_DISABLED = 1<<0, 115 - IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, 116 - IEEE80211_CHAN_NO_IBSS = 1<<2, 116 + IEEE80211_CHAN_NO_IR = 1<<1, 117 + /* hole at 1<<2 */ 117 118 IEEE80211_CHAN_RADAR = 1<<3, 118 119 IEEE80211_CHAN_NO_HT40PLUS = 1<<4, 119 120 IEEE80211_CHAN_NO_HT40MINUS = 1<<5, ··· 1944 1945 }; 1945 1946 1946 1947 /** 1948 + * struct cfg80211_mgmt_tx_params - mgmt tx parameters 1949 + * 1950 + * This structure provides information needed to transmit a mgmt frame 1951 + * 1952 + * @chan: channel to use 1953 + * @offchan: indicates wether off channel operation is required 1954 + * @wait: duration for ROC 1955 + * @buf: buffer to transmit 1956 + * @len: buffer length 1957 + * @no_cck: don't use cck rates for this frame 1958 + * @dont_wait_for_ack: tells the low level not to wait for an ack 1959 + */ 1960 + struct cfg80211_mgmt_tx_params { 1961 + struct ieee80211_channel *chan; 1962 + bool offchan; 1963 + unsigned int wait; 1964 + const u8 *buf; 1965 + size_t len; 1966 + bool no_cck; 1967 + bool dont_wait_for_ack; 1968 + }; 1969 + 1970 + /** 1947 1971 * struct cfg80211_ops - backend description for wireless configuration 1948 1972 * 1949 1973 * This struct is registered by fullmac card drivers and/or wireless stacks ··· 2364 2342 u64 cookie); 2365 2343 2366 2344 int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, 2367 - struct ieee80211_channel *chan, bool offchan, 2368 - unsigned int wait, const u8 *buf, size_t len, 2369 - bool no_cck, bool dont_wait_for_ack, u64 *cookie); 2345 + struct cfg80211_mgmt_tx_params *params, 2346 + u64 *cookie); 2370 2347 int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, 2371 2348 struct wireless_dev *wdev, 2372 2349 u64 cookie); ··· 2459 2438 /** 2460 2439 * enum wiphy_flags - wiphy capability flags 2461 2440 * 2462 - * @WIPHY_FLAG_CUSTOM_REGULATORY: tells us the driver for this device 2463 - * has its own custom regulatory domain and cannot identify the 2464 - * ISO / IEC 3166 alpha2 it belongs to. When this is enabled 2465 - * we will disregard the first regulatory hint (when the 2466 - * initiator is %REGDOM_SET_BY_CORE). 2467 - * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will 2468 - * ignore regulatory domain settings until it gets its own regulatory 2469 - * domain via its regulatory_hint() unless the regulatory hint is 2470 - * from a country IE. After its gets its own regulatory domain it will 2471 - * only allow further regulatory domain settings to further enhance 2472 - * compliance. For example if channel 13 and 14 are disabled by this 2473 - * regulatory domain no user regulatory domain can enable these channels 2474 - * at a later time. This can be used for devices which do not have 2475 - * calibration information guaranteed for frequencies or settings 2476 - * outside of its regulatory domain. If used in combination with 2477 - * WIPHY_FLAG_CUSTOM_REGULATORY the inspected country IE power settings 2478 - * will be followed. 2479 - * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure 2480 - * that passive scan flags and beaconing flags may not be lifted by 2481 - * cfg80211 due to regulatory beacon hints. For more information on beacon 2482 - * hints read the documenation for regulatory_hint_found_beacon() 2483 2441 * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this 2484 2442 * wiphy at all 2485 2443 * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled ··· 2497 2497 * beaconing mode (AP, IBSS, Mesh, ...). 2498 2498 */ 2499 2499 enum wiphy_flags { 2500 - WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 2501 - WIPHY_FLAG_STRICT_REGULATORY = BIT(1), 2502 - WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), 2500 + /* use hole at 0 */ 2501 + /* use hole at 1 */ 2502 + /* use hole at 2 */ 2503 2503 WIPHY_FLAG_NETNS_OK = BIT(3), 2504 2504 WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), 2505 2505 WIPHY_FLAG_4ADDR_AP = BIT(5), ··· 2721 2721 * @software_iftypes: bitmask of software interface types, these are not 2722 2722 * subject to any restrictions since they are purely managed in SW. 2723 2723 * @flags: wiphy flags, see &enum wiphy_flags 2724 + * @regulatory_flags: wiphy regulatory flags, see 2725 + * &enum ieee80211_regulatory_flags 2724 2726 * @features: features advertised to nl80211, see &enum nl80211_feature_flags. 2725 2727 * @bss_priv_size: each BSS struct has private data allocated with it, 2726 2728 * this variable determines its size ··· 2811 2809 2812 2810 u16 max_acl_mac_addrs; 2813 2811 2814 - u32 flags, features; 2812 + u32 flags, regulatory_flags, features; 2815 2813 2816 2814 u32 ap_sme_capa; 2817 2815 ··· 3474 3472 * custom regulatory domain will be trusted completely and as such previous 3475 3473 * default channel settings will be disregarded. If no rule is found for a 3476 3474 * channel on the regulatory domain the channel will be disabled. 3475 + * Drivers using this for a wiphy should also set the wiphy flag 3476 + * WIPHY_FLAG_CUSTOM_REGULATORY or cfg80211 will set it for the wiphy 3477 + * that called this helper. 3477 3478 */ 3478 3479 void wiphy_apply_custom_regulatory(struct wiphy *wiphy, 3479 3480 const struct ieee80211_regdomain *regd); ··· 4151 4146 /** 4152 4147 * cfg80211_cac_event - Channel availability check (CAC) event 4153 4148 * @netdev: network device 4149 + * @chandef: chandef for the current channel 4154 4150 * @event: type of event 4155 4151 * @gfp: context flags 4156 4152 * ··· 4160 4154 * also by full-MAC drivers. 4161 4155 */ 4162 4156 void cfg80211_cac_event(struct net_device *netdev, 4157 + const struct cfg80211_chan_def *chandef, 4163 4158 enum nl80211_radar_event event, gfp_t gfp); 4164 4159 4165 4160 ··· 4286 4279 * @dev: the device which switched channels 4287 4280 * @chandef: the new channel definition 4288 4281 * 4289 - * Acquires wdev_lock, so must only be called from sleepable driver context! 4282 + * Caller must acquire wdev_lock, therefore must only be called from sleepable 4283 + * driver context! 4290 4284 */ 4291 4285 void cfg80211_ch_switch_notify(struct net_device *dev, 4292 4286 struct cfg80211_chan_def *chandef);
+40
include/net/mac80211.h
··· 154 154 * @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed 155 155 * @IEEE80211_CHANCTX_CHANGE_CHANNEL: switched to another operating channel, 156 156 * this is used only with channel switching with CSA 157 + * @IEEE80211_CHANCTX_CHANGE_MIN_WIDTH: The min required channel width changed 157 158 */ 158 159 enum ieee80211_chanctx_change { 159 160 IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0), 160 161 IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1), 161 162 IEEE80211_CHANCTX_CHANGE_RADAR = BIT(2), 162 163 IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(3), 164 + IEEE80211_CHANCTX_CHANGE_MIN_WIDTH = BIT(4), 163 165 }; 164 166 165 167 /** ··· 171 169 * that contains it is visible in mac80211 only. 172 170 * 173 171 * @def: the channel definition 172 + * @min_def: the minimum channel definition currently required. 174 173 * @rx_chains_static: The number of RX chains that must always be 175 174 * active on the channel to receive MIMO transmissions 176 175 * @rx_chains_dynamic: The number of RX chains that must be enabled ··· 183 180 */ 184 181 struct ieee80211_chanctx_conf { 185 182 struct cfg80211_chan_def def; 183 + struct cfg80211_chan_def min_def; 186 184 187 185 u8 rx_chains_static, rx_chains_dynamic; 188 186 ··· 1233 1229 }; 1234 1230 1235 1231 /** 1232 + * struct ieee80211_cipher_scheme - cipher scheme 1233 + * 1234 + * This structure contains a cipher scheme information defining 1235 + * the secure packet crypto handling. 1236 + * 1237 + * @cipher: a cipher suite selector 1238 + * @iftype: a cipher iftype bit mask indicating an allowed cipher usage 1239 + * @hdr_len: a length of a security header used the cipher 1240 + * @pn_len: a length of a packet number in the security header 1241 + * @pn_off: an offset of pn from the beginning of the security header 1242 + * @key_idx_off: an offset of key index byte in the security header 1243 + * @key_idx_mask: a bit mask of key_idx bits 1244 + * @key_idx_shift: a bit shift needed to get key_idx 1245 + * key_idx value calculation: 1246 + * (sec_header_base[key_idx_off] & key_idx_mask) >> key_idx_shift 1247 + * @mic_len: a mic length in bytes 1248 + */ 1249 + struct ieee80211_cipher_scheme { 1250 + u32 cipher; 1251 + u16 iftype; 1252 + u8 hdr_len; 1253 + u8 pn_len; 1254 + u8 pn_off; 1255 + u8 key_idx_off; 1256 + u8 key_idx_mask; 1257 + u8 key_idx_shift; 1258 + u8 mic_len; 1259 + }; 1260 + 1261 + /** 1236 1262 * enum set_key_cmd - key command 1237 1263 * 1238 1264 * Used with the set_key() callback in &struct ieee80211_ops, this ··· 1670 1636 * @uapsd_max_sp_len: maximum number of total buffered frames the WMM AP may 1671 1637 * deliver to a WMM STA during any Service Period triggered by the WMM STA. 1672 1638 * Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct values. 1639 + * 1640 + * @n_cipher_schemes: a size of an array of cipher schemes definitions. 1641 + * @cipher_schemes: a pointer to an array of cipher scheme definitions 1642 + * supported by HW. 1673 1643 */ 1674 1644 struct ieee80211_hw { 1675 1645 struct ieee80211_conf conf; ··· 1701 1663 netdev_features_t netdev_features; 1702 1664 u8 uapsd_queues; 1703 1665 u8 uapsd_max_sp_len; 1666 + u8 n_cipher_schemes; 1667 + const struct ieee80211_cipher_scheme *cipher_schemes; 1704 1668 }; 1705 1669 1706 1670 /**
+65 -15
include/net/regulatory.h
··· 38 38 * 39 39 * @rcu_head: RCU head struct used to free the request 40 40 * @wiphy_idx: this is set if this request's initiator is 41 - * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This 42 - * can be used by the wireless core to deal with conflicts 43 - * and potentially inform users of which devices specifically 44 - * cased the conflicts. 41 + * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This 42 + * can be used by the wireless core to deal with conflicts 43 + * and potentially inform users of which devices specifically 44 + * cased the conflicts. 45 45 * @initiator: indicates who sent this request, could be any of 46 - * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*) 46 + * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*) 47 47 * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested 48 - * regulatory domain. We have a few special codes: 49 - * 00 - World regulatory domain 50 - * 99 - built by driver but a specific alpha2 cannot be determined 51 - * 98 - result of an intersection between two regulatory domains 48 + * regulatory domain. We have a few special codes: 49 + * 00 - World regulatory domain 50 + * 99 - built by driver but a specific alpha2 cannot be determined 51 + * 98 - result of an intersection between two regulatory domains 52 52 * 97 - regulatory domain has not yet been configured 53 53 * @dfs_region: If CRDA responded with a regulatory domain that requires 54 54 * DFS master operation on a known DFS region (NL80211_DFS_*), ··· 59 59 * of hint passed. This could be any of the %NL80211_USER_REG_HINT_* 60 60 * types. 61 61 * @intersect: indicates whether the wireless core should intersect 62 - * the requested regulatory domain with the presently set regulatory 63 - * domain. 62 + * the requested regulatory domain with the presently set regulatory 63 + * domain. 64 64 * @processed: indicates whether or not this requests has already been 65 65 * processed. When the last request is processed it means that the 66 66 * currently regulatory domain set on cfg80211 is updated from ··· 68 68 * the last request is not yet processed we must yield until it 69 69 * is processed before processing any new requests. 70 70 * @country_ie_checksum: checksum of the last processed and accepted 71 - * country IE 71 + * country IE 72 72 * @country_ie_env: lets us know if the AP is telling us we are outdoor, 73 - * indoor, or if it doesn't matter 73 + * indoor, or if it doesn't matter 74 74 * @list: used to insert into the reg_requests_list linked list 75 75 */ 76 76 struct regulatory_request { ··· 79 79 enum nl80211_reg_initiator initiator; 80 80 enum nl80211_user_reg_hint_type user_reg_hint_type; 81 81 char alpha2[2]; 82 - u8 dfs_region; 82 + enum nl80211_dfs_regions dfs_region; 83 83 bool intersect; 84 84 bool processed; 85 85 enum environment_cap country_ie_env; 86 86 struct list_head list; 87 + }; 88 + 89 + /** 90 + * enum ieee80211_regulatory_flags - device regulatory flags 91 + * 92 + * @REGULATORY_CUSTOM_REG: tells us the driver for this device 93 + * has its own custom regulatory domain and cannot identify the 94 + * ISO / IEC 3166 alpha2 it belongs to. When this is enabled 95 + * we will disregard the first regulatory hint (when the 96 + * initiator is %REGDOM_SET_BY_CORE). Drivers that use 97 + * wiphy_apply_custom_regulatory() should have this flag set 98 + * or the regulatory core will set it for the wiphy. 99 + * @REGULATORY_STRICT_REG: tells us that the wiphy for this device 100 + * has regulatory domain that it wishes to be considered as the 101 + * superset for regulatory rules. After this device gets its regulatory 102 + * domain programmed further regulatory hints shall only be considered 103 + * for this device to enhance regulatory compliance, forcing the 104 + * device to only possibly use subsets of the original regulatory 105 + * rules. For example if channel 13 and 14 are disabled by this 106 + * device's regulatory domain no user specified regulatory hint which 107 + * has these channels enabled would enable them for this wiphy, 108 + * the device's original regulatory domain will be trusted as the 109 + * base. You can program the superset of regulatory rules for this 110 + * wiphy with regulatory_hint() for cards programmed with an 111 + * ISO3166-alpha2 country code. wiphys that use regulatory_hint() 112 + * will have their wiphy->regd programmed once the regulatory 113 + * domain is set, and all other regulatory hints will be ignored 114 + * until their own regulatory domain gets programmed. 115 + * @REGULATORY_DISABLE_BEACON_HINTS: enable this if your driver needs to 116 + * ensure that passive scan flags and beaconing flags may not be lifted by 117 + * cfg80211 due to regulatory beacon hints. For more information on beacon 118 + * hints read the documenation for regulatory_hint_found_beacon() 119 + * @REGULATORY_COUNTRY_IE_FOLLOW_POWER: for devices that have a preference 120 + * that even though they may have programmed their own custom power 121 + * setting prior to wiphy registration, they want to ensure their channel 122 + * power settings are updated for this connection with the power settings 123 + * derived from the regulatory domain. The regulatory domain used will be 124 + * based on the ISO3166-alpha2 from country IE provided through 125 + * regulatory_hint_country_ie() 126 + * @REGULATORY_COUNTRY_IE_IGNORE: for devices that have a preference to ignore 127 + * all country IE information processed by the regulatory core. This will 128 + * override %REGULATORY_COUNTRY_IE_FOLLOW_POWER as all country IEs will 129 + * be ignored. 130 + */ 131 + enum ieee80211_regulatory_flags { 132 + REGULATORY_CUSTOM_REG = BIT(0), 133 + REGULATORY_STRICT_REG = BIT(1), 134 + REGULATORY_DISABLE_BEACON_HINTS = BIT(2), 135 + REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(3), 136 + REGULATORY_COUNTRY_IE_IGNORE = BIT(4), 87 137 }; 88 138 89 139 struct ieee80211_freq_range { ··· 157 107 struct rcu_head rcu_head; 158 108 u32 n_reg_rules; 159 109 char alpha2[2]; 160 - u8 dfs_region; 110 + enum nl80211_dfs_regions dfs_region; 161 111 struct ieee80211_reg_rule reg_rules[]; 162 112 }; 163 113
+36 -11
include/uapi/linux/nl80211.h
··· 581 581 * operation, %NL80211_ATTR_MAC contains the peer MAC address, and 582 582 * %NL80211_ATTR_REASON_CODE the reason code to be used (only with 583 583 * %NL80211_TDLS_TEARDOWN). 584 - * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. 584 + * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. The 585 + * %NL80211_ATTR_TDLS_ACTION attribute determines the type of frame to be 586 + * sent. Public Action codes (802.11-2012 8.1.5.1) will be sent as 587 + * 802.11 management frames, while TDLS action codes (802.11-2012 588 + * 8.5.13.1) will be encapsulated and sent as data frames. The currently 589 + * supported Public Action code is %WLAN_PUB_ACTION_TDLS_DISCOVER_RES 590 + * and the currently supported TDLS actions codes are given in 591 + * &enum ieee80211_tdls_actioncode. 585 592 * 586 593 * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP 587 594 * (or GO) interface (i.e. hostapd) to ask for unexpected frames to ··· 1515 1508 * to react to radar events, e.g. initiate a channel switch or leave the 1516 1509 * IBSS network. 1517 1510 * 1511 + * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports 1512 + * 5 MHz channel bandwidth. 1513 + * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports 1514 + * 10 MHz channel bandwidth. 1515 + * 1518 1516 * @NL80211_ATTR_MAX: highest attribute number currently defined 1519 1517 * @__NL80211_ATTR_AFTER_LAST: internal use 1520 1518 */ ··· 1835 1823 NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES, 1836 1824 1837 1825 NL80211_ATTR_HANDLE_DFS, 1826 + 1827 + NL80211_ATTR_SUPPORT_5_MHZ, 1828 + NL80211_ATTR_SUPPORT_10_MHZ, 1838 1829 1839 1830 /* add attributes here, update the policy in nl80211.c */ 1840 1831 ··· 2239 2224 * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz 2240 2225 * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current 2241 2226 * regulatory domain. 2242 - * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is 2243 - * permitted on this channel in current regulatory domain. 2244 - * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted 2245 - * on this channel in current regulatory domain. 2227 + * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation 2228 + * are permitted on this channel, this includes sending probe 2229 + * requests, or modes of operation that require beaconing. 2246 2230 * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory 2247 2231 * on this channel in current regulatory domain. 2248 2232 * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm ··· 2268 2254 __NL80211_FREQUENCY_ATTR_INVALID, 2269 2255 NL80211_FREQUENCY_ATTR_FREQ, 2270 2256 NL80211_FREQUENCY_ATTR_DISABLED, 2271 - NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, 2272 - NL80211_FREQUENCY_ATTR_NO_IBSS, 2257 + NL80211_FREQUENCY_ATTR_NO_IR, 2258 + __NL80211_FREQUENCY_ATTR_NO_IBSS, 2273 2259 NL80211_FREQUENCY_ATTR_RADAR, 2274 2260 NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2275 2261 NL80211_FREQUENCY_ATTR_DFS_STATE, ··· 2285 2271 }; 2286 2272 2287 2273 #define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER 2274 + #define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR 2275 + #define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR 2276 + #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR 2288 2277 2289 2278 /** 2290 2279 * enum nl80211_bitrate_attr - bitrate attributes ··· 2430 2413 * @NL80211_RRF_DFS: DFS support is required to be used 2431 2414 * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links 2432 2415 * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links 2433 - * @NL80211_RRF_PASSIVE_SCAN: passive scan is required 2434 - * @NL80211_RRF_NO_IBSS: no IBSS is allowed 2416 + * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, 2417 + * this includes probe requests or modes of operation that require 2418 + * beaconing. 2435 2419 */ 2436 2420 enum nl80211_reg_rule_flags { 2437 2421 NL80211_RRF_NO_OFDM = 1<<0, ··· 2442 2424 NL80211_RRF_DFS = 1<<4, 2443 2425 NL80211_RRF_PTP_ONLY = 1<<5, 2444 2426 NL80211_RRF_PTMP_ONLY = 1<<6, 2445 - NL80211_RRF_PASSIVE_SCAN = 1<<7, 2446 - NL80211_RRF_NO_IBSS = 1<<8, 2427 + NL80211_RRF_NO_IR = 1<<7, 2428 + __NL80211_RRF_NO_IBSS = 1<<8, 2447 2429 }; 2430 + 2431 + #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR 2432 + #define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR 2433 + #define NL80211_RRF_NO_IR NL80211_RRF_NO_IR 2434 + 2435 + /* For backport compatibility with older userspace */ 2436 + #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) 2448 2437 2449 2438 /** 2450 2439 * enum nl80211_dfs_regions - regulatory DFS regions
+80 -43
net/mac80211/cfg.c
··· 133 133 struct key_params *params) 134 134 { 135 135 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 136 + struct ieee80211_local *local = sdata->local; 136 137 struct sta_info *sta = NULL; 138 + const struct ieee80211_cipher_scheme *cs = NULL; 137 139 struct ieee80211_key *key; 138 140 int err; 139 141 ··· 147 145 case WLAN_CIPHER_SUITE_WEP40: 148 146 case WLAN_CIPHER_SUITE_TKIP: 149 147 case WLAN_CIPHER_SUITE_WEP104: 150 - if (IS_ERR(sdata->local->wep_tx_tfm)) 148 + if (IS_ERR(local->wep_tx_tfm)) 151 149 return -EINVAL; 152 150 break; 151 + case WLAN_CIPHER_SUITE_CCMP: 152 + case WLAN_CIPHER_SUITE_AES_CMAC: 153 + case WLAN_CIPHER_SUITE_GCMP: 154 + break; 153 155 default: 156 + cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type); 154 157 break; 155 158 } 156 159 157 160 key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, 158 - params->key, params->seq_len, params->seq); 161 + params->key, params->seq_len, params->seq, 162 + cs); 159 163 if (IS_ERR(key)) 160 164 return PTR_ERR(key); 161 165 162 166 if (pairwise) 163 167 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; 164 168 165 - mutex_lock(&sdata->local->sta_mtx); 169 + mutex_lock(&local->sta_mtx); 166 170 167 171 if (mac_addr) { 168 172 if (ieee80211_vif_is_mesh(&sdata->vif)) ··· 224 216 break; 225 217 } 226 218 219 + if (sta) 220 + sta->cipher_scheme = cs; 221 + 227 222 err = ieee80211_key_link(key, sdata, sta); 228 223 229 224 out_unlock: 230 - mutex_unlock(&sdata->local->sta_mtx); 225 + mutex_unlock(&local->sta_mtx); 231 226 232 227 return err; 233 228 } ··· 255 244 goto out_unlock; 256 245 257 246 if (pairwise) 258 - key = key_mtx_dereference(local, sta->ptk); 247 + key = key_mtx_dereference(local, sta->ptk[key_idx]); 259 248 else 260 249 key = key_mtx_dereference(local, sta->gtk[key_idx]); 261 250 } else ··· 302 291 goto out; 303 292 304 293 if (pairwise) 305 - key = rcu_dereference(sta->ptk); 294 + key = rcu_dereference(sta->ptk[key_idx]); 306 295 else if (key_idx < NUM_DEFAULT_KEYS) 307 296 key = rcu_dereference(sta->gtk[key_idx]); 308 297 } else ··· 532 521 STATION_INFO_PEER_PM | 533 522 STATION_INFO_NONPEER_PM; 534 523 535 - sinfo->llid = le16_to_cpu(sta->llid); 536 - sinfo->plid = le16_to_cpu(sta->plid); 524 + sinfo->llid = sta->llid; 525 + sinfo->plid = sta->plid; 537 526 sinfo->plink_state = sta->plink_state; 538 527 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { 539 528 sinfo->filled |= STATION_INFO_T_OFFSET; ··· 857 846 if (!resp || !resp_len) 858 847 return 1; 859 848 860 - old = rtnl_dereference(sdata->u.ap.probe_resp); 849 + old = sdata_dereference(sdata->u.ap.probe_resp, sdata); 861 850 862 851 new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); 863 852 if (!new) ··· 881 870 int size, err; 882 871 u32 changed = BSS_CHANGED_BEACON; 883 872 884 - old = rtnl_dereference(sdata->u.ap.beacon); 873 + old = sdata_dereference(sdata->u.ap.beacon, sdata); 874 + 885 875 886 876 /* Need to have a beacon head if we don't have one yet */ 887 877 if (!params->head && !old) ··· 959 947 BSS_CHANGED_P2P_PS; 960 948 int err; 961 949 962 - old = rtnl_dereference(sdata->u.ap.beacon); 950 + old = sdata_dereference(sdata->u.ap.beacon, sdata); 963 951 if (old) 964 952 return -EALREADY; 965 953 ··· 980 968 */ 981 969 sdata->control_port_protocol = params->crypto.control_port_ethertype; 982 970 sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; 971 + sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local, 972 + &params->crypto, 973 + sdata->vif.type); 974 + 983 975 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { 984 976 vlan->control_port_protocol = 985 977 params->crypto.control_port_ethertype; 986 978 vlan->control_port_no_encrypt = 987 979 params->crypto.control_port_no_encrypt; 980 + vlan->encrypt_headroom = 981 + ieee80211_cs_headroom(sdata->local, 982 + &params->crypto, 983 + vlan->vif.type); 988 984 } 989 985 990 986 sdata->vif.bss_conf.beacon_int = params->beacon_interval; ··· 1021 1001 1022 1002 err = drv_start_ap(sdata->local, sdata); 1023 1003 if (err) { 1024 - old = rtnl_dereference(sdata->u.ap.beacon); 1004 + old = sdata_dereference(sdata->u.ap.beacon, sdata); 1005 + 1025 1006 if (old) 1026 1007 kfree_rcu(old, rcu_head); 1027 1008 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); ··· 1053 1032 if (sdata->vif.csa_active) 1054 1033 return -EBUSY; 1055 1034 1056 - old = rtnl_dereference(sdata->u.ap.beacon); 1035 + old = sdata_dereference(sdata->u.ap.beacon, sdata); 1057 1036 if (!old) 1058 1037 return -ENOENT; 1059 1038 ··· 1071 1050 struct ieee80211_local *local = sdata->local; 1072 1051 struct beacon_data *old_beacon; 1073 1052 struct probe_resp *old_probe_resp; 1053 + struct cfg80211_chan_def chandef; 1074 1054 1075 - old_beacon = rtnl_dereference(sdata->u.ap.beacon); 1055 + old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata); 1076 1056 if (!old_beacon) 1077 1057 return -ENOENT; 1078 - old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); 1058 + old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata); 1079 1059 1080 1060 /* abort any running channel switch */ 1081 1061 sdata->vif.csa_active = false; 1082 - cancel_work_sync(&sdata->csa_finalize_work); 1062 + kfree(sdata->u.ap.next_beacon); 1063 + sdata->u.ap.next_beacon = NULL; 1064 + 1083 1065 cancel_work_sync(&sdata->u.ap.request_smps_work); 1084 1066 1085 1067 /* turn off carrier for this interface and dependent VLANs */ ··· 1115 1091 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 1116 1092 1117 1093 if (sdata->wdev.cac_started) { 1094 + chandef = sdata->vif.bss_conf.chandef; 1118 1095 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 1119 - cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, 1096 + cfg80211_cac_event(sdata->dev, &chandef, 1097 + NL80211_RADAR_CAC_ABORTED, 1120 1098 GFP_KERNEL); 1121 1099 } 1122 1100 ··· 1979 1953 enum ieee80211_band band; 1980 1954 u32 changed = 0; 1981 1955 1982 - if (!rtnl_dereference(sdata->u.ap.beacon)) 1956 + if (!sdata_dereference(sdata->u.ap.beacon, sdata)) 1983 1957 return -ENOENT; 1984 1958 1985 1959 band = ieee80211_get_sdata_band(sdata); ··· 2989 2963 struct ieee80211_local *local = sdata->local; 2990 2964 int err, changed = 0; 2991 2965 2966 + sdata_lock(sdata); 2967 + /* AP might have been stopped while waiting for the lock. */ 2968 + if (!sdata->vif.csa_active) 2969 + goto unlock; 2970 + 2992 2971 if (!ieee80211_sdata_running(sdata)) 2993 - return; 2972 + goto unlock; 2994 2973 2995 2974 sdata->radar_required = sdata->csa_radar_required; 2996 - err = ieee80211_vif_change_channel(sdata, &local->csa_chandef, 2997 - &changed); 2975 + err = ieee80211_vif_change_channel(sdata, &changed); 2998 2976 if (WARN_ON(err < 0)) 2999 - return; 2977 + goto unlock; 3000 2978 3001 2979 if (!local->use_chanctx) { 3002 - local->_oper_chandef = local->csa_chandef; 2980 + local->_oper_chandef = sdata->csa_chandef; 3003 2981 ieee80211_hw_config(local, 0); 3004 2982 } 3005 2983 3006 2984 ieee80211_bss_info_change_notify(sdata, changed); 3007 2985 2986 + sdata->vif.csa_active = false; 3008 2987 switch (sdata->vif.type) { 3009 2988 case NL80211_IFTYPE_AP: 3010 2989 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); 3011 2990 if (err < 0) 3012 - return; 2991 + goto unlock; 2992 + 3013 2993 changed |= err; 3014 2994 kfree(sdata->u.ap.next_beacon); 3015 2995 sdata->u.ap.next_beacon = NULL; ··· 3029 2997 case NL80211_IFTYPE_MESH_POINT: 3030 2998 err = ieee80211_mesh_finish_csa(sdata); 3031 2999 if (err < 0) 3032 - return; 3000 + goto unlock; 3033 3001 break; 3034 3002 #endif 3035 3003 default: 3036 3004 WARN_ON(1); 3037 - return; 3005 + goto unlock; 3038 3006 } 3039 - sdata->vif.csa_active = false; 3040 3007 3041 3008 ieee80211_wake_queues_by_reason(&sdata->local->hw, 3042 3009 IEEE80211_MAX_QUEUE_MAP, 3043 3010 IEEE80211_QUEUE_STOP_REASON_CSA); 3044 3011 3045 - cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef); 3012 + cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); 3013 + 3014 + unlock: 3015 + sdata_unlock(sdata); 3046 3016 } 3047 3017 3048 3018 static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, ··· 3056 3022 struct ieee80211_chanctx *chanctx; 3057 3023 struct ieee80211_if_mesh __maybe_unused *ifmsh; 3058 3024 int err, num_chanctx; 3025 + 3026 + lockdep_assert_held(&sdata->wdev.mtx); 3059 3027 3060 3028 if (!list_empty(&local->roc_list) || local->scanning) 3061 3029 return -EBUSY; ··· 3179 3143 IEEE80211_MAX_QUEUE_MAP, 3180 3144 IEEE80211_QUEUE_STOP_REASON_CSA); 3181 3145 3182 - local->csa_chandef = params->chandef; 3146 + sdata->csa_chandef = params->chandef; 3183 3147 sdata->vif.csa_active = true; 3184 3148 3185 3149 ieee80211_bss_info_change_notify(sdata, err); ··· 3189 3153 } 3190 3154 3191 3155 static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3192 - struct ieee80211_channel *chan, bool offchan, 3193 - unsigned int wait, const u8 *buf, size_t len, 3194 - bool no_cck, bool dont_wait_for_ack, u64 *cookie) 3156 + struct cfg80211_mgmt_tx_params *params, 3157 + u64 *cookie) 3195 3158 { 3196 3159 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3197 3160 struct ieee80211_local *local = sdata->local; 3198 3161 struct sk_buff *skb; 3199 3162 struct sta_info *sta; 3200 - const struct ieee80211_mgmt *mgmt = (void *)buf; 3163 + const struct ieee80211_mgmt *mgmt = (void *)params->buf; 3201 3164 bool need_offchan = false; 3202 3165 u32 flags; 3203 3166 int ret; 3204 3167 3205 - if (dont_wait_for_ack) 3168 + if (params->dont_wait_for_ack) 3206 3169 flags = IEEE80211_TX_CTL_NO_ACK; 3207 3170 else 3208 3171 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | 3209 3172 IEEE80211_TX_CTL_REQ_TX_STATUS; 3210 3173 3211 - if (no_cck) 3174 + if (params->no_cck) 3212 3175 flags |= IEEE80211_TX_CTL_NO_CCK_RATE; 3213 3176 3214 3177 switch (sdata->vif.type) { ··· 3255 3220 /* configurations requiring offchan cannot work if no channel has been 3256 3221 * specified 3257 3222 */ 3258 - if (need_offchan && !chan) 3223 + if (need_offchan && !params->chan) 3259 3224 return -EINVAL; 3260 3225 3261 3226 mutex_lock(&local->mtx); ··· 3268 3233 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3269 3234 3270 3235 if (chanctx_conf) { 3271 - need_offchan = chan && (chan != chanctx_conf->def.chan); 3272 - } else if (!chan) { 3236 + need_offchan = params->chan && 3237 + (params->chan != 3238 + chanctx_conf->def.chan); 3239 + } else if (!params->chan) { 3273 3240 ret = -EINVAL; 3274 3241 rcu_read_unlock(); 3275 3242 goto out_unlock; ··· 3281 3244 rcu_read_unlock(); 3282 3245 } 3283 3246 3284 - if (need_offchan && !offchan) { 3247 + if (need_offchan && !params->offchan) { 3285 3248 ret = -EBUSY; 3286 3249 goto out_unlock; 3287 3250 } 3288 3251 3289 - skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); 3252 + skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len); 3290 3253 if (!skb) { 3291 3254 ret = -ENOMEM; 3292 3255 goto out_unlock; 3293 3256 } 3294 3257 skb_reserve(skb, local->hw.extra_tx_headroom); 3295 3258 3296 - memcpy(skb_put(skb, len), buf, len); 3259 + memcpy(skb_put(skb, params->len), params->buf, params->len); 3297 3260 3298 3261 IEEE80211_SKB_CB(skb)->flags = flags; 3299 3262 ··· 3313 3276 local->hw.offchannel_tx_hw_queue; 3314 3277 3315 3278 /* This will handle all kinds of coalescing and immediate TX */ 3316 - ret = ieee80211_start_roc_work(local, sdata, chan, 3317 - wait, cookie, skb, 3279 + ret = ieee80211_start_roc_work(local, sdata, params->chan, 3280 + params->wait, cookie, skb, 3318 3281 IEEE80211_ROC_TYPE_MGMT_TX); 3319 3282 if (ret) 3320 3283 kfree_skb(skb);
+140 -1
net/mac80211/chan.c
··· 9 9 #include "ieee80211_i.h" 10 10 #include "driver-ops.h" 11 11 12 + static enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta) 13 + { 14 + switch (sta->bandwidth) { 15 + case IEEE80211_STA_RX_BW_20: 16 + if (sta->ht_cap.ht_supported) 17 + return NL80211_CHAN_WIDTH_20; 18 + else 19 + return NL80211_CHAN_WIDTH_20_NOHT; 20 + case IEEE80211_STA_RX_BW_40: 21 + return NL80211_CHAN_WIDTH_40; 22 + case IEEE80211_STA_RX_BW_80: 23 + return NL80211_CHAN_WIDTH_80; 24 + case IEEE80211_STA_RX_BW_160: 25 + /* 26 + * This applied for both 160 and 80+80. since we use 27 + * the returned value to consider degradation of 28 + * ctx->conf.min_def, we have to make sure to take 29 + * the bigger one (NL80211_CHAN_WIDTH_160). 30 + * Otherwise we might try degrading even when not 31 + * needed, as the max required sta_bw returned (80+80) 32 + * might be smaller than the configured bw (160). 33 + */ 34 + return NL80211_CHAN_WIDTH_160; 35 + default: 36 + WARN_ON(1); 37 + return NL80211_CHAN_WIDTH_20; 38 + } 39 + } 40 + 41 + static enum nl80211_chan_width 42 + ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata) 43 + { 44 + enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; 45 + struct sta_info *sta; 46 + 47 + rcu_read_lock(); 48 + list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { 49 + if (sdata != sta->sdata && 50 + !(sta->sdata->bss && sta->sdata->bss == sdata->bss)) 51 + continue; 52 + 53 + if (!sta->uploaded) 54 + continue; 55 + 56 + max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta)); 57 + } 58 + rcu_read_unlock(); 59 + 60 + return max_bw; 61 + } 62 + 63 + static enum nl80211_chan_width 64 + ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, 65 + struct ieee80211_chanctx_conf *conf) 66 + { 67 + struct ieee80211_sub_if_data *sdata; 68 + enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; 69 + 70 + rcu_read_lock(); 71 + list_for_each_entry_rcu(sdata, &local->interfaces, list) { 72 + struct ieee80211_vif *vif = &sdata->vif; 73 + enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT; 74 + 75 + if (!ieee80211_sdata_running(sdata)) 76 + continue; 77 + 78 + if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) 79 + continue; 80 + 81 + switch (vif->type) { 82 + case NL80211_IFTYPE_AP: 83 + case NL80211_IFTYPE_AP_VLAN: 84 + width = ieee80211_get_max_required_bw(sdata); 85 + break; 86 + case NL80211_IFTYPE_P2P_DEVICE: 87 + continue; 88 + case NL80211_IFTYPE_STATION: 89 + case NL80211_IFTYPE_ADHOC: 90 + case NL80211_IFTYPE_WDS: 91 + case NL80211_IFTYPE_MESH_POINT: 92 + width = vif->bss_conf.chandef.width; 93 + break; 94 + case NL80211_IFTYPE_UNSPECIFIED: 95 + case NUM_NL80211_IFTYPES: 96 + case NL80211_IFTYPE_MONITOR: 97 + case NL80211_IFTYPE_P2P_CLIENT: 98 + case NL80211_IFTYPE_P2P_GO: 99 + WARN_ON_ONCE(1); 100 + } 101 + max_bw = max(max_bw, width); 102 + } 103 + rcu_read_unlock(); 104 + 105 + return max_bw; 106 + } 107 + 108 + /* 109 + * recalc the min required chan width of the channel context, which is 110 + * the max of min required widths of all the interfaces bound to this 111 + * channel context. 112 + */ 113 + void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 114 + struct ieee80211_chanctx *ctx) 115 + { 116 + enum nl80211_chan_width max_bw; 117 + struct cfg80211_chan_def min_def; 118 + 119 + lockdep_assert_held(&local->chanctx_mtx); 120 + 121 + /* don't optimize 5MHz, 10MHz, and radar_enabled confs */ 122 + if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 || 123 + ctx->conf.def.width == NL80211_CHAN_WIDTH_10 || 124 + ctx->conf.radar_enabled) { 125 + ctx->conf.min_def = ctx->conf.def; 126 + return; 127 + } 128 + 129 + max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf); 130 + 131 + /* downgrade chandef up to max_bw */ 132 + min_def = ctx->conf.def; 133 + while (min_def.width > max_bw) 134 + ieee80211_chandef_downgrade(&min_def); 135 + 136 + if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def)) 137 + return; 138 + 139 + ctx->conf.min_def = min_def; 140 + if (!ctx->driver_present) 141 + return; 142 + 143 + drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH); 144 + } 145 + 12 146 static void ieee80211_change_chanctx(struct ieee80211_local *local, 13 147 struct ieee80211_chanctx *ctx, 14 148 const struct cfg80211_chan_def *chandef) ··· 154 20 155 21 ctx->conf.def = *chandef; 156 22 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); 23 + ieee80211_recalc_chanctx_min_def(local, ctx); 157 24 158 25 if (!local->use_chanctx) { 159 26 local->_oper_chandef = *chandef; ··· 228 93 ctx->conf.rx_chains_dynamic = 1; 229 94 ctx->mode = mode; 230 95 ctx->conf.radar_enabled = ieee80211_is_radar_required(local); 96 + ieee80211_recalc_chanctx_min_def(local, ctx); 231 97 if (!local->use_chanctx) 232 98 local->hw.conf.radar_enabled = ctx->conf.radar_enabled; 233 99 ··· 315 179 ctx->refcount++; 316 180 317 181 ieee80211_recalc_txpower(sdata); 182 + ieee80211_recalc_chanctx_min_def(local, ctx); 318 183 sdata->vif.bss_conf.idle = false; 319 184 320 185 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && ··· 380 243 ieee80211_recalc_chanctx_chantype(sdata->local, ctx); 381 244 ieee80211_recalc_smps_chanctx(local, ctx); 382 245 ieee80211_recalc_radar_chanctx(local, ctx); 246 + ieee80211_recalc_chanctx_min_def(local, ctx); 383 247 } 384 248 } 385 249 ··· 549 411 } 550 412 551 413 int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, 552 - const struct cfg80211_chan_def *chandef, 553 414 u32 *changed) 554 415 { 555 416 struct ieee80211_local *local = sdata->local; 556 417 struct ieee80211_chanctx_conf *conf; 557 418 struct ieee80211_chanctx *ctx; 419 + const struct cfg80211_chan_def *chandef = &sdata->csa_chandef; 558 420 int ret; 559 421 u32 chanctx_changed = 0; 560 422 ··· 594 456 ieee80211_recalc_chanctx_chantype(local, ctx); 595 457 ieee80211_recalc_smps_chanctx(local, ctx); 596 458 ieee80211_recalc_radar_chanctx(local, ctx); 459 + ieee80211_recalc_chanctx_min_def(local, ctx); 597 460 598 461 ret = 0; 599 462 out:
+168
net/mac80211/debugfs.c
··· 17 17 18 18 #define DEBUGFS_FORMAT_BUFFER_SIZE 100 19 19 20 + #define TX_LATENCY_BIN_DELIMTER_C ',' 21 + #define TX_LATENCY_BIN_DELIMTER_S "," 22 + #define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n" 23 + #define TX_LATENCY_DISABLED "disable\n" 24 + 25 + 26 + /* 27 + * Display if Tx latency statistics & bins are enabled/disabled 28 + */ 29 + static ssize_t sta_tx_latency_stat_read(struct file *file, 30 + char __user *userbuf, 31 + size_t count, loff_t *ppos) 32 + { 33 + struct ieee80211_local *local = file->private_data; 34 + struct ieee80211_tx_latency_bin_ranges *tx_latency; 35 + char *buf; 36 + int bufsz, i, ret; 37 + int pos = 0; 38 + 39 + rcu_read_lock(); 40 + 41 + tx_latency = rcu_dereference(local->tx_latency); 42 + 43 + if (tx_latency && tx_latency->n_ranges) { 44 + bufsz = tx_latency->n_ranges * 15; 45 + buf = kzalloc(bufsz, GFP_ATOMIC); 46 + if (!buf) 47 + goto err; 48 + 49 + for (i = 0; i < tx_latency->n_ranges; i++) 50 + pos += scnprintf(buf + pos, bufsz - pos, "%d,", 51 + tx_latency->ranges[i]); 52 + pos += scnprintf(buf + pos, bufsz - pos, "\n"); 53 + } else if (tx_latency) { 54 + bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1; 55 + buf = kzalloc(bufsz, GFP_ATOMIC); 56 + if (!buf) 57 + goto err; 58 + 59 + pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 60 + TX_LATENCY_BINS_DISABLED); 61 + } else { 62 + bufsz = sizeof(TX_LATENCY_DISABLED) + 1; 63 + buf = kzalloc(bufsz, GFP_ATOMIC); 64 + if (!buf) 65 + goto err; 66 + 67 + pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 68 + TX_LATENCY_DISABLED); 69 + } 70 + 71 + rcu_read_unlock(); 72 + 73 + ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 74 + kfree(buf); 75 + 76 + return ret; 77 + err: 78 + rcu_read_unlock(); 79 + return -ENOMEM; 80 + } 81 + 82 + /* 83 + * Receive input from user regarding Tx latency statistics 84 + * The input should indicate if Tx latency statistics and bins are 85 + * enabled/disabled. 86 + * If bins are enabled input should indicate the amount of different bins and 87 + * their ranges. Each bin will count how many Tx frames transmitted within the 88 + * appropriate latency. 89 + * Legal input is: 90 + * a) "enable(bins disabled)" - to enable only general statistics 91 + * b) "a,b,c,d,...z" - to enable general statistics and bins, where all are 92 + * numbers and a < b < c < d.. < z 93 + * c) "disable" - disable all statistics 94 + * NOTE: must configure Tx latency statistics bins before stations connected. 95 + */ 96 + 97 + static ssize_t sta_tx_latency_stat_write(struct file *file, 98 + const char __user *userbuf, 99 + size_t count, loff_t *ppos) 100 + { 101 + struct ieee80211_local *local = file->private_data; 102 + char buf[128] = {}; 103 + char *bins = buf; 104 + char *token; 105 + int buf_size, i, alloc_size; 106 + int prev_bin = 0; 107 + int n_ranges = 0; 108 + int ret = count; 109 + struct ieee80211_tx_latency_bin_ranges *tx_latency; 110 + 111 + if (sizeof(buf) <= count) 112 + return -EINVAL; 113 + buf_size = count; 114 + if (copy_from_user(buf, userbuf, buf_size)) 115 + return -EFAULT; 116 + 117 + mutex_lock(&local->sta_mtx); 118 + 119 + /* cannot change config once we have stations */ 120 + if (local->num_sta) 121 + goto unlock; 122 + 123 + tx_latency = 124 + rcu_dereference_protected(local->tx_latency, 125 + lockdep_is_held(&local->sta_mtx)); 126 + 127 + /* disable Tx statistics */ 128 + if (!strcmp(buf, TX_LATENCY_DISABLED)) { 129 + if (!tx_latency) 130 + goto unlock; 131 + rcu_assign_pointer(local->tx_latency, NULL); 132 + synchronize_rcu(); 133 + kfree(tx_latency); 134 + goto unlock; 135 + } 136 + 137 + /* Tx latency already enabled */ 138 + if (tx_latency) 139 + goto unlock; 140 + 141 + if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) { 142 + /* check how many bins and between what ranges user requested */ 143 + token = buf; 144 + while (*token != '\0') { 145 + if (*token == TX_LATENCY_BIN_DELIMTER_C) 146 + n_ranges++; 147 + token++; 148 + } 149 + n_ranges++; 150 + } 151 + 152 + alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) + 153 + n_ranges * sizeof(u32); 154 + tx_latency = kzalloc(alloc_size, GFP_ATOMIC); 155 + if (!tx_latency) { 156 + ret = -ENOMEM; 157 + goto unlock; 158 + } 159 + tx_latency->n_ranges = n_ranges; 160 + for (i = 0; i < n_ranges; i++) { /* setting bin ranges */ 161 + token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S); 162 + sscanf(token, "%d", &tx_latency->ranges[i]); 163 + /* bins values should be in ascending order */ 164 + if (prev_bin >= tx_latency->ranges[i]) { 165 + ret = -EINVAL; 166 + kfree(tx_latency); 167 + goto unlock; 168 + } 169 + prev_bin = tx_latency->ranges[i]; 170 + } 171 + rcu_assign_pointer(local->tx_latency, tx_latency); 172 + 173 + unlock: 174 + mutex_unlock(&local->sta_mtx); 175 + 176 + return ret; 177 + } 178 + 179 + static const struct file_operations stats_tx_latency_ops = { 180 + .write = sta_tx_latency_stat_write, 181 + .read = sta_tx_latency_stat_read, 182 + .open = simple_open, 183 + .llseek = generic_file_llseek, 184 + }; 185 + 20 186 int mac80211_format_buffer(char __user *userbuf, size_t count, 21 187 loff_t *ppos, char *fmt, ...) 22 188 { ··· 481 315 DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); 482 316 DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount); 483 317 DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount); 318 + 319 + DEBUGFS_DEVSTATS_ADD(tx_latency); 484 320 }
+134
net/mac80211/debugfs_sta.c
··· 38 38 .llseek = generic_file_llseek, \ 39 39 } 40 40 41 + #define STA_OPS_W(name) \ 42 + static const struct file_operations sta_ ##name## _ops = { \ 43 + .write = sta_##name##_write, \ 44 + .open = simple_open, \ 45 + .llseek = generic_file_llseek, \ 46 + } 47 + 41 48 #define STA_OPS_RW(name) \ 42 49 static const struct file_operations sta_ ##name## _ops = { \ 43 50 .read = sta_##name##_read, \ ··· 395 388 } 396 389 STA_OPS(last_rx_rate); 397 390 391 + static int 392 + sta_tx_latency_stat_header(struct ieee80211_tx_latency_bin_ranges *tx_latency, 393 + char *buf, int pos, int bufsz) 394 + { 395 + int i; 396 + int range_count = tx_latency->n_ranges; 397 + u32 *bin_ranges = tx_latency->ranges; 398 + 399 + pos += scnprintf(buf + pos, bufsz - pos, 400 + "Station\t\t\tTID\tMax\tAvg"); 401 + if (range_count) { 402 + pos += scnprintf(buf + pos, bufsz - pos, 403 + "\t<=%d", bin_ranges[0]); 404 + for (i = 0; i < range_count - 1; i++) 405 + pos += scnprintf(buf + pos, bufsz - pos, "\t%d-%d", 406 + bin_ranges[i], bin_ranges[i+1]); 407 + pos += scnprintf(buf + pos, bufsz - pos, 408 + "\t%d<", bin_ranges[range_count - 1]); 409 + } 410 + 411 + pos += scnprintf(buf + pos, bufsz - pos, "\n"); 412 + 413 + return pos; 414 + } 415 + 416 + static int 417 + sta_tx_latency_stat_table(struct ieee80211_tx_latency_bin_ranges *tx_lat_range, 418 + struct ieee80211_tx_latency_stat *tx_lat, 419 + char *buf, int pos, int bufsz, int tid) 420 + { 421 + u32 avg = 0; 422 + int j; 423 + int bin_count = tx_lat->bin_count; 424 + 425 + pos += scnprintf(buf + pos, bufsz - pos, "\t\t\t%d", tid); 426 + /* make sure you don't divide in 0 */ 427 + if (tx_lat->counter) 428 + avg = tx_lat->sum / tx_lat->counter; 429 + 430 + pos += scnprintf(buf + pos, bufsz - pos, "\t%d\t%d", 431 + tx_lat->max, avg); 432 + 433 + if (tx_lat_range->n_ranges && tx_lat->bins) 434 + for (j = 0; j < bin_count; j++) 435 + pos += scnprintf(buf + pos, bufsz - pos, 436 + "\t%d", tx_lat->bins[j]); 437 + pos += scnprintf(buf + pos, bufsz - pos, "\n"); 438 + 439 + return pos; 440 + } 441 + 442 + /* 443 + * Output Tx latency statistics station && restart all statistics information 444 + */ 445 + static ssize_t sta_tx_latency_stat_read(struct file *file, 446 + char __user *userbuf, 447 + size_t count, loff_t *ppos) 448 + { 449 + struct sta_info *sta = file->private_data; 450 + struct ieee80211_local *local = sta->local; 451 + struct ieee80211_tx_latency_bin_ranges *tx_latency; 452 + char *buf; 453 + int bufsz, ret, i; 454 + int pos = 0; 455 + 456 + bufsz = 20 * IEEE80211_NUM_TIDS * 457 + sizeof(struct ieee80211_tx_latency_stat); 458 + buf = kzalloc(bufsz, GFP_KERNEL); 459 + if (!buf) 460 + return -ENOMEM; 461 + 462 + rcu_read_lock(); 463 + 464 + tx_latency = rcu_dereference(local->tx_latency); 465 + 466 + if (!sta->tx_lat) { 467 + pos += scnprintf(buf + pos, bufsz - pos, 468 + "Tx latency statistics are not enabled\n"); 469 + goto unlock; 470 + } 471 + 472 + pos = sta_tx_latency_stat_header(tx_latency, buf, pos, bufsz); 473 + 474 + pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", sta->sta.addr); 475 + for (i = 0; i < IEEE80211_NUM_TIDS; i++) 476 + pos = sta_tx_latency_stat_table(tx_latency, &sta->tx_lat[i], 477 + buf, pos, bufsz, i); 478 + unlock: 479 + rcu_read_unlock(); 480 + 481 + ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 482 + kfree(buf); 483 + 484 + return ret; 485 + } 486 + STA_OPS(tx_latency_stat); 487 + 488 + static ssize_t sta_tx_latency_stat_reset_write(struct file *file, 489 + const char __user *userbuf, 490 + size_t count, loff_t *ppos) 491 + { 492 + u32 *bins; 493 + int bin_count; 494 + struct sta_info *sta = file->private_data; 495 + int i; 496 + 497 + if (!sta->tx_lat) 498 + return -EINVAL; 499 + 500 + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 501 + bins = sta->tx_lat[i].bins; 502 + bin_count = sta->tx_lat[i].bin_count; 503 + 504 + sta->tx_lat[i].max = 0; 505 + sta->tx_lat[i].sum = 0; 506 + sta->tx_lat[i].counter = 0; 507 + 508 + if (bin_count) 509 + memset(bins, 0, bin_count * sizeof(u32)); 510 + } 511 + 512 + return count; 513 + } 514 + STA_OPS_W(tx_latency_stat_reset); 515 + 398 516 #define DEBUGFS_ADD(name) \ 399 517 debugfs_create_file(#name, 0400, \ 400 518 sta->debugfs.dir, sta, &sta_ ##name## _ops); ··· 573 441 DEBUGFS_ADD(last_ack_signal); 574 442 DEBUGFS_ADD(current_tx_rate); 575 443 DEBUGFS_ADD(last_rx_rate); 444 + DEBUGFS_ADD(tx_latency_stat); 445 + DEBUGFS_ADD(tx_latency_stat_reset); 576 446 577 447 DEBUGFS_ADD_COUNTER(rx_packets, rx_packets); 578 448 DEBUGFS_ADD_COUNTER(tx_packets, tx_packets);
+3 -3
net/mac80211/ibss.c
··· 550 550 capability); 551 551 /* XXX: should not really modify cfg80211 data */ 552 552 if (cbss) { 553 - cbss->channel = sdata->local->csa_chandef.chan; 553 + cbss->channel = sdata->csa_chandef.chan; 554 554 cfg80211_put_bss(sdata->local->hw.wiphy, cbss); 555 555 } 556 556 } 557 557 558 - ifibss->chandef = sdata->local->csa_chandef; 558 + ifibss->chandef = sdata->csa_chandef; 559 559 560 560 /* generate the beacon */ 561 561 err = ieee80211_ibss_csa_beacon(sdata, NULL); ··· 926 926 IEEE80211_MAX_QUEUE_MAP, 927 927 IEEE80211_QUEUE_STOP_REASON_CSA); 928 928 929 - sdata->local->csa_chandef = params.chandef; 929 + sdata->csa_chandef = params.chandef; 930 930 sdata->vif.csa_active = true; 931 931 932 932 ieee80211_bss_info_change_notify(sdata, err);
+41 -2
net/mac80211/ieee80211_i.h
··· 728 728 u16 sequence_number; 729 729 __be16 control_port_protocol; 730 730 bool control_port_no_encrypt; 731 + int encrypt_headroom; 731 732 732 733 struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; 733 734 ··· 736 735 int csa_counter_offset_beacon; 737 736 int csa_counter_offset_presp; 738 737 bool csa_radar_required; 738 + struct cfg80211_chan_def csa_chandef; 739 739 740 740 /* used to reconfigure hardware SM PS */ 741 741 struct work_struct recalc_smps; ··· 812 810 mutex_unlock(&sdata->wdev.mtx); 813 811 __release(&sdata->wdev.mtx); 814 812 } 813 + 814 + #define sdata_dereference(p, sdata) \ 815 + rcu_dereference_protected(p, lockdep_is_held(&sdata->wdev.mtx)) 815 816 816 817 static inline void 817 818 sdata_assert_lock(struct ieee80211_sub_if_data *sdata) ··· 900 895 bool running; 901 896 }; 902 897 #endif 898 + 899 + /* 900 + * struct ieee80211_tx_latency_bin_ranges - Tx latency statistics bins ranges 901 + * 902 + * Measuring Tx latency statistics. Counts how many Tx frames transmitted in a 903 + * certain latency range (in Milliseconds). Each station that uses these 904 + * ranges will have bins to count the amount of frames received in that range. 905 + * The user can configure the ranges via debugfs. 906 + * If ranges is NULL then Tx latency statistics bins are disabled for all 907 + * stations. 908 + * 909 + * @n_ranges: number of ranges that are taken in account 910 + * @ranges: the ranges that the user requested or NULL if disabled. 911 + */ 912 + struct ieee80211_tx_latency_bin_ranges { 913 + int n_ranges; 914 + u32 ranges[]; 915 + }; 903 916 904 917 /** 905 918 * mac80211 scan flags - currently active scan mode ··· 1071 1048 struct timer_list sta_cleanup; 1072 1049 int sta_generation; 1073 1050 1051 + /* 1052 + * Tx latency statistics parameters for all stations. 1053 + * Can enable via debugfs (NULL when disabled). 1054 + */ 1055 + struct ieee80211_tx_latency_bin_ranges __rcu *tx_latency; 1056 + 1074 1057 struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; 1075 1058 struct tasklet_struct tx_pending_tasklet; 1076 1059 ··· 1122 1093 enum mac80211_scan_state next_scan_state; 1123 1094 struct delayed_work scan_work; 1124 1095 struct ieee80211_sub_if_data __rcu *scan_sdata; 1125 - struct cfg80211_chan_def csa_chandef; 1126 1096 /* For backward compatibility only -- do not use */ 1127 1097 struct cfg80211_chan_def _oper_chandef; 1128 1098 ··· 1721 1693 int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, 1722 1694 enum ieee80211_smps_mode smps_mode); 1723 1695 void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); 1696 + void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); 1724 1697 1725 1698 size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1726 1699 const u8 *ids, int n_ids, size_t offset); ··· 1760 1731 /* NOTE: only use ieee80211_vif_change_channel() for channel switch */ 1761 1732 int __must_check 1762 1733 ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, 1763 - const struct cfg80211_chan_def *chandef, 1764 1734 u32 *changed); 1765 1735 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1766 1736 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); ··· 1770 1742 struct ieee80211_chanctx *chanctx); 1771 1743 void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 1772 1744 struct ieee80211_chanctx *chanctx); 1745 + void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, 1746 + struct ieee80211_chanctx *ctx); 1773 1747 1774 1748 void ieee80211_dfs_cac_timer(unsigned long data); 1775 1749 void ieee80211_dfs_cac_timer_work(struct work_struct *work); ··· 1779 1749 void ieee80211_dfs_radar_detected_work(struct work_struct *work); 1780 1750 int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, 1781 1751 struct cfg80211_csa_settings *csa_settings); 1752 + 1753 + bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs); 1754 + bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n); 1755 + const struct ieee80211_cipher_scheme * 1756 + ieee80211_cs_get(struct ieee80211_local *local, u32 cipher, 1757 + enum nl80211_iftype iftype); 1758 + int ieee80211_cs_headroom(struct ieee80211_local *local, 1759 + struct cfg80211_crypto_settings *crypto, 1760 + enum nl80211_iftype iftype); 1782 1761 1783 1762 #ifdef CONFIG_MAC80211_NOINLINE 1784 1763 #define debug_noinline noinline
+9 -5
net/mac80211/iface.c
··· 401 401 snprintf(sdata->name, IFNAMSIZ, "%s-monitor", 402 402 wiphy_name(local->hw.wiphy)); 403 403 404 + sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 405 + 404 406 ieee80211_set_default_queues(sdata); 405 407 406 408 ret = drv_add_interface(local, sdata); ··· 751 749 u32 hw_reconf_flags = 0; 752 750 int i, flushed; 753 751 struct ps_data *ps; 752 + struct cfg80211_chan_def chandef; 754 753 755 754 clear_bit(SDATA_STATE_RUNNING, &sdata->state); 756 755 ··· 826 823 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 827 824 828 825 if (sdata->wdev.cac_started) { 826 + chandef = sdata->vif.bss_conf.chandef; 829 827 WARN_ON(local->suspended); 830 828 mutex_lock(&local->iflist_mtx); 831 829 ieee80211_vif_release_channel(sdata); 832 830 mutex_unlock(&local->iflist_mtx); 833 - cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, 831 + cfg80211_cac_event(sdata->dev, &chandef, 832 + NL80211_RADAR_CAC_ABORTED, 834 833 GFP_KERNEL); 835 834 } 836 835 ··· 1041 1036 */ 1042 1037 static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) 1043 1038 { 1044 - int flushed; 1045 1039 int i; 1046 1040 1047 1041 /* free extra data */ ··· 1054 1050 1055 1051 if (ieee80211_vif_is_mesh(&sdata->vif)) 1056 1052 mesh_rmc_free(sdata); 1057 - 1058 - flushed = sta_info_flush(sdata); 1059 - WARN_ON(flushed); 1060 1053 } 1061 1054 1062 1055 static void ieee80211_uninit(struct net_device *dev) ··· 1271 1270 1272 1271 sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); 1273 1272 sdata->control_port_no_encrypt = false; 1273 + sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1274 1274 1275 1275 sdata->noack_map = 0; 1276 1276 ··· 1686 1684 1687 1685 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; 1688 1686 sdata->user_power_level = local->user_power_level; 1687 + 1688 + sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1689 1689 1690 1690 /* setup type-dependent data */ 1691 1691 ieee80211_setup_sdata(sdata, type);
+42 -22
net/mac80211/key.c
··· 260 260 int idx; 261 261 bool defunikey, defmultikey, defmgmtkey; 262 262 263 + /* caller must provide at least one old/new */ 264 + if (WARN_ON(!new && !old)) 265 + return; 266 + 263 267 if (new) 264 268 list_add_tail(&new->list, &sdata->key_list); 265 269 266 - if (sta && pairwise) { 267 - rcu_assign_pointer(sta->ptk, new); 268 - } else if (sta) { 269 - if (old) 270 - idx = old->conf.keyidx; 271 - else 272 - idx = new->conf.keyidx; 273 - rcu_assign_pointer(sta->gtk[idx], new); 270 + WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); 271 + 272 + if (old) 273 + idx = old->conf.keyidx; 274 + else 275 + idx = new->conf.keyidx; 276 + 277 + if (sta) { 278 + if (pairwise) { 279 + rcu_assign_pointer(sta->ptk[idx], new); 280 + sta->ptk_idx = idx; 281 + } else { 282 + rcu_assign_pointer(sta->gtk[idx], new); 283 + sta->gtk_idx = idx; 284 + } 274 285 } else { 275 - WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); 276 - 277 - if (old) 278 - idx = old->conf.keyidx; 279 - else 280 - idx = new->conf.keyidx; 281 - 282 286 defunikey = old && 283 287 old == key_mtx_dereference(sdata->local, 284 288 sdata->default_unicast_key); ··· 316 312 list_del(&old->list); 317 313 } 318 314 319 - struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 320 - const u8 *key_data, 321 - size_t seq_len, const u8 *seq) 315 + struct ieee80211_key * 316 + ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 317 + const u8 *key_data, 318 + size_t seq_len, const u8 *seq, 319 + const struct ieee80211_cipher_scheme *cs) 322 320 { 323 321 struct ieee80211_key *key; 324 322 int i, j, err; ··· 399 393 return ERR_PTR(err); 400 394 } 401 395 break; 396 + default: 397 + if (cs) { 398 + size_t len = (seq_len > MAX_PN_LEN) ? 399 + MAX_PN_LEN : seq_len; 400 + 401 + key->conf.iv_len = cs->hdr_len; 402 + key->conf.icv_len = cs->mic_len; 403 + for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) 404 + for (j = 0; j < len; j++) 405 + key->u.gen.rx_pn[i][j] = 406 + seq[len - j - 1]; 407 + } 402 408 } 403 409 memcpy(key->conf.key, key_data, key_len); 404 410 INIT_LIST_HEAD(&key->list); ··· 493 475 mutex_lock(&sdata->local->key_mtx); 494 476 495 477 if (sta && pairwise) 496 - old_key = key_mtx_dereference(sdata->local, sta->ptk); 478 + old_key = key_mtx_dereference(sdata->local, sta->ptk[idx]); 497 479 else if (sta) 498 480 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]); 499 481 else ··· 643 625 list_add(&key->list, &keys); 644 626 } 645 627 646 - key = key_mtx_dereference(local, sta->ptk); 647 - if (key) { 628 + for (i = 0; i < NUM_DEFAULT_KEYS; i++) { 629 + key = key_mtx_dereference(local, sta->ptk[i]); 630 + if (!key) 631 + continue; 648 632 ieee80211_key_replace(key->sdata, key->sta, 649 633 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, 650 634 key, NULL); ··· 897 877 898 878 key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx, 899 879 keyconf->keylen, keyconf->key, 900 - 0, NULL); 880 + 0, NULL, NULL); 901 881 if (IS_ERR(key)) 902 882 return ERR_CAST(key); 903 883
+10 -3
net/mac80211/key.h
··· 18 18 19 19 #define NUM_DEFAULT_KEYS 4 20 20 #define NUM_DEFAULT_MGMT_KEYS 2 21 + #define MAX_PN_LEN 16 21 22 22 23 struct ieee80211_local; 23 24 struct ieee80211_sub_if_data; ··· 94 93 u32 replays; /* dot11RSNAStatsCMACReplays */ 95 94 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ 96 95 } aes_cmac; 96 + struct { 97 + /* generic cipher scheme */ 98 + u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN]; 99 + } gen; 97 100 } u; 98 101 99 102 /* number of times this key has been used */ ··· 118 113 struct ieee80211_key_conf conf; 119 114 }; 120 115 121 - struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 122 - const u8 *key_data, 123 - size_t seq_len, const u8 *seq); 116 + struct ieee80211_key * 117 + ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 118 + const u8 *key_data, 119 + size_t seq_len, const u8 *seq, 120 + const struct ieee80211_cipher_scheme *cs); 124 121 /* 125 122 * Insert a key into data structures (sdata, sta if necessary) 126 123 * to make it used, free old key. On failure, also free the new key.
+101 -44
net/mac80211/main.c
··· 651 651 } 652 652 EXPORT_SYMBOL(ieee80211_alloc_hw); 653 653 654 - int ieee80211_register_hw(struct ieee80211_hw *hw) 654 + static int ieee80211_init_cipher_suites(struct ieee80211_local *local) 655 655 { 656 - struct ieee80211_local *local = hw_to_local(hw); 657 - int result, i; 658 - enum ieee80211_band band; 659 - int channels, max_bitrates; 660 - bool supp_ht, supp_vht; 661 - netdev_features_t feature_whitelist; 662 - struct cfg80211_chan_def dflt_chandef = {}; 656 + bool have_wep = !(IS_ERR(local->wep_tx_tfm) || 657 + IS_ERR(local->wep_rx_tfm)); 658 + bool have_mfp = local->hw.flags & IEEE80211_HW_MFP_CAPABLE; 659 + const struct ieee80211_cipher_scheme *cs = local->hw.cipher_schemes; 660 + int n_suites = 0, r = 0, w = 0; 661 + u32 *suites; 663 662 static const u32 cipher_suites[] = { 664 663 /* keep WEP first, it may be removed below */ 665 664 WLAN_CIPHER_SUITE_WEP40, ··· 669 670 /* keep last -- depends on hw flags! */ 670 671 WLAN_CIPHER_SUITE_AES_CMAC 671 672 }; 673 + 674 + /* Driver specifies the ciphers, we have nothing to do... */ 675 + if (local->hw.wiphy->cipher_suites && have_wep) 676 + return 0; 677 + 678 + /* Set up cipher suites if driver relies on mac80211 cipher defs */ 679 + if (!local->hw.wiphy->cipher_suites && !cs) { 680 + local->hw.wiphy->cipher_suites = cipher_suites; 681 + local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 682 + 683 + if (!have_mfp) 684 + local->hw.wiphy->n_cipher_suites--; 685 + 686 + if (!have_wep) { 687 + local->hw.wiphy->cipher_suites += 2; 688 + local->hw.wiphy->n_cipher_suites -= 2; 689 + } 690 + 691 + return 0; 692 + } 693 + 694 + if (!local->hw.wiphy->cipher_suites) { 695 + /* 696 + * Driver specifies cipher schemes only 697 + * We start counting ciphers defined by schemes, TKIP and CCMP 698 + */ 699 + n_suites = local->hw.n_cipher_schemes + 2; 700 + 701 + /* check if we have WEP40 and WEP104 */ 702 + if (have_wep) 703 + n_suites += 2; 704 + 705 + /* check if we have AES_CMAC */ 706 + if (have_mfp) 707 + n_suites++; 708 + 709 + suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL); 710 + if (!suites) 711 + return -ENOMEM; 712 + 713 + suites[w++] = WLAN_CIPHER_SUITE_CCMP; 714 + suites[w++] = WLAN_CIPHER_SUITE_TKIP; 715 + 716 + if (have_wep) { 717 + suites[w++] = WLAN_CIPHER_SUITE_WEP40; 718 + suites[w++] = WLAN_CIPHER_SUITE_WEP104; 719 + } 720 + 721 + if (have_mfp) 722 + suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC; 723 + 724 + for (r = 0; r < local->hw.n_cipher_schemes; r++) 725 + suites[w++] = cs[r].cipher; 726 + } else { 727 + /* Driver provides cipher suites, but we need to exclude WEP */ 728 + suites = kmemdup(local->hw.wiphy->cipher_suites, 729 + sizeof(u32) * local->hw.wiphy->n_cipher_suites, 730 + GFP_KERNEL); 731 + if (!suites) 732 + return -ENOMEM; 733 + 734 + for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { 735 + u32 suite = local->hw.wiphy->cipher_suites[r]; 736 + 737 + if (suite == WLAN_CIPHER_SUITE_WEP40 || 738 + suite == WLAN_CIPHER_SUITE_WEP104) 739 + continue; 740 + suites[w++] = suite; 741 + } 742 + } 743 + 744 + local->hw.wiphy->cipher_suites = suites; 745 + local->hw.wiphy->n_cipher_suites = w; 746 + local->wiphy_ciphers_allocated = true; 747 + 748 + return 0; 749 + } 750 + 751 + int ieee80211_register_hw(struct ieee80211_hw *hw) 752 + { 753 + struct ieee80211_local *local = hw_to_local(hw); 754 + int result, i; 755 + enum ieee80211_band band; 756 + int channels, max_bitrates; 757 + bool supp_ht, supp_vht; 758 + netdev_features_t feature_whitelist; 759 + struct cfg80211_chan_def dflt_chandef = {}; 672 760 673 761 if (hw->flags & IEEE80211_HW_QUEUE_CONTROL && 674 762 (local->hw.offchannel_tx_hw_queue == IEEE80211_INVAL_HW_QUEUE || ··· 937 851 if (local->hw.wiphy->max_scan_ie_len) 938 852 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; 939 853 940 - /* Set up cipher suites unless driver already did */ 941 - if (!local->hw.wiphy->cipher_suites) { 942 - local->hw.wiphy->cipher_suites = cipher_suites; 943 - local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 944 - if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) 945 - local->hw.wiphy->n_cipher_suites--; 946 - } 947 - if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { 948 - if (local->hw.wiphy->cipher_suites == cipher_suites) { 949 - local->hw.wiphy->cipher_suites += 2; 950 - local->hw.wiphy->n_cipher_suites -= 2; 951 - } else { 952 - u32 *suites; 953 - int r, w = 0; 854 + WARN_ON(!ieee80211_cs_list_valid(local->hw.cipher_schemes, 855 + local->hw.n_cipher_schemes)); 954 856 955 - /* Filter out WEP */ 956 - 957 - suites = kmemdup( 958 - local->hw.wiphy->cipher_suites, 959 - sizeof(u32) * local->hw.wiphy->n_cipher_suites, 960 - GFP_KERNEL); 961 - if (!suites) { 962 - result = -ENOMEM; 963 - goto fail_wiphy_register; 964 - } 965 - for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { 966 - u32 suite = local->hw.wiphy->cipher_suites[r]; 967 - if (suite == WLAN_CIPHER_SUITE_WEP40 || 968 - suite == WLAN_CIPHER_SUITE_WEP104) 969 - continue; 970 - suites[w++] = suite; 971 - } 972 - local->hw.wiphy->cipher_suites = suites; 973 - local->hw.wiphy->n_cipher_suites = w; 974 - local->wiphy_ciphers_allocated = true; 975 - } 976 - } 857 + result = ieee80211_init_cipher_suites(local); 858 + if (result < 0) 859 + goto fail_wiphy_register; 977 860 978 861 if (!local->ops->remain_on_channel) 979 862 local->hw.wiphy->max_remain_on_channel_duration = 5000; ··· 1144 1089 idr_for_each(&local->ack_status_frames, 1145 1090 ieee80211_free_ack_frame, NULL); 1146 1091 idr_destroy(&local->ack_status_frames); 1092 + 1093 + kfree(rcu_access_pointer(local->tx_latency)); 1147 1094 1148 1095 wiphy_free(local->hw.wiphy); 1149 1096 }
+2 -5
net/mac80211/mesh.c
··· 674 674 rcu_read_lock(); 675 675 csa = rcu_dereference(ifmsh->csa); 676 676 if (csa) { 677 - __le16 pre_value; 678 - 679 677 pos = skb_put(skb, 13); 680 678 memset(pos, 0, 13); 681 679 *pos++ = WLAN_EID_CHANNEL_SWITCH; ··· 695 697 WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; 696 698 put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); 697 699 pos += 2; 698 - pre_value = cpu_to_le16(ifmsh->pre_value); 699 - memcpy(pos, &pre_value, 2); 700 + put_unaligned_le16(ifmsh->pre_value, pos); 700 701 pos += 2; 701 702 } 702 703 rcu_read_unlock(); ··· 961 964 IEEE80211_MAX_QUEUE_MAP, 962 965 IEEE80211_QUEUE_STOP_REASON_CSA); 963 966 964 - sdata->local->csa_chandef = params.chandef; 967 + sdata->csa_chandef = params.chandef; 965 968 sdata->vif.csa_active = true; 966 969 967 970 ieee80211_bss_info_change_notify(sdata, err);
+2 -4
net/mac80211/mesh.h
··· 215 215 bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, 216 216 struct ieee802_11_elems *ie); 217 217 void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); 218 - void mesh_mgmt_ies_add(struct ieee80211_sub_if_data *sdata, 219 - struct sk_buff *skb); 220 218 int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, 221 219 struct sk_buff *skb); 222 220 int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata, ··· 301 303 void mesh_mpp_table_grow(void); 302 304 /* Mesh paths */ 303 305 int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, 304 - u8 ttl, const u8 *target, __le32 target_sn, 305 - __le16 target_rcode, const u8 *ra); 306 + u8 ttl, const u8 *target, u32 target_sn, 307 + u16 target_rcode, const u8 *ra); 306 308 void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); 307 309 void mesh_path_flush_pending(struct mesh_path *mpath); 308 310 void mesh_path_tx_pending(struct mesh_path *mpath);
+39 -52
net/mac80211/mesh_hwmp.c
··· 102 102 static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 103 103 104 104 static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, 105 - const u8 *orig_addr, __le32 orig_sn, 105 + const u8 *orig_addr, u32 orig_sn, 106 106 u8 target_flags, const u8 *target, 107 - __le32 target_sn, const u8 *da, 107 + u32 target_sn, const u8 *da, 108 108 u8 hop_count, u8 ttl, 109 - __le32 lifetime, __le32 metric, 110 - __le32 preq_id, 109 + u32 lifetime, u32 metric, u32 preq_id, 111 110 struct ieee80211_sub_if_data *sdata) 112 111 { 113 112 struct ieee80211_local *local = sdata->local; ··· 166 167 if (action == MPATH_PREP) { 167 168 memcpy(pos, target, ETH_ALEN); 168 169 pos += ETH_ALEN; 169 - memcpy(pos, &target_sn, 4); 170 + put_unaligned_le32(target_sn, pos); 170 171 pos += 4; 171 172 } else { 172 173 if (action == MPATH_PREQ) { 173 - memcpy(pos, &preq_id, 4); 174 + put_unaligned_le32(preq_id, pos); 174 175 pos += 4; 175 176 } 176 177 memcpy(pos, orig_addr, ETH_ALEN); 177 178 pos += ETH_ALEN; 178 - memcpy(pos, &orig_sn, 4); 179 + put_unaligned_le32(orig_sn, pos); 179 180 pos += 4; 180 181 } 181 - memcpy(pos, &lifetime, 4); /* interval for RANN */ 182 + put_unaligned_le32(lifetime, pos); /* interval for RANN */ 182 183 pos += 4; 183 - memcpy(pos, &metric, 4); 184 + put_unaligned_le32(metric, pos); 184 185 pos += 4; 185 186 if (action == MPATH_PREQ) { 186 187 *pos++ = 1; /* destination count */ 187 188 *pos++ = target_flags; 188 189 memcpy(pos, target, ETH_ALEN); 189 190 pos += ETH_ALEN; 190 - memcpy(pos, &target_sn, 4); 191 + put_unaligned_le32(target_sn, pos); 191 192 pos += 4; 192 193 } else if (action == MPATH_PREP) { 193 194 memcpy(pos, orig_addr, ETH_ALEN); 194 195 pos += ETH_ALEN; 195 - memcpy(pos, &orig_sn, 4); 196 + put_unaligned_le32(orig_sn, pos); 196 197 pos += 4; 197 198 } 198 199 ··· 238 239 * frame directly but add it to the pending queue instead. 239 240 */ 240 241 int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, 241 - u8 ttl, const u8 *target, __le32 target_sn, 242 - __le16 target_rcode, const u8 *ra) 242 + u8 ttl, const u8 *target, u32 target_sn, 243 + u16 target_rcode, const u8 *ra) 243 244 { 244 245 struct ieee80211_local *local = sdata->local; 245 246 struct sk_buff *skb; ··· 253 254 return -EAGAIN; 254 255 255 256 skb = dev_alloc_skb(local->tx_headroom + 256 - IEEE80211_ENCRYPT_HEADROOM + 257 + sdata->encrypt_headroom + 257 258 IEEE80211_ENCRYPT_TAILROOM + 258 259 hdr_len + 259 260 2 + 15 /* PERR IE */); 260 261 if (!skb) 261 262 return -1; 262 - skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM); 263 + skb_reserve(skb, local->tx_headroom + sdata->encrypt_headroom); 263 264 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 264 265 memset(mgmt, 0, hdr_len); 265 266 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | ··· 292 293 pos++; 293 294 memcpy(pos, target, ETH_ALEN); 294 295 pos += ETH_ALEN; 295 - memcpy(pos, &target_sn, 4); 296 + put_unaligned_le32(target_sn, pos); 296 297 pos += 4; 297 - memcpy(pos, &target_rcode, 2); 298 + put_unaligned_le16(target_rcode, pos); 298 299 299 300 /* see note in function header */ 300 301 prepare_frame_for_deferred_tx(sdata, skb); ··· 591 592 if (ttl != 0) { 592 593 mhwmp_dbg(sdata, "replying to the PREQ\n"); 593 594 mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, 594 - cpu_to_le32(orig_sn), 0, target_addr, 595 - cpu_to_le32(target_sn), mgmt->sa, 0, ttl, 596 - cpu_to_le32(lifetime), cpu_to_le32(metric), 597 - 0, sdata); 595 + orig_sn, 0, target_addr, 596 + target_sn, mgmt->sa, 0, ttl, 597 + lifetime, metric, 0, sdata); 598 598 } else { 599 599 ifmsh->mshstats.dropped_frames_ttl++; 600 600 } ··· 623 625 } 624 626 625 627 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, 626 - cpu_to_le32(orig_sn), target_flags, target_addr, 627 - cpu_to_le32(target_sn), da, 628 - hopcount, ttl, cpu_to_le32(lifetime), 629 - cpu_to_le32(metric), cpu_to_le32(preq_id), 630 - sdata); 628 + orig_sn, target_flags, target_addr, 629 + target_sn, da, hopcount, ttl, lifetime, 630 + metric, preq_id, sdata); 631 631 if (!is_multicast_ether_addr(da)) 632 632 ifmsh->mshstats.fwded_unicast++; 633 633 else ··· 691 695 target_sn = PREP_IE_TARGET_SN(prep_elem); 692 696 orig_sn = PREP_IE_ORIG_SN(prep_elem); 693 697 694 - mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, 695 - cpu_to_le32(orig_sn), 0, target_addr, 696 - cpu_to_le32(target_sn), next_hop, hopcount, 697 - ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), 698 - 0, sdata); 698 + mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, orig_sn, 0, 699 + target_addr, target_sn, next_hop, hopcount, 700 + ttl, lifetime, metric, 0, sdata); 699 701 rcu_read_unlock(); 700 702 701 703 sdata->u.mesh.mshstats.fwded_unicast++; ··· 744 750 if (!ifmsh->mshcfg.dot11MeshForwarding) 745 751 goto endperr; 746 752 mesh_path_error_tx(sdata, ttl, target_addr, 747 - cpu_to_le32(target_sn), 748 - cpu_to_le16(target_rcode), 753 + target_sn, target_rcode, 749 754 broadcast_addr); 750 755 } else 751 756 spin_unlock_bh(&mpath->state_lock); ··· 840 847 841 848 if (ifmsh->mshcfg.dot11MeshForwarding) { 842 849 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 843 - cpu_to_le32(orig_sn), 844 - 0, NULL, 0, broadcast_addr, 845 - hopcount, ttl, cpu_to_le32(interval), 846 - cpu_to_le32(metric + metric_txsta), 847 - 0, sdata); 850 + orig_sn, 0, NULL, 0, broadcast_addr, 851 + hopcount, ttl, interval, 852 + metric + metric_txsta, 0, sdata); 848 853 } 849 854 850 855 rcu_read_unlock(); ··· 1040 1049 1041 1050 spin_unlock_bh(&mpath->state_lock); 1042 1051 da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; 1043 - mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, 1044 - cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, 1045 - cpu_to_le32(mpath->sn), da, 0, 1046 - ttl, cpu_to_le32(lifetime), 0, 1047 - cpu_to_le32(ifmsh->preq_id++), sdata); 1052 + mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, ifmsh->sn, 1053 + target_flags, mpath->dst, mpath->sn, da, 0, 1054 + ttl, lifetime, 0, ifmsh->preq_id++, sdata); 1048 1055 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); 1049 1056 1050 1057 enddiscovery: ··· 1201 1212 switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) { 1202 1213 case IEEE80211_PROACTIVE_RANN: 1203 1214 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, 1204 - cpu_to_le32(++ifmsh->sn), 1205 - 0, NULL, 0, broadcast_addr, 1206 - 0, ifmsh->mshcfg.element_ttl, 1207 - cpu_to_le32(interval), 0, 0, sdata); 1215 + ++ifmsh->sn, 0, NULL, 0, broadcast_addr, 1216 + 0, ifmsh->mshcfg.element_ttl, 1217 + interval, 0, 0, sdata); 1208 1218 break; 1209 1219 case IEEE80211_PROACTIVE_PREQ_WITH_PREP: 1210 1220 flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG; ··· 1212 1224 target_flags |= IEEE80211_PREQ_TO_FLAG | 1213 1225 IEEE80211_PREQ_USN_FLAG; 1214 1226 mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr, 1215 - cpu_to_le32(++ifmsh->sn), target_flags, 1216 - (u8 *) broadcast_addr, 0, broadcast_addr, 1217 - 0, ifmsh->mshcfg.element_ttl, 1218 - cpu_to_le32(interval), 1219 - 0, cpu_to_le32(ifmsh->preq_id++), sdata); 1227 + ++ifmsh->sn, target_flags, 1228 + (u8 *) broadcast_addr, 0, broadcast_addr, 1229 + 0, ifmsh->mshcfg.element_ttl, interval, 1230 + 0, ifmsh->preq_id++, sdata); 1220 1231 break; 1221 1232 default: 1222 1233 mhwmp_dbg(sdata, "Proactive mechanism not supported\n");
+3 -4
net/mac80211/mesh_pathtbl.c
··· 722 722 struct mpath_node *node; 723 723 struct ieee80211_sub_if_data *sdata = sta->sdata; 724 724 int i; 725 - __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE); 726 725 727 726 rcu_read_lock(); 728 727 tbl = rcu_dereference(mesh_paths); ··· 735 736 ++mpath->sn; 736 737 spin_unlock_bh(&mpath->state_lock); 737 738 mesh_path_error_tx(sdata, 738 - sdata->u.mesh.mshcfg.element_ttl, 739 - mpath->dst, cpu_to_le32(mpath->sn), 740 - reason, bcast); 739 + sdata->u.mesh.mshcfg.element_ttl, 740 + mpath->dst, mpath->sn, 741 + WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, bcast); 741 742 } 742 743 } 743 744 rcu_read_unlock();
+449 -423
net/mac80211/mesh_plink.c
··· 19 19 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 20 20 jiffies + HZ * t / 1000)) 21 21 22 - /* We only need a valid sta if user configured a minimum rssi_threshold. */ 23 - #define rssi_threshold_check(sta, sdata) \ 24 - (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ 25 - (sta && (s8) -ewma_read(&sta->avg_signal) > \ 26 - sdata->u.mesh.mshcfg.rssi_threshold)) 27 - 28 22 enum plink_event { 29 23 PLINK_UNDEFINED, 30 24 OPN_ACPT, ··· 55 61 56 62 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 57 63 enum ieee80211_self_protected_actioncode action, 58 - u8 *da, __le16 llid, __le16 plid, __le16 reason); 64 + u8 *da, u16 llid, u16 plid, u16 reason); 65 + 66 + 67 + /* We only need a valid sta if user configured a minimum rssi_threshold. */ 68 + static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata, 69 + struct sta_info *sta) 70 + { 71 + s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold; 72 + return rssi_threshold == 0 || 73 + (sta && (s8) -ewma_read(&sta->avg_signal) > rssi_threshold); 74 + } 59 75 60 76 /** 61 77 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine ··· 246 242 247 243 spin_lock_bh(&sta->lock); 248 244 changed = __mesh_plink_deactivate(sta); 249 - sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); 245 + sta->reason = WLAN_REASON_MESH_PEER_CANCELED; 250 246 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 251 247 sta->sta.addr, sta->llid, sta->plid, 252 248 sta->reason); ··· 257 253 258 254 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 259 255 enum ieee80211_self_protected_actioncode action, 260 - u8 *da, __le16 llid, __le16 plid, __le16 reason) 256 + u8 *da, u16 llid, u16 plid, u16 reason) 261 257 { 262 258 struct ieee80211_local *local = sdata->local; 263 259 struct sk_buff *skb; ··· 283 279 2 + 8 + /* peering IE */ 284 280 sdata->u.mesh.ie_len); 285 281 if (!skb) 286 - return -1; 282 + return err; 287 283 info = IEEE80211_SKB_CB(skb); 288 284 skb_reserve(skb, local->tx_headroom); 289 285 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); ··· 305 301 if (action == WLAN_SP_MESH_PEERING_CONFIRM) { 306 302 /* AID */ 307 303 pos = skb_put(skb, 2); 308 - memcpy(pos + 2, &plid, 2); 304 + put_unaligned_le16(plid, pos + 2); 309 305 } 310 306 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 311 307 ieee80211_add_ext_srates_ie(sdata, skb, true, band) || ··· 347 343 *pos++ = ie_len; 348 344 memcpy(pos, &peering_proto, 2); 349 345 pos += 2; 350 - memcpy(pos, &llid, 2); 346 + put_unaligned_le16(llid, pos); 351 347 pos += 2; 352 348 if (include_plid) { 353 - memcpy(pos, &plid, 2); 349 + put_unaligned_le16(plid, pos); 354 350 pos += 2; 355 351 } 356 352 if (action == WLAN_SP_MESH_PEERING_CLOSE) { 357 - memcpy(pos, &reason, 2); 353 + put_unaligned_le16(reason, pos); 358 354 pos += 2; 359 355 } 360 356 ··· 522 518 sta->plink_state == NL80211_PLINK_LISTEN && 523 519 sdata->u.mesh.accepting_plinks && 524 520 sdata->u.mesh.mshcfg.auto_open_plinks && 525 - rssi_threshold_check(sta, sdata)) 521 + rssi_threshold_check(sdata, sta)) 526 522 changed = mesh_plink_open(sta); 527 523 528 524 ieee80211_mps_frame_release(sta, elems); ··· 534 530 static void mesh_plink_timer(unsigned long data) 535 531 { 536 532 struct sta_info *sta; 537 - __le16 llid, plid, reason; 533 + u16 reason = 0; 538 534 struct ieee80211_sub_if_data *sdata; 539 535 struct mesh_config *mshcfg; 536 + enum ieee80211_self_protected_actioncode action = 0; 540 537 541 538 /* 542 539 * This STA is valid because sta_info_destroy() will ··· 558 553 mpl_dbg(sta->sdata, 559 554 "Mesh plink timer for %pM fired on state %s\n", 560 555 sta->sta.addr, mplstates[sta->plink_state]); 561 - reason = 0; 562 - llid = sta->llid; 563 - plid = sta->plid; 564 556 sdata = sta->sdata; 565 557 mshcfg = &sdata->u.mesh.mshcfg; 566 558 ··· 576 574 rand % sta->plink_timeout; 577 575 ++sta->plink_retries; 578 576 mod_plink_timer(sta, sta->plink_timeout); 579 - spin_unlock_bh(&sta->lock); 580 - mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 581 - sta->sta.addr, llid, 0, 0); 577 + action = WLAN_SP_MESH_PEERING_OPEN; 582 578 break; 583 579 } 584 - reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES); 580 + reason = WLAN_REASON_MESH_MAX_RETRIES; 585 581 /* fall through on else */ 586 582 case NL80211_PLINK_CNF_RCVD: 587 583 /* confirm timer */ 588 584 if (!reason) 589 - reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); 585 + reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT; 590 586 sta->plink_state = NL80211_PLINK_HOLDING; 591 587 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 592 - spin_unlock_bh(&sta->lock); 593 - mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 594 - sta->sta.addr, llid, plid, reason); 588 + action = WLAN_SP_MESH_PEERING_CLOSE; 595 589 break; 596 590 case NL80211_PLINK_HOLDING: 597 591 /* holding timer */ 598 592 del_timer(&sta->plink_timer); 599 593 mesh_plink_fsm_restart(sta); 600 - spin_unlock_bh(&sta->lock); 601 594 break; 602 595 default: 603 - spin_unlock_bh(&sta->lock); 604 596 break; 605 597 } 598 + spin_unlock_bh(&sta->lock); 599 + if (action) 600 + mesh_plink_frame_tx(sdata, action, sta->sta.addr, 601 + sta->llid, sta->plid, reason); 606 602 } 607 603 608 604 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) ··· 612 612 add_timer(&sta->plink_timer); 613 613 } 614 614 615 + static bool llid_in_use(struct ieee80211_sub_if_data *sdata, 616 + u16 llid) 617 + { 618 + struct ieee80211_local *local = sdata->local; 619 + bool in_use = false; 620 + struct sta_info *sta; 621 + 622 + rcu_read_lock(); 623 + list_for_each_entry_rcu(sta, &local->sta_list, list) { 624 + if (!memcmp(&sta->llid, &llid, sizeof(llid))) { 625 + in_use = true; 626 + break; 627 + } 628 + } 629 + rcu_read_unlock(); 630 + 631 + return in_use; 632 + } 633 + 634 + static u16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata) 635 + { 636 + u16 llid; 637 + 638 + do { 639 + get_random_bytes(&llid, sizeof(llid)); 640 + /* for mesh PS we still only have the AID range for TIM bits */ 641 + llid = (llid % IEEE80211_MAX_AID) + 1; 642 + } while (llid_in_use(sdata, llid)); 643 + 644 + return llid; 645 + } 646 + 615 647 u32 mesh_plink_open(struct sta_info *sta) 616 648 { 617 - __le16 llid; 618 649 struct ieee80211_sub_if_data *sdata = sta->sdata; 619 650 u32 changed; 620 651 ··· 653 622 return 0; 654 623 655 624 spin_lock_bh(&sta->lock); 656 - get_random_bytes(&llid, 2); 657 - sta->llid = llid; 625 + sta->llid = mesh_get_new_llid(sdata); 658 626 if (sta->plink_state != NL80211_PLINK_LISTEN && 659 627 sta->plink_state != NL80211_PLINK_BLOCKED) { 660 628 spin_unlock_bh(&sta->lock); ··· 670 640 changed = ieee80211_mps_local_status_update(sdata); 671 641 672 642 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 673 - sta->sta.addr, llid, 0, 0); 643 + sta->sta.addr, sta->llid, 0, 0); 674 644 return changed; 675 645 } 676 646 ··· 686 656 return changed; 687 657 } 688 658 659 + static void mesh_plink_close(struct ieee80211_sub_if_data *sdata, 660 + struct sta_info *sta, 661 + enum plink_event event) 662 + { 663 + struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 664 + 665 + u16 reason = (event == CLS_ACPT) ? 666 + WLAN_REASON_MESH_CLOSE : WLAN_REASON_MESH_CONFIG; 667 + 668 + sta->reason = reason; 669 + sta->plink_state = NL80211_PLINK_HOLDING; 670 + mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 671 + } 672 + 673 + static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata, 674 + struct sta_info *sta) 675 + { 676 + struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 677 + u32 changed = 0; 678 + 679 + del_timer(&sta->plink_timer); 680 + sta->plink_state = NL80211_PLINK_ESTAB; 681 + changed |= mesh_plink_inc_estab_count(sdata); 682 + changed |= mesh_set_ht_prot_mode(sdata); 683 + changed |= mesh_set_short_slot_time(sdata); 684 + mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr); 685 + ieee80211_mps_sta_status_update(sta); 686 + changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode); 687 + return changed; 688 + } 689 + 690 + /** 691 + * mesh_plink_fsm - step @sta MPM based on @event 692 + * 693 + * @sdata: interface 694 + * @sta: mesh neighbor 695 + * @event: peering event 696 + * 697 + * Return: changed MBSS flags 698 + */ 699 + static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata, 700 + struct sta_info *sta, enum plink_event event) 701 + { 702 + struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 703 + enum ieee80211_self_protected_actioncode action = 0; 704 + u32 changed = 0; 705 + 706 + mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr, 707 + mplstates[sta->plink_state], mplevents[event]); 708 + 709 + spin_lock_bh(&sta->lock); 710 + switch (sta->plink_state) { 711 + case NL80211_PLINK_LISTEN: 712 + switch (event) { 713 + case CLS_ACPT: 714 + mesh_plink_fsm_restart(sta); 715 + break; 716 + case OPN_ACPT: 717 + sta->plink_state = NL80211_PLINK_OPN_RCVD; 718 + sta->llid = mesh_get_new_llid(sdata); 719 + mesh_plink_timer_set(sta, 720 + mshcfg->dot11MeshRetryTimeout); 721 + 722 + /* set the non-peer mode to active during peering */ 723 + changed |= ieee80211_mps_local_status_update(sdata); 724 + action = WLAN_SP_MESH_PEERING_OPEN; 725 + break; 726 + default: 727 + break; 728 + } 729 + break; 730 + case NL80211_PLINK_OPN_SNT: 731 + switch (event) { 732 + case OPN_RJCT: 733 + case CNF_RJCT: 734 + case CLS_ACPT: 735 + mesh_plink_close(sdata, sta, event); 736 + action = WLAN_SP_MESH_PEERING_CLOSE; 737 + break; 738 + case OPN_ACPT: 739 + /* retry timer is left untouched */ 740 + sta->plink_state = NL80211_PLINK_OPN_RCVD; 741 + action = WLAN_SP_MESH_PEERING_CONFIRM; 742 + break; 743 + case CNF_ACPT: 744 + sta->plink_state = NL80211_PLINK_CNF_RCVD; 745 + if (!mod_plink_timer(sta, 746 + mshcfg->dot11MeshConfirmTimeout)) 747 + sta->ignore_plink_timer = true; 748 + break; 749 + default: 750 + break; 751 + } 752 + break; 753 + case NL80211_PLINK_OPN_RCVD: 754 + switch (event) { 755 + case OPN_RJCT: 756 + case CNF_RJCT: 757 + case CLS_ACPT: 758 + mesh_plink_close(sdata, sta, event); 759 + action = WLAN_SP_MESH_PEERING_CLOSE; 760 + break; 761 + case OPN_ACPT: 762 + action = WLAN_SP_MESH_PEERING_CONFIRM; 763 + break; 764 + case CNF_ACPT: 765 + changed |= mesh_plink_establish(sdata, sta); 766 + break; 767 + default: 768 + break; 769 + } 770 + break; 771 + case NL80211_PLINK_CNF_RCVD: 772 + switch (event) { 773 + case OPN_RJCT: 774 + case CNF_RJCT: 775 + case CLS_ACPT: 776 + mesh_plink_close(sdata, sta, event); 777 + action = WLAN_SP_MESH_PEERING_CLOSE; 778 + break; 779 + case OPN_ACPT: 780 + changed |= mesh_plink_establish(sdata, sta); 781 + action = WLAN_SP_MESH_PEERING_CONFIRM; 782 + break; 783 + default: 784 + break; 785 + } 786 + break; 787 + case NL80211_PLINK_ESTAB: 788 + switch (event) { 789 + case CLS_ACPT: 790 + changed |= __mesh_plink_deactivate(sta); 791 + changed |= mesh_set_ht_prot_mode(sdata); 792 + changed |= mesh_set_short_slot_time(sdata); 793 + mesh_plink_close(sdata, sta, event); 794 + action = WLAN_SP_MESH_PEERING_CLOSE; 795 + break; 796 + case OPN_ACPT: 797 + action = WLAN_SP_MESH_PEERING_CONFIRM; 798 + break; 799 + default: 800 + break; 801 + } 802 + break; 803 + case NL80211_PLINK_HOLDING: 804 + switch (event) { 805 + case CLS_ACPT: 806 + if (del_timer(&sta->plink_timer)) 807 + sta->ignore_plink_timer = 1; 808 + mesh_plink_fsm_restart(sta); 809 + break; 810 + case OPN_ACPT: 811 + case CNF_ACPT: 812 + case OPN_RJCT: 813 + case CNF_RJCT: 814 + action = WLAN_SP_MESH_PEERING_CLOSE; 815 + break; 816 + default: 817 + break; 818 + } 819 + break; 820 + default: 821 + /* should not get here, PLINK_BLOCKED is dealt with at the 822 + * beginning of the function 823 + */ 824 + break; 825 + } 826 + spin_unlock_bh(&sta->lock); 827 + if (action) { 828 + mesh_plink_frame_tx(sdata, action, sta->sta.addr, 829 + sta->llid, sta->plid, sta->reason); 830 + 831 + /* also send confirm in open case */ 832 + if (action == WLAN_SP_MESH_PEERING_OPEN) { 833 + mesh_plink_frame_tx(sdata, 834 + WLAN_SP_MESH_PEERING_CONFIRM, 835 + sta->sta.addr, sta->llid, 836 + sta->plid, 0); 837 + } 838 + } 839 + 840 + return changed; 841 + } 842 + 843 + /* 844 + * mesh_plink_get_event - get correct MPM event 845 + * 846 + * @sdata: interface 847 + * @sta: peer, leave NULL if processing a frame from a new suitable peer 848 + * @elems: peering management IEs 849 + * @ftype: frame type 850 + * @llid: peer's peer link ID 851 + * @plid: peer's local link ID 852 + * 853 + * Return: new peering event for @sta, but PLINK_UNDEFINED should be treated as 854 + * an error. 855 + */ 856 + static enum plink_event 857 + mesh_plink_get_event(struct ieee80211_sub_if_data *sdata, 858 + struct sta_info *sta, 859 + struct ieee802_11_elems *elems, 860 + enum ieee80211_self_protected_actioncode ftype, 861 + u16 llid, u16 plid) 862 + { 863 + enum plink_event event = PLINK_UNDEFINED; 864 + u8 ie_len = elems->peering_len; 865 + bool matches_local; 866 + 867 + matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE || 868 + mesh_matches_local(sdata, elems)); 869 + 870 + /* deny open request from non-matching peer */ 871 + if (!matches_local && !sta) { 872 + event = OPN_RJCT; 873 + goto out; 874 + } 875 + 876 + if (!sta) { 877 + if (ftype != WLAN_SP_MESH_PEERING_OPEN) { 878 + mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n"); 879 + goto out; 880 + } 881 + /* ftype == WLAN_SP_MESH_PEERING_OPEN */ 882 + if (!mesh_plink_free_count(sdata)) { 883 + mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); 884 + goto out; 885 + } 886 + } else { 887 + if (!test_sta_flag(sta, WLAN_STA_AUTH)) { 888 + mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n"); 889 + goto out; 890 + } 891 + if (sta->plink_state == NL80211_PLINK_BLOCKED) 892 + goto out; 893 + } 894 + 895 + /* new matching peer */ 896 + if (!sta) { 897 + event = OPN_ACPT; 898 + goto out; 899 + } 900 + 901 + switch (ftype) { 902 + case WLAN_SP_MESH_PEERING_OPEN: 903 + if (!matches_local) 904 + event = OPN_RJCT; 905 + if (!mesh_plink_free_count(sdata) || 906 + (sta->plid && sta->plid != plid)) 907 + event = OPN_IGNR; 908 + else 909 + event = OPN_ACPT; 910 + break; 911 + case WLAN_SP_MESH_PEERING_CONFIRM: 912 + if (!matches_local) 913 + event = CNF_RJCT; 914 + if (!mesh_plink_free_count(sdata) || 915 + (sta->llid != llid || sta->plid != plid)) 916 + event = CNF_IGNR; 917 + else 918 + event = CNF_ACPT; 919 + break; 920 + case WLAN_SP_MESH_PEERING_CLOSE: 921 + if (sta->plink_state == NL80211_PLINK_ESTAB) 922 + /* Do not check for llid or plid. This does not 923 + * follow the standard but since multiple plinks 924 + * per sta are not supported, it is necessary in 925 + * order to avoid a livelock when MP A sees an 926 + * establish peer link to MP B but MP B does not 927 + * see it. This can be caused by a timeout in 928 + * B's peer link establishment or B beign 929 + * restarted. 930 + */ 931 + event = CLS_ACPT; 932 + else if (sta->plid != plid) 933 + event = CLS_IGNR; 934 + else if (ie_len == 8 && sta->llid != llid) 935 + event = CLS_IGNR; 936 + else 937 + event = CLS_ACPT; 938 + break; 939 + default: 940 + mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n"); 941 + break; 942 + } 943 + 944 + out: 945 + return event; 946 + } 947 + 948 + static void 949 + mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, 950 + struct ieee80211_mgmt *mgmt, 951 + struct ieee802_11_elems *elems) 952 + { 953 + 954 + struct sta_info *sta; 955 + enum plink_event event; 956 + enum ieee80211_self_protected_actioncode ftype; 957 + u32 changed = 0; 958 + u8 ie_len = elems->peering_len; 959 + __le16 _plid, _llid; 960 + u16 plid, llid = 0; 961 + 962 + if (!elems->peering) { 963 + mpl_dbg(sdata, 964 + "Mesh plink: missing necessary peer link ie\n"); 965 + return; 966 + } 967 + 968 + if (elems->rsn_len && 969 + sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 970 + mpl_dbg(sdata, 971 + "Mesh plink: can't establish link with secure peer\n"); 972 + return; 973 + } 974 + 975 + ftype = mgmt->u.action.u.self_prot.action_code; 976 + if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || 977 + (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || 978 + (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 979 + && ie_len != 8)) { 980 + mpl_dbg(sdata, 981 + "Mesh plink: incorrect plink ie length %d %d\n", 982 + ftype, ie_len); 983 + return; 984 + } 985 + 986 + if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 987 + (!elems->mesh_id || !elems->mesh_config)) { 988 + mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); 989 + return; 990 + } 991 + /* Note the lines below are correct, the llid in the frame is the plid 992 + * from the point of view of this host. 993 + */ 994 + memcpy(&_plid, PLINK_GET_LLID(elems->peering), sizeof(__le16)); 995 + plid = le16_to_cpu(_plid); 996 + if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || 997 + (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) { 998 + memcpy(&_llid, PLINK_GET_PLID(elems->peering), sizeof(__le16)); 999 + llid = le16_to_cpu(_llid); 1000 + } 1001 + 1002 + /* WARNING: Only for sta pointer, is dropped & re-acquired */ 1003 + rcu_read_lock(); 1004 + 1005 + sta = sta_info_get(sdata, mgmt->sa); 1006 + 1007 + if (ftype == WLAN_SP_MESH_PEERING_OPEN && 1008 + !rssi_threshold_check(sdata, sta)) { 1009 + mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n", 1010 + mgmt->sa); 1011 + goto unlock_rcu; 1012 + } 1013 + 1014 + /* Now we will figure out the appropriate event... */ 1015 + event = mesh_plink_get_event(sdata, sta, elems, ftype, llid, plid); 1016 + 1017 + if (event == OPN_ACPT) { 1018 + rcu_read_unlock(); 1019 + /* allocate sta entry if necessary and update info */ 1020 + sta = mesh_sta_info_get(sdata, mgmt->sa, elems); 1021 + if (!sta) { 1022 + mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); 1023 + goto unlock_rcu; 1024 + } 1025 + sta->plid = plid; 1026 + } else if (!sta && event == OPN_RJCT) { 1027 + mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1028 + mgmt->sa, 0, plid, 1029 + WLAN_REASON_MESH_CONFIG); 1030 + goto unlock_rcu; 1031 + } else if (!sta || event == PLINK_UNDEFINED) { 1032 + /* something went wrong */ 1033 + goto unlock_rcu; 1034 + } 1035 + 1036 + changed |= mesh_plink_fsm(sdata, sta, event); 1037 + 1038 + unlock_rcu: 1039 + rcu_read_unlock(); 1040 + 1041 + if (changed) 1042 + ieee80211_mbss_info_change_notify(sdata, changed); 1043 + } 689 1044 690 1045 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, 691 1046 struct ieee80211_mgmt *mgmt, size_t len, 692 1047 struct ieee80211_rx_status *rx_status) 693 1048 { 694 - struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 695 1049 struct ieee802_11_elems elems; 696 - struct sta_info *sta; 697 - enum plink_event event; 698 - enum ieee80211_self_protected_actioncode ftype; 699 1050 size_t baselen; 700 - bool matches_local = true; 701 - u8 ie_len; 702 1051 u8 *baseaddr; 703 - u32 changed = 0; 704 - __le16 plid, llid, reason; 705 1052 706 1053 /* need action_code, aux */ 707 1054 if (len < IEEE80211_MIN_ACTION_SIZE + 3) ··· 1102 695 baselen += 4; 1103 696 } 1104 697 ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems); 1105 - 1106 - if (!elems.peering) { 1107 - mpl_dbg(sdata, 1108 - "Mesh plink: missing necessary peer link ie\n"); 1109 - return; 1110 - } 1111 - 1112 - if (elems.rsn_len && 1113 - sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 1114 - mpl_dbg(sdata, 1115 - "Mesh plink: can't establish link with secure peer\n"); 1116 - return; 1117 - } 1118 - 1119 - ftype = mgmt->u.action.u.self_prot.action_code; 1120 - ie_len = elems.peering_len; 1121 - if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || 1122 - (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || 1123 - (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 1124 - && ie_len != 8)) { 1125 - mpl_dbg(sdata, 1126 - "Mesh plink: incorrect plink ie length %d %d\n", 1127 - ftype, ie_len); 1128 - return; 1129 - } 1130 - 1131 - if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 1132 - (!elems.mesh_id || !elems.mesh_config)) { 1133 - mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); 1134 - return; 1135 - } 1136 - /* Note the lines below are correct, the llid in the frame is the plid 1137 - * from the point of view of this host. 1138 - */ 1139 - memcpy(&plid, PLINK_GET_LLID(elems.peering), 2); 1140 - if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || 1141 - (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) 1142 - memcpy(&llid, PLINK_GET_PLID(elems.peering), 2); 1143 - 1144 - /* WARNING: Only for sta pointer, is dropped & re-acquired */ 1145 - rcu_read_lock(); 1146 - 1147 - sta = sta_info_get(sdata, mgmt->sa); 1148 - if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { 1149 - mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n"); 1150 - rcu_read_unlock(); 1151 - return; 1152 - } 1153 - 1154 - if (ftype == WLAN_SP_MESH_PEERING_OPEN && 1155 - !rssi_threshold_check(sta, sdata)) { 1156 - mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n", 1157 - mgmt->sa); 1158 - rcu_read_unlock(); 1159 - return; 1160 - } 1161 - 1162 - if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { 1163 - mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n"); 1164 - rcu_read_unlock(); 1165 - return; 1166 - } 1167 - 1168 - if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { 1169 - rcu_read_unlock(); 1170 - return; 1171 - } 1172 - 1173 - /* Now we will figure out the appropriate event... */ 1174 - event = PLINK_UNDEFINED; 1175 - if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 1176 - !mesh_matches_local(sdata, &elems)) { 1177 - matches_local = false; 1178 - switch (ftype) { 1179 - case WLAN_SP_MESH_PEERING_OPEN: 1180 - event = OPN_RJCT; 1181 - break; 1182 - case WLAN_SP_MESH_PEERING_CONFIRM: 1183 - event = CNF_RJCT; 1184 - break; 1185 - default: 1186 - break; 1187 - } 1188 - } 1189 - 1190 - if (!sta && !matches_local) { 1191 - rcu_read_unlock(); 1192 - reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 1193 - llid = 0; 1194 - mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1195 - mgmt->sa, llid, plid, reason); 1196 - return; 1197 - } else if (!sta) { 1198 - /* ftype == WLAN_SP_MESH_PEERING_OPEN */ 1199 - if (!mesh_plink_free_count(sdata)) { 1200 - mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); 1201 - rcu_read_unlock(); 1202 - return; 1203 - } 1204 - event = OPN_ACPT; 1205 - } else if (matches_local) { 1206 - switch (ftype) { 1207 - case WLAN_SP_MESH_PEERING_OPEN: 1208 - if (!mesh_plink_free_count(sdata) || 1209 - (sta->plid && sta->plid != plid)) 1210 - event = OPN_IGNR; 1211 - else 1212 - event = OPN_ACPT; 1213 - break; 1214 - case WLAN_SP_MESH_PEERING_CONFIRM: 1215 - if (!mesh_plink_free_count(sdata) || 1216 - (sta->llid != llid || sta->plid != plid)) 1217 - event = CNF_IGNR; 1218 - else 1219 - event = CNF_ACPT; 1220 - break; 1221 - case WLAN_SP_MESH_PEERING_CLOSE: 1222 - if (sta->plink_state == NL80211_PLINK_ESTAB) 1223 - /* Do not check for llid or plid. This does not 1224 - * follow the standard but since multiple plinks 1225 - * per sta are not supported, it is necessary in 1226 - * order to avoid a livelock when MP A sees an 1227 - * establish peer link to MP B but MP B does not 1228 - * see it. This can be caused by a timeout in 1229 - * B's peer link establishment or B beign 1230 - * restarted. 1231 - */ 1232 - event = CLS_ACPT; 1233 - else if (sta->plid != plid) 1234 - event = CLS_IGNR; 1235 - else if (ie_len == 7 && sta->llid != llid) 1236 - event = CLS_IGNR; 1237 - else 1238 - event = CLS_ACPT; 1239 - break; 1240 - default: 1241 - mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n"); 1242 - rcu_read_unlock(); 1243 - return; 1244 - } 1245 - } 1246 - 1247 - if (event == OPN_ACPT) { 1248 - rcu_read_unlock(); 1249 - /* allocate sta entry if necessary and update info */ 1250 - sta = mesh_sta_info_get(sdata, mgmt->sa, &elems); 1251 - if (!sta) { 1252 - mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); 1253 - rcu_read_unlock(); 1254 - return; 1255 - } 1256 - } 1257 - 1258 - mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa, 1259 - mplstates[sta->plink_state], mplevents[event]); 1260 - reason = 0; 1261 - spin_lock_bh(&sta->lock); 1262 - switch (sta->plink_state) { 1263 - /* spin_unlock as soon as state is updated at each case */ 1264 - case NL80211_PLINK_LISTEN: 1265 - switch (event) { 1266 - case CLS_ACPT: 1267 - mesh_plink_fsm_restart(sta); 1268 - spin_unlock_bh(&sta->lock); 1269 - break; 1270 - case OPN_ACPT: 1271 - sta->plink_state = NL80211_PLINK_OPN_RCVD; 1272 - sta->plid = plid; 1273 - get_random_bytes(&llid, 2); 1274 - sta->llid = llid; 1275 - mesh_plink_timer_set(sta, 1276 - mshcfg->dot11MeshRetryTimeout); 1277 - 1278 - /* set the non-peer mode to active during peering */ 1279 - changed |= ieee80211_mps_local_status_update(sdata); 1280 - 1281 - spin_unlock_bh(&sta->lock); 1282 - mesh_plink_frame_tx(sdata, 1283 - WLAN_SP_MESH_PEERING_OPEN, 1284 - sta->sta.addr, llid, 0, 0); 1285 - mesh_plink_frame_tx(sdata, 1286 - WLAN_SP_MESH_PEERING_CONFIRM, 1287 - sta->sta.addr, llid, plid, 0); 1288 - break; 1289 - default: 1290 - spin_unlock_bh(&sta->lock); 1291 - break; 1292 - } 1293 - break; 1294 - 1295 - case NL80211_PLINK_OPN_SNT: 1296 - switch (event) { 1297 - case OPN_RJCT: 1298 - case CNF_RJCT: 1299 - reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 1300 - case CLS_ACPT: 1301 - if (!reason) 1302 - reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 1303 - sta->reason = reason; 1304 - sta->plink_state = NL80211_PLINK_HOLDING; 1305 - if (!mod_plink_timer(sta, 1306 - mshcfg->dot11MeshHoldingTimeout)) 1307 - sta->ignore_plink_timer = true; 1308 - 1309 - llid = sta->llid; 1310 - spin_unlock_bh(&sta->lock); 1311 - mesh_plink_frame_tx(sdata, 1312 - WLAN_SP_MESH_PEERING_CLOSE, 1313 - sta->sta.addr, llid, plid, reason); 1314 - break; 1315 - case OPN_ACPT: 1316 - /* retry timer is left untouched */ 1317 - sta->plink_state = NL80211_PLINK_OPN_RCVD; 1318 - sta->plid = plid; 1319 - llid = sta->llid; 1320 - spin_unlock_bh(&sta->lock); 1321 - mesh_plink_frame_tx(sdata, 1322 - WLAN_SP_MESH_PEERING_CONFIRM, 1323 - sta->sta.addr, llid, plid, 0); 1324 - break; 1325 - case CNF_ACPT: 1326 - sta->plink_state = NL80211_PLINK_CNF_RCVD; 1327 - if (!mod_plink_timer(sta, 1328 - mshcfg->dot11MeshConfirmTimeout)) 1329 - sta->ignore_plink_timer = true; 1330 - 1331 - spin_unlock_bh(&sta->lock); 1332 - break; 1333 - default: 1334 - spin_unlock_bh(&sta->lock); 1335 - break; 1336 - } 1337 - break; 1338 - 1339 - case NL80211_PLINK_OPN_RCVD: 1340 - switch (event) { 1341 - case OPN_RJCT: 1342 - case CNF_RJCT: 1343 - reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 1344 - case CLS_ACPT: 1345 - if (!reason) 1346 - reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 1347 - sta->reason = reason; 1348 - sta->plink_state = NL80211_PLINK_HOLDING; 1349 - if (!mod_plink_timer(sta, 1350 - mshcfg->dot11MeshHoldingTimeout)) 1351 - sta->ignore_plink_timer = true; 1352 - 1353 - llid = sta->llid; 1354 - spin_unlock_bh(&sta->lock); 1355 - mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1356 - sta->sta.addr, llid, plid, reason); 1357 - break; 1358 - case OPN_ACPT: 1359 - llid = sta->llid; 1360 - spin_unlock_bh(&sta->lock); 1361 - mesh_plink_frame_tx(sdata, 1362 - WLAN_SP_MESH_PEERING_CONFIRM, 1363 - sta->sta.addr, llid, plid, 0); 1364 - break; 1365 - case CNF_ACPT: 1366 - del_timer(&sta->plink_timer); 1367 - sta->plink_state = NL80211_PLINK_ESTAB; 1368 - spin_unlock_bh(&sta->lock); 1369 - changed |= mesh_plink_inc_estab_count(sdata); 1370 - changed |= mesh_set_ht_prot_mode(sdata); 1371 - changed |= mesh_set_short_slot_time(sdata); 1372 - mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 1373 - sta->sta.addr); 1374 - ieee80211_mps_sta_status_update(sta); 1375 - changed |= ieee80211_mps_set_sta_local_pm(sta, 1376 - mshcfg->power_mode); 1377 - break; 1378 - default: 1379 - spin_unlock_bh(&sta->lock); 1380 - break; 1381 - } 1382 - break; 1383 - 1384 - case NL80211_PLINK_CNF_RCVD: 1385 - switch (event) { 1386 - case OPN_RJCT: 1387 - case CNF_RJCT: 1388 - reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 1389 - case CLS_ACPT: 1390 - if (!reason) 1391 - reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 1392 - sta->reason = reason; 1393 - sta->plink_state = NL80211_PLINK_HOLDING; 1394 - if (!mod_plink_timer(sta, 1395 - mshcfg->dot11MeshHoldingTimeout)) 1396 - sta->ignore_plink_timer = true; 1397 - 1398 - llid = sta->llid; 1399 - spin_unlock_bh(&sta->lock); 1400 - mesh_plink_frame_tx(sdata, 1401 - WLAN_SP_MESH_PEERING_CLOSE, 1402 - sta->sta.addr, llid, plid, reason); 1403 - break; 1404 - case OPN_ACPT: 1405 - del_timer(&sta->plink_timer); 1406 - sta->plink_state = NL80211_PLINK_ESTAB; 1407 - spin_unlock_bh(&sta->lock); 1408 - changed |= mesh_plink_inc_estab_count(sdata); 1409 - changed |= mesh_set_ht_prot_mode(sdata); 1410 - changed |= mesh_set_short_slot_time(sdata); 1411 - mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", 1412 - sta->sta.addr); 1413 - mesh_plink_frame_tx(sdata, 1414 - WLAN_SP_MESH_PEERING_CONFIRM, 1415 - sta->sta.addr, llid, plid, 0); 1416 - ieee80211_mps_sta_status_update(sta); 1417 - changed |= ieee80211_mps_set_sta_local_pm(sta, 1418 - mshcfg->power_mode); 1419 - break; 1420 - default: 1421 - spin_unlock_bh(&sta->lock); 1422 - break; 1423 - } 1424 - break; 1425 - 1426 - case NL80211_PLINK_ESTAB: 1427 - switch (event) { 1428 - case CLS_ACPT: 1429 - reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 1430 - sta->reason = reason; 1431 - changed |= __mesh_plink_deactivate(sta); 1432 - sta->plink_state = NL80211_PLINK_HOLDING; 1433 - llid = sta->llid; 1434 - mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 1435 - spin_unlock_bh(&sta->lock); 1436 - changed |= mesh_set_ht_prot_mode(sdata); 1437 - changed |= mesh_set_short_slot_time(sdata); 1438 - mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1439 - sta->sta.addr, llid, plid, reason); 1440 - break; 1441 - case OPN_ACPT: 1442 - llid = sta->llid; 1443 - spin_unlock_bh(&sta->lock); 1444 - mesh_plink_frame_tx(sdata, 1445 - WLAN_SP_MESH_PEERING_CONFIRM, 1446 - sta->sta.addr, llid, plid, 0); 1447 - break; 1448 - default: 1449 - spin_unlock_bh(&sta->lock); 1450 - break; 1451 - } 1452 - break; 1453 - case NL80211_PLINK_HOLDING: 1454 - switch (event) { 1455 - case CLS_ACPT: 1456 - if (del_timer(&sta->plink_timer)) 1457 - sta->ignore_plink_timer = 1; 1458 - mesh_plink_fsm_restart(sta); 1459 - spin_unlock_bh(&sta->lock); 1460 - break; 1461 - case OPN_ACPT: 1462 - case CNF_ACPT: 1463 - case OPN_RJCT: 1464 - case CNF_RJCT: 1465 - llid = sta->llid; 1466 - reason = sta->reason; 1467 - spin_unlock_bh(&sta->lock); 1468 - mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 1469 - sta->sta.addr, llid, plid, reason); 1470 - break; 1471 - default: 1472 - spin_unlock_bh(&sta->lock); 1473 - } 1474 - break; 1475 - default: 1476 - /* should not get here, PLINK_BLOCKED is dealt with at the 1477 - * beginning of the function 1478 - */ 1479 - spin_unlock_bh(&sta->lock); 1480 - break; 1481 - } 1482 - 1483 - rcu_read_unlock(); 1484 - 1485 - if (changed) 1486 - ieee80211_mbss_info_change_notify(sdata, changed); 698 + mesh_process_plink_frame(sdata, mgmt, &elems); 1487 699 }
+1 -2
net/mac80211/mesh_ps.c
··· 576 576 int ac, buffer_local = 0; 577 577 bool has_buffered = false; 578 578 579 - /* TIM map only for LLID <= IEEE80211_MAX_AID */ 580 579 if (sta->plink_state == NL80211_PLINK_ESTAB) 581 580 has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len, 582 - le16_to_cpu(sta->llid) % IEEE80211_MAX_AID); 581 + sta->llid); 583 582 584 583 if (has_buffered) 585 584 mps_dbg(sta->sdata, "%pM indicates buffered frames\n",
+14 -14
net/mac80211/mesh_sync.c
··· 92 92 if (stype != IEEE80211_STYPE_BEACON) 93 93 return; 94 94 95 - /* The current tsf is a first approximation for the timestamp 96 - * for the received beacon. Further down we try to get a 97 - * better value from the rx_status->mactime field if 98 - * available. Also we have to call drv_get_tsf() before 99 - * entering the rcu-read section.*/ 100 - t_r = drv_get_tsf(local, sdata); 95 + /* 96 + * Get time when timestamp field was received. If we don't 97 + * have rx timestamps, then use current tsf as an approximation. 98 + * drv_get_tsf() must be called before entering the rcu-read 99 + * section. 100 + */ 101 + if (ieee80211_have_rx_timestamp(rx_status)) 102 + t_r = ieee80211_calculate_rx_timestamp(local, rx_status, 103 + 24 + 12 + 104 + elems->total_len + 105 + FCS_LEN, 106 + 24); 107 + else 108 + t_r = drv_get_tsf(local, sdata); 101 109 102 110 rcu_read_lock(); 103 111 sta = sta_info_get(sdata, mgmt->sa); ··· 124 116 sta->sta.addr); 125 117 goto no_sync; 126 118 } 127 - 128 - if (ieee80211_have_rx_timestamp(rx_status)) 129 - /* time when timestamp field was received */ 130 - t_r = ieee80211_calculate_rx_timestamp(local, rx_status, 131 - 24 + 12 + 132 - elems->total_len + 133 - FCS_LEN, 134 - 24); 135 119 136 120 /* Timing offset calculation (see 13.13.2.2.2) */ 137 121 t_t = le64_to_cpu(mgmt->u.beacon.timestamp);
+25 -18
net/mac80211/mlme.c
··· 330 330 if (WARN_ON_ONCE(!sta)) 331 331 return -EINVAL; 332 332 333 + /* 334 + * if bss configuration changed store the new one - 335 + * this may be applicable even if channel is identical 336 + */ 337 + ht_opmode = le16_to_cpu(ht_oper->operation_mode); 338 + if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) { 339 + *changed |= BSS_CHANGED_HT; 340 + sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 341 + } 342 + 333 343 chan = sdata->vif.bss_conf.chandef.chan; 334 344 sband = local->hw.wiphy->bands[chan->band]; 335 345 ··· 424 414 sta->sta.bandwidth = new_sta_bw; 425 415 rate_control_rate_update(local, sband, sta, 426 416 IEEE80211_RC_BW_CHANGED); 427 - } 428 - 429 - ht_opmode = le16_to_cpu(ht_oper->operation_mode); 430 - 431 - /* if bss configuration changed store the new one */ 432 - if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) { 433 - *changed |= BSS_CHANGED_HT; 434 - sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 435 417 } 436 418 437 419 return 0; ··· 716 714 } 717 715 718 716 /* if present, add any custom IEs that go before HT */ 719 - if (assoc_data->ie_len && assoc_data->ie) { 717 + if (assoc_data->ie_len) { 720 718 static const u8 before_ht[] = { 721 719 WLAN_EID_SSID, 722 720 WLAN_EID_SUPP_RATES, ··· 750 748 &assoc_data->ap_vht_cap); 751 749 752 750 /* if present, add any custom non-vendor IEs that go after HT */ 753 - if (assoc_data->ie_len && assoc_data->ie) { 751 + if (assoc_data->ie_len) { 754 752 noffset = ieee80211_ie_split_vendor(assoc_data->ie, 755 753 assoc_data->ie_len, 756 754 offset); ··· 781 779 } 782 780 783 781 /* add any remaining custom (i.e. vendor specific here) IEs */ 784 - if (assoc_data->ie_len && assoc_data->ie) { 782 + if (assoc_data->ie_len) { 785 783 noffset = assoc_data->ie_len; 786 784 pos = skb_put(skb, noffset - offset); 787 785 memcpy(pos, assoc_data->ie + offset, noffset - offset); ··· 888 886 if (!ifmgd->associated) 889 887 goto out; 890 888 891 - ret = ieee80211_vif_change_channel(sdata, &local->csa_chandef, 892 - &changed); 889 + ret = ieee80211_vif_change_channel(sdata, &changed); 893 890 if (ret) { 894 891 sdata_info(sdata, 895 892 "vif channel switch failed, disconnecting\n"); ··· 898 897 } 899 898 900 899 if (!local->use_chanctx) { 901 - local->_oper_chandef = local->csa_chandef; 900 + local->_oper_chandef = sdata->csa_chandef; 902 901 /* Call "hw_config" only if doing sw channel switch. 903 902 * Otherwise update the channel directly 904 903 */ ··· 909 908 } 910 909 911 910 /* XXX: shouldn't really modify cfg80211-owned data! */ 912 - ifmgd->associated->channel = local->csa_chandef.chan; 911 + ifmgd->associated->channel = sdata->csa_chandef.chan; 913 912 914 913 /* XXX: wait for a beacon first? */ 915 914 ieee80211_wake_queues_by_reason(&local->hw, ··· 1036 1035 } 1037 1036 mutex_unlock(&local->chanctx_mtx); 1038 1037 1039 - local->csa_chandef = csa_ie.chandef; 1038 + sdata->csa_chandef = csa_ie.chandef; 1040 1039 1041 1040 if (csa_ie.mode) 1042 1041 ieee80211_stop_queues_by_reason(&local->hw, ··· 1399 1398 struct ieee80211_sub_if_data *sdata = 1400 1399 container_of(delayed_work, struct ieee80211_sub_if_data, 1401 1400 dfs_cac_timer_work); 1401 + struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef; 1402 1402 1403 1403 ieee80211_vif_release_channel(sdata); 1404 - 1405 - cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); 1404 + cfg80211_cac_event(sdata->dev, &chandef, 1405 + NL80211_RADAR_CAC_FINISHED, 1406 + GFP_KERNEL); 1406 1407 } 1407 1408 1408 1409 /* MLME */ ··· 1748 1745 1749 1746 ifmgd->flags = 0; 1750 1747 ieee80211_vif_release_channel(sdata); 1748 + 1749 + sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1751 1750 } 1752 1751 1753 1752 void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, ··· 4196 4191 4197 4192 sdata->control_port_protocol = req->crypto.control_port_ethertype; 4198 4193 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; 4194 + sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto, 4195 + sdata->vif.type); 4199 4196 4200 4197 /* kick off associate process */ 4201 4198
+2 -2
net/mac80211/rate.h
··· 54 54 struct ieee80211_supported_band *sband; 55 55 struct ieee80211_chanctx_conf *chanctx_conf; 56 56 57 + ieee80211_sta_set_rx_nss(sta); 58 + 57 59 if (!ref) 58 60 return; 59 61 ··· 68 66 } 69 67 70 68 sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band]; 71 - 72 - ieee80211_sta_set_rx_nss(sta); 73 69 74 70 ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista, 75 71 priv_sta);
+1 -2
net/mac80211/rc80211_minstrel.c
··· 422 422 memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates); 423 423 424 424 for (col = 0; col < SAMPLE_COLUMNS; col++) { 425 + prandom_bytes(rnd, sizeof(rnd)); 425 426 for (i = 0; i < mi->n_rates; i++) { 426 - get_random_bytes(rnd, sizeof(rnd)); 427 427 new_idx = (i + rnd[i & 7]) % mi->n_rates; 428 - 429 428 while (SAMPLE_TBL(mi, new_idx, col) != 0xff) 430 429 new_idx = (new_idx + 1) % mi->n_rates; 431 430
+13 -11
net/mac80211/rc80211_minstrel_ht.c
··· 135 135 static int 136 136 minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) 137 137 { 138 - return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, 138 + return GROUP_IDX((rate->idx / 8) + 1, 139 139 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), 140 140 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); 141 141 } ··· 148 148 149 149 if (rate->flags & IEEE80211_TX_RC_MCS) { 150 150 group = minstrel_ht_get_group_idx(rate); 151 - idx = rate->idx % MCS_GROUP_RATES; 151 + idx = rate->idx % 8; 152 152 } else { 153 153 group = MINSTREL_CCK_GROUP; 154 154 ··· 637 637 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 638 638 flags = 0; 639 639 } else { 640 - idx = index % MCS_GROUP_RATES + 641 - (group->streams - 1) * MCS_GROUP_RATES; 640 + idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; 642 641 flags = IEEE80211_TX_RC_MCS | group->flags; 643 642 } 644 643 ··· 701 702 if (!mi->sample_tries) 702 703 return -1; 703 704 704 - mg = &mi->groups[mi->sample_group]; 705 - sample_idx = sample_table[mg->column][mg->index]; 706 - mr = &mg->rates[sample_idx]; 707 705 sample_group = mi->sample_group; 708 - sample_idx += sample_group * MCS_GROUP_RATES; 706 + mg = &mi->groups[sample_group]; 707 + sample_idx = sample_table[mg->column][mg->index]; 709 708 minstrel_next_sample_idx(mi); 709 + 710 + if (!(mg->supported & BIT(sample_idx))) 711 + return -1; 712 + 713 + mr = &mg->rates[sample_idx]; 714 + sample_idx += sample_group * MCS_GROUP_RATES; 710 715 711 716 /* 712 717 * Sampling might add some overhead (RTS, no aggregation) ··· 821 818 } 822 819 823 820 rate->idx = sample_idx % MCS_GROUP_RATES + 824 - (sample_group->streams - 1) * MCS_GROUP_RATES; 821 + (sample_group->streams - 1) * 8; 825 822 rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; 826 823 } 827 824 ··· 1056 1053 1057 1054 memset(sample_table, 0xff, sizeof(sample_table)); 1058 1055 for (col = 0; col < SAMPLE_COLUMNS; col++) { 1056 + prandom_bytes(rnd, sizeof(rnd)); 1059 1057 for (i = 0; i < MCS_GROUP_RATES; i++) { 1060 - get_random_bytes(rnd, sizeof(rnd)); 1061 1058 new_idx = (i + rnd[i]) % MCS_GROUP_RATES; 1062 - 1063 1059 while (sample_table[col][new_idx] != 0xff) 1064 1060 new_idx = (new_idx + 1) % MCS_GROUP_RATES; 1065 1061
+1 -2
net/mac80211/rc80211_minstrel_ht_debugfs.c
··· 54 54 int r = bitrates[j % 4]; 55 55 p += sprintf(p, " %2u.%1uM", r / 10, r % 10); 56 56 } else { 57 - p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 58 - MCS_GROUP_RATES + j); 57 + p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); 59 58 } 60 59 61 60 tp = mr->cur_tp / 10;
+58 -32
net/mac80211/rx.c
··· 638 638 return le16_to_cpu(mmie->key_id); 639 639 } 640 640 641 + static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs, 642 + struct sk_buff *skb) 643 + { 644 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 645 + __le16 fc; 646 + int hdrlen; 647 + u8 keyid; 648 + 649 + fc = hdr->frame_control; 650 + hdrlen = ieee80211_hdrlen(fc); 651 + 652 + if (skb->len < hdrlen + cs->hdr_len) 653 + return -EINVAL; 654 + 655 + skb_copy_bits(skb, hdrlen + cs->key_idx_off, &keyid, 1); 656 + keyid &= cs->key_idx_mask; 657 + keyid >>= cs->key_idx_shift; 658 + 659 + return keyid; 660 + } 661 + 641 662 static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) 642 663 { 643 664 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; ··· 750 729 lockdep_assert_held(&tid_agg_rx->reorder_lock); 751 730 752 731 while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) { 753 - index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 754 - tid_agg_rx->ssn) % 755 - tid_agg_rx->buf_size; 732 + index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; 756 733 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, 757 734 frames); 758 735 } ··· 776 757 lockdep_assert_held(&tid_agg_rx->reorder_lock); 777 758 778 759 /* release the buffer until next missing frame */ 779 - index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 780 - tid_agg_rx->ssn) % tid_agg_rx->buf_size; 760 + index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; 781 761 if (!tid_agg_rx->reorder_buf[index] && 782 762 tid_agg_rx->stored_mpdu_num) { 783 763 /* ··· 811 793 } else while (tid_agg_rx->reorder_buf[index]) { 812 794 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, 813 795 frames); 814 - index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 815 - tid_agg_rx->ssn) % 816 - tid_agg_rx->buf_size; 796 + index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; 817 797 } 818 798 819 799 if (tid_agg_rx->stored_mpdu_num) { 820 - j = index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 821 - tid_agg_rx->ssn) % 822 - tid_agg_rx->buf_size; 800 + j = index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; 823 801 824 802 for (; j != (index - 1) % tid_agg_rx->buf_size; 825 803 j = (j + 1) % tid_agg_rx->buf_size) { ··· 875 861 876 862 /* Now the new frame is always in the range of the reordering buffer */ 877 863 878 - index = ieee80211_sn_sub(mpdu_seq_num, 879 - tid_agg_rx->ssn) % tid_agg_rx->buf_size; 864 + index = mpdu_seq_num % tid_agg_rx->buf_size; 880 865 881 866 /* check if we already stored this frame */ 882 867 if (tid_agg_rx->reorder_buf[index]) { ··· 1382 1369 struct ieee80211_key *sta_ptk = NULL; 1383 1370 int mmie_keyidx = -1; 1384 1371 __le16 fc; 1372 + const struct ieee80211_cipher_scheme *cs = NULL; 1385 1373 1386 1374 /* 1387 1375 * Key selection 101 ··· 1420 1406 1421 1407 /* start without a key */ 1422 1408 rx->key = NULL; 1423 - 1424 - if (rx->sta) 1425 - sta_ptk = rcu_dereference(rx->sta->ptk); 1426 - 1427 1409 fc = hdr->frame_control; 1410 + 1411 + if (rx->sta) { 1412 + int keyid = rx->sta->ptk_idx; 1413 + 1414 + if (ieee80211_has_protected(fc) && rx->sta->cipher_scheme) { 1415 + cs = rx->sta->cipher_scheme; 1416 + keyid = iwl80211_get_cs_keyid(cs, rx->skb); 1417 + if (unlikely(keyid < 0)) 1418 + return RX_DROP_UNUSABLE; 1419 + } 1420 + sta_ptk = rcu_dereference(rx->sta->ptk[keyid]); 1421 + } 1428 1422 1429 1423 if (!ieee80211_has_protected(fc)) 1430 1424 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); ··· 1494 1472 return RX_CONTINUE; 1495 1473 } else { 1496 1474 u8 keyid; 1475 + 1497 1476 /* 1498 1477 * The device doesn't give us the IV so we won't be 1499 1478 * able to look up the key. That's ok though, we ··· 1510 1487 1511 1488 hdrlen = ieee80211_hdrlen(fc); 1512 1489 1513 - if (rx->skb->len < 8 + hdrlen) 1514 - return RX_DROP_UNUSABLE; /* TODO: count this? */ 1490 + if (cs) { 1491 + keyidx = iwl80211_get_cs_keyid(cs, rx->skb); 1515 1492 1516 - /* 1517 - * no need to call ieee80211_wep_get_keyidx, 1518 - * it verifies a bunch of things we've done already 1519 - */ 1520 - skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); 1521 - keyidx = keyid >> 6; 1493 + if (unlikely(keyidx < 0)) 1494 + return RX_DROP_UNUSABLE; 1495 + } else { 1496 + if (rx->skb->len < 8 + hdrlen) 1497 + return RX_DROP_UNUSABLE; /* TODO: count this? */ 1498 + /* 1499 + * no need to call ieee80211_wep_get_keyidx, 1500 + * it verifies a bunch of things we've done already 1501 + */ 1502 + skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); 1503 + keyidx = keyid >> 6; 1504 + } 1522 1505 1523 1506 /* check per-station GTK first, if multicast packet */ 1524 1507 if (is_multicast_ether_addr(hdr->addr1) && rx->sta) ··· 1572 1543 result = ieee80211_crypto_aes_cmac_decrypt(rx); 1573 1544 break; 1574 1545 default: 1575 - /* 1576 - * We can reach here only with HW-only algorithms 1577 - * but why didn't it decrypt the frame?! 1578 - */ 1579 - return RX_DROP_UNUSABLE; 1546 + result = ieee80211_crypto_hw_decrypt(rx); 1580 1547 } 1581 1548 1582 1549 /* the hdr variable is invalid after the decrypt handlers */ ··· 2082 2057 struct ieee80211_sub_if_data *sdata = rx->sdata; 2083 2058 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2084 2059 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 2085 - __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD); 2086 2060 u16 q, hdrlen; 2087 2061 2088 2062 hdr = (struct ieee80211_hdr *) skb->data; ··· 2189 2165 } else { 2190 2166 /* unable to resolve next hop */ 2191 2167 mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, 2192 - fwd_hdr->addr3, 0, reason, fwd_hdr->addr2); 2168 + fwd_hdr->addr3, 0, 2169 + WLAN_REASON_MESH_PATH_NOFORWARD, 2170 + fwd_hdr->addr2); 2193 2171 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); 2194 2172 kfree_skb(fwd_skb); 2195 2173 return RX_DROP_MONITOR;
+5 -5
net/mac80211/scan.c
··· 526 526 ieee80211_hw_config(local, 0); 527 527 528 528 if ((req->channels[0]->flags & 529 - IEEE80211_CHAN_PASSIVE_SCAN) || 529 + IEEE80211_CHAN_NO_IR) || 530 530 !local->scan_req->n_ssids) { 531 531 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; 532 532 } else { ··· 572 572 * TODO: channel switching also consumes quite some time, 573 573 * add that delay as well to get a better estimation 574 574 */ 575 - if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 575 + if (chan->flags & IEEE80211_CHAN_NO_IR) 576 576 return IEEE80211_PASSIVE_CHANNEL_TIME; 577 577 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; 578 578 } ··· 696 696 * 697 697 * In any case, it is not necessary for a passive scan. 698 698 */ 699 - if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || 699 + if (chan->flags & IEEE80211_CHAN_NO_IR || 700 700 !local->scan_req->n_ssids) { 701 701 *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; 702 702 local->next_scan_state = SCAN_DECISION; ··· 881 881 struct ieee80211_channel *tmp_ch = 882 882 &local->hw.wiphy->bands[band]->channels[i]; 883 883 884 - if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS | 884 + if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR | 885 885 IEEE80211_CHAN_DISABLED)) 886 886 continue; 887 887 ··· 895 895 896 896 local->int_scan_req->n_channels = n_ch; 897 897 } else { 898 - if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS | 898 + if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IR | 899 899 IEEE80211_CHAN_DISABLED))) 900 900 goto unlock; 901 901
+38 -2
net/mac80211/sta_info.c
··· 266 266 */ 267 267 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) 268 268 { 269 + int i; 270 + 269 271 if (sta->rate_ctrl) 270 272 rate_control_free_sta(sta); 273 + 274 + if (sta->tx_lat) { 275 + for (i = 0; i < IEEE80211_NUM_TIDS; i++) 276 + kfree(sta->tx_lat[i].bins); 277 + kfree(sta->tx_lat); 278 + } 271 279 272 280 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); 273 281 ··· 341 333 struct ieee80211_local *local = sdata->local; 342 334 struct sta_info *sta; 343 335 struct timespec uptime; 336 + struct ieee80211_tx_latency_bin_ranges *tx_latency; 344 337 int i; 345 338 346 339 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); ··· 418 409 WARN_ON(1); 419 410 } 420 411 } 412 + 413 + rcu_read_lock(); 414 + 415 + tx_latency = rcu_dereference(local->tx_latency); 416 + /* init stations Tx latency statistics && TID bins */ 417 + if (tx_latency) 418 + sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS * 419 + sizeof(struct ieee80211_tx_latency_stat), 420 + GFP_ATOMIC); 421 + 422 + /* 423 + * if Tx latency and bins are enabled and the previous allocation 424 + * succeeded 425 + */ 426 + if (tx_latency && tx_latency->n_ranges && sta->tx_lat) 427 + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 428 + /* size of bins is size of the ranges +1 */ 429 + sta->tx_lat[i].bin_count = 430 + tx_latency->n_ranges + 1; 431 + sta->tx_lat[i].bins = kcalloc(sta->tx_lat[i].bin_count, 432 + sizeof(u32), 433 + GFP_ATOMIC); 434 + } 435 + 436 + rcu_read_unlock(); 421 437 422 438 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); 423 439 ··· 541 507 542 508 set_sta_flag(sta, WLAN_STA_INSERTED); 543 509 510 + ieee80211_recalc_min_chandef(sdata); 544 511 ieee80211_sta_debugfs_add(sta); 545 512 rate_control_add_sta_debugfs(sta); 546 513 ··· 665 630 #ifdef CONFIG_MAC80211_MESH 666 631 } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) { 667 632 ps = &sta->sdata->u.mesh.ps; 668 - /* TIM map only for PLID <= IEEE80211_MAX_AID */ 669 - id = le16_to_cpu(sta->plid) % IEEE80211_MAX_AID; 633 + /* TIM map only for 1 <= PLID <= IEEE80211_MAX_AID */ 634 + id = sta->plid % (IEEE80211_MAX_AID + 1); 670 635 #endif 671 636 } else { 672 637 return; ··· 904 869 905 870 rate_control_remove_sta_debugfs(sta); 906 871 ieee80211_sta_debugfs_remove(sta); 872 + ieee80211_recalc_min_chandef(sdata); 907 873 908 874 call_rcu(&sta->rcu_head, free_sta_rcu); 909 875
+33 -5
net/mac80211/sta_info.h
··· 220 220 u8 dialog_token_allocator; 221 221 }; 222 222 223 + /* 224 + * struct ieee80211_tx_latency_stat - Tx latency statistics 225 + * 226 + * Measures TX latency and jitter for a station per TID. 227 + * 228 + * @max: worst case latency 229 + * @sum: sum of all latencies 230 + * @counter: amount of Tx frames sent from interface 231 + * @bins: each bin counts how many frames transmitted within a certain 232 + * latency range. when disabled it is NULL. 233 + * @bin_count: amount of bins. 234 + */ 235 + struct ieee80211_tx_latency_stat { 236 + u32 max; 237 + u32 sum; 238 + u32 counter; 239 + u32 *bins; 240 + u32 bin_count; 241 + }; 223 242 224 243 /** 225 244 * struct sta_info - STA information ··· 250 231 * @hnext: hash table linked list pointer 251 232 * @local: pointer to the global information 252 233 * @sdata: virtual interface this station belongs to 253 - * @ptk: peer key negotiated with this station, if any 234 + * @ptk: peer keys negotiated with this station, if any 235 + * @ptk_idx: last installed peer key index 254 236 * @gtk: group keys negotiated with this station, if any 237 + * @gtk_idx: last installed group key index 255 238 * @rate_ctrl: rate control algorithm reference 256 239 * @rate_ctrl_priv: rate control private per-STA pointer 257 240 * @last_tx_rate: rate used for last transmit, to report to userspace as ··· 295 274 * @tid_seq: per-TID sequence numbers for sending to this STA 296 275 * @ampdu_mlme: A-MPDU state machine state 297 276 * @timer_to_tid: identity mapping to ID timers 277 + * @tx_lat: Tx latency statistics 298 278 * @llid: Local link ID 299 279 * @plid: Peer link ID 300 280 * @reason: Cancel reason on PLINK_HOLDING state ··· 325 303 * @chain_signal_avg: signal average (per chain) 326 304 * @known_smps_mode: the smps_mode the client thinks we are in. Relevant for 327 305 * AP only. 306 + * @cipher_scheme: optional cipher scheme for this station 328 307 */ 329 308 struct sta_info { 330 309 /* General information, mostly static */ ··· 335 312 struct ieee80211_local *local; 336 313 struct ieee80211_sub_if_data *sdata; 337 314 struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 338 - struct ieee80211_key __rcu *ptk; 315 + struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS]; 316 + u8 gtk_idx; 317 + u8 ptk_idx; 339 318 struct rate_control_ref *rate_ctrl; 340 319 void *rate_ctrl_priv; 341 320 spinlock_t lock; ··· 405 380 struct sta_ampdu_mlme ampdu_mlme; 406 381 u8 timer_to_tid[IEEE80211_NUM_TIDS]; 407 382 383 + struct ieee80211_tx_latency_stat *tx_lat; 384 + 408 385 #ifdef CONFIG_MAC80211_MESH 409 386 /* 410 387 * Mesh peer link attributes 411 388 * TODO: move to a sub-structure that is referenced with pointer? 412 389 */ 413 - __le16 llid; 414 - __le16 plid; 415 - __le16 reason; 390 + u16 llid; 391 + u16 plid; 392 + u16 reason; 416 393 u8 plink_retries; 417 394 bool ignore_plink_timer; 418 395 enum nl80211_plink_state plink_state; ··· 441 414 unsigned int beacon_loss_count; 442 415 443 416 enum ieee80211_smps_mode known_smps_mode; 417 + const struct ieee80211_cipher_scheme *cipher_scheme; 444 418 445 419 /* keep last! */ 446 420 struct ieee80211_sta sta;
+78
net/mac80211/status.c
··· 11 11 12 12 #include <linux/export.h> 13 13 #include <linux/etherdevice.h> 14 + #include <linux/time.h> 14 15 #include <net/mac80211.h> 15 16 #include <asm/unaligned.h> 16 17 #include "ieee80211_i.h" ··· 464 463 } 465 464 466 465 /* 466 + * Measure Tx frame completion and removal time for Tx latency statistics 467 + * calculation. A single Tx frame latency should be measured from when it 468 + * is entering the Kernel until we receive Tx complete confirmation indication 469 + * and remove the skb. 470 + */ 471 + static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local, 472 + struct sk_buff *skb, 473 + struct sta_info *sta, 474 + struct ieee80211_hdr *hdr) 475 + { 476 + ktime_t skb_dprt; 477 + struct timespec dprt_time; 478 + u32 msrmnt; 479 + u16 tid; 480 + u8 *qc; 481 + int i, bin_range_count, bin_count; 482 + u32 *bin_ranges; 483 + __le16 fc; 484 + struct ieee80211_tx_latency_stat *tx_lat; 485 + struct ieee80211_tx_latency_bin_ranges *tx_latency; 486 + ktime_t skb_arv = skb->tstamp; 487 + 488 + tx_latency = rcu_dereference(local->tx_latency); 489 + 490 + /* assert Tx latency stats are enabled & frame arrived when enabled */ 491 + if (!tx_latency || !ktime_to_ns(skb_arv)) 492 + return; 493 + 494 + fc = hdr->frame_control; 495 + 496 + if (!ieee80211_is_data(fc)) /* make sure it is a data frame */ 497 + return; 498 + 499 + /* get frame tid */ 500 + if (ieee80211_is_data_qos(hdr->frame_control)) { 501 + qc = ieee80211_get_qos_ctl(hdr); 502 + tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 503 + } else { 504 + tid = 0; 505 + } 506 + 507 + tx_lat = &sta->tx_lat[tid]; 508 + 509 + ktime_get_ts(&dprt_time); /* time stamp completion time */ 510 + skb_dprt = ktime_set(dprt_time.tv_sec, dprt_time.tv_nsec); 511 + msrmnt = ktime_to_ms(ktime_sub(skb_dprt, skb_arv)); 512 + 513 + if (tx_lat->max < msrmnt) /* update stats */ 514 + tx_lat->max = msrmnt; 515 + tx_lat->counter++; 516 + tx_lat->sum += msrmnt; 517 + 518 + if (!tx_lat->bins) /* bins not activated */ 519 + return; 520 + 521 + /* count how many Tx frames transmitted with the appropriate latency */ 522 + bin_range_count = tx_latency->n_ranges; 523 + bin_ranges = tx_latency->ranges; 524 + bin_count = tx_lat->bin_count; 525 + 526 + for (i = 0; i < bin_range_count; i++) { 527 + if (msrmnt <= bin_ranges[i]) { 528 + tx_lat->bins[i]++; 529 + break; 530 + } 531 + } 532 + if (i == bin_range_count) /* msrmnt is bigger than the biggest range */ 533 + tx_lat->bins[i]++; 534 + } 535 + 536 + /* 467 537 * Use a static threshold for now, best value to be determined 468 538 * by testing ... 469 539 * Should it depend on: ··· 692 620 693 621 if (acked) 694 622 sta->last_ack_signal = info->status.ack_signal; 623 + 624 + /* 625 + * Measure frame removal for tx latency 626 + * statistics calculation 627 + */ 628 + ieee80211_tx_latency_end_msrmnt(local, skb, sta, hdr); 695 629 } 696 630 697 631 rcu_read_unlock();
+19 -2
net/mac80211/trace.h
··· 41 41 #define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \ 42 42 __entry->center_freq1, __entry->center_freq2 43 43 44 + #define MIN_CHANDEF_ENTRY \ 45 + __field(u32, min_control_freq) \ 46 + __field(u32, min_chan_width) \ 47 + __field(u32, min_center_freq1) \ 48 + __field(u32, min_center_freq2) 49 + 50 + #define MIN_CHANDEF_ASSIGN(c) \ 51 + __entry->min_control_freq = (c)->chan ? (c)->chan->center_freq : 0; \ 52 + __entry->min_chan_width = (c)->width; \ 53 + __entry->min_center_freq1 = (c)->center_freq1; \ 54 + __entry->min_center_freq2 = (c)->center_freq2; 55 + #define MIN_CHANDEF_PR_FMT " min_control:%d MHz min_width:%d min_center: %d/%d MHz" 56 + #define MIN_CHANDEF_PR_ARG __entry->min_control_freq, __entry->min_chan_width, \ 57 + __entry->min_center_freq1, __entry->min_center_freq2 58 + 44 59 #define CHANCTX_ENTRY CHANDEF_ENTRY \ 60 + MIN_CHANDEF_ENTRY \ 45 61 __field(u8, rx_chains_static) \ 46 62 __field(u8, rx_chains_dynamic) 47 63 #define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def) \ 64 + MIN_CHANDEF_ASSIGN(&ctx->conf.min_def) \ 48 65 __entry->rx_chains_static = ctx->conf.rx_chains_static; \ 49 66 __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic 50 - #define CHANCTX_PR_FMT CHANDEF_PR_FMT " chains:%d/%d" 51 - #define CHANCTX_PR_ARG CHANDEF_PR_ARG, \ 67 + #define CHANCTX_PR_FMT CHANDEF_PR_FMT MIN_CHANDEF_PR_FMT " chains:%d/%d" 68 + #define CHANCTX_PR_ARG CHANDEF_PR_ARG, MIN_CHANDEF_PR_ARG, \ 52 69 __entry->rx_chains_static, __entry->rx_chains_dynamic 53 70 54 71
+33 -8
net/mac80211/tx.c
··· 19 19 #include <linux/bitmap.h> 20 20 #include <linux/rcupdate.h> 21 21 #include <linux/export.h> 22 + #include <linux/time.h> 22 23 #include <net/net_namespace.h> 23 24 #include <net/ieee80211_radiotap.h> 24 25 #include <net/cfg80211.h> ··· 558 557 559 558 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) 560 559 tx->key = NULL; 561 - else if (tx->sta && (key = rcu_dereference(tx->sta->ptk))) 560 + else if (tx->sta && 561 + (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx]))) 562 562 tx->key = key; 563 563 else if (ieee80211_is_mgmt(hdr->frame_control) && 564 564 is_multicast_ether_addr(hdr->addr1) && ··· 842 840 rem -= fraglen; 843 841 tmp = dev_alloc_skb(local->tx_headroom + 844 842 frag_threshold + 845 - IEEE80211_ENCRYPT_HEADROOM + 843 + tx->sdata->encrypt_headroom + 846 844 IEEE80211_ENCRYPT_TAILROOM); 847 845 if (!tmp) 848 846 return -ENOMEM; 849 847 850 848 __skb_queue_tail(&tx->skbs, tmp); 851 849 852 - skb_reserve(tmp, local->tx_headroom + 853 - IEEE80211_ENCRYPT_HEADROOM); 850 + skb_reserve(tmp, 851 + local->tx_headroom + tx->sdata->encrypt_headroom); 852 + 854 853 /* copy control information */ 855 854 memcpy(tmp->cb, skb->cb, sizeof(tmp->cb)); 856 855 ··· 1488 1485 1489 1486 headroom = local->tx_headroom; 1490 1487 if (may_encrypt) 1491 - headroom += IEEE80211_ENCRYPT_HEADROOM; 1488 + headroom += sdata->encrypt_headroom; 1492 1489 headroom -= skb_headroom(skb); 1493 1490 headroom = max_t(int, 0, headroom); 1494 1491 ··· 1727 1724 * radar detection by itself. We can do that later by adding a 1728 1725 * monitor flag interfaces used for AP support. 1729 1726 */ 1730 - if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | 1731 - IEEE80211_CHAN_PASSIVE_SCAN))) 1727 + if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR))) 1732 1728 goto fail_rcu; 1733 1729 1734 1730 ieee80211_xmit(sdata, skb, chan->band); ··· 1740 1738 fail: 1741 1739 dev_kfree_skb(skb); 1742 1740 return NETDEV_TX_OK; /* meaning, we dealt with the skb */ 1741 + } 1742 + 1743 + /* 1744 + * Measure Tx frame arrival time for Tx latency statistics calculation 1745 + * A single Tx frame latency should be measured from when it is entering the 1746 + * Kernel until we receive Tx complete confirmation indication and the skb is 1747 + * freed. 1748 + */ 1749 + static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, 1750 + struct sk_buff *skb) 1751 + { 1752 + struct timespec skb_arv; 1753 + struct ieee80211_tx_latency_bin_ranges *tx_latency; 1754 + 1755 + tx_latency = rcu_dereference(local->tx_latency); 1756 + if (!tx_latency) 1757 + return; 1758 + 1759 + ktime_get_ts(&skb_arv); 1760 + skb->tstamp = ktime_set(skb_arv.tv_sec, skb_arv.tv_nsec); 1743 1761 } 1744 1762 1745 1763 /** ··· 1811 1789 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); 1812 1790 1813 1791 rcu_read_lock(); 1792 + 1793 + /* Measure frame arrival for Tx latency statistics calculation */ 1794 + ieee80211_tx_latency_start_msrmnt(local, skb); 1814 1795 1815 1796 switch (sdata->vif.type) { 1816 1797 case NL80211_IFTYPE_AP_VLAN: ··· 2134 2109 */ 2135 2110 2136 2111 if (head_need > 0 || skb_cloned(skb)) { 2137 - head_need += IEEE80211_ENCRYPT_HEADROOM; 2112 + head_need += sdata->encrypt_headroom; 2138 2113 head_need += local->tx_headroom; 2139 2114 head_need = max_t(int, 0, head_need); 2140 2115 if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
+92 -3
net/mac80211/util.c
··· 1804 1804 mutex_unlock(&local->chanctx_mtx); 1805 1805 } 1806 1806 1807 + void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata) 1808 + { 1809 + struct ieee80211_local *local = sdata->local; 1810 + struct ieee80211_chanctx_conf *chanctx_conf; 1811 + struct ieee80211_chanctx *chanctx; 1812 + 1813 + mutex_lock(&local->chanctx_mtx); 1814 + 1815 + chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 1816 + lockdep_is_held(&local->chanctx_mtx)); 1817 + 1818 + if (WARN_ON_ONCE(!chanctx_conf)) 1819 + goto unlock; 1820 + 1821 + chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf); 1822 + ieee80211_recalc_chanctx_min_def(local, chanctx); 1823 + unlock: 1824 + mutex_unlock(&local->chanctx_mtx); 1825 + } 1826 + 1807 1827 static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) 1808 1828 { 1809 1829 int i; ··· 2279 2259 void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) 2280 2260 { 2281 2261 struct ieee80211_sub_if_data *sdata; 2262 + struct cfg80211_chan_def chandef; 2282 2263 2283 2264 mutex_lock(&local->iflist_mtx); 2284 2265 list_for_each_entry(sdata, &local->interfaces, list) { 2285 2266 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 2286 2267 2287 2268 if (sdata->wdev.cac_started) { 2269 + chandef = sdata->vif.bss_conf.chandef; 2288 2270 ieee80211_vif_release_channel(sdata); 2289 2271 cfg80211_cac_event(sdata->dev, 2272 + &chandef, 2290 2273 NL80211_RADAR_CAC_ABORTED, 2291 2274 GFP_KERNEL); 2292 2275 } ··· 2468 2445 2469 2446 if (ieee80211_vif_is_mesh(&sdata->vif)) { 2470 2447 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 2471 - __le16 pre_value; 2472 2448 2473 2449 skb_put(skb, 8); 2474 2450 *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; /* EID */ ··· 2479 2457 WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; 2480 2458 put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ 2481 2459 pos += 2; 2482 - pre_value = cpu_to_le16(ifmsh->pre_value); 2483 - memcpy(pos, &pre_value, 2); /* Precedence Value */ 2460 + put_unaligned_le16(ifmsh->pre_value, pos);/* Precedence Value */ 2484 2461 pos += 2; 2485 2462 } 2486 2463 2487 2464 ieee80211_tx_skb(sdata, skb); 2488 2465 return 0; 2466 + } 2467 + 2468 + bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs) 2469 + { 2470 + return !(cs == NULL || cs->cipher == 0 || 2471 + cs->hdr_len < cs->pn_len + cs->pn_off || 2472 + cs->hdr_len <= cs->key_idx_off || 2473 + cs->key_idx_shift > 7 || 2474 + cs->key_idx_mask == 0); 2475 + } 2476 + 2477 + bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n) 2478 + { 2479 + int i; 2480 + 2481 + /* Ensure we have enough iftype bitmap space for all iftype values */ 2482 + WARN_ON((NUM_NL80211_IFTYPES / 8 + 1) > sizeof(cs[0].iftype)); 2483 + 2484 + for (i = 0; i < n; i++) 2485 + if (!ieee80211_cs_valid(&cs[i])) 2486 + return false; 2487 + 2488 + return true; 2489 + } 2490 + 2491 + const struct ieee80211_cipher_scheme * 2492 + ieee80211_cs_get(struct ieee80211_local *local, u32 cipher, 2493 + enum nl80211_iftype iftype) 2494 + { 2495 + const struct ieee80211_cipher_scheme *l = local->hw.cipher_schemes; 2496 + int n = local->hw.n_cipher_schemes; 2497 + int i; 2498 + const struct ieee80211_cipher_scheme *cs = NULL; 2499 + 2500 + for (i = 0; i < n; i++) { 2501 + if (l[i].cipher == cipher) { 2502 + cs = &l[i]; 2503 + break; 2504 + } 2505 + } 2506 + 2507 + if (!cs || !(cs->iftype & BIT(iftype))) 2508 + return NULL; 2509 + 2510 + return cs; 2511 + } 2512 + 2513 + int ieee80211_cs_headroom(struct ieee80211_local *local, 2514 + struct cfg80211_crypto_settings *crypto, 2515 + enum nl80211_iftype iftype) 2516 + { 2517 + const struct ieee80211_cipher_scheme *cs; 2518 + int headroom = IEEE80211_ENCRYPT_HEADROOM; 2519 + int i; 2520 + 2521 + for (i = 0; i < crypto->n_ciphers_pairwise; i++) { 2522 + cs = ieee80211_cs_get(local, crypto->ciphers_pairwise[i], 2523 + iftype); 2524 + 2525 + if (cs && headroom < cs->hdr_len) 2526 + headroom = cs->hdr_len; 2527 + } 2528 + 2529 + cs = ieee80211_cs_get(local, crypto->cipher_group, iftype); 2530 + if (cs && headroom < cs->hdr_len) 2531 + headroom = cs->hdr_len; 2532 + 2533 + return headroom; 2489 2534 }
+3 -4
net/mac80211/vht.c
··· 182 182 IEEE80211_VHT_CAP_SHORT_GI_160); 183 183 184 184 /* remaining ones */ 185 - if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) { 185 + if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) 186 186 vht_cap->cap |= cap_info & 187 187 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | 188 - IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX); 189 - } 188 + IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK); 190 189 191 190 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) 192 191 vht_cap->cap |= cap_info & 193 192 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | 194 - IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX); 193 + IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); 195 194 196 195 if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) 197 196 vht_cap->cap |= cap_info &
+116
net/mac80211/wpa.c
··· 545 545 return RX_CONTINUE; 546 546 } 547 547 548 + static ieee80211_tx_result 549 + ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, 550 + struct sk_buff *skb) 551 + { 552 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 553 + struct ieee80211_key *key = tx->key; 554 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 555 + const struct ieee80211_cipher_scheme *cs = key->sta->cipher_scheme; 556 + int hdrlen; 557 + u8 *pos; 558 + 559 + if (info->control.hw_key && 560 + !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { 561 + /* hwaccel has no need for preallocated head room */ 562 + return TX_CONTINUE; 563 + } 564 + 565 + if (unlikely(skb_headroom(skb) < cs->hdr_len && 566 + pskb_expand_head(skb, cs->hdr_len, 0, GFP_ATOMIC))) 567 + return TX_DROP; 568 + 569 + hdrlen = ieee80211_hdrlen(hdr->frame_control); 570 + 571 + pos = skb_push(skb, cs->hdr_len); 572 + memmove(pos, pos + cs->hdr_len, hdrlen); 573 + skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len); 574 + 575 + return TX_CONTINUE; 576 + } 577 + 578 + static inline int ieee80211_crypto_cs_pn_compare(u8 *pn1, u8 *pn2, int len) 579 + { 580 + int i; 581 + 582 + /* pn is little endian */ 583 + for (i = len - 1; i >= 0; i--) { 584 + if (pn1[i] < pn2[i]) 585 + return -1; 586 + else if (pn1[i] > pn2[i]) 587 + return 1; 588 + } 589 + 590 + return 0; 591 + } 592 + 593 + static ieee80211_rx_result 594 + ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx) 595 + { 596 + struct ieee80211_key *key = rx->key; 597 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 598 + const struct ieee80211_cipher_scheme *cs = NULL; 599 + int hdrlen = ieee80211_hdrlen(hdr->frame_control); 600 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); 601 + int data_len; 602 + u8 *rx_pn; 603 + u8 *skb_pn; 604 + u8 qos_tid; 605 + 606 + if (!rx->sta || !rx->sta->cipher_scheme || 607 + !(status->flag & RX_FLAG_DECRYPTED)) 608 + return RX_DROP_UNUSABLE; 609 + 610 + if (!ieee80211_is_data(hdr->frame_control)) 611 + return RX_CONTINUE; 612 + 613 + cs = rx->sta->cipher_scheme; 614 + 615 + data_len = rx->skb->len - hdrlen - cs->hdr_len; 616 + 617 + if (data_len < 0) 618 + return RX_DROP_UNUSABLE; 619 + 620 + if (ieee80211_is_data_qos(hdr->frame_control)) 621 + qos_tid = *ieee80211_get_qos_ctl(hdr) & 622 + IEEE80211_QOS_CTL_TID_MASK; 623 + else 624 + qos_tid = 0; 625 + 626 + if (skb_linearize(rx->skb)) 627 + return RX_DROP_UNUSABLE; 628 + 629 + hdr = (struct ieee80211_hdr *)rx->skb->data; 630 + 631 + rx_pn = key->u.gen.rx_pn[qos_tid]; 632 + skb_pn = rx->skb->data + hdrlen + cs->pn_off; 633 + 634 + if (ieee80211_crypto_cs_pn_compare(skb_pn, rx_pn, cs->pn_len) <= 0) 635 + return RX_DROP_UNUSABLE; 636 + 637 + memcpy(rx_pn, skb_pn, cs->pn_len); 638 + 639 + /* remove security header and MIC */ 640 + if (pskb_trim(rx->skb, rx->skb->len - cs->mic_len)) 641 + return RX_DROP_UNUSABLE; 642 + 643 + memmove(rx->skb->data + cs->hdr_len, rx->skb->data, hdrlen); 644 + skb_pull(rx->skb, cs->hdr_len); 645 + 646 + return RX_CONTINUE; 647 + } 548 648 549 649 static void bip_aad(struct sk_buff *skb, u8 *aad) 550 650 { ··· 785 685 { 786 686 struct sk_buff *skb; 787 687 struct ieee80211_tx_info *info = NULL; 688 + ieee80211_tx_result res; 788 689 789 690 skb_queue_walk(&tx->skbs, skb) { 790 691 info = IEEE80211_SKB_CB(skb); ··· 793 692 /* handle hw-only algorithm */ 794 693 if (!info->control.hw_key) 795 694 return TX_DROP; 695 + 696 + if (tx->key->sta->cipher_scheme) { 697 + res = ieee80211_crypto_cs_encrypt(tx, skb); 698 + if (res != TX_CONTINUE) 699 + return res; 700 + } 796 701 } 797 702 798 703 ieee80211_tx_set_protected(tx); 799 704 800 705 return TX_CONTINUE; 706 + } 707 + 708 + ieee80211_rx_result 709 + ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx) 710 + { 711 + if (rx->sta->cipher_scheme) 712 + return ieee80211_crypto_cs_decrypt(rx); 713 + 714 + return RX_DROP_UNUSABLE; 801 715 }
+2
net/mac80211/wpa.h
··· 34 34 ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx); 35 35 ieee80211_tx_result 36 36 ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx); 37 + ieee80211_rx_result 38 + ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx); 37 39 38 40 #endif /* WPA_H */
+182 -29
net/wireless/chan.c
··· 277 277 width, dfs_state); 278 278 } 279 279 280 + static u32 cfg80211_get_start_freq(u32 center_freq, 281 + u32 bandwidth) 282 + { 283 + u32 start_freq; 284 + 285 + if (bandwidth <= 20) 286 + start_freq = center_freq; 287 + else 288 + start_freq = center_freq - bandwidth/2 + 10; 289 + 290 + return start_freq; 291 + } 292 + 293 + static u32 cfg80211_get_end_freq(u32 center_freq, 294 + u32 bandwidth) 295 + { 296 + u32 end_freq; 297 + 298 + if (bandwidth <= 20) 299 + end_freq = center_freq; 300 + else 301 + end_freq = center_freq + bandwidth/2 - 10; 302 + 303 + return end_freq; 304 + } 305 + 280 306 static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy, 281 307 u32 center_freq, 282 308 u32 bandwidth) ··· 310 284 struct ieee80211_channel *c; 311 285 u32 freq, start_freq, end_freq; 312 286 313 - if (bandwidth <= 20) { 314 - start_freq = center_freq; 315 - end_freq = center_freq; 316 - } else { 317 - start_freq = center_freq - bandwidth/2 + 10; 318 - end_freq = center_freq + bandwidth/2 - 10; 319 - } 287 + start_freq = cfg80211_get_start_freq(center_freq, bandwidth); 288 + end_freq = cfg80211_get_end_freq(center_freq, bandwidth); 320 289 321 290 for (freq = start_freq; freq <= end_freq; freq += 20) { 322 291 c = ieee80211_get_channel(wiphy, freq); ··· 351 330 } 352 331 EXPORT_SYMBOL(cfg80211_chandef_dfs_required); 353 332 333 + static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy, 334 + u32 center_freq, 335 + u32 bandwidth) 336 + { 337 + struct ieee80211_channel *c; 338 + u32 freq, start_freq, end_freq; 339 + int count = 0; 340 + 341 + start_freq = cfg80211_get_start_freq(center_freq, bandwidth); 342 + end_freq = cfg80211_get_end_freq(center_freq, bandwidth); 343 + 344 + /* 345 + * Check entire range of channels for the bandwidth. 346 + * Check all channels are DFS channels (DFS_USABLE or 347 + * DFS_AVAILABLE). Return number of usable channels 348 + * (require CAC). Allow DFS and non-DFS channel mix. 349 + */ 350 + for (freq = start_freq; freq <= end_freq; freq += 20) { 351 + c = ieee80211_get_channel(wiphy, freq); 352 + if (!c) 353 + return -EINVAL; 354 + 355 + if (c->flags & IEEE80211_CHAN_DISABLED) 356 + return -EINVAL; 357 + 358 + if (c->flags & IEEE80211_CHAN_RADAR) { 359 + if (c->dfs_state == NL80211_DFS_UNAVAILABLE) 360 + return -EINVAL; 361 + 362 + if (c->dfs_state == NL80211_DFS_USABLE) 363 + count++; 364 + } 365 + } 366 + 367 + return count; 368 + } 369 + 370 + bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, 371 + const struct cfg80211_chan_def *chandef) 372 + { 373 + int width; 374 + int r1, r2 = 0; 375 + 376 + if (WARN_ON(!cfg80211_chandef_valid(chandef))) 377 + return false; 378 + 379 + width = cfg80211_chandef_get_width(chandef); 380 + if (width < 0) 381 + return false; 382 + 383 + r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1, 384 + width); 385 + 386 + if (r1 < 0) 387 + return false; 388 + 389 + switch (chandef->width) { 390 + case NL80211_CHAN_WIDTH_80P80: 391 + WARN_ON(!chandef->center_freq2); 392 + r2 = cfg80211_get_chans_dfs_usable(wiphy, 393 + chandef->center_freq2, 394 + width); 395 + if (r2 < 0) 396 + return false; 397 + break; 398 + default: 399 + WARN_ON(chandef->center_freq2); 400 + break; 401 + } 402 + 403 + return (r1 + r2 > 0); 404 + } 405 + 406 + 407 + static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy, 408 + u32 center_freq, 409 + u32 bandwidth) 410 + { 411 + struct ieee80211_channel *c; 412 + u32 freq, start_freq, end_freq; 413 + 414 + start_freq = cfg80211_get_start_freq(center_freq, bandwidth); 415 + end_freq = cfg80211_get_end_freq(center_freq, bandwidth); 416 + 417 + /* 418 + * Check entire range of channels for the bandwidth. 419 + * If any channel in between is disabled or has not 420 + * had gone through CAC return false 421 + */ 422 + for (freq = start_freq; freq <= end_freq; freq += 20) { 423 + c = ieee80211_get_channel(wiphy, freq); 424 + if (!c) 425 + return false; 426 + 427 + if (c->flags & IEEE80211_CHAN_DISABLED) 428 + return false; 429 + 430 + if ((c->flags & IEEE80211_CHAN_RADAR) && 431 + (c->dfs_state != NL80211_DFS_AVAILABLE)) 432 + return false; 433 + } 434 + 435 + return true; 436 + } 437 + 438 + static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy, 439 + const struct cfg80211_chan_def *chandef) 440 + { 441 + int width; 442 + int r; 443 + 444 + if (WARN_ON(!cfg80211_chandef_valid(chandef))) 445 + return false; 446 + 447 + width = cfg80211_chandef_get_width(chandef); 448 + if (width < 0) 449 + return false; 450 + 451 + r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1, 452 + width); 453 + 454 + /* If any of channels unavailable for cf1 just return */ 455 + if (!r) 456 + return r; 457 + 458 + switch (chandef->width) { 459 + case NL80211_CHAN_WIDTH_80P80: 460 + WARN_ON(!chandef->center_freq2); 461 + r = cfg80211_get_chans_dfs_available(wiphy, 462 + chandef->center_freq2, 463 + width); 464 + default: 465 + WARN_ON(chandef->center_freq2); 466 + break; 467 + } 468 + 469 + return r; 470 + } 471 + 472 + 354 473 static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, 355 474 u32 center_freq, u32 bandwidth, 356 475 u32 prohibited_flags) ··· 498 337 struct ieee80211_channel *c; 499 338 u32 freq, start_freq, end_freq; 500 339 501 - if (bandwidth <= 20) { 502 - start_freq = center_freq; 503 - end_freq = center_freq; 504 - } else { 505 - start_freq = center_freq - bandwidth/2 + 10; 506 - end_freq = center_freq + bandwidth/2 - 10; 507 - } 340 + start_freq = cfg80211_get_start_freq(center_freq, bandwidth); 341 + end_freq = cfg80211_get_end_freq(center_freq, bandwidth); 508 342 509 343 for (freq = start_freq; freq <= end_freq; freq += 20) { 510 344 c = ieee80211_get_channel(wiphy, freq); 511 - if (!c) 512 - return false; 513 - 514 - /* check for radar flags */ 515 - if ((prohibited_flags & c->flags & IEEE80211_CHAN_RADAR) && 516 - (c->dfs_state != NL80211_DFS_AVAILABLE)) 517 - return false; 518 - 519 - /* check for the other flags */ 520 - if (c->flags & prohibited_flags & ~IEEE80211_CHAN_RADAR) 345 + if (!c || c->flags & prohibited_flags) 521 346 return false; 522 347 } 523 348 ··· 609 462 struct cfg80211_chan_def *chandef) 610 463 { 611 464 bool res; 465 + u32 prohibited_flags = IEEE80211_CHAN_DISABLED | 466 + IEEE80211_CHAN_NO_IR | 467 + IEEE80211_CHAN_RADAR; 612 468 613 469 trace_cfg80211_reg_can_beacon(wiphy, chandef); 614 470 615 - res = cfg80211_chandef_usable(wiphy, chandef, 616 - IEEE80211_CHAN_DISABLED | 617 - IEEE80211_CHAN_PASSIVE_SCAN | 618 - IEEE80211_CHAN_NO_IBSS | 619 - IEEE80211_CHAN_RADAR); 471 + if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 && 472 + cfg80211_chandef_dfs_available(wiphy, chandef)) { 473 + /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ 474 + prohibited_flags = IEEE80211_CHAN_DISABLED; 475 + } 476 + 477 + res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags); 620 478 621 479 trace_cfg80211_return_bool(res); 622 480 return res; ··· 662 510 : CHAN_MODE_EXCLUSIVE; 663 511 return; 664 512 } 513 + break; 665 514 case NL80211_IFTYPE_STATION: 666 515 case NL80211_IFTYPE_P2P_CLIENT: 667 516 if (wdev->current_bss) {
+3 -3
net/wireless/core.c
··· 357 357 rdev->wiphy.rts_threshold = (u32) -1; 358 358 rdev->wiphy.coverage_class = 0; 359 359 360 - rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH; 361 - 362 360 return &rdev->wiphy; 363 361 } 364 362 EXPORT_SYMBOL(wiphy_new); ··· 573 575 /* check and set up bitrates */ 574 576 ieee80211_set_bitrate_flags(wiphy); 575 577 578 + rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH; 579 + 576 580 rtnl_lock(); 577 581 res = device_add(&rdev->wiphy.dev); 578 582 if (res) { ··· 595 595 if (IS_ERR(rdev->wiphy.debugfsdir)) 596 596 rdev->wiphy.debugfsdir = NULL; 597 597 598 - if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { 598 + if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) { 599 599 struct regulatory_request request; 600 600 601 601 request.wiphy_idx = get_wiphy_idx(wiphy);
+15 -3
net/wireless/core.h
··· 317 317 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); 318 318 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 319 319 struct wireless_dev *wdev, 320 - struct ieee80211_channel *chan, bool offchan, 321 - unsigned int wait, const u8 *buf, size_t len, 322 - bool no_cck, bool dont_wait_for_ack, u64 *cookie); 320 + struct cfg80211_mgmt_tx_params *params, 321 + u64 *cookie); 323 322 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 324 323 const struct ieee80211_ht_cap *ht_capa_mask); 325 324 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa, ··· 380 381 struct ieee80211_channel *chan, 381 382 enum cfg80211_chan_mode chanmode, 382 383 u8 radar_detect); 384 + 385 + /** 386 + * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable 387 + * @wiphy: the wiphy to validate against 388 + * @chandef: the channel definition to check 389 + * 390 + * Checks if chandef is usable and we can/need start CAC on such channel. 391 + * 392 + * Return: Return true if all channels available and at least 393 + * one channel require CAC (NL80211_DFS_USABLE) 394 + */ 395 + bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, 396 + const struct cfg80211_chan_def *chandef); 383 397 384 398 void cfg80211_set_dfs_state(struct wiphy *wiphy, 385 399 const struct cfg80211_chan_def *chandef,
+32 -13
net/wireless/genregdb.awk
··· 33 33 regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n" 34 34 } 35 35 36 - /^[ \t]*#/ { 37 - # Ignore 38 - } 39 - 40 - !active && /^[ \t]*$/ { 41 - # Ignore 42 - } 43 - 44 - !active && /country/ { 36 + function parse_country_head() { 45 37 country=$2 46 38 sub(/:/, "", country) 47 39 printf "static const struct ieee80211_regdomain regdom_%s = {\n", country ··· 49 57 regdb = regdb "\t&regdom_" country ",\n" 50 58 } 51 59 52 - active && /^[ \t]*\(/ { 60 + function parse_reg_rule() 61 + { 53 62 start = $1 54 63 sub(/\(/, "", start) 55 64 end = $3 ··· 100 107 } else if (flagarray[arg] == "PTMP-ONLY") { 101 108 flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | " 102 109 } else if (flagarray[arg] == "PASSIVE-SCAN") { 103 - flags = flags "\n\t\t\tNL80211_RRF_PASSIVE_SCAN | " 110 + flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 104 111 } else if (flagarray[arg] == "NO-IBSS") { 105 - flags = flags "\n\t\t\tNL80211_RRF_NO_IBSS | " 112 + flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 113 + } else if (flagarray[arg] == "NO-IR") { 114 + flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 106 115 } 116 + 107 117 } 108 118 flags = flags "0" 109 119 printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags 110 120 rules++ 111 121 } 112 122 113 - active && /^[ \t]*$/ { 123 + function print_tail_country() 124 + { 114 125 active = 0 115 126 printf "\t},\n" 116 127 printf "\t.n_reg_rules = %d\n", rules ··· 122 125 rules = 0; 123 126 } 124 127 128 + /^[ \t]*#/ { 129 + # Ignore 130 + } 131 + 132 + !active && /^[ \t]*$/ { 133 + # Ignore 134 + } 135 + 136 + !active && /country/ { 137 + parse_country_head() 138 + } 139 + 140 + active && /^[ \t]*\(/ { 141 + parse_reg_rule() 142 + } 143 + 144 + active && /^[ \t]*$/ { 145 + print_tail_country() 146 + } 147 + 125 148 END { 149 + if (active) 150 + print_tail_country() 126 151 print regdb "};" 127 152 print "" 128 153 print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);"
+2 -2
net/wireless/ibss.c
··· 274 274 275 275 for (i = 0; i < sband->n_channels; i++) { 276 276 chan = &sband->channels[i]; 277 - if (chan->flags & IEEE80211_CHAN_NO_IBSS) 277 + if (chan->flags & IEEE80211_CHAN_NO_IR) 278 278 continue; 279 279 if (chan->flags & IEEE80211_CHAN_DISABLED) 280 280 continue; ··· 346 346 chan = ieee80211_get_channel(wdev->wiphy, freq); 347 347 if (!chan) 348 348 return -EINVAL; 349 - if (chan->flags & IEEE80211_CHAN_NO_IBSS || 349 + if (chan->flags & IEEE80211_CHAN_NO_IR || 350 350 chan->flags & IEEE80211_CHAN_DISABLED) 351 351 return -EINVAL; 352 352 }
+1 -2
net/wireless/mesh.c
··· 141 141 142 142 for (i = 0; i < sband->n_channels; i++) { 143 143 chan = &sband->channels[i]; 144 - if (chan->flags & (IEEE80211_CHAN_NO_IBSS | 145 - IEEE80211_CHAN_PASSIVE_SCAN | 144 + if (chan->flags & (IEEE80211_CHAN_NO_IR | 146 145 IEEE80211_CHAN_DISABLED | 147 146 IEEE80211_CHAN_RADAR)) 148 147 continue;
+7 -13
net/wireless/mlme.c
··· 520 520 521 521 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 522 522 struct wireless_dev *wdev, 523 - struct ieee80211_channel *chan, bool offchan, 524 - unsigned int wait, const u8 *buf, size_t len, 525 - bool no_cck, bool dont_wait_for_ack, u64 *cookie) 523 + struct cfg80211_mgmt_tx_params *params, u64 *cookie) 526 524 { 527 525 const struct ieee80211_mgmt *mgmt; 528 526 u16 stype; ··· 531 533 if (!rdev->ops->mgmt_tx) 532 534 return -EOPNOTSUPP; 533 535 534 - if (len < 24 + 1) 536 + if (params->len < 24 + 1) 535 537 return -EINVAL; 536 538 537 - mgmt = (const struct ieee80211_mgmt *) buf; 539 + mgmt = (const struct ieee80211_mgmt *)params->buf; 538 540 539 541 if (!ieee80211_is_mgmt(mgmt->frame_control)) 540 542 return -EINVAL; ··· 613 615 return -EINVAL; 614 616 615 617 /* Transmit the Action frame as requested by user space */ 616 - return rdev_mgmt_tx(rdev, wdev, chan, offchan, 617 - wait, buf, len, no_cck, dont_wait_for_ack, 618 - cookie); 618 + return rdev_mgmt_tx(rdev, wdev, params, cookie); 619 619 } 620 620 621 621 bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, ··· 759 763 EXPORT_SYMBOL(cfg80211_radar_event); 760 764 761 765 void cfg80211_cac_event(struct net_device *netdev, 766 + const struct cfg80211_chan_def *chandef, 762 767 enum nl80211_radar_event event, gfp_t gfp) 763 768 { 764 769 struct wireless_dev *wdev = netdev->ieee80211_ptr; 765 770 struct wiphy *wiphy = wdev->wiphy; 766 771 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 767 - struct cfg80211_chan_def chandef; 768 772 unsigned long timeout; 769 773 770 774 trace_cfg80211_cac_event(netdev, event); ··· 775 779 if (WARN_ON(!wdev->channel)) 776 780 return; 777 781 778 - cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT); 779 - 780 782 switch (event) { 781 783 case NL80211_RADAR_CAC_FINISHED: 782 784 timeout = wdev->cac_start_time + 783 785 msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); 784 786 WARN_ON(!time_after_eq(jiffies, timeout)); 785 - cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE); 787 + cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); 786 788 break; 787 789 case NL80211_RADAR_CAC_ABORTED: 788 790 break; ··· 790 796 } 791 797 wdev->cac_started = false; 792 798 793 - nl80211_radar_notify(rdev, &chandef, event, netdev, gfp); 799 + nl80211_radar_notify(rdev, chandef, event, netdev, gfp); 794 800 } 795 801 EXPORT_SYMBOL(cfg80211_cac_event);
+60 -47
net/wireless/nl80211.c
··· 564 564 if ((chan->flags & IEEE80211_CHAN_DISABLED) && 565 565 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) 566 566 goto nla_put_failure; 567 - if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 568 - nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN)) 569 - goto nla_put_failure; 570 - if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && 571 - nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) 572 - goto nla_put_failure; 567 + if (chan->flags & IEEE80211_CHAN_NO_IR) { 568 + if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR)) 569 + goto nla_put_failure; 570 + if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS)) 571 + goto nla_put_failure; 572 + } 573 573 if (chan->flags & IEEE80211_CHAN_RADAR) { 574 574 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) 575 575 goto nla_put_failure; ··· 1247 1247 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && 1248 1248 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) 1249 1249 goto nla_put_failure; 1250 - if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) && 1251 - nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ)) 1252 - goto nla_put_failure; 1253 - 1254 1250 state->split_start++; 1255 1251 if (state->split) 1256 1252 break; ··· 1573 1577 break; 1574 1578 case 10: 1575 1579 if (nl80211_send_coalesce(msg, dev)) 1580 + goto nla_put_failure; 1581 + 1582 + if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) && 1583 + (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) || 1584 + nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ))) 1576 1585 goto nla_put_failure; 1577 1586 1578 1587 /* done */ ··· 2188 2187 } 2189 2188 2190 2189 static int nl80211_send_chandef(struct sk_buff *msg, 2191 - struct cfg80211_chan_def *chandef) 2190 + const struct cfg80211_chan_def *chandef) 2192 2191 { 2193 2192 WARN_ON(!cfg80211_chandef_valid(chandef)); 2194 2193 ··· 3237 3236 return PTR_ERR(params.acl); 3238 3237 } 3239 3238 3239 + wdev_lock(wdev); 3240 3240 err = rdev_start_ap(rdev, dev, &params); 3241 3241 if (!err) { 3242 3242 wdev->preset_chandef = params.chandef; ··· 3246 3244 wdev->ssid_len = params.ssid_len; 3247 3245 memcpy(wdev->ssid, params.ssid, wdev->ssid_len); 3248 3246 } 3247 + wdev_unlock(wdev); 3249 3248 3250 3249 kfree(params.acl); 3251 3250 ··· 3275 3272 if (err) 3276 3273 return err; 3277 3274 3278 - return rdev_change_beacon(rdev, dev, &params); 3275 + wdev_lock(wdev); 3276 + err = rdev_change_beacon(rdev, dev, &params); 3277 + wdev_unlock(wdev); 3278 + 3279 + return err; 3279 3280 } 3280 3281 3281 3282 static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) ··· 4485 4478 { 4486 4479 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4487 4480 struct net_device *dev = info->user_ptr[1]; 4481 + struct wireless_dev *wdev = dev->ieee80211_ptr; 4488 4482 struct bss_parameters params; 4483 + int err; 4489 4484 4490 4485 memset(&params, 0, sizeof(params)); 4491 4486 /* default to not changing parameters */ ··· 4553 4544 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4554 4545 return -EOPNOTSUPP; 4555 4546 4556 - return rdev_change_bss(rdev, dev, &params); 4547 + wdev_lock(wdev); 4548 + err = rdev_change_bss(rdev, dev, &params); 4549 + wdev_unlock(wdev); 4550 + 4551 + return err; 4557 4552 } 4558 4553 4559 4554 static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { ··· 5111 5098 char *alpha2 = NULL; 5112 5099 int rem_reg_rules = 0, r = 0; 5113 5100 u32 num_rules = 0, rule_idx = 0, size_of_regd; 5114 - u8 dfs_region = 0; 5101 + enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET; 5115 5102 struct ieee80211_regdomain *rd = NULL; 5116 5103 5117 5104 if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) ··· 5131 5118 if (num_rules > NL80211_MAX_SUPP_REG_RULES) 5132 5119 return -EINVAL; 5133 5120 } 5121 + 5122 + if (!reg_is_valid_request(alpha2)) 5123 + return -EINVAL; 5134 5124 5135 5125 size_of_regd = sizeof(struct ieee80211_regdomain) + 5136 5126 num_rules * sizeof(struct ieee80211_reg_rule); ··· 5381 5365 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { 5382 5366 request->flags = nla_get_u32( 5383 5367 info->attrs[NL80211_ATTR_SCAN_FLAGS]); 5384 - if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 5385 - !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || 5386 - ((request->flags & NL80211_SCAN_FLAG_FLUSH) && 5387 - !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { 5368 + if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 5369 + !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) { 5388 5370 err = -EOPNOTSUPP; 5389 5371 goto out_free; 5390 5372 } ··· 5622 5608 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { 5623 5609 request->flags = nla_get_u32( 5624 5610 info->attrs[NL80211_ATTR_SCAN_FLAGS]); 5625 - if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 5626 - !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || 5627 - ((request->flags & NL80211_SCAN_FLAG_FLUSH) && 5628 - !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { 5611 + if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 5612 + !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) { 5629 5613 err = -EOPNOTSUPP; 5630 5614 goto out_free; 5631 5615 } ··· 5686 5674 if (err == 0) 5687 5675 return -EINVAL; 5688 5676 5689 - if (chandef.chan->dfs_state != NL80211_DFS_USABLE) 5677 + if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef)) 5690 5678 return -EINVAL; 5691 5679 5692 5680 if (!rdev->ops->start_radar_detection) ··· 5826 5814 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) 5827 5815 params.block_tx = true; 5828 5816 5829 - return rdev_channel_switch(rdev, dev, &params); 5817 + wdev_lock(wdev); 5818 + err = rdev_channel_switch(rdev, dev, &params); 5819 + wdev_unlock(wdev); 5820 + 5821 + return err; 5830 5822 } 5831 5823 5832 5824 static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, ··· 7463 7447 void *hdr = NULL; 7464 7448 u64 cookie; 7465 7449 struct sk_buff *msg = NULL; 7466 - unsigned int wait = 0; 7467 - bool offchan, no_cck, dont_wait_for_ack; 7468 - 7469 - dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; 7450 + struct cfg80211_mgmt_tx_params params = { 7451 + .dont_wait_for_ack = 7452 + info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK], 7453 + }; 7470 7454 7471 7455 if (!info->attrs[NL80211_ATTR_FRAME]) 7472 7456 return -EINVAL; ··· 7493 7477 if (info->attrs[NL80211_ATTR_DURATION]) { 7494 7478 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 7495 7479 return -EINVAL; 7496 - wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); 7480 + params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); 7497 7481 7498 7482 /* 7499 7483 * We should wait on the channel for at least a minimum amount 7500 7484 * of time (10ms) but no longer than the driver supports. 7501 7485 */ 7502 - if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || 7503 - wait > rdev->wiphy.max_remain_on_channel_duration) 7486 + if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || 7487 + params.wait > rdev->wiphy.max_remain_on_channel_duration) 7504 7488 return -EINVAL; 7505 7489 7506 7490 } 7507 7491 7508 - offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 7492 + params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 7509 7493 7510 - if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 7494 + if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 7511 7495 return -EINVAL; 7512 7496 7513 - no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 7497 + params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 7514 7498 7515 7499 /* get the channel if any has been specified, otherwise pass NULL to 7516 7500 * the driver. The latter will use the current one ··· 7522 7506 return err; 7523 7507 } 7524 7508 7525 - if (!chandef.chan && offchan) 7509 + if (!chandef.chan && params.offchan) 7526 7510 return -EINVAL; 7527 7511 7528 - if (!dont_wait_for_ack) { 7512 + if (!params.dont_wait_for_ack) { 7529 7513 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7530 7514 if (!msg) 7531 7515 return -ENOMEM; ··· 7538 7522 } 7539 7523 } 7540 7524 7541 - err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait, 7542 - nla_data(info->attrs[NL80211_ATTR_FRAME]), 7543 - nla_len(info->attrs[NL80211_ATTR_FRAME]), 7544 - no_cck, dont_wait_for_ack, &cookie); 7525 + params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); 7526 + params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); 7527 + params.chan = chandef.chan; 7528 + err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie); 7545 7529 if (err) 7546 7530 goto free_msg; 7547 7531 ··· 10826 10810 struct wiphy *wiphy = wdev->wiphy; 10827 10811 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 10828 10812 10829 - trace_cfg80211_ch_switch_notify(dev, chandef); 10813 + ASSERT_WDEV_LOCK(wdev); 10830 10814 10831 - wdev_lock(wdev); 10815 + trace_cfg80211_ch_switch_notify(dev, chandef); 10832 10816 10833 10817 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && 10834 10818 wdev->iftype != NL80211_IFTYPE_P2P_GO && 10835 10819 wdev->iftype != NL80211_IFTYPE_ADHOC && 10836 10820 wdev->iftype != NL80211_IFTYPE_MESH_POINT)) 10837 - goto out; 10821 + return; 10838 10822 10839 10823 wdev->channel = chandef->chan; 10840 10824 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL); 10841 - out: 10842 - wdev_unlock(wdev); 10843 - return; 10844 10825 } 10845 10826 EXPORT_SYMBOL(cfg80211_ch_switch_notify); 10846 10827 ··· 10896 10883 10897 10884 void 10898 10885 nl80211_radar_notify(struct cfg80211_registered_device *rdev, 10899 - struct cfg80211_chan_def *chandef, 10886 + const struct cfg80211_chan_def *chandef, 10900 10887 enum nl80211_radar_event event, 10901 10888 struct net_device *netdev, gfp_t gfp) 10902 10889 {
+1 -1
net/wireless/nl80211.h
··· 70 70 71 71 void 72 72 nl80211_radar_notify(struct cfg80211_registered_device *rdev, 73 - struct cfg80211_chan_def *chandef, 73 + const struct cfg80211_chan_def *chandef, 74 74 enum nl80211_radar_event event, 75 75 struct net_device *netdev, gfp_t gfp); 76 76
+4 -8
net/wireless/rdev-ops.h
··· 624 624 625 625 static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, 626 626 struct wireless_dev *wdev, 627 - struct ieee80211_channel *chan, bool offchan, 628 - unsigned int wait, const u8 *buf, size_t len, 629 - bool no_cck, bool dont_wait_for_ack, u64 *cookie) 627 + struct cfg80211_mgmt_tx_params *params, 628 + u64 *cookie) 630 629 { 631 630 int ret; 632 - trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, 633 - wait, no_cck, dont_wait_for_ack); 634 - ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, 635 - wait, buf, len, no_cck, 636 - dont_wait_for_ack, cookie); 631 + trace_rdev_mgmt_tx(&rdev->wiphy, wdev, params); 632 + ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, params, cookie); 637 633 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); 638 634 return ret; 639 635 }
+502 -354
net/wireless/reg.c
··· 120 120 return rtnl_dereference(wiphy->regd); 121 121 } 122 122 123 + static const char *reg_dfs_region_str(enum nl80211_dfs_regions dfs_region) 124 + { 125 + switch (dfs_region) { 126 + case NL80211_DFS_UNSET: 127 + return "unset"; 128 + case NL80211_DFS_FCC: 129 + return "FCC"; 130 + case NL80211_DFS_ETSI: 131 + return "ETSI"; 132 + case NL80211_DFS_JP: 133 + return "JP"; 134 + } 135 + return "Unknown"; 136 + } 137 + 123 138 static void rcu_free_regdom(const struct ieee80211_regdomain *r) 124 139 { 125 140 if (!r) ··· 178 163 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), 179 164 /* IEEE 802.11b/g, channels 12..13. */ 180 165 REG_RULE(2467-10, 2472+10, 40, 6, 20, 181 - NL80211_RRF_PASSIVE_SCAN | 182 - NL80211_RRF_NO_IBSS), 166 + NL80211_RRF_NO_IR), 183 167 /* IEEE 802.11 channel 14 - Only JP enables 184 168 * this and for 802.11b only */ 185 169 REG_RULE(2484-10, 2484+10, 20, 6, 20, 186 - NL80211_RRF_PASSIVE_SCAN | 187 - NL80211_RRF_NO_IBSS | 170 + NL80211_RRF_NO_IR | 188 171 NL80211_RRF_NO_OFDM), 189 172 /* IEEE 802.11a, channel 36..48 */ 190 173 REG_RULE(5180-10, 5240+10, 160, 6, 20, 191 - NL80211_RRF_PASSIVE_SCAN | 192 - NL80211_RRF_NO_IBSS), 174 + NL80211_RRF_NO_IR), 193 175 194 176 /* IEEE 802.11a, channel 52..64 - DFS required */ 195 177 REG_RULE(5260-10, 5320+10, 160, 6, 20, 196 - NL80211_RRF_PASSIVE_SCAN | 197 - NL80211_RRF_NO_IBSS | 178 + NL80211_RRF_NO_IR | 198 179 NL80211_RRF_DFS), 199 180 200 181 /* IEEE 802.11a, channel 100..144 - DFS required */ 201 182 REG_RULE(5500-10, 5720+10, 160, 6, 20, 202 - NL80211_RRF_PASSIVE_SCAN | 203 - NL80211_RRF_NO_IBSS | 183 + NL80211_RRF_NO_IR | 204 184 NL80211_RRF_DFS), 205 185 206 186 /* IEEE 802.11a, channel 149..165 */ 207 187 REG_RULE(5745-10, 5825+10, 80, 6, 20, 208 - NL80211_RRF_PASSIVE_SCAN | 209 - NL80211_RRF_NO_IBSS), 188 + NL80211_RRF_NO_IR), 210 189 211 190 /* IEEE 802.11ad (60gHz), channels 1..3 */ 212 191 REG_RULE(56160+2160*1-1080, 56160+2160*3+1080, 2160, 0, 0, 0), ··· 217 208 module_param(ieee80211_regdom, charp, 0444); 218 209 MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 219 210 211 + static void reg_kfree_last_request(void) 212 + { 213 + struct regulatory_request *lr; 214 + 215 + lr = get_last_request(); 216 + 217 + if (lr != &core_request_world && lr) 218 + kfree_rcu(lr, rcu_head); 219 + } 220 + 221 + static void reg_update_last_request(struct regulatory_request *request) 222 + { 223 + reg_kfree_last_request(); 224 + rcu_assign_pointer(last_request, request); 225 + } 226 + 220 227 static void reset_regdomains(bool full_reset, 221 228 const struct ieee80211_regdomain *new_regdom) 222 229 { 223 230 const struct ieee80211_regdomain *r; 224 - struct regulatory_request *lr; 225 231 226 232 ASSERT_RTNL(); 227 233 ··· 259 235 if (!full_reset) 260 236 return; 261 237 262 - lr = get_last_request(); 263 - if (lr != &core_request_world && lr) 264 - kfree_rcu(lr, rcu_head); 265 - rcu_assign_pointer(last_request, &core_request_world); 238 + reg_update_last_request(&core_request_world); 266 239 } 267 240 268 241 /* ··· 477 456 return kobject_uevent(&reg_pdev->dev.kobj, KOBJ_CHANGE); 478 457 } 479 458 480 - static bool reg_is_valid_request(const char *alpha2) 459 + static enum reg_request_treatment 460 + reg_call_crda(struct regulatory_request *request) 461 + { 462 + if (call_crda(request->alpha2)) 463 + return REG_REQ_IGNORE; 464 + return REG_REQ_OK; 465 + } 466 + 467 + bool reg_is_valid_request(const char *alpha2) 481 468 { 482 469 struct regulatory_request *lr = get_last_request(); 483 470 ··· 583 554 return true; 584 555 return false; 585 556 #undef ONE_GHZ_IN_KHZ 557 + } 558 + 559 + /* 560 + * Later on we can perhaps use the more restrictive DFS 561 + * region but we don't have information for that yet so 562 + * for now simply disallow conflicts. 563 + */ 564 + static enum nl80211_dfs_regions 565 + reg_intersect_dfs_region(const enum nl80211_dfs_regions dfs_region1, 566 + const enum nl80211_dfs_regions dfs_region2) 567 + { 568 + if (dfs_region1 != dfs_region2) 569 + return NL80211_DFS_UNSET; 570 + return dfs_region1; 586 571 } 587 572 588 573 /* ··· 730 687 rd->n_reg_rules = num_rules; 731 688 rd->alpha2[0] = '9'; 732 689 rd->alpha2[1] = '8'; 690 + rd->dfs_region = reg_intersect_dfs_region(rd1->dfs_region, 691 + rd2->dfs_region); 733 692 734 693 return rd; 735 694 } ··· 743 698 static u32 map_regdom_flags(u32 rd_flags) 744 699 { 745 700 u32 channel_flags = 0; 746 - if (rd_flags & NL80211_RRF_PASSIVE_SCAN) 747 - channel_flags |= IEEE80211_CHAN_PASSIVE_SCAN; 748 - if (rd_flags & NL80211_RRF_NO_IBSS) 749 - channel_flags |= IEEE80211_CHAN_NO_IBSS; 701 + if (rd_flags & NL80211_RRF_NO_IR_ALL) 702 + channel_flags |= IEEE80211_CHAN_NO_IR; 750 703 if (rd_flags & NL80211_RRF_DFS) 751 704 channel_flags |= IEEE80211_CHAN_RADAR; 752 705 if (rd_flags & NL80211_RRF_NO_OFDM) ··· 897 854 PTR_ERR(reg_rule) == -ERANGE) 898 855 return; 899 856 900 - REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq); 901 - chan->flags |= IEEE80211_CHAN_DISABLED; 857 + if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 858 + request_wiphy && request_wiphy == wiphy && 859 + request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) { 860 + REG_DBG_PRINT("Disabling freq %d MHz for good\n", 861 + chan->center_freq); 862 + chan->orig_flags |= IEEE80211_CHAN_DISABLED; 863 + chan->flags = chan->orig_flags; 864 + } else { 865 + REG_DBG_PRINT("Disabling freq %d MHz\n", 866 + chan->center_freq); 867 + chan->flags |= IEEE80211_CHAN_DISABLED; 868 + } 902 869 return; 903 870 } 904 871 ··· 926 873 927 874 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 928 875 request_wiphy && request_wiphy == wiphy && 929 - request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { 876 + request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) { 930 877 /* 931 878 * This guarantees the driver's requested regulatory domain 932 879 * will always be used as a base for further regulatory ··· 952 899 chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp); 953 900 if (chan->orig_mpwr) { 954 901 /* 955 - * Devices that have their own custom regulatory domain 956 - * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the 957 - * passed country IE power settings. 902 + * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER 903 + * will always follow the passed country IE power settings. 958 904 */ 959 905 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 960 - wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY && 961 - wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) 906 + wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_FOLLOW_POWER) 962 907 chan->max_power = chan->max_reg_power; 963 908 else 964 909 chan->max_power = min(chan->orig_mpwr, ··· 1026 975 1027 976 static bool wiphy_strict_alpha2_regd(struct wiphy *wiphy) 1028 977 { 1029 - if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && 1030 - !(wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)) 978 + if (wiphy->regulatory_flags & REGULATORY_STRICT_REG && 979 + !(wiphy->regulatory_flags & REGULATORY_CUSTOM_REG)) 1031 980 return true; 1032 981 return false; 1033 982 } ··· 1045 994 } 1046 995 1047 996 if (initiator == NL80211_REGDOM_SET_BY_CORE && 1048 - wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { 997 + wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) { 1049 998 REG_DBG_PRINT("Ignoring regulatory request set by %s " 1050 999 "since the driver uses its own custom " 1051 1000 "regulatory domain\n", ··· 1083 1032 return true; 1084 1033 1085 1034 if (lr && lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && 1086 - wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) 1035 + wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) 1087 1036 return true; 1088 1037 1089 1038 return false; ··· 1111 1060 if (!reg_is_world_roaming(wiphy)) 1112 1061 return; 1113 1062 1114 - if (wiphy->flags & WIPHY_FLAG_DISABLE_BEACON_HINTS) 1063 + if (wiphy->regulatory_flags & REGULATORY_DISABLE_BEACON_HINTS) 1115 1064 return; 1116 1065 1117 1066 chan_before.center_freq = chan->center_freq; 1118 1067 chan_before.flags = chan->flags; 1119 1068 1120 - if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) { 1121 - chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 1122 - channel_changed = true; 1123 - } 1124 - 1125 - if (chan->flags & IEEE80211_CHAN_NO_IBSS) { 1126 - chan->flags &= ~IEEE80211_CHAN_NO_IBSS; 1069 + if (chan->flags & IEEE80211_CHAN_NO_IR) { 1070 + chan->flags &= ~IEEE80211_CHAN_NO_IR; 1127 1071 channel_changed = true; 1128 1072 } 1129 1073 ··· 1251 1205 reg_process_ht_flags_band(wiphy, wiphy->bands[band]); 1252 1206 } 1253 1207 1208 + static void reg_call_notifier(struct wiphy *wiphy, 1209 + struct regulatory_request *request) 1210 + { 1211 + if (wiphy->reg_notifier) 1212 + wiphy->reg_notifier(wiphy, request); 1213 + } 1214 + 1254 1215 static void wiphy_update_regulatory(struct wiphy *wiphy, 1255 1216 enum nl80211_reg_initiator initiator) 1256 1217 { 1257 1218 enum ieee80211_band band; 1258 1219 struct regulatory_request *lr = get_last_request(); 1259 1220 1260 - if (ignore_reg_update(wiphy, initiator)) 1221 + if (ignore_reg_update(wiphy, initiator)) { 1222 + /* 1223 + * Regulatory updates set by CORE are ignored for custom 1224 + * regulatory cards. Let us notify the changes to the driver, 1225 + * as some drivers used this to restore its orig_* reg domain. 1226 + */ 1227 + if (initiator == NL80211_REGDOM_SET_BY_CORE && 1228 + wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) 1229 + reg_call_notifier(wiphy, lr); 1261 1230 return; 1231 + } 1262 1232 1263 1233 lr->dfs_region = get_cfg80211_regdom()->dfs_region; 1264 1234 ··· 1283 1221 1284 1222 reg_process_beacons(wiphy); 1285 1223 reg_process_ht_flags(wiphy); 1286 - 1287 - if (wiphy->reg_notifier) 1288 - wiphy->reg_notifier(wiphy, lr); 1224 + reg_call_notifier(wiphy, lr); 1289 1225 } 1290 1226 1291 1227 static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) ··· 1296 1236 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 1297 1237 wiphy = &rdev->wiphy; 1298 1238 wiphy_update_regulatory(wiphy, initiator); 1299 - /* 1300 - * Regulatory updates set by CORE are ignored for custom 1301 - * regulatory cards. Let us notify the changes to the driver, 1302 - * as some drivers used this to restore its orig_* reg domain. 1303 - */ 1304 - if (initiator == NL80211_REGDOM_SET_BY_CORE && 1305 - wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY && 1306 - wiphy->reg_notifier) 1307 - wiphy->reg_notifier(wiphy, get_last_request()); 1308 1239 } 1309 1240 } 1310 1241 ··· 1314 1263 if (IS_ERR(reg_rule)) { 1315 1264 REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n", 1316 1265 chan->center_freq); 1317 - chan->flags = IEEE80211_CHAN_DISABLED; 1266 + chan->orig_flags |= IEEE80211_CHAN_DISABLED; 1267 + chan->flags = chan->orig_flags; 1318 1268 return; 1319 1269 } 1320 1270 ··· 1357 1305 enum ieee80211_band band; 1358 1306 unsigned int bands_set = 0; 1359 1307 1308 + WARN(!(wiphy->regulatory_flags & REGULATORY_CUSTOM_REG), 1309 + "wiphy should have REGULATORY_CUSTOM_REG\n"); 1310 + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 1311 + 1360 1312 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1361 1313 if (!wiphy->bands[band]) 1362 1314 continue; ··· 1375 1319 WARN_ON(!bands_set); 1376 1320 } 1377 1321 EXPORT_SYMBOL(wiphy_apply_custom_regulatory); 1378 - 1379 - /* This has the logic which determines when a new request 1380 - * should be ignored. */ 1381 - static enum reg_request_treatment 1382 - get_reg_request_treatment(struct wiphy *wiphy, 1383 - struct regulatory_request *pending_request) 1384 - { 1385 - struct wiphy *last_wiphy = NULL; 1386 - struct regulatory_request *lr = get_last_request(); 1387 - 1388 - /* All initial requests are respected */ 1389 - if (!lr) 1390 - return REG_REQ_OK; 1391 - 1392 - switch (pending_request->initiator) { 1393 - case NL80211_REGDOM_SET_BY_CORE: 1394 - return REG_REQ_OK; 1395 - case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1396 - if (reg_request_cell_base(lr)) { 1397 - /* Trust a Cell base station over the AP's country IE */ 1398 - if (regdom_changes(pending_request->alpha2)) 1399 - return REG_REQ_IGNORE; 1400 - return REG_REQ_ALREADY_SET; 1401 - } 1402 - 1403 - last_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); 1404 - 1405 - if (unlikely(!is_an_alpha2(pending_request->alpha2))) 1406 - return -EINVAL; 1407 - if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 1408 - if (last_wiphy != wiphy) { 1409 - /* 1410 - * Two cards with two APs claiming different 1411 - * Country IE alpha2s. We could 1412 - * intersect them, but that seems unlikely 1413 - * to be correct. Reject second one for now. 1414 - */ 1415 - if (regdom_changes(pending_request->alpha2)) 1416 - return REG_REQ_IGNORE; 1417 - return REG_REQ_ALREADY_SET; 1418 - } 1419 - /* 1420 - * Two consecutive Country IE hints on the same wiphy. 1421 - * This should be picked up early by the driver/stack 1422 - */ 1423 - if (WARN_ON(regdom_changes(pending_request->alpha2))) 1424 - return REG_REQ_OK; 1425 - return REG_REQ_ALREADY_SET; 1426 - } 1427 - return REG_REQ_OK; 1428 - case NL80211_REGDOM_SET_BY_DRIVER: 1429 - if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { 1430 - if (regdom_changes(pending_request->alpha2)) 1431 - return REG_REQ_OK; 1432 - return REG_REQ_ALREADY_SET; 1433 - } 1434 - 1435 - /* 1436 - * This would happen if you unplug and plug your card 1437 - * back in or if you add a new device for which the previously 1438 - * loaded card also agrees on the regulatory domain. 1439 - */ 1440 - if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 1441 - !regdom_changes(pending_request->alpha2)) 1442 - return REG_REQ_ALREADY_SET; 1443 - 1444 - return REG_REQ_INTERSECT; 1445 - case NL80211_REGDOM_SET_BY_USER: 1446 - if (reg_request_cell_base(pending_request)) 1447 - return reg_ignore_cell_hint(pending_request); 1448 - 1449 - if (reg_request_cell_base(lr)) 1450 - return REG_REQ_IGNORE; 1451 - 1452 - if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) 1453 - return REG_REQ_INTERSECT; 1454 - /* 1455 - * If the user knows better the user should set the regdom 1456 - * to their country before the IE is picked up 1457 - */ 1458 - if (lr->initiator == NL80211_REGDOM_SET_BY_USER && 1459 - lr->intersect) 1460 - return REG_REQ_IGNORE; 1461 - /* 1462 - * Process user requests only after previous user/driver/core 1463 - * requests have been processed 1464 - */ 1465 - if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE || 1466 - lr->initiator == NL80211_REGDOM_SET_BY_DRIVER || 1467 - lr->initiator == NL80211_REGDOM_SET_BY_USER) && 1468 - regdom_changes(lr->alpha2)) 1469 - return REG_REQ_IGNORE; 1470 - 1471 - if (!regdom_changes(pending_request->alpha2)) 1472 - return REG_REQ_ALREADY_SET; 1473 - 1474 - return REG_REQ_OK; 1475 - } 1476 - 1477 - return REG_REQ_IGNORE; 1478 - } 1479 1322 1480 1323 static void reg_set_request_processed(void) 1481 1324 { ··· 1396 1441 } 1397 1442 1398 1443 /** 1399 - * __regulatory_hint - hint to the wireless core a regulatory domain 1400 - * @wiphy: if the hint comes from country information from an AP, this 1401 - * is required to be set to the wiphy that received the information 1402 - * @pending_request: the regulatory request currently being processed 1444 + * reg_process_hint_core - process core regulatory requests 1445 + * @pending_request: a pending core regulatory request 1403 1446 * 1404 - * The Wireless subsystem can use this function to hint to the wireless core 1405 - * what it believes should be the current regulatory domain. 1447 + * The wireless subsystem can use this function to process 1448 + * a regulatory request issued by the regulatory core. 1406 1449 * 1407 1450 * Returns one of the different reg request treatment values. 1408 1451 */ 1409 1452 static enum reg_request_treatment 1410 - __regulatory_hint(struct wiphy *wiphy, 1411 - struct regulatory_request *pending_request) 1453 + reg_process_hint_core(struct regulatory_request *core_request) 1412 1454 { 1413 - const struct ieee80211_regdomain *regd; 1414 - bool intersect = false; 1415 - enum reg_request_treatment treatment; 1416 - struct regulatory_request *lr; 1417 1455 1418 - treatment = get_reg_request_treatment(wiphy, pending_request); 1456 + core_request->intersect = false; 1457 + core_request->processed = false; 1419 1458 1420 - switch (treatment) { 1421 - case REG_REQ_INTERSECT: 1422 - if (pending_request->initiator == 1423 - NL80211_REGDOM_SET_BY_DRIVER) { 1424 - regd = reg_copy_regd(get_cfg80211_regdom()); 1425 - if (IS_ERR(regd)) { 1426 - kfree(pending_request); 1427 - return PTR_ERR(regd); 1428 - } 1429 - rcu_assign_pointer(wiphy->regd, regd); 1430 - } 1431 - intersect = true; 1432 - break; 1433 - case REG_REQ_OK: 1434 - break; 1435 - default: 1436 - /* 1437 - * If the regulatory domain being requested by the 1438 - * driver has already been set just copy it to the 1439 - * wiphy 1440 - */ 1441 - if (treatment == REG_REQ_ALREADY_SET && 1442 - pending_request->initiator == NL80211_REGDOM_SET_BY_DRIVER) { 1443 - regd = reg_copy_regd(get_cfg80211_regdom()); 1444 - if (IS_ERR(regd)) { 1445 - kfree(pending_request); 1446 - return REG_REQ_IGNORE; 1447 - } 1448 - treatment = REG_REQ_ALREADY_SET; 1449 - rcu_assign_pointer(wiphy->regd, regd); 1450 - goto new_request; 1451 - } 1452 - kfree(pending_request); 1453 - return treatment; 1454 - } 1459 + reg_update_last_request(core_request); 1455 1460 1456 - new_request: 1457 - lr = get_last_request(); 1458 - if (lr != &core_request_world && lr) 1459 - kfree_rcu(lr, rcu_head); 1461 + return reg_call_crda(core_request); 1462 + } 1460 1463 1461 - pending_request->intersect = intersect; 1462 - pending_request->processed = false; 1463 - rcu_assign_pointer(last_request, pending_request); 1464 - lr = pending_request; 1464 + static enum reg_request_treatment 1465 + __reg_process_hint_user(struct regulatory_request *user_request) 1466 + { 1467 + struct regulatory_request *lr = get_last_request(); 1465 1468 1466 - pending_request = NULL; 1469 + if (reg_request_cell_base(user_request)) 1470 + return reg_ignore_cell_hint(user_request); 1467 1471 1468 - if (lr->initiator == NL80211_REGDOM_SET_BY_USER) { 1469 - user_alpha2[0] = lr->alpha2[0]; 1470 - user_alpha2[1] = lr->alpha2[1]; 1471 - } 1472 - 1473 - /* When r == REG_REQ_INTERSECT we do need to call CRDA */ 1474 - if (treatment != REG_REQ_OK && treatment != REG_REQ_INTERSECT) { 1475 - /* 1476 - * Since CRDA will not be called in this case as we already 1477 - * have applied the requested regulatory domain before we just 1478 - * inform userspace we have processed the request 1479 - */ 1480 - if (treatment == REG_REQ_ALREADY_SET) { 1481 - nl80211_send_reg_change_event(lr); 1482 - reg_set_request_processed(); 1483 - } 1484 - return treatment; 1485 - } 1486 - 1487 - if (call_crda(lr->alpha2)) 1472 + if (reg_request_cell_base(lr)) 1488 1473 return REG_REQ_IGNORE; 1474 + 1475 + if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) 1476 + return REG_REQ_INTERSECT; 1477 + /* 1478 + * If the user knows better the user should set the regdom 1479 + * to their country before the IE is picked up 1480 + */ 1481 + if (lr->initiator == NL80211_REGDOM_SET_BY_USER && 1482 + lr->intersect) 1483 + return REG_REQ_IGNORE; 1484 + /* 1485 + * Process user requests only after previous user/driver/core 1486 + * requests have been processed 1487 + */ 1488 + if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE || 1489 + lr->initiator == NL80211_REGDOM_SET_BY_DRIVER || 1490 + lr->initiator == NL80211_REGDOM_SET_BY_USER) && 1491 + regdom_changes(lr->alpha2)) 1492 + return REG_REQ_IGNORE; 1493 + 1494 + if (!regdom_changes(user_request->alpha2)) 1495 + return REG_REQ_ALREADY_SET; 1496 + 1489 1497 return REG_REQ_OK; 1490 1498 } 1491 1499 1500 + /** 1501 + * reg_process_hint_user - process user regulatory requests 1502 + * @user_request: a pending user regulatory request 1503 + * 1504 + * The wireless subsystem can use this function to process 1505 + * a regulatory request initiated by userspace. 1506 + * 1507 + * Returns one of the different reg request treatment values. 1508 + */ 1509 + static enum reg_request_treatment 1510 + reg_process_hint_user(struct regulatory_request *user_request) 1511 + { 1512 + enum reg_request_treatment treatment; 1513 + 1514 + treatment = __reg_process_hint_user(user_request); 1515 + if (treatment == REG_REQ_IGNORE || 1516 + treatment == REG_REQ_ALREADY_SET) { 1517 + kfree(user_request); 1518 + return treatment; 1519 + } 1520 + 1521 + user_request->intersect = treatment == REG_REQ_INTERSECT; 1522 + user_request->processed = false; 1523 + 1524 + reg_update_last_request(user_request); 1525 + 1526 + user_alpha2[0] = user_request->alpha2[0]; 1527 + user_alpha2[1] = user_request->alpha2[1]; 1528 + 1529 + return reg_call_crda(user_request); 1530 + } 1531 + 1532 + static enum reg_request_treatment 1533 + __reg_process_hint_driver(struct regulatory_request *driver_request) 1534 + { 1535 + struct regulatory_request *lr = get_last_request(); 1536 + 1537 + if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { 1538 + if (regdom_changes(driver_request->alpha2)) 1539 + return REG_REQ_OK; 1540 + return REG_REQ_ALREADY_SET; 1541 + } 1542 + 1543 + /* 1544 + * This would happen if you unplug and plug your card 1545 + * back in or if you add a new device for which the previously 1546 + * loaded card also agrees on the regulatory domain. 1547 + */ 1548 + if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 1549 + !regdom_changes(driver_request->alpha2)) 1550 + return REG_REQ_ALREADY_SET; 1551 + 1552 + return REG_REQ_INTERSECT; 1553 + } 1554 + 1555 + /** 1556 + * reg_process_hint_driver - process driver regulatory requests 1557 + * @driver_request: a pending driver regulatory request 1558 + * 1559 + * The wireless subsystem can use this function to process 1560 + * a regulatory request issued by an 802.11 driver. 1561 + * 1562 + * Returns one of the different reg request treatment values. 1563 + */ 1564 + static enum reg_request_treatment 1565 + reg_process_hint_driver(struct wiphy *wiphy, 1566 + struct regulatory_request *driver_request) 1567 + { 1568 + const struct ieee80211_regdomain *regd; 1569 + enum reg_request_treatment treatment; 1570 + 1571 + treatment = __reg_process_hint_driver(driver_request); 1572 + 1573 + switch (treatment) { 1574 + case REG_REQ_OK: 1575 + break; 1576 + case REG_REQ_IGNORE: 1577 + kfree(driver_request); 1578 + return treatment; 1579 + case REG_REQ_INTERSECT: 1580 + /* fall through */ 1581 + case REG_REQ_ALREADY_SET: 1582 + regd = reg_copy_regd(get_cfg80211_regdom()); 1583 + if (IS_ERR(regd)) { 1584 + kfree(driver_request); 1585 + return REG_REQ_IGNORE; 1586 + } 1587 + rcu_assign_pointer(wiphy->regd, regd); 1588 + } 1589 + 1590 + 1591 + driver_request->intersect = treatment == REG_REQ_INTERSECT; 1592 + driver_request->processed = false; 1593 + 1594 + reg_update_last_request(driver_request); 1595 + 1596 + /* 1597 + * Since CRDA will not be called in this case as we already 1598 + * have applied the requested regulatory domain before we just 1599 + * inform userspace we have processed the request 1600 + */ 1601 + if (treatment == REG_REQ_ALREADY_SET) { 1602 + nl80211_send_reg_change_event(driver_request); 1603 + reg_set_request_processed(); 1604 + return treatment; 1605 + } 1606 + 1607 + return reg_call_crda(driver_request); 1608 + } 1609 + 1610 + static enum reg_request_treatment 1611 + __reg_process_hint_country_ie(struct wiphy *wiphy, 1612 + struct regulatory_request *country_ie_request) 1613 + { 1614 + struct wiphy *last_wiphy = NULL; 1615 + struct regulatory_request *lr = get_last_request(); 1616 + 1617 + if (reg_request_cell_base(lr)) { 1618 + /* Trust a Cell base station over the AP's country IE */ 1619 + if (regdom_changes(country_ie_request->alpha2)) 1620 + return REG_REQ_IGNORE; 1621 + return REG_REQ_ALREADY_SET; 1622 + } else { 1623 + if (wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_IGNORE) 1624 + return REG_REQ_IGNORE; 1625 + } 1626 + 1627 + if (unlikely(!is_an_alpha2(country_ie_request->alpha2))) 1628 + return -EINVAL; 1629 + 1630 + if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) 1631 + return REG_REQ_OK; 1632 + 1633 + last_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); 1634 + 1635 + if (last_wiphy != wiphy) { 1636 + /* 1637 + * Two cards with two APs claiming different 1638 + * Country IE alpha2s. We could 1639 + * intersect them, but that seems unlikely 1640 + * to be correct. Reject second one for now. 1641 + */ 1642 + if (regdom_changes(country_ie_request->alpha2)) 1643 + return REG_REQ_IGNORE; 1644 + return REG_REQ_ALREADY_SET; 1645 + } 1646 + /* 1647 + * Two consecutive Country IE hints on the same wiphy. 1648 + * This should be picked up early by the driver/stack 1649 + */ 1650 + if (WARN_ON(regdom_changes(country_ie_request->alpha2))) 1651 + return REG_REQ_OK; 1652 + return REG_REQ_ALREADY_SET; 1653 + } 1654 + 1655 + /** 1656 + * reg_process_hint_country_ie - process regulatory requests from country IEs 1657 + * @country_ie_request: a regulatory request from a country IE 1658 + * 1659 + * The wireless subsystem can use this function to process 1660 + * a regulatory request issued by a country Information Element. 1661 + * 1662 + * Returns one of the different reg request treatment values. 1663 + */ 1664 + static enum reg_request_treatment 1665 + reg_process_hint_country_ie(struct wiphy *wiphy, 1666 + struct regulatory_request *country_ie_request) 1667 + { 1668 + enum reg_request_treatment treatment; 1669 + 1670 + treatment = __reg_process_hint_country_ie(wiphy, country_ie_request); 1671 + 1672 + switch (treatment) { 1673 + case REG_REQ_OK: 1674 + break; 1675 + case REG_REQ_IGNORE: 1676 + /* fall through */ 1677 + case REG_REQ_ALREADY_SET: 1678 + kfree(country_ie_request); 1679 + return treatment; 1680 + case REG_REQ_INTERSECT: 1681 + kfree(country_ie_request); 1682 + /* 1683 + * This doesn't happen yet, not sure we 1684 + * ever want to support it for this case. 1685 + */ 1686 + WARN_ONCE(1, "Unexpected intersection for country IEs"); 1687 + return REG_REQ_IGNORE; 1688 + } 1689 + 1690 + country_ie_request->intersect = false; 1691 + country_ie_request->processed = false; 1692 + 1693 + reg_update_last_request(country_ie_request); 1694 + 1695 + return reg_call_crda(country_ie_request); 1696 + } 1697 + 1492 1698 /* This processes *all* regulatory hints */ 1493 - static void reg_process_hint(struct regulatory_request *reg_request, 1494 - enum nl80211_reg_initiator reg_initiator) 1699 + static void reg_process_hint(struct regulatory_request *reg_request) 1495 1700 { 1496 1701 struct wiphy *wiphy = NULL; 1702 + enum reg_request_treatment treatment; 1497 1703 1498 1704 if (WARN_ON(!reg_request->alpha2)) 1499 1705 return; ··· 1662 1546 if (reg_request->wiphy_idx != WIPHY_IDX_INVALID) 1663 1547 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx); 1664 1548 1665 - if (reg_initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) { 1549 + if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) { 1666 1550 kfree(reg_request); 1667 1551 return; 1668 1552 } 1669 1553 1670 - switch (__regulatory_hint(wiphy, reg_request)) { 1671 - case REG_REQ_ALREADY_SET: 1672 - /* This is required so that the orig_* parameters are saved */ 1673 - if (wiphy && wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) 1674 - wiphy_update_regulatory(wiphy, reg_initiator); 1554 + switch (reg_request->initiator) { 1555 + case NL80211_REGDOM_SET_BY_CORE: 1556 + reg_process_hint_core(reg_request); 1557 + return; 1558 + case NL80211_REGDOM_SET_BY_USER: 1559 + treatment = reg_process_hint_user(reg_request); 1560 + if (treatment == REG_REQ_OK || 1561 + treatment == REG_REQ_ALREADY_SET) 1562 + return; 1563 + schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142)); 1564 + return; 1565 + case NL80211_REGDOM_SET_BY_DRIVER: 1566 + treatment = reg_process_hint_driver(wiphy, reg_request); 1567 + break; 1568 + case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1569 + treatment = reg_process_hint_country_ie(wiphy, reg_request); 1675 1570 break; 1676 1571 default: 1677 - if (reg_initiator == NL80211_REGDOM_SET_BY_USER) 1678 - schedule_delayed_work(&reg_timeout, 1679 - msecs_to_jiffies(3142)); 1680 - break; 1572 + WARN(1, "invalid initiator %d\n", reg_request->initiator); 1573 + return; 1681 1574 } 1575 + 1576 + /* This is required so that the orig_* parameters are saved */ 1577 + if (treatment == REG_REQ_ALREADY_SET && wiphy && 1578 + wiphy->regulatory_flags & REGULATORY_STRICT_REG) 1579 + wiphy_update_regulatory(wiphy, reg_request->initiator); 1682 1580 } 1683 1581 1684 1582 /* ··· 1726 1596 1727 1597 spin_unlock(&reg_requests_lock); 1728 1598 1729 - reg_process_hint(reg_request, reg_request->initiator); 1599 + reg_process_hint(reg_request); 1730 1600 } 1731 1601 1732 1602 /* Processes beacon hints -- this has nothing to do with country IEs */ ··· 2018 1888 world_alpha2[1] = cfg80211_world_regdom->alpha2[1]; 2019 1889 2020 1890 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2021 - if (rdev->wiphy.flags & WIPHY_FLAG_CUSTOM_REGULATORY) 1891 + if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG) 2022 1892 restore_custom_reg_settings(&rdev->wiphy); 2023 1893 } 2024 1894 ··· 2146 2016 } 2147 2017 } 2148 2018 2149 - bool reg_supported_dfs_region(u8 dfs_region) 2019 + bool reg_supported_dfs_region(enum nl80211_dfs_regions dfs_region) 2150 2020 { 2151 2021 switch (dfs_region) { 2152 2022 case NL80211_DFS_UNSET: ··· 2158 2028 REG_DBG_PRINT("Ignoring uknown DFS master region: %d\n", 2159 2029 dfs_region); 2160 2030 return false; 2161 - } 2162 - } 2163 - 2164 - static void print_dfs_region(u8 dfs_region) 2165 - { 2166 - if (!dfs_region) 2167 - return; 2168 - 2169 - switch (dfs_region) { 2170 - case NL80211_DFS_FCC: 2171 - pr_info(" DFS Master region FCC"); 2172 - break; 2173 - case NL80211_DFS_ETSI: 2174 - pr_info(" DFS Master region ETSI"); 2175 - break; 2176 - case NL80211_DFS_JP: 2177 - pr_info(" DFS Master region JP"); 2178 - break; 2179 - default: 2180 - pr_info(" DFS Master region Unknown"); 2181 - break; 2182 2031 } 2183 2032 } 2184 2033 ··· 2192 2083 } 2193 2084 } 2194 2085 2195 - print_dfs_region(rd->dfs_region); 2086 + pr_info(" DFS Master region: %s", reg_dfs_region_str(rd->dfs_region)); 2196 2087 print_rd_rules(rd); 2197 2088 } 2198 2089 ··· 2202 2093 print_rd_rules(rd); 2203 2094 } 2204 2095 2205 - /* Takes ownership of rd only if it doesn't fail */ 2206 - static int __set_regdom(const struct ieee80211_regdomain *rd) 2096 + static int reg_set_rd_core(const struct ieee80211_regdomain *rd) 2207 2097 { 2208 - const struct ieee80211_regdomain *regd; 2098 + if (!is_world_regdom(rd->alpha2)) 2099 + return -EINVAL; 2100 + update_world_regdomain(rd); 2101 + return 0; 2102 + } 2103 + 2104 + static int reg_set_rd_user(const struct ieee80211_regdomain *rd, 2105 + struct regulatory_request *user_request) 2106 + { 2209 2107 const struct ieee80211_regdomain *intersected_rd = NULL; 2210 - struct wiphy *request_wiphy; 2211 - struct regulatory_request *lr = get_last_request(); 2212 2108 2213 - /* Some basic sanity checks first */ 2214 - 2215 - if (!reg_is_valid_request(rd->alpha2)) 2109 + if (is_world_regdom(rd->alpha2)) 2216 2110 return -EINVAL; 2217 2111 2218 - if (is_world_regdom(rd->alpha2)) { 2219 - update_world_regdomain(rd); 2220 - return 0; 2221 - } 2222 - 2223 - if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) && 2224 - !is_unknown_alpha2(rd->alpha2)) 2225 - return -EINVAL; 2226 - 2227 - /* 2228 - * Lets only bother proceeding on the same alpha2 if the current 2229 - * rd is non static (it means CRDA was present and was used last) 2230 - * and the pending request came in from a country IE 2231 - */ 2232 - if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 2233 - /* 2234 - * If someone else asked us to change the rd lets only bother 2235 - * checking if the alpha2 changes if CRDA was already called 2236 - */ 2237 - if (!regdom_changes(rd->alpha2)) 2238 - return -EALREADY; 2239 - } 2240 - 2241 - /* 2242 - * Now lets set the regulatory domain, update all driver channels 2243 - * and finally inform them of what we have done, in case they want 2244 - * to review or adjust their own settings based on their own 2245 - * internal EEPROM data 2246 - */ 2112 + if (!regdom_changes(rd->alpha2)) 2113 + return -EALREADY; 2247 2114 2248 2115 if (!is_valid_rd(rd)) { 2249 2116 pr_err("Invalid regulatory domain detected:\n"); ··· 2227 2142 return -EINVAL; 2228 2143 } 2229 2144 2230 - request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); 2231 - if (!request_wiphy && 2232 - (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER || 2233 - lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) { 2145 + if (!user_request->intersect) { 2146 + reset_regdomains(false, rd); 2147 + return 0; 2148 + } 2149 + 2150 + intersected_rd = regdom_intersect(rd, get_cfg80211_regdom()); 2151 + if (!intersected_rd) 2152 + return -EINVAL; 2153 + 2154 + kfree(rd); 2155 + rd = NULL; 2156 + reset_regdomains(false, intersected_rd); 2157 + 2158 + return 0; 2159 + } 2160 + 2161 + static int reg_set_rd_driver(const struct ieee80211_regdomain *rd, 2162 + struct regulatory_request *driver_request) 2163 + { 2164 + const struct ieee80211_regdomain *regd; 2165 + const struct ieee80211_regdomain *intersected_rd = NULL; 2166 + const struct ieee80211_regdomain *tmp; 2167 + struct wiphy *request_wiphy; 2168 + 2169 + if (is_world_regdom(rd->alpha2)) 2170 + return -EINVAL; 2171 + 2172 + if (!regdom_changes(rd->alpha2)) 2173 + return -EALREADY; 2174 + 2175 + if (!is_valid_rd(rd)) { 2176 + pr_err("Invalid regulatory domain detected:\n"); 2177 + print_regdomain_info(rd); 2178 + return -EINVAL; 2179 + } 2180 + 2181 + request_wiphy = wiphy_idx_to_wiphy(driver_request->wiphy_idx); 2182 + if (!request_wiphy) { 2234 2183 schedule_delayed_work(&reg_timeout, 0); 2235 2184 return -ENODEV; 2236 2185 } 2237 2186 2238 - if (!lr->intersect) { 2239 - if (lr->initiator != NL80211_REGDOM_SET_BY_DRIVER) { 2240 - reset_regdomains(false, rd); 2241 - return 0; 2242 - } 2243 - 2244 - /* 2245 - * For a driver hint, lets copy the regulatory domain the 2246 - * driver wanted to the wiphy to deal with conflicts 2247 - */ 2248 - 2249 - /* 2250 - * Userspace could have sent two replies with only 2251 - * one kernel request. 2252 - */ 2187 + if (!driver_request->intersect) { 2253 2188 if (request_wiphy->regd) 2254 2189 return -EALREADY; 2255 2190 ··· 2282 2177 return 0; 2283 2178 } 2284 2179 2285 - /* Intersection requires a bit more work */ 2180 + intersected_rd = regdom_intersect(rd, get_cfg80211_regdom()); 2181 + if (!intersected_rd) 2182 + return -EINVAL; 2286 2183 2287 - if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 2288 - intersected_rd = regdom_intersect(rd, get_cfg80211_regdom()); 2289 - if (!intersected_rd) 2290 - return -EINVAL; 2184 + /* 2185 + * We can trash what CRDA provided now. 2186 + * However if a driver requested this specific regulatory 2187 + * domain we keep it for its private use 2188 + */ 2189 + tmp = get_wiphy_regdom(request_wiphy); 2190 + rcu_assign_pointer(request_wiphy->regd, rd); 2191 + rcu_free_regdom(tmp); 2291 2192 2292 - /* 2293 - * We can trash what CRDA provided now. 2294 - * However if a driver requested this specific regulatory 2295 - * domain we keep it for its private use 2296 - */ 2297 - if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) { 2298 - const struct ieee80211_regdomain *tmp; 2193 + rd = NULL; 2299 2194 2300 - tmp = get_wiphy_regdom(request_wiphy); 2301 - rcu_assign_pointer(request_wiphy->regd, rd); 2302 - rcu_free_regdom(tmp); 2303 - } else { 2304 - kfree(rd); 2305 - } 2195 + reset_regdomains(false, intersected_rd); 2306 2196 2307 - rd = NULL; 2308 - 2309 - reset_regdomains(false, intersected_rd); 2310 - 2311 - return 0; 2312 - } 2313 - 2314 - return -EINVAL; 2197 + return 0; 2315 2198 } 2316 2199 2200 + static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd, 2201 + struct regulatory_request *country_ie_request) 2202 + { 2203 + struct wiphy *request_wiphy; 2204 + 2205 + if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) && 2206 + !is_unknown_alpha2(rd->alpha2)) 2207 + return -EINVAL; 2208 + 2209 + /* 2210 + * Lets only bother proceeding on the same alpha2 if the current 2211 + * rd is non static (it means CRDA was present and was used last) 2212 + * and the pending request came in from a country IE 2213 + */ 2214 + 2215 + if (!is_valid_rd(rd)) { 2216 + pr_err("Invalid regulatory domain detected:\n"); 2217 + print_regdomain_info(rd); 2218 + return -EINVAL; 2219 + } 2220 + 2221 + request_wiphy = wiphy_idx_to_wiphy(country_ie_request->wiphy_idx); 2222 + if (!request_wiphy) { 2223 + schedule_delayed_work(&reg_timeout, 0); 2224 + return -ENODEV; 2225 + } 2226 + 2227 + if (country_ie_request->intersect) 2228 + return -EINVAL; 2229 + 2230 + reset_regdomains(false, rd); 2231 + return 0; 2232 + } 2317 2233 2318 2234 /* 2319 2235 * Use this call to set the current regulatory domain. Conflicts with ··· 2346 2220 struct regulatory_request *lr; 2347 2221 int r; 2348 2222 2223 + if (!reg_is_valid_request(rd->alpha2)) { 2224 + kfree(rd); 2225 + return -EINVAL; 2226 + } 2227 + 2349 2228 lr = get_last_request(); 2350 2229 2351 2230 /* Note that this doesn't update the wiphys, this is done below */ 2352 - r = __set_regdom(rd); 2231 + switch (lr->initiator) { 2232 + case NL80211_REGDOM_SET_BY_CORE: 2233 + r = reg_set_rd_core(rd); 2234 + break; 2235 + case NL80211_REGDOM_SET_BY_USER: 2236 + r = reg_set_rd_user(rd, lr); 2237 + break; 2238 + case NL80211_REGDOM_SET_BY_DRIVER: 2239 + r = reg_set_rd_driver(rd, lr); 2240 + break; 2241 + case NL80211_REGDOM_SET_BY_COUNTRY_IE: 2242 + r = reg_set_rd_country_ie(rd, lr); 2243 + break; 2244 + default: 2245 + WARN(1, "invalid initiator %d\n", lr->initiator); 2246 + return -EINVAL; 2247 + } 2248 + 2353 2249 if (r) { 2354 2250 if (r == -EALREADY) 2355 2251 reg_set_request_processed();
+2 -1
net/wireless/reg.h
··· 18 18 19 19 extern const struct ieee80211_regdomain __rcu *cfg80211_regdomain; 20 20 21 + bool reg_is_valid_request(const char *alpha2); 21 22 bool is_world_regdom(const char *alpha2); 22 - bool reg_supported_dfs_region(u8 dfs_region); 23 + bool reg_supported_dfs_region(enum nl80211_dfs_regions dfs_region); 23 24 24 25 int regulatory_hint_user(const char *alpha2, 25 26 enum nl80211_user_reg_hint_type user_reg_hint_type);
+7 -8
net/wireless/trace.h
··· 1653 1653 1654 1654 TRACE_EVENT(rdev_mgmt_tx, 1655 1655 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1656 - struct ieee80211_channel *chan, bool offchan, 1657 - unsigned int wait, bool no_cck, bool dont_wait_for_ack), 1658 - TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack), 1656 + struct cfg80211_mgmt_tx_params *params), 1657 + TP_ARGS(wiphy, wdev, params), 1659 1658 TP_STRUCT__entry( 1660 1659 WIPHY_ENTRY 1661 1660 WDEV_ENTRY ··· 1667 1668 TP_fast_assign( 1668 1669 WIPHY_ASSIGN; 1669 1670 WDEV_ASSIGN; 1670 - CHAN_ASSIGN(chan); 1671 - __entry->offchan = offchan; 1672 - __entry->wait = wait; 1673 - __entry->no_cck = no_cck; 1674 - __entry->dont_wait_for_ack = dont_wait_for_ack; 1671 + CHAN_ASSIGN(params->chan); 1672 + __entry->offchan = params->offchan; 1673 + __entry->wait = params->wait; 1674 + __entry->no_cck = params->no_cck; 1675 + __entry->dont_wait_for_ack = params->dont_wait_for_ack; 1675 1676 ), 1676 1677 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s," 1677 1678 " wait: %u, no cck: %s, dont wait for ack: %s",