aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-08-16 14:48:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-08-16 14:48:40 -0400
commit24de851b79a414f0e1813eb131a7d90849cc22c2 (patch)
tree4da554a6d83adbfea3e00e242f97028a69cc0bb7 /drivers/net
parentd0746663667f37e7be5646bf68cb452c8375a23d (diff)
parent89716344806bd49d213ad5960661e8c2d38c4982 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c151
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h24
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h228
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c199
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c474
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h64
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c61
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c96
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c43
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c26
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c38
20 files changed, 809 insertions, 713 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index e5c133ee7901..3eb2102ce236 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -22,6 +22,8 @@ config IWLWIFI
22 Intel Wireless WiFi Link 6150BGN 2 Adapter 22 Intel Wireless WiFi Link 6150BGN 2 Adapter
23 Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) 23 Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN)
24 Intel 2000 Series Wi-Fi Adapters 24 Intel 2000 Series Wi-Fi Adapters
25 Intel 7260 Wi-Fi Adapter
26 Intel 3160 Wi-Fi Adapter
25 27
26 28
27 This driver uses the kernel's mac80211 subsystem. 29 This driver uses the kernel's mac80211 subsystem.
@@ -46,17 +48,16 @@ config IWLDVM
46 depends on IWLWIFI 48 depends on IWLWIFI
47 default IWLWIFI 49 default IWLWIFI
48 help 50 help
49 This is the driver supporting the DVM firmware which is 51 This is the driver that supports the DVM firmware which is
50 currently the only firmware available for existing devices. 52 used by most existing devices (with the exception of 7260
53 and 3160).
51 54
52config IWLMVM 55config IWLMVM
53 tristate "Intel Wireless WiFi MVM Firmware support" 56 tristate "Intel Wireless WiFi MVM Firmware support"
54 depends on IWLWIFI 57 depends on IWLWIFI
55 help 58 help
56 This is the driver supporting the MVM firmware which is 59 This is the driver that supports the MVM firmware which is
57 currently only available for 7000 series devices. 60 currently only available for 7260 and 3160 devices.
58
59 Say yes if you have such a device.
60 61
61# don't call it _MODULE -- will confuse Kconfig/fixdep/... 62# don't call it _MODULE -- will confuse Kconfig/fixdep/...
62config IWLWIFI_OPMODE_MODULAR 63config IWLWIFI_OPMODE_MODULAR
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 7edb8519c8a4..b2bb32a781dd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -145,6 +145,7 @@ do { \
145#define IWL_DL_RX 0x01000000 145#define IWL_DL_RX 0x01000000
146#define IWL_DL_ISR 0x02000000 146#define IWL_DL_ISR 0x02000000
147#define IWL_DL_HT 0x04000000 147#define IWL_DL_HT 0x04000000
148#define IWL_DL_EXTERNAL 0x08000000
148/* 0xF0000000 - 0x10000000 */ 149/* 0xF0000000 - 0x10000000 */
149#define IWL_DL_11H 0x10000000 150#define IWL_DL_11H 0x10000000
150#define IWL_DL_STATS 0x20000000 151#define IWL_DL_STATS 0x20000000
@@ -153,6 +154,7 @@ do { \
153 154
154#define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) 155#define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a)
155#define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) 156#define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a)
157#define IWL_DEBUG_EXTERNAL(p, f, a...) IWL_DEBUG(p, IWL_DL_EXTERNAL, f, ## a)
156#define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a) 158#define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a)
157#define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a) 159#define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a)
158#define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a) 160#define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index d0162d426f88..99e1da3123c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -843,7 +843,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
843 int i; 843 int i;
844 bool load_module = false; 844 bool load_module = false;
845 845
846 fw->ucode_capa.max_probe_length = 200; 846 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
847 fw->ucode_capa.standard_phy_calibration_size = 847 fw->ucode_capa.standard_phy_calibration_size =
848 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; 848 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
849 849
@@ -1032,8 +1032,10 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
1032 int ret; 1032 int ret;
1033 1033
1034 drv = kzalloc(sizeof(*drv), GFP_KERNEL); 1034 drv = kzalloc(sizeof(*drv), GFP_KERNEL);
1035 if (!drv) 1035 if (!drv) {
1036 return NULL; 1036 ret = -ENOMEM;
1037 goto err;
1038 }
1037 1039
1038 drv->trans = trans; 1040 drv->trans = trans;
1039 drv->dev = trans->dev; 1041 drv->dev = trans->dev;
@@ -1078,7 +1080,7 @@ err_free_dbgfs:
1078err_free_drv: 1080err_free_drv:
1079#endif 1081#endif
1080 kfree(drv); 1082 kfree(drv);
1081 1083err:
1082 return ERR_PTR(ret); 1084 return ERR_PTR(ret);
1083} 1085}
1084 1086
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index bd335f0c40d1..a1223680bc70 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -76,6 +76,7 @@
76 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS 76 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
77 * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD 77 * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
78 * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api 78 * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
79 * @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.
79 * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six 80 * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
80 * (rather than two) IPv6 addresses 81 * (rather than two) IPv6 addresses
81 * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API 82 * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
@@ -88,6 +89,7 @@ enum iwl_ucode_tlv_flag {
88 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), 89 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
89 IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6), 90 IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6),
90 IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8), 91 IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8),
92 IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9),
91 IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10), 93 IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
92 IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11), 94 IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11),
93}; 95};
@@ -97,6 +99,9 @@ enum iwl_ucode_tlv_flag {
97#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 99#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
98#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 100#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253
99 101
102/* The default max probe length if not specified by the firmware file */
103#define IWL_DEFAULT_MAX_PROBE_LENGTH 200
104
100/** 105/**
101 * enum iwl_ucode_type 106 * enum iwl_ucode_type
102 * 107 *
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 64656e0c8f91..2bf29f7992ee 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -67,5 +67,14 @@
67#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC) 67#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
68#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC) 68#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
69#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC) 69#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
70#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
71#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
72#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20
73#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 20
74#define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50
75#define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50
76#define IWL_MVM_PS_SNOOZE_INTERVAL 25
77#define IWL_MVM_PS_SNOOZE_WINDOW 50
78#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
70 79
71#endif /* __MVM_CONSTANTS_H */ 80#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index d0d7a20266e6..417639f77b01 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1109,73 +1109,16 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1109 return __iwl_mvm_suspend(hw, wowlan, false); 1109 return __iwl_mvm_suspend(hw, wowlan, false);
1110} 1110}
1111 1111
1112static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, 1112static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1113 struct ieee80211_vif *vif) 1113 struct ieee80211_vif *vif,
1114 struct iwl_wowlan_status *status)
1114{ 1115{
1115 u32 base = mvm->error_event_table; 1116 struct sk_buff *pkt = NULL;
1116 struct error_table_start {
1117 /* cf. struct iwl_error_event_table */
1118 u32 valid;
1119 u32 error_id;
1120 } err_info;
1121 struct cfg80211_wowlan_wakeup wakeup = { 1117 struct cfg80211_wowlan_wakeup wakeup = {
1122 .pattern_idx = -1, 1118 .pattern_idx = -1,
1123 }; 1119 };
1124 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; 1120 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1125 struct iwl_host_cmd cmd = { 1121 u32 reasons = le32_to_cpu(status->wakeup_reasons);
1126 .id = WOWLAN_GET_STATUSES,
1127 .flags = CMD_SYNC | CMD_WANT_SKB,
1128 };
1129 struct iwl_wowlan_status *status;
1130 u32 reasons;
1131 int ret, len;
1132 struct sk_buff *pkt = NULL;
1133
1134 iwl_trans_read_mem_bytes(mvm->trans, base,
1135 &err_info, sizeof(err_info));
1136
1137 if (err_info.valid) {
1138 IWL_INFO(mvm, "error table is valid (%d)\n",
1139 err_info.valid);
1140 if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
1141 wakeup.rfkill_release = true;
1142 ieee80211_report_wowlan_wakeup(vif, &wakeup,
1143 GFP_KERNEL);
1144 }
1145 return;
1146 }
1147
1148 /* only for tracing for now */
1149 ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL);
1150 if (ret)
1151 IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);
1152
1153 ret = iwl_mvm_send_cmd(mvm, &cmd);
1154 if (ret) {
1155 IWL_ERR(mvm, "failed to query status (%d)\n", ret);
1156 return;
1157 }
1158
1159 /* RF-kill already asserted again... */
1160 if (!cmd.resp_pkt)
1161 return;
1162
1163 len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
1164 if (len - sizeof(struct iwl_cmd_header) < sizeof(*status)) {
1165 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1166 goto out;
1167 }
1168
1169 status = (void *)cmd.resp_pkt->data;
1170
1171 if (len - sizeof(struct iwl_cmd_header) !=
1172 sizeof(*status) +
1173 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
1174 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1175 goto out;
1176 }
1177
1178 reasons = le32_to_cpu(status->wakeup_reasons);
1179 1122
1180 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { 1123 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
1181 wakeup_report = NULL; 1124 wakeup_report = NULL;
@@ -1238,6 +1181,12 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1238 pktsize -= hdrlen; 1181 pktsize -= hdrlen;
1239 1182
1240 if (ieee80211_has_protected(hdr->frame_control)) { 1183 if (ieee80211_has_protected(hdr->frame_control)) {
1184 /*
1185 * This is unlocked and using gtk_i(c)vlen,
1186 * but since everything is under RTNL still
1187 * that's not really a problem - changing
1188 * it would be difficult.
1189 */
1241 if (is_multicast_ether_addr(hdr->addr1)) { 1190 if (is_multicast_ether_addr(hdr->addr1)) {
1242 ivlen = mvm->gtk_ivlen; 1191 ivlen = mvm->gtk_ivlen;
1243 icvlen += mvm->gtk_icvlen; 1192 icvlen += mvm->gtk_icvlen;
@@ -1288,9 +1237,82 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1288 report: 1237 report:
1289 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); 1238 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1290 kfree_skb(pkt); 1239 kfree_skb(pkt);
1240}
1291 1241
1292 out: 1242/* releases the MVM mutex */
1243static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1244 struct ieee80211_vif *vif)
1245{
1246 u32 base = mvm->error_event_table;
1247 struct error_table_start {
1248 /* cf. struct iwl_error_event_table */
1249 u32 valid;
1250 u32 error_id;
1251 } err_info;
1252 struct iwl_host_cmd cmd = {
1253 .id = WOWLAN_GET_STATUSES,
1254 .flags = CMD_SYNC | CMD_WANT_SKB,
1255 };
1256 struct iwl_wowlan_status *status;
1257 int ret, len;
1258
1259 iwl_trans_read_mem_bytes(mvm->trans, base,
1260 &err_info, sizeof(err_info));
1261
1262 if (err_info.valid) {
1263 IWL_INFO(mvm, "error table is valid (%d)\n",
1264 err_info.valid);
1265 if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
1266 struct cfg80211_wowlan_wakeup wakeup = {
1267 .rfkill_release = true,
1268 };
1269 ieee80211_report_wowlan_wakeup(vif, &wakeup,
1270 GFP_KERNEL);
1271 }
1272 goto out_unlock;
1273 }
1274
1275 /* only for tracing for now */
1276 ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, CMD_SYNC, 0, NULL);
1277 if (ret)
1278 IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);
1279
1280 ret = iwl_mvm_send_cmd(mvm, &cmd);
1281 if (ret) {
1282 IWL_ERR(mvm, "failed to query status (%d)\n", ret);
1283 goto out_unlock;
1284 }
1285
1286 /* RF-kill already asserted again... */
1287 if (!cmd.resp_pkt)
1288 goto out_unlock;
1289
1290 len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
1291 if (len - sizeof(struct iwl_cmd_header) < sizeof(*status)) {
1292 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1293 goto out_free_resp;
1294 }
1295
1296 status = (void *)cmd.resp_pkt->data;
1297
1298 if (len - sizeof(struct iwl_cmd_header) !=
1299 sizeof(*status) +
1300 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
1301 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1302 goto out_free_resp;
1303 }
1304
1305 /* now we have all the data we need, unlock to avoid mac80211 issues */
1306 mutex_unlock(&mvm->mutex);
1307
1308 iwl_mvm_report_wakeup_reasons(mvm, vif, status);
1309 iwl_free_resp(&cmd);
1310 return;
1311
1312 out_free_resp:
1293 iwl_free_resp(&cmd); 1313 iwl_free_resp(&cmd);
1314 out_unlock:
1315 mutex_unlock(&mvm->mutex);
1294} 1316}
1295 1317
1296static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm) 1318static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
@@ -1347,10 +1369,13 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1347 iwl_mvm_read_d3_sram(mvm); 1369 iwl_mvm_read_d3_sram(mvm);
1348 1370
1349 iwl_mvm_query_wakeup_reasons(mvm, vif); 1371 iwl_mvm_query_wakeup_reasons(mvm, vif);
1372 /* has unlocked the mutex, so skip that */
1373 goto out;
1350 1374
1351 out_unlock: 1375 out_unlock:
1352 mutex_unlock(&mvm->mutex); 1376 mutex_unlock(&mvm->mutex);
1353 1377
1378 out:
1354 if (!test && vif) 1379 if (!test && vif)
1355 ieee80211_resume_disconnect(vif); 1380 ieee80211_resume_disconnect(vif);
1356 1381
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index cc157734eb21..aac81b8984b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -352,6 +352,10 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
352 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val); 352 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
353 dbgfs_pm->lprx_rssi_threshold = val; 353 dbgfs_pm->lprx_rssi_threshold = val;
354 break; 354 break;
355 case MVM_DEBUGFS_PM_SNOOZE_ENABLE:
356 IWL_DEBUG_POWER(mvm, "snooze_enable=%d\n", val);
357 dbgfs_pm->snooze_ena = val;
358 break;
355 } 359 }
356} 360}
357 361
@@ -405,6 +409,10 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
405 POWER_LPRX_RSSI_THRESHOLD_MIN) 409 POWER_LPRX_RSSI_THRESHOLD_MIN)
406 return -EINVAL; 410 return -EINVAL;
407 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD; 411 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
412 } else if (!strncmp("snooze_enable=", buf, 14)) {
413 if (sscanf(buf + 14, "%d", &val) != 1)
414 return -EINVAL;
415 param = MVM_DEBUGFS_PM_SNOOZE_ENABLE;
408 } else { 416 } else {
409 return -EINVAL; 417 return -EINVAL;
410 } 418 }
@@ -424,7 +432,7 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
424 struct ieee80211_vif *vif = file->private_data; 432 struct ieee80211_vif *vif = file->private_data;
425 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 433 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
426 struct iwl_mvm *mvm = mvmvif->dbgfs_data; 434 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
427 char buf[256]; 435 char buf[512];
428 int bufsz = sizeof(buf); 436 int bufsz = sizeof(buf);
429 int pos; 437 int pos;
430 438
@@ -895,10 +903,7 @@ static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
895 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) { 903 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
896 ret = iwl_mvm_disable_beacon_filter(mvm, vif); 904 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
897 } else { 905 } else {
898 if (mvmvif->bf_enabled) 906 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
899 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
900 else
901 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
902 } 907 }
903 mutex_unlock(&mvm->mutex); 908 mutex_unlock(&mvm->mutex);
904 909
@@ -923,7 +928,7 @@ static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
923 }; 928 };
924 929
925 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); 930 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
926 if (mvmvif->bf_enabled) 931 if (mvmvif->bf_data.bf_enabled)
927 cmd.bf_enable_beacon_filter = cpu_to_le32(1); 932 cmd.bf_enable_beacon_filter = cpu_to_le32(1);
928 else 933 else
929 cmd.bf_enable_beacon_filter = 0; 934 cmd.bf_enable_beacon_filter = 0;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 060e630b3d82..8e7ab41079ca 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -155,8 +155,12 @@ struct iwl_powertable_cmd {
155 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. 155 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
156 * Default: 80dbm 156 * Default: 80dbm
157 * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set 157 * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set
158 * @snooze_interval: TBD 158 * @snooze_interval: Maximum time between attempts to retrieve buffered data
159 * @snooze_window: TBD 159 * from the AP [msec]
160 * @snooze_window: A window of time in which PBW snoozing insures that all
161 * packets received. It is also the minimum time from last
162 * received unicast RX packet, before client stops snoozing
163 * for data. [msec]
160 * @snooze_step: TBD 164 * @snooze_step: TBD
161 * @qndp_tid: TID client shall use for uAPSD QNDP triggers 165 * @qndp_tid: TID client shall use for uAPSD QNDP triggers
162 * @uapsd_ac_flags: Set trigger-enabled and delivery-enabled indication for 166 * @uapsd_ac_flags: Set trigger-enabled and delivery-enabled indication for
@@ -164,10 +168,10 @@ struct iwl_powertable_cmd {
164 * Use IEEE80211_WMM_IE_STA_QOSINFO_AC* for correct values. 168 * Use IEEE80211_WMM_IE_STA_QOSINFO_AC* for correct values.
165 * @uapsd_max_sp: Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct 169 * @uapsd_max_sp: Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct
166 * values. 170 * values.
167 * @heavy_traffic_thr_tx_pkts: TX threshold measured in number of packets 171 * @heavy_tx_thld_packets: TX threshold measured in number of packets
168 * @heavy_traffic_thr_rx_pkts: RX threshold measured in number of packets 172 * @heavy_rx_thld_packets: RX threshold measured in number of packets
169 * @heavy_traffic_thr_tx_load: TX threshold measured in load's percentage 173 * @heavy_tx_thld_percentage: TX threshold measured in load's percentage
170 * @heavy_traffic_thr_rx_load: RX threshold measured in load's percentage 174 * @heavy_rx_thld_percentage: RX threshold measured in load's percentage
171 * @limited_ps_threshold: 175 * @limited_ps_threshold:
172*/ 176*/
173struct iwl_mac_power_cmd { 177struct iwl_mac_power_cmd {
@@ -189,10 +193,10 @@ struct iwl_mac_power_cmd {
189 u8 qndp_tid; 193 u8 qndp_tid;
190 u8 uapsd_ac_flags; 194 u8 uapsd_ac_flags;
191 u8 uapsd_max_sp; 195 u8 uapsd_max_sp;
192 u8 heavy_traffic_threshold_tx_packets; 196 u8 heavy_tx_thld_packets;
193 u8 heavy_traffic_threshold_rx_packets; 197 u8 heavy_rx_thld_packets;
194 u8 heavy_traffic_threshold_tx_percentage; 198 u8 heavy_tx_thld_percentage;
195 u8 heavy_traffic_threshold_rx_percentage; 199 u8 heavy_rx_thld_percentage;
196 u8 limited_ps_threshold; 200 u8 limited_ps_threshold;
197 u8 reserved; 201 u8 reserved;
198} __packed; 202} __packed;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 55854a309f94..66264cc5a016 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -499,71 +499,199 @@ enum iwl_time_event_type {
499 TE_MAX 499 TE_MAX
500}; /* MAC_EVENT_TYPE_API_E_VER_1 */ 500}; /* MAC_EVENT_TYPE_API_E_VER_1 */
501 501
502
503
504/* Time event - defines for command API v1 */
505
506/*
507 * @TE_V1_FRAG_NONE: fragmentation of the time event is NOT allowed.
508 * @TE_V1_FRAG_SINGLE: fragmentation of the time event is allowed, but only
509 * the first fragment is scheduled.
510 * @TE_V1_FRAG_DUAL: fragmentation of the time event is allowed, but only
511 * the first 2 fragments are scheduled.
512 * @TE_V1_FRAG_ENDLESS: fragmentation of the time event is allowed, and any
513 * number of fragments are valid.
514 *
515 * Other than the constant defined above, specifying a fragmentation value 'x'
516 * means that the event can be fragmented but only the first 'x' will be
517 * scheduled.
518 */
519enum {
520 TE_V1_FRAG_NONE = 0,
521 TE_V1_FRAG_SINGLE = 1,
522 TE_V1_FRAG_DUAL = 2,
523 TE_V1_FRAG_ENDLESS = 0xffffffff
524};
525
526/* If a Time Event can be fragmented, this is the max number of fragments */
527#define TE_V1_FRAG_MAX_MSK 0x0fffffff
528/* Repeat the time event endlessly (until removed) */
529#define TE_V1_REPEAT_ENDLESS 0xffffffff
530/* If a Time Event has bounded repetitions, this is the maximal value */
531#define TE_V1_REPEAT_MAX_MSK_V1 0x0fffffff
532
502/* Time Event dependencies: none, on another TE, or in a specific time */ 533/* Time Event dependencies: none, on another TE, or in a specific time */
503enum { 534enum {
504 TE_INDEPENDENT = 0, 535 TE_V1_INDEPENDENT = 0,
505 TE_DEP_OTHER = 1, 536 TE_V1_DEP_OTHER = BIT(0),
506 TE_DEP_TSF = 2, 537 TE_V1_DEP_TSF = BIT(1),
507 TE_EVENT_SOCIOPATHIC = 4, 538 TE_V1_EVENT_SOCIOPATHIC = BIT(2),
508}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ 539}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */
540
509/* 541/*
542 * @TE_V1_NOTIF_NONE: no notifications
543 * @TE_V1_NOTIF_HOST_EVENT_START: request/receive notification on event start
544 * @TE_V1_NOTIF_HOST_EVENT_END:request/receive notification on event end
545 * @TE_V1_NOTIF_INTERNAL_EVENT_START: internal FW use
546 * @TE_V1_NOTIF_INTERNAL_EVENT_END: internal FW use.
547 * @TE_V1_NOTIF_HOST_FRAG_START: request/receive notification on frag start
548 * @TE_V1_NOTIF_HOST_FRAG_END:request/receive notification on frag end
549 * @TE_V1_NOTIF_INTERNAL_FRAG_START: internal FW use.
550 * @TE_V1_NOTIF_INTERNAL_FRAG_END: internal FW use.
551 *
510 * Supported Time event notifications configuration. 552 * Supported Time event notifications configuration.
511 * A notification (both event and fragment) includes a status indicating weather 553 * A notification (both event and fragment) includes a status indicating weather
512 * the FW was able to schedule the event or not. For fragment start/end 554 * the FW was able to schedule the event or not. For fragment start/end
513 * notification the status is always success. There is no start/end fragment 555 * notification the status is always success. There is no start/end fragment
514 * notification for monolithic events. 556 * notification for monolithic events.
515 *
516 * @TE_NOTIF_NONE: no notifications
517 * @TE_NOTIF_HOST_EVENT_START: request/receive notification on event start
518 * @TE_NOTIF_HOST_EVENT_END:request/receive notification on event end
519 * @TE_NOTIF_INTERNAL_EVENT_START: internal FW use
520 * @TE_NOTIF_INTERNAL_EVENT_END: internal FW use.
521 * @TE_NOTIF_HOST_FRAG_START: request/receive notification on frag start
522 * @TE_NOTIF_HOST_FRAG_END:request/receive notification on frag end
523 * @TE_NOTIF_INTERNAL_FRAG_START: internal FW use.
524 * @TE_NOTIF_INTERNAL_FRAG_END: internal FW use.
525 */ 557 */
526enum { 558enum {
527 TE_NOTIF_NONE = 0, 559 TE_V1_NOTIF_NONE = 0,
528 TE_NOTIF_HOST_EVENT_START = 0x1, 560 TE_V1_NOTIF_HOST_EVENT_START = BIT(0),
529 TE_NOTIF_HOST_EVENT_END = 0x2, 561 TE_V1_NOTIF_HOST_EVENT_END = BIT(1),
530 TE_NOTIF_INTERNAL_EVENT_START = 0x4, 562 TE_V1_NOTIF_INTERNAL_EVENT_START = BIT(2),
531 TE_NOTIF_INTERNAL_EVENT_END = 0x8, 563 TE_V1_NOTIF_INTERNAL_EVENT_END = BIT(3),
532 TE_NOTIF_HOST_FRAG_START = 0x10, 564 TE_V1_NOTIF_HOST_FRAG_START = BIT(4),
533 TE_NOTIF_HOST_FRAG_END = 0x20, 565 TE_V1_NOTIF_HOST_FRAG_END = BIT(5),
534 TE_NOTIF_INTERNAL_FRAG_START = 0x40, 566 TE_V1_NOTIF_INTERNAL_FRAG_START = BIT(6),
535 TE_NOTIF_INTERNAL_FRAG_END = 0x80 567 TE_V1_NOTIF_INTERNAL_FRAG_END = BIT(7),
536}; /* MAC_EVENT_ACTION_API_E_VER_2 */ 568}; /* MAC_EVENT_ACTION_API_E_VER_2 */
537 569
570
571/**
572 * struct iwl_time_event_cmd_api_v1 - configuring Time Events
573 * with struct MAC_TIME_EVENT_DATA_API_S_VER_1 (see also
574 * with version 2. determined by IWL_UCODE_TLV_FLAGS)
575 * ( TIME_EVENT_CMD = 0x29 )
576 * @id_and_color: ID and color of the relevant MAC
577 * @action: action to perform, one of FW_CTXT_ACTION_*
578 * @id: this field has two meanings, depending on the action:
579 * If the action is ADD, then it means the type of event to add.
580 * For all other actions it is the unique event ID assigned when the
581 * event was added by the FW.
582 * @apply_time: When to start the Time Event (in GP2)
583 * @max_delay: maximum delay to event's start (apply time), in TU
584 * @depends_on: the unique ID of the event we depend on (if any)
585 * @interval: interval between repetitions, in TU
586 * @interval_reciprocal: 2^32 / interval
587 * @duration: duration of event in TU
588 * @repeat: how many repetitions to do, can be TE_REPEAT_ENDLESS
589 * @dep_policy: one of TE_V1_INDEPENDENT, TE_V1_DEP_OTHER, TE_V1_DEP_TSF
590 * and TE_V1_EVENT_SOCIOPATHIC
591 * @is_present: 0 or 1, are we present or absent during the Time Event
592 * @max_frags: maximal number of fragments the Time Event can be divided to
593 * @notify: notifications using TE_V1_NOTIF_* (whom to notify when)
594 */
595struct iwl_time_event_cmd_v1 {
596 /* COMMON_INDEX_HDR_API_S_VER_1 */
597 __le32 id_and_color;
598 __le32 action;
599 __le32 id;
600 /* MAC_TIME_EVENT_DATA_API_S_VER_1 */
601 __le32 apply_time;
602 __le32 max_delay;
603 __le32 dep_policy;
604 __le32 depends_on;
605 __le32 is_present;
606 __le32 max_frags;
607 __le32 interval;
608 __le32 interval_reciprocal;
609 __le32 duration;
610 __le32 repeat;
611 __le32 notify;
612} __packed; /* MAC_TIME_EVENT_CMD_API_S_VER_1 */
613
614
615/* Time event - defines for command API v2 */
616
538/* 617/*
539 * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed. 618 * @TE_V2_FRAG_NONE: fragmentation of the time event is NOT allowed.
540 * @TE_FRAG_SINGLE: fragmentation of the time event is allowed, but only 619 * @TE_V2_FRAG_SINGLE: fragmentation of the time event is allowed, but only
541 * the first fragment is scheduled. 620 * the first fragment is scheduled.
542 * @TE_FRAG_DUAL: fragmentation of the time event is allowed, but only 621 * @TE_V2_FRAG_DUAL: fragmentation of the time event is allowed, but only
543 * the first 2 fragments are scheduled. 622 * the first 2 fragments are scheduled.
544 * @TE_FRAG_ENDLESS: fragmentation of the time event is allowed, and any number 623 * @TE_V2_FRAG_ENDLESS: fragmentation of the time event is allowed, and any
545 * of fragments are valid. 624 * number of fragments are valid.
546 * 625 *
547 * Other than the constant defined above, specifying a fragmentation value 'x' 626 * Other than the constant defined above, specifying a fragmentation value 'x'
548 * means that the event can be fragmented but only the first 'x' will be 627 * means that the event can be fragmented but only the first 'x' will be
549 * scheduled. 628 * scheduled.
550 */ 629 */
551enum { 630enum {
552 TE_FRAG_NONE = 0, 631 TE_V2_FRAG_NONE = 0,
553 TE_FRAG_SINGLE = 1, 632 TE_V2_FRAG_SINGLE = 1,
554 TE_FRAG_DUAL = 2, 633 TE_V2_FRAG_DUAL = 2,
555 TE_FRAG_ENDLESS = 0xffffffff 634 TE_V2_FRAG_MAX = 0xfe,
635 TE_V2_FRAG_ENDLESS = 0xff
556}; 636};
557 637
558/* Repeat the time event endlessly (until removed) */ 638/* Repeat the time event endlessly (until removed) */
559#define TE_REPEAT_ENDLESS (0xffffffff) 639#define TE_V2_REPEAT_ENDLESS 0xff
560/* If a Time Event has bounded repetitions, this is the maximal value */ 640/* If a Time Event has bounded repetitions, this is the maximal value */
561#define TE_REPEAT_MAX_MSK (0x0fffffff) 641#define TE_V2_REPEAT_MAX 0xfe
562/* If a Time Event can be fragmented, this is the max number of fragments */ 642
563#define TE_FRAG_MAX_MSK (0x0fffffff) 643#define TE_V2_PLACEMENT_POS 12
644#define TE_V2_ABSENCE_POS 15
645
646/* Time event policy values (for time event cmd api v2)
647 * A notification (both event and fragment) includes a status indicating weather
648 * the FW was able to schedule the event or not. For fragment start/end
649 * notification the status is always success. There is no start/end fragment
650 * notification for monolithic events.
651 *
652 * @TE_V2_DEFAULT_POLICY: independent, social, present, unoticable
653 * @TE_V2_NOTIF_HOST_EVENT_START: request/receive notification on event start
654 * @TE_V2_NOTIF_HOST_EVENT_END:request/receive notification on event end
655 * @TE_V2_NOTIF_INTERNAL_EVENT_START: internal FW use
656 * @TE_V2_NOTIF_INTERNAL_EVENT_END: internal FW use.
657 * @TE_V2_NOTIF_HOST_FRAG_START: request/receive notification on frag start
658 * @TE_V2_NOTIF_HOST_FRAG_END:request/receive notification on frag end
659 * @TE_V2_NOTIF_INTERNAL_FRAG_START: internal FW use.
660 * @TE_V2_NOTIF_INTERNAL_FRAG_END: internal FW use.
661 * @TE_V2_DEP_OTHER: depends on another time event
662 * @TE_V2_DEP_TSF: depends on a specific time
663 * @TE_V2_EVENT_SOCIOPATHIC: can't co-exist with other events of tha same MAC
664 * @TE_V2_ABSENCE: are we present or absent during the Time Event.
665 */
666enum {
667 TE_V2_DEFAULT_POLICY = 0x0,
668
669 /* notifications (event start/stop, fragment start/stop) */
670 TE_V2_NOTIF_HOST_EVENT_START = BIT(0),
671 TE_V2_NOTIF_HOST_EVENT_END = BIT(1),
672 TE_V2_NOTIF_INTERNAL_EVENT_START = BIT(2),
673 TE_V2_NOTIF_INTERNAL_EVENT_END = BIT(3),
674
675 TE_V2_NOTIF_HOST_FRAG_START = BIT(4),
676 TE_V2_NOTIF_HOST_FRAG_END = BIT(5),
677 TE_V2_NOTIF_INTERNAL_FRAG_START = BIT(6),
678 TE_V2_NOTIF_INTERNAL_FRAG_END = BIT(7),
679
680 TE_V2_NOTIF_MSK = 0xff,
681
682 /* placement characteristics */
683 TE_V2_DEP_OTHER = BIT(TE_V2_PLACEMENT_POS),
684 TE_V2_DEP_TSF = BIT(TE_V2_PLACEMENT_POS + 1),
685 TE_V2_EVENT_SOCIOPATHIC = BIT(TE_V2_PLACEMENT_POS + 2),
686
687 /* are we present or absent during the Time Event. */
688 TE_V2_ABSENCE = BIT(TE_V2_ABSENCE_POS),
689};
564 690
565/** 691/**
566 * struct iwl_time_event_cmd - configuring Time Events 692 * struct iwl_time_event_cmd_api_v2 - configuring Time Events
693 * with struct MAC_TIME_EVENT_DATA_API_S_VER_2 (see also
694 * with version 1. determined by IWL_UCODE_TLV_FLAGS)
567 * ( TIME_EVENT_CMD = 0x29 ) 695 * ( TIME_EVENT_CMD = 0x29 )
568 * @id_and_color: ID and color of the relevant MAC 696 * @id_and_color: ID and color of the relevant MAC
569 * @action: action to perform, one of FW_CTXT_ACTION_* 697 * @action: action to perform, one of FW_CTXT_ACTION_*
@@ -575,32 +703,30 @@ enum {
575 * @max_delay: maximum delay to event's start (apply time), in TU 703 * @max_delay: maximum delay to event's start (apply time), in TU
576 * @depends_on: the unique ID of the event we depend on (if any) 704 * @depends_on: the unique ID of the event we depend on (if any)
577 * @interval: interval between repetitions, in TU 705 * @interval: interval between repetitions, in TU
578 * @interval_reciprocal: 2^32 / interval
579 * @duration: duration of event in TU 706 * @duration: duration of event in TU
580 * @repeat: how many repetitions to do, can be TE_REPEAT_ENDLESS 707 * @repeat: how many repetitions to do, can be TE_REPEAT_ENDLESS
581 * @dep_policy: one of TE_INDEPENDENT, TE_DEP_OTHER, TE_DEP_TSF
582 * @is_present: 0 or 1, are we present or absent during the Time Event
583 * @max_frags: maximal number of fragments the Time Event can be divided to 708 * @max_frags: maximal number of fragments the Time Event can be divided to
584 * @notify: notifications using TE_NOTIF_* (whom to notify when) 709 * @policy: defines whether uCode shall notify the host or other uCode modules
710 * on event and/or fragment start and/or end
711 * using one of TE_INDEPENDENT, TE_DEP_OTHER, TE_DEP_TSF
712 * TE_EVENT_SOCIOPATHIC
713 * using TE_ABSENCE and using TE_NOTIF_*
585 */ 714 */
586struct iwl_time_event_cmd { 715struct iwl_time_event_cmd_v2 {
587 /* COMMON_INDEX_HDR_API_S_VER_1 */ 716 /* COMMON_INDEX_HDR_API_S_VER_1 */
588 __le32 id_and_color; 717 __le32 id_and_color;
589 __le32 action; 718 __le32 action;
590 __le32 id; 719 __le32 id;
591 /* MAC_TIME_EVENT_DATA_API_S_VER_1 */ 720 /* MAC_TIME_EVENT_DATA_API_S_VER_2 */
592 __le32 apply_time; 721 __le32 apply_time;
593 __le32 max_delay; 722 __le32 max_delay;
594 __le32 dep_policy;
595 __le32 depends_on; 723 __le32 depends_on;
596 __le32 is_present;
597 __le32 max_frags;
598 __le32 interval; 724 __le32 interval;
599 __le32 interval_reciprocal;
600 __le32 duration; 725 __le32 duration;
601 __le32 repeat; 726 u8 repeat;
602 __le32 notify; 727 u8 max_frags;
603} __packed; /* MAC_TIME_EVENT_CMD_API_S_VER_1 */ 728 __le16 policy;
729} __packed; /* MAC_TIME_EVENT_CMD_API_S_VER_2 */
604 730
605/** 731/**
606 * struct iwl_time_event_resp - response structure to iwl_time_event_cmd 732 * struct iwl_time_event_resp - response structure to iwl_time_event_cmd
@@ -1195,7 +1321,7 @@ struct mvm_statistics_general {
1195 struct mvm_statistics_general_common common; 1321 struct mvm_statistics_general_common common;
1196 __le32 beacon_filtered; 1322 __le32 beacon_filtered;
1197 __le32 missed_beacons; 1323 __le32 missed_beacons;
1198 __s8 beacon_filter_everage_energy; 1324 __s8 beacon_filter_average_energy;
1199 __s8 beacon_filter_reason; 1325 __s8 beacon_filter_reason;
1200 __s8 beacon_filter_current_energy; 1326 __s8 beacon_filter_current_energy;
1201 __s8 beacon_filter_reserved; 1327 __s8 beacon_filter_reserved;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 995f0250105e..9833cdf6177c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -155,7 +155,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
155 IEEE80211_HW_TIMING_BEACON_ONLY | 155 IEEE80211_HW_TIMING_BEACON_ONLY |
156 IEEE80211_HW_CONNECTION_MONITOR | 156 IEEE80211_HW_CONNECTION_MONITOR |
157 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 157 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
158 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 158 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
159 IEEE80211_HW_SUPPORTS_UAPSD;
159 160
160 hw->queues = IWL_MVM_FIRST_AGG_QUEUE; 161 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
161 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 162 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -190,6 +191,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
190 191
191 hw->wiphy->max_remain_on_channel_duration = 10000; 192 hw->wiphy->max_remain_on_channel_duration = 10000;
192 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 193 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
194 hw->uapsd_queues = IWL_UAPSD_AC_INFO;
195 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
193 196
194 /* Extract MAC address */ 197 /* Extract MAC address */
195 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); 198 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
@@ -577,7 +580,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
577 vif->type == NL80211_IFTYPE_STATION && !vif->p2p && 580 vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
578 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){ 581 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){
579 mvm->bf_allowed_vif = mvmvif; 582 mvm->bf_allowed_vif = mvmvif;
580 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; 583 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
584 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
581 } 585 }
582 586
583 /* 587 /*
@@ -617,7 +621,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
617 out_free_bf: 621 out_free_bf:
618 if (mvm->bf_allowed_vif == mvmvif) { 622 if (mvm->bf_allowed_vif == mvmvif) {
619 mvm->bf_allowed_vif = NULL; 623 mvm->bf_allowed_vif = NULL;
620 vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER; 624 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER |
625 IEEE80211_VIF_SUPPORTS_CQM_RSSI);
621 } 626 }
622 out_remove_mac: 627 out_remove_mac:
623 mvmvif->phy_ctxt = NULL; 628 mvmvif->phy_ctxt = NULL;
@@ -683,7 +688,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
683 688
684 if (mvm->bf_allowed_vif == mvmvif) { 689 if (mvm->bf_allowed_vif == mvmvif) {
685 mvm->bf_allowed_vif = NULL; 690 mvm->bf_allowed_vif = NULL;
686 vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER; 691 vif->driver_flags &= ~(IEEE80211_VIF_BEACON_FILTER |
692 IEEE80211_VIF_SUPPORTS_CQM_RSSI);
687 } 693 }
688 694
689 iwl_mvm_vif_dbgfs_clean(mvm, vif); 695 iwl_mvm_vif_dbgfs_clean(mvm, vif);
@@ -801,6 +807,10 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
801 if (ret) 807 if (ret)
802 IWL_ERR(mvm, "failed to update quotas\n"); 808 IWL_ERR(mvm, "failed to update quotas\n");
803 } 809 }
810
811 /* reset rssi values */
812 mvmvif->bf_data.ave_beacon_signal = 0;
813
804 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD)) { 814 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD)) {
805 /* Workaround for FW bug, otherwise FW disables device 815 /* Workaround for FW bug, otherwise FW disables device
806 * power save upon disassociation 816 * power save upon disassociation
@@ -817,7 +827,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
817 */ 827 */
818 iwl_mvm_remove_time_event(mvm, mvmvif, 828 iwl_mvm_remove_time_event(mvm, mvmvif,
819 &mvmvif->time_event_data); 829 &mvmvif->time_event_data);
820 } else if (changes & BSS_CHANGED_PS) { 830 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_QOS)) {
821 ret = iwl_mvm_power_update_mode(mvm, vif); 831 ret = iwl_mvm_power_update_mode(mvm, vif);
822 if (ret) 832 if (ret)
823 IWL_ERR(mvm, "failed to update power mode\n"); 833 IWL_ERR(mvm, "failed to update power mode\n");
@@ -827,6 +837,15 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
827 bss_conf->txpower); 837 bss_conf->txpower);
828 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower); 838 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
829 } 839 }
840
841 if (changes & BSS_CHANGED_CQM) {
842 IWL_DEBUG_MAC80211(mvm, "cqm info_changed");
843 /* reset cqm events tracking */
844 mvmvif->bf_data.last_cqm_event = 0;
845 ret = iwl_mvm_update_beacon_filter(mvm, vif);
846 if (ret)
847 IWL_ERR(mvm, "failed to update CQM thresholds\n");
848 }
830} 849}
831 850
832static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 851static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 4173bb57585f..b0389279cc1e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -153,6 +153,11 @@ enum iwl_power_scheme {
153}; 153};
154 154
155#define IWL_CONN_MAX_LISTEN_INTERVAL 70 155#define IWL_CONN_MAX_LISTEN_INTERVAL 70
156#define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
157 IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
158 IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
159 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
160#define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2
156 161
157struct iwl_mvm_power_ops { 162struct iwl_mvm_power_ops {
158 int (*power_update_mode)(struct iwl_mvm *mvm, 163 int (*power_update_mode)(struct iwl_mvm *mvm,
@@ -175,6 +180,7 @@ enum iwl_dbgfs_pm_mask {
175 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5), 180 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
176 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6), 181 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
177 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), 182 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
183 MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8),
178}; 184};
179 185
180struct iwl_dbgfs_pm { 186struct iwl_dbgfs_pm {
@@ -186,6 +192,7 @@ struct iwl_dbgfs_pm {
186 bool disable_power_off; 192 bool disable_power_off;
187 bool lprx_ena; 193 bool lprx_ena;
188 u32 lprx_rssi_threshold; 194 u32 lprx_rssi_threshold;
195 bool snooze_ena;
189 int mask; 196 int mask;
190}; 197};
191 198
@@ -228,6 +235,21 @@ enum iwl_mvm_smps_type_request {
228}; 235};
229 236
230/** 237/**
238* struct iwl_mvm_vif_bf_data - beacon filtering related data
239* @bf_enabled: indicates if beacon filtering is enabled
240* @ba_enabled: indicated if beacon abort is enabled
241* @last_beacon_signal: last beacon rssi signal in dbm
242* @ave_beacon_signal: average beacon signal
243* @last_cqm_event: rssi of the last cqm event
244*/
245struct iwl_mvm_vif_bf_data {
246 bool bf_enabled;
247 bool ba_enabled;
248 s8 ave_beacon_signal;
249 s8 last_cqm_event;
250};
251
252/**
231 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context 253 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
232 * @id: between 0 and 3 254 * @id: between 0 and 3
233 * @color: to solve races upon MAC addition and removal 255 * @color: to solve races upon MAC addition and removal
@@ -252,8 +274,7 @@ struct iwl_mvm_vif {
252 bool uploaded; 274 bool uploaded;
253 bool ap_active; 275 bool ap_active;
254 bool monitor_active; 276 bool monitor_active;
255 /* indicate whether beacon filtering is enabled */ 277 struct iwl_mvm_vif_bf_data bf_data;
256 bool bf_enabled;
257 278
258 u32 ap_beacon_time; 279 u32 ap_beacon_time;
259 280
@@ -754,6 +775,8 @@ int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
754 struct iwl_beacon_filter_cmd *cmd); 775 struct iwl_beacon_filter_cmd *cmd);
755int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm, 776int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
756 struct ieee80211_vif *vif, bool enable); 777 struct ieee80211_vif *vif, bool enable);
778int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm,
779 struct ieee80211_vif *vif);
757 780
758/* SMPS */ 781/* SMPS */
759void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 782void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 4e7c9f245846..21407a353a3b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -110,6 +110,23 @@ int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
110 return ret; 110 return ret;
111} 111}
112 112
113static
114void iwl_mvm_beacon_filter_set_cqm_params(struct iwl_mvm *mvm,
115 struct ieee80211_vif *vif,
116 struct iwl_beacon_filter_cmd *cmd)
117{
118 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
119
120 if (vif->bss_conf.cqm_rssi_thold) {
121 cmd->bf_energy_delta =
122 cpu_to_le32(vif->bss_conf.cqm_rssi_hyst);
123 /* fw uses an absolute value for this */
124 cmd->bf_roaming_state =
125 cpu_to_le32(-vif->bss_conf.cqm_rssi_thold);
126 }
127 cmd->ba_enable_beacon_abort = cpu_to_le32(mvmvif->bf_data.ba_enabled);
128}
129
113int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm, 130int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
114 struct ieee80211_vif *vif, bool enable) 131 struct ieee80211_vif *vif, bool enable)
115{ 132{
@@ -120,12 +137,14 @@ int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
120 .ba_enable_beacon_abort = cpu_to_le32(enable), 137 .ba_enable_beacon_abort = cpu_to_le32(enable),
121 }; 138 };
122 139
123 if (!mvmvif->bf_enabled) 140 if (!mvmvif->bf_data.bf_enabled)
124 return 0; 141 return 0;
125 142
126 if (mvm->cur_ucode == IWL_UCODE_WOWLAN) 143 if (mvm->cur_ucode == IWL_UCODE_WOWLAN)
127 cmd.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3); 144 cmd.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3);
128 145
146 mvmvif->bf_data.ba_enabled = enable;
147 iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, &cmd);
129 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); 148 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
130 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 149 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
131} 150}
@@ -140,17 +159,30 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
140 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", 159 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n",
141 le16_to_cpu(cmd->keep_alive_seconds)); 160 le16_to_cpu(cmd->keep_alive_seconds));
142 161
143 if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { 162 if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK))) {
144 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n", 163 IWL_DEBUG_POWER(mvm, "Disable power management\n");
145 le32_to_cpu(cmd->rx_data_timeout)); 164 return;
146 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", 165 }
147 le32_to_cpu(cmd->tx_data_timeout)); 166
148 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) 167 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
149 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", 168 le32_to_cpu(cmd->rx_data_timeout));
150 cmd->skip_dtim_periods); 169 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
151 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) 170 le32_to_cpu(cmd->tx_data_timeout));
152 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", 171 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
153 cmd->lprx_rssi_threshold); 172 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
173 cmd->skip_dtim_periods);
174 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
175 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
176 cmd->lprx_rssi_threshold);
177 if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
178 IWL_DEBUG_POWER(mvm, "uAPSD enabled\n");
179 IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n",
180 le32_to_cpu(cmd->rx_data_timeout_uapsd));
181 IWL_DEBUG_POWER(mvm, "Tx timeout (uAPSD) = %u usec\n",
182 le32_to_cpu(cmd->tx_data_timeout_uapsd));
183 IWL_DEBUG_POWER(mvm, "QNDP TID = %d\n", cmd->qndp_tid);
184 IWL_DEBUG_POWER(mvm, "ACs flags = 0x%x\n", cmd->uapsd_ac_flags);
185 IWL_DEBUG_POWER(mvm, "Max SP = %d\n", cmd->uapsd_max_sp);
154 } 186 }
155} 187}
156 188
@@ -166,6 +198,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
166 bool radar_detect = false; 198 bool radar_detect = false;
167 struct iwl_mvm_vif *mvmvif __maybe_unused = 199 struct iwl_mvm_vif *mvmvif __maybe_unused =
168 iwl_mvm_vif_from_mac80211(vif); 200 iwl_mvm_vif_from_mac80211(vif);
201 enum ieee80211_ac_numbers ac;
202 bool tid_found = false;
169 203
170 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 204 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
171 mvmvif->color)); 205 mvmvif->color));
@@ -235,6 +269,63 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
235 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); 269 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
236 } 270 }
237 271
272 for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) {
273 if (!mvmvif->queue_params[ac].uapsd)
274 continue;
275
276 cmd->flags |= cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
277 cmd->uapsd_ac_flags |= BIT(ac);
278
279 /* QNDP TID - the highest TID with no admission control */
280 if (!tid_found && !mvmvif->queue_params[ac].acm) {
281 tid_found = true;
282 switch (ac) {
283 case IEEE80211_AC_VO:
284 cmd->qndp_tid = 6;
285 break;
286 case IEEE80211_AC_VI:
287 cmd->qndp_tid = 5;
288 break;
289 case IEEE80211_AC_BE:
290 cmd->qndp_tid = 0;
291 break;
292 case IEEE80211_AC_BK:
293 cmd->qndp_tid = 1;
294 break;
295 }
296 }
297 }
298
299 if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
300 cmd->rx_data_timeout_uapsd =
301 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
302 cmd->tx_data_timeout_uapsd =
303 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
304
305 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
306 BIT(IEEE80211_AC_VI) |
307 BIT(IEEE80211_AC_BE) |
308 BIT(IEEE80211_AC_BK))) {
309 cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
310 cmd->snooze_interval =
311 cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL);
312 cmd->snooze_window =
313 (mvm->cur_ucode == IWL_UCODE_WOWLAN) ?
314 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) :
315 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
316 }
317
318 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
319 cmd->heavy_tx_thld_packets =
320 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
321 cmd->heavy_rx_thld_packets =
322 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
323 cmd->heavy_tx_thld_percentage =
324 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
325 cmd->heavy_rx_thld_percentage =
326 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
327 }
328
238#ifdef CONFIG_IWLWIFI_DEBUGFS 329#ifdef CONFIG_IWLWIFI_DEBUGFS
239 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) 330 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
240 cmd->keep_alive_seconds = 331 cmd->keep_alive_seconds =
@@ -263,6 +354,14 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
263 } 354 }
264 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD) 355 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
265 cmd->lprx_rssi_threshold = mvmvif->dbgfs_pm.lprx_rssi_threshold; 356 cmd->lprx_rssi_threshold = mvmvif->dbgfs_pm.lprx_rssi_threshold;
357 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SNOOZE_ENABLE) {
358 if (mvmvif->dbgfs_pm.snooze_ena)
359 cmd->flags |=
360 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
361 else
362 cmd->flags &=
363 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK);
364 }
266#endif /* CONFIG_IWLWIFI_DEBUGFS */ 365#endif /* CONFIG_IWLWIFI_DEBUGFS */
267} 366}
268 367
@@ -342,8 +441,6 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
342 (cmd.flags & 441 (cmd.flags &
343 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? 442 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
344 0 : 1); 443 0 : 1);
345 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
346 cmd.skip_dtim_periods);
347 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", 444 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
348 iwlmvm_mod_params.power_scheme); 445 iwlmvm_mod_params.power_scheme);
349 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n", 446 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
@@ -356,14 +453,64 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
356 (cmd.flags & 453 (cmd.flags &
357 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 454 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
358 1 : 0); 455 1 : 0);
359 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n", 456 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
360 le32_to_cpu(cmd.rx_data_timeout)); 457 cmd.skip_dtim_periods);
361 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", 458 if (!(cmd.flags &
362 le32_to_cpu(cmd.tx_data_timeout)); 459 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) {
460 pos += scnprintf(buf+pos, bufsz-pos,
461 "rx_data_timeout = %d\n",
462 le32_to_cpu(cmd.rx_data_timeout));
463 pos += scnprintf(buf+pos, bufsz-pos,
464 "tx_data_timeout = %d\n",
465 le32_to_cpu(cmd.tx_data_timeout));
466 }
363 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK)) 467 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
364 pos += scnprintf(buf+pos, bufsz-pos, 468 pos += scnprintf(buf+pos, bufsz-pos,
365 "lprx_rssi_threshold = %d\n", 469 "lprx_rssi_threshold = %d\n",
366 cmd.lprx_rssi_threshold); 470 cmd.lprx_rssi_threshold);
471 if (cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
472 pos +=
473 scnprintf(buf+pos, bufsz-pos,
474 "rx_data_timeout_uapsd = %d\n",
475 le32_to_cpu(cmd.rx_data_timeout_uapsd));
476 pos +=
477 scnprintf(buf+pos, bufsz-pos,
478 "tx_data_timeout_uapsd = %d\n",
479 le32_to_cpu(cmd.tx_data_timeout_uapsd));
480 pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n",
481 cmd.qndp_tid);
482 pos += scnprintf(buf+pos, bufsz-pos,
483 "uapsd_ac_flags = 0x%x\n",
484 cmd.uapsd_ac_flags);
485 pos += scnprintf(buf+pos, bufsz-pos,
486 "uapsd_max_sp = %d\n",
487 cmd.uapsd_max_sp);
488 pos += scnprintf(buf+pos, bufsz-pos,
489 "heavy_tx_thld_packets = %d\n",
490 cmd.heavy_tx_thld_packets);
491 pos += scnprintf(buf+pos, bufsz-pos,
492 "heavy_rx_thld_packets = %d\n",
493 cmd.heavy_rx_thld_packets);
494 pos += scnprintf(buf+pos, bufsz-pos,
495 "heavy_tx_thld_percentage = %d\n",
496 cmd.heavy_tx_thld_percentage);
497 pos += scnprintf(buf+pos, bufsz-pos,
498 "heavy_rx_thld_percentage = %d\n",
499 cmd.heavy_rx_thld_percentage);
500 pos +=
501 scnprintf(buf+pos, bufsz-pos, "snooze_enable = %d\n",
502 (cmd.flags &
503 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) ?
504 1 : 0);
505 }
506 if (cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
507 pos += scnprintf(buf+pos, bufsz-pos,
508 "snooze_interval = %d\n",
509 cmd.snooze_interval);
510 pos += scnprintf(buf+pos, bufsz-pos,
511 "snooze_window = %d\n",
512 cmd.snooze_window);
513 }
367 } 514 }
368 return pos; 515 return pos;
369} 516}
@@ -417,11 +564,12 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
417 vif->type != NL80211_IFTYPE_STATION || vif->p2p) 564 vif->type != NL80211_IFTYPE_STATION || vif->p2p)
418 return 0; 565 return 0;
419 566
567 iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, &cmd);
420 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd); 568 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
421 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 569 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
422 570
423 if (!ret) 571 if (!ret)
424 mvmvif->bf_enabled = true; 572 mvmvif->bf_data.bf_enabled = true;
425 573
426 return ret; 574 return ret;
427} 575}
@@ -440,11 +588,22 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
440 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 588 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
441 589
442 if (!ret) 590 if (!ret)
443 mvmvif->bf_enabled = false; 591 mvmvif->bf_data.bf_enabled = false;
444 592
445 return ret; 593 return ret;
446} 594}
447 595
596int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm,
597 struct ieee80211_vif *vif)
598{
599 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
600
601 if (!mvmvif->bf_data.bf_enabled)
602 return 0;
603
604 return iwl_mvm_enable_beacon_filter(mvm, vif);
605}
606
448const struct iwl_mvm_power_ops pm_mac_ops = { 607const struct iwl_mvm_power_ops pm_mac_ops = {
449 .power_update_mode = iwl_mvm_power_mac_update_mode, 608 .power_update_mode = iwl_mvm_power_mac_update_mode,
450 .power_disable = iwl_mvm_power_mac_disable, 609 .power_disable = iwl_mvm_power_mac_disable,
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index c47a635b56ff..4ffaa3fa153f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -82,41 +82,35 @@ static const u8 ant_toggle_lookup[] = {
82 [ANT_ABC] = ANT_ABC, 82 [ANT_ABC] = ANT_ABC,
83}; 83};
84 84
85#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ 85#define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \
86 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ 86 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
87 IWL_RATE_SISO_##s##M_PLCP, \ 87 IWL_RATE_SISO_##s##M_PLCP, \
88 IWL_RATE_MIMO2_##s##M_PLCP,\ 88 IWL_RATE_MIMO2_##s##M_PLCP,\
89 IWL_RATE_MIMO3_##s##M_PLCP,\
90 IWL_RATE_##r##M_IEEE, \
91 IWL_RATE_##ip##M_INDEX, \
92 IWL_RATE_##in##M_INDEX, \
93 IWL_RATE_##rp##M_INDEX, \ 89 IWL_RATE_##rp##M_INDEX, \
94 IWL_RATE_##rn##M_INDEX, \ 90 IWL_RATE_##rn##M_INDEX }
95 IWL_RATE_##pp##M_INDEX, \
96 IWL_RATE_##np##M_INDEX }
97 91
98/* 92/*
99 * Parameter order: 93 * Parameter order:
100 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate 94 * rate, ht rate, prev rate, next rate
101 * 95 *
102 * If there isn't a valid next or previous rate then INV is used which 96 * If there isn't a valid next or previous rate then INV is used which
103 * maps to IWL_RATE_INVALID 97 * maps to IWL_RATE_INVALID
104 * 98 *
105 */ 99 */
106static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { 100static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {
107 IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ 101 IWL_DECLARE_RATE_INFO(1, INV, INV, 2), /* 1mbps */
108 IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ 102 IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */
109 IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ 103 IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */
110 IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ 104 IWL_DECLARE_RATE_INFO(11, INV, 9, 12), /* 11mbps */
111 IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ 105 IWL_DECLARE_RATE_INFO(6, 6, 5, 11), /* 6mbps */
112 IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ 106 IWL_DECLARE_RATE_INFO(9, 6, 6, 11), /* 9mbps */
113 IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ 107 IWL_DECLARE_RATE_INFO(12, 12, 11, 18), /* 12mbps */
114 IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ 108 IWL_DECLARE_RATE_INFO(18, 18, 12, 24), /* 18mbps */
115 IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ 109 IWL_DECLARE_RATE_INFO(24, 24, 18, 36), /* 24mbps */
116 IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ 110 IWL_DECLARE_RATE_INFO(36, 36, 24, 48), /* 36mbps */
117 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ 111 IWL_DECLARE_RATE_INFO(48, 48, 36, 54), /* 48mbps */
118 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ 112 IWL_DECLARE_RATE_INFO(54, 54, 48, INV), /* 54mbps */
119 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ 113 IWL_DECLARE_RATE_INFO(60, 60, 48, INV), /* 60mbps */
120 /* FIXME:RS: ^^ should be INV (legacy) */ 114 /* FIXME:RS: ^^ should be INV (legacy) */
121}; 115};
122 116
@@ -134,9 +128,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
134 if (rate_n_flags & RATE_MCS_HT_MSK) { 128 if (rate_n_flags & RATE_MCS_HT_MSK) {
135 idx = rs_extract_rate(rate_n_flags); 129 idx = rs_extract_rate(rate_n_flags);
136 130
137 if (idx >= IWL_RATE_MIMO3_6M_PLCP) 131 WARN_ON_ONCE(idx >= IWL_RATE_MIMO3_6M_PLCP);
138 idx = idx - IWL_RATE_MIMO3_6M_PLCP; 132 if (idx >= IWL_RATE_MIMO2_6M_PLCP)
139 else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
140 idx = idx - IWL_RATE_MIMO2_6M_PLCP; 133 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
141 134
142 idx += IWL_FIRST_OFDM_RATE; 135 idx += IWL_FIRST_OFDM_RATE;
@@ -168,10 +161,10 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
168 161
169#ifdef CONFIG_MAC80211_DEBUGFS 162#ifdef CONFIG_MAC80211_DEBUGFS
170static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, 163static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
171 u32 *rate_n_flags, int index); 164 u32 *rate_n_flags);
172#else 165#else
173static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, 166static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
174 u32 *rate_n_flags, int index) 167 u32 *rate_n_flags)
175{} 168{}
176#endif 169#endif
177 170
@@ -218,20 +211,6 @@ static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {
218 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */ 211 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */
219}; 212};
220 213
221static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = {
222 {0, 0, 0, 0, 99, 0, 153, 186, 208, 239, 256, 263, 268}, /* Norm */
223 {0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273}, /* SGI */
224 {0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775}, /* AGG */
225 {0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818}, /* AGG+SGI */
226};
227
228static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = {
229 {0, 0, 0, 0, 152, 0, 211, 239, 255, 279, 290, 294, 297}, /* Norm */
230 {0, 0, 0, 0, 160, 0, 219, 245, 261, 284, 294, 297, 300}, /* SGI */
231 {0, 0, 0, 0, 254, 0, 443, 584, 695, 868, 984, 1030, 1070}, /* AGG */
232 {0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109}, /* AGG+SGI */
233};
234
235/* mbps, mcs */ 214/* mbps, mcs */
236static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { 215static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
237 { "1", "BPSK DSSS"}, 216 { "1", "BPSK DSSS"},
@@ -279,7 +258,6 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
279 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ 258 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
280 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 259 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
281 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 260 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
282 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
283 261
284 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n", 262 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
285 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); 263 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
@@ -459,7 +437,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm,
459 else if (is_mimo2(tbl->lq_type)) 437 else if (is_mimo2(tbl->lq_type))
460 rate_n_flags |= iwl_rates[index].plcp_mimo2; 438 rate_n_flags |= iwl_rates[index].plcp_mimo2;
461 else 439 else
462 rate_n_flags |= iwl_rates[index].plcp_mimo3; 440 WARN_ON_ONCE(1);
463 } else { 441 } else {
464 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type); 442 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type);
465 } 443 }
@@ -497,7 +475,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
497 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); 475 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
498 u8 mcs; 476 u8 mcs;
499 477
500 memset(tbl, 0, sizeof(struct iwl_scale_tbl_info)); 478 memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win));
501 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); 479 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
502 480
503 if (*rate_idx == IWL_RATE_INVALID) { 481 if (*rate_idx == IWL_RATE_INVALID) {
@@ -536,12 +514,8 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
536 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) { 514 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) {
537 if (num_of_ant == 2) 515 if (num_of_ant == 2)
538 tbl->lq_type = LQ_MIMO2; 516 tbl->lq_type = LQ_MIMO2;
539 /* MIMO3 */
540 } else { 517 } else {
541 if (num_of_ant == 3) { 518 WARN_ON_ONCE(num_of_ant == 3);
542 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
543 tbl->lq_type = LQ_MIMO3;
544 }
545 } 519 }
546 } 520 }
547 return 0; 521 return 0;
@@ -607,10 +581,10 @@ static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
607 } else { 581 } else {
608 if (is_siso(rate_type)) 582 if (is_siso(rate_type))
609 return lq_sta->active_siso_rate; 583 return lq_sta->active_siso_rate;
610 else if (is_mimo2(rate_type)) 584 else {
585 WARN_ON_ONCE(!is_mimo2(rate_type));
611 return lq_sta->active_mimo2_rate; 586 return lq_sta->active_mimo2_rate;
612 else 587 }
613 return lq_sta->active_mimo3_rate;
614 } 588 }
615} 589}
616 590
@@ -985,7 +959,7 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
985 } 959 }
986 960
987 /* Choose among many HT tables depending on number of streams 961 /* Choose among many HT tables depending on number of streams
988 * (SISO/MIMO2/MIMO3), channel width (20/40), SGI, and aggregation 962 * (SISO/MIMO2), channel width (20/40), SGI, and aggregation
989 * status */ 963 * status */
990 if (is_siso(tbl->lq_type) && !tbl->is_ht40) 964 if (is_siso(tbl->lq_type) && !tbl->is_ht40)
991 ht_tbl_pointer = expected_tpt_siso20MHz; 965 ht_tbl_pointer = expected_tpt_siso20MHz;
@@ -993,12 +967,10 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
993 ht_tbl_pointer = expected_tpt_siso40MHz; 967 ht_tbl_pointer = expected_tpt_siso40MHz;
994 else if (is_mimo2(tbl->lq_type) && !tbl->is_ht40) 968 else if (is_mimo2(tbl->lq_type) && !tbl->is_ht40)
995 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 969 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
996 else if (is_mimo2(tbl->lq_type)) 970 else {
971 WARN_ON_ONCE(!is_mimo2(tbl->lq_type));
997 ht_tbl_pointer = expected_tpt_mimo2_40MHz; 972 ht_tbl_pointer = expected_tpt_mimo2_40MHz;
998 else if (is_mimo3(tbl->lq_type) && !tbl->is_ht40) 973 }
999 ht_tbl_pointer = expected_tpt_mimo3_20MHz;
1000 else /* if (is_mimo3(tbl->lq_type)) <-- must be true */
1001 ht_tbl_pointer = expected_tpt_mimo3_40MHz;
1002 974
1003 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ 975 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */
1004 tbl->expected_tpt = ht_tbl_pointer[0]; 976 tbl->expected_tpt = ht_tbl_pointer[0];
@@ -1170,58 +1142,6 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1170} 1142}
1171 1143
1172/* 1144/*
1173 * Set up search table for MIMO3
1174 */
1175static int rs_switch_to_mimo3(struct iwl_mvm *mvm,
1176 struct iwl_lq_sta *lq_sta,
1177 struct ieee80211_sta *sta,
1178 struct iwl_scale_tbl_info *tbl, int index)
1179{
1180 u16 rate_mask;
1181 s32 rate;
1182 s8 is_green = lq_sta->is_green;
1183
1184 if (!sta->ht_cap.ht_supported)
1185 return -1;
1186
1187 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
1188 return -1;
1189
1190 /* Need both Tx chains/antennas to support MIMO */
1191 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 3)
1192 return -1;
1193
1194 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n");
1195
1196 tbl->lq_type = LQ_MIMO3;
1197 tbl->action = 0;
1198 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
1199 rate_mask = lq_sta->active_mimo3_rate;
1200
1201 if (iwl_is_ht40_tx_allowed(sta))
1202 tbl->is_ht40 = 1;
1203 else
1204 tbl->is_ht40 = 0;
1205
1206 rs_set_expected_tpt_table(lq_sta, tbl);
1207
1208 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1209
1210 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 best rate %d mask %X\n",
1211 rate, rate_mask);
1212 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1213 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1214 rate, rate_mask);
1215 return -1;
1216 }
1217 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green);
1218
1219 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n",
1220 tbl->current_rate, is_green);
1221 return 0;
1222}
1223
1224/*
1225 * Set up search table for SISO 1145 * Set up search table for SISO
1226 */ 1146 */
1227static int rs_switch_to_siso(struct iwl_mvm *mvm, 1147static int rs_switch_to_siso(struct iwl_mvm *mvm,
@@ -1330,21 +1250,14 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1330 } 1250 }
1331 1251
1332 break; 1252 break;
1333 case IWL_LEGACY_SWITCH_MIMO2_AB: 1253 case IWL_LEGACY_SWITCH_MIMO2:
1334 case IWL_LEGACY_SWITCH_MIMO2_AC:
1335 case IWL_LEGACY_SWITCH_MIMO2_BC:
1336 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO2\n"); 1254 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO2\n");
1337 1255
1338 /* Set up search table to try MIMO */ 1256 /* Set up search table to try MIMO */
1339 memcpy(search_tbl, tbl, sz); 1257 memcpy(search_tbl, tbl, sz);
1340 search_tbl->is_SGI = 0; 1258 search_tbl->is_SGI = 0;
1341 1259
1342 if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB) 1260 search_tbl->ant_type = ANT_AB;
1343 search_tbl->ant_type = ANT_AB;
1344 else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)
1345 search_tbl->ant_type = ANT_AC;
1346 else
1347 search_tbl->ant_type = ANT_BC;
1348 1261
1349 if (!rs_is_valid_ant(valid_tx_ant, 1262 if (!rs_is_valid_ant(valid_tx_ant,
1350 search_tbl->ant_type)) 1263 search_tbl->ant_type))
@@ -1357,30 +1270,11 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1357 goto out; 1270 goto out;
1358 } 1271 }
1359 break; 1272 break;
1360 1273 default:
1361 case IWL_LEGACY_SWITCH_MIMO3_ABC: 1274 WARN_ON_ONCE(1);
1362 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO3\n");
1363
1364 /* Set up search table to try MIMO3 */
1365 memcpy(search_tbl, tbl, sz);
1366 search_tbl->is_SGI = 0;
1367
1368 search_tbl->ant_type = ANT_ABC;
1369
1370 if (!rs_is_valid_ant(valid_tx_ant,
1371 search_tbl->ant_type))
1372 break;
1373
1374 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1375 search_tbl, index);
1376 if (!ret) {
1377 lq_sta->action_counter = 0;
1378 goto out;
1379 }
1380 break;
1381 } 1275 }
1382 tbl->action++; 1276 tbl->action++;
1383 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) 1277 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
1384 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 1278 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1385 1279
1386 if (tbl->action == start_action) 1280 if (tbl->action == start_action)
@@ -1392,7 +1286,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1392out: 1286out:
1393 lq_sta->search_better_tbl = 1; 1287 lq_sta->search_better_tbl = 1;
1394 tbl->action++; 1288 tbl->action++;
1395 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) 1289 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
1396 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 1290 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1397 if (update_search_tbl_counter) 1291 if (update_search_tbl_counter)
1398 search_tbl->action = tbl->action; 1292 search_tbl->action = tbl->action;
@@ -1427,7 +1321,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1427 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 1321 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1428 /* avoid antenna B unless MIMO */ 1322 /* avoid antenna B unless MIMO */
1429 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) 1323 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
1430 tbl->action = IWL_SISO_SWITCH_MIMO2_AB; 1324 tbl->action = IWL_SISO_SWITCH_MIMO2;
1431 break; 1325 break;
1432 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: 1326 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1433 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 1327 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
@@ -1469,19 +1363,12 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1469 goto out; 1363 goto out;
1470 } 1364 }
1471 break; 1365 break;
1472 case IWL_SISO_SWITCH_MIMO2_AB: 1366 case IWL_SISO_SWITCH_MIMO2:
1473 case IWL_SISO_SWITCH_MIMO2_AC:
1474 case IWL_SISO_SWITCH_MIMO2_BC:
1475 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n"); 1367 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n");
1476 memcpy(search_tbl, tbl, sz); 1368 memcpy(search_tbl, tbl, sz);
1477 search_tbl->is_SGI = 0; 1369 search_tbl->is_SGI = 0;
1478 1370
1479 if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB) 1371 search_tbl->ant_type = ANT_AB;
1480 search_tbl->ant_type = ANT_AB;
1481 else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)
1482 search_tbl->ant_type = ANT_AC;
1483 else
1484 search_tbl->ant_type = ANT_BC;
1485 1372
1486 if (!rs_is_valid_ant(valid_tx_ant, 1373 if (!rs_is_valid_ant(valid_tx_ant,
1487 search_tbl->ant_type)) 1374 search_tbl->ant_type))
@@ -1522,24 +1409,11 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1522 index, is_green); 1409 index, is_green);
1523 update_search_tbl_counter = 1; 1410 update_search_tbl_counter = 1;
1524 goto out; 1411 goto out;
1525 case IWL_SISO_SWITCH_MIMO3_ABC: 1412 default:
1526 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO3\n"); 1413 WARN_ON_ONCE(1);
1527 memcpy(search_tbl, tbl, sz);
1528 search_tbl->is_SGI = 0;
1529 search_tbl->ant_type = ANT_ABC;
1530
1531 if (!rs_is_valid_ant(valid_tx_ant,
1532 search_tbl->ant_type))
1533 break;
1534
1535 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1536 search_tbl, index);
1537 if (!ret)
1538 goto out;
1539 break;
1540 } 1414 }
1541 tbl->action++; 1415 tbl->action++;
1542 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) 1416 if (tbl->action > IWL_SISO_SWITCH_GI)
1543 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1417 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1544 1418
1545 if (tbl->action == start_action) 1419 if (tbl->action == start_action)
@@ -1551,7 +1425,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1551 out: 1425 out:
1552 lq_sta->search_better_tbl = 1; 1426 lq_sta->search_better_tbl = 1;
1553 tbl->action++; 1427 tbl->action++;
1554 if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC) 1428 if (tbl->action > IWL_SISO_SWITCH_GI)
1555 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1429 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1556 if (update_search_tbl_counter) 1430 if (update_search_tbl_counter)
1557 search_tbl->action = tbl->action; 1431 search_tbl->action = tbl->action;
@@ -1592,8 +1466,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1592 break; 1466 break;
1593 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 1467 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1594 /* avoid antenna B unless MIMO */ 1468 /* avoid antenna B unless MIMO */
1595 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B || 1469 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
1596 tbl->action == IWL_MIMO2_SWITCH_SISO_C)
1597 tbl->action = IWL_MIMO2_SWITCH_SISO_A; 1470 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1598 break; 1471 break;
1599 default: 1472 default:
@@ -1626,7 +1499,6 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1626 break; 1499 break;
1627 case IWL_MIMO2_SWITCH_SISO_A: 1500 case IWL_MIMO2_SWITCH_SISO_A:
1628 case IWL_MIMO2_SWITCH_SISO_B: 1501 case IWL_MIMO2_SWITCH_SISO_B:
1629 case IWL_MIMO2_SWITCH_SISO_C:
1630 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n"); 1502 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n");
1631 1503
1632 /* Set up new search table for SISO */ 1504 /* Set up new search table for SISO */
@@ -1634,10 +1506,8 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1634 1506
1635 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A) 1507 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1636 search_tbl->ant_type = ANT_A; 1508 search_tbl->ant_type = ANT_A;
1637 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B) 1509 else /* tbl->action == IWL_MIMO2_SWITCH_SISO_B */
1638 search_tbl->ant_type = ANT_B; 1510 search_tbl->ant_type = ANT_B;
1639 else
1640 search_tbl->ant_type = ANT_C;
1641 1511
1642 if (!rs_is_valid_ant(valid_tx_ant, 1512 if (!rs_is_valid_ant(valid_tx_ant,
1643 search_tbl->ant_type)) 1513 search_tbl->ant_type))
@@ -1680,26 +1550,11 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1680 index, is_green); 1550 index, is_green);
1681 update_search_tbl_counter = 1; 1551 update_search_tbl_counter = 1;
1682 goto out; 1552 goto out;
1683 1553 default:
1684 case IWL_MIMO2_SWITCH_MIMO3_ABC: 1554 WARN_ON_ONCE(1);
1685 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to MIMO3\n");
1686 memcpy(search_tbl, tbl, sz);
1687 search_tbl->is_SGI = 0;
1688 search_tbl->ant_type = ANT_ABC;
1689
1690 if (!rs_is_valid_ant(valid_tx_ant,
1691 search_tbl->ant_type))
1692 break;
1693
1694 ret = rs_switch_to_mimo3(mvm, lq_sta, sta,
1695 search_tbl, index);
1696 if (!ret)
1697 goto out;
1698
1699 break;
1700 } 1555 }
1701 tbl->action++; 1556 tbl->action++;
1702 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) 1557 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1703 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; 1558 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1704 1559
1705 if (tbl->action == start_action) 1560 if (tbl->action == start_action)
@@ -1710,7 +1565,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1710 out: 1565 out:
1711 lq_sta->search_better_tbl = 1; 1566 lq_sta->search_better_tbl = 1;
1712 tbl->action++; 1567 tbl->action++;
1713 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) 1568 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1714 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; 1569 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1715 if (update_search_tbl_counter) 1570 if (update_search_tbl_counter)
1716 search_tbl->action = tbl->action; 1571 search_tbl->action = tbl->action;
@@ -1719,171 +1574,6 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1719} 1574}
1720 1575
1721/* 1576/*
1722 * Try to switch to new modulation mode from MIMO3
1723 */
1724static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
1725 struct iwl_lq_sta *lq_sta,
1726 struct ieee80211_sta *sta, int index)
1727{
1728 s8 is_green = lq_sta->is_green;
1729 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1730 struct iwl_scale_tbl_info *search_tbl =
1731 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1732 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1733 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1734 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1735 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1736 u8 start_action;
1737 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1738 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1739 int ret;
1740 u8 update_search_tbl_counter = 0;
1741
1742 switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
1743 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1744 /* nothing */
1745 break;
1746 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1747 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1748 /* avoid antenna B and MIMO */
1749 if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
1750 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1751 break;
1752 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1753 /* avoid antenna B unless MIMO */
1754 if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
1755 tbl->action == IWL_MIMO3_SWITCH_SISO_C)
1756 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1757 break;
1758 default:
1759 IWL_ERR(mvm, "Invalid BT load %d",
1760 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
1761 break;
1762 }
1763
1764 start_action = tbl->action;
1765 while (1) {
1766 lq_sta->action_counter++;
1767 switch (tbl->action) {
1768 case IWL_MIMO3_SWITCH_ANTENNA1:
1769 case IWL_MIMO3_SWITCH_ANTENNA2:
1770 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 toggle Antennas\n");
1771
1772 if (tx_chains_num <= 3)
1773 break;
1774
1775 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1776 break;
1777
1778 memcpy(search_tbl, tbl, sz);
1779 if (rs_toggle_antenna(valid_tx_ant,
1780 &search_tbl->current_rate,
1781 search_tbl))
1782 goto out;
1783 break;
1784 case IWL_MIMO3_SWITCH_SISO_A:
1785 case IWL_MIMO3_SWITCH_SISO_B:
1786 case IWL_MIMO3_SWITCH_SISO_C:
1787 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 switch to SISO\n");
1788
1789 /* Set up new search table for SISO */
1790 memcpy(search_tbl, tbl, sz);
1791
1792 if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)
1793 search_tbl->ant_type = ANT_A;
1794 else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)
1795 search_tbl->ant_type = ANT_B;
1796 else
1797 search_tbl->ant_type = ANT_C;
1798
1799 if (!rs_is_valid_ant(valid_tx_ant,
1800 search_tbl->ant_type))
1801 break;
1802
1803 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1804 search_tbl, index);
1805 if (!ret)
1806 goto out;
1807
1808 break;
1809
1810 case IWL_MIMO3_SWITCH_MIMO2_AB:
1811 case IWL_MIMO3_SWITCH_MIMO2_AC:
1812 case IWL_MIMO3_SWITCH_MIMO2_BC:
1813 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 switch to MIMO2\n");
1814
1815 memcpy(search_tbl, tbl, sz);
1816 search_tbl->is_SGI = 0;
1817 if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)
1818 search_tbl->ant_type = ANT_AB;
1819 else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)
1820 search_tbl->ant_type = ANT_AC;
1821 else
1822 search_tbl->ant_type = ANT_BC;
1823
1824 if (!rs_is_valid_ant(valid_tx_ant,
1825 search_tbl->ant_type))
1826 break;
1827
1828 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1829 search_tbl, index);
1830 if (!ret)
1831 goto out;
1832
1833 break;
1834
1835 case IWL_MIMO3_SWITCH_GI:
1836 if (!tbl->is_ht40 && !(ht_cap->cap &
1837 IEEE80211_HT_CAP_SGI_20))
1838 break;
1839 if (tbl->is_ht40 && !(ht_cap->cap &
1840 IEEE80211_HT_CAP_SGI_40))
1841 break;
1842
1843 IWL_DEBUG_RATE(mvm, "LQ: MIMO3 toggle SGI/NGI\n");
1844
1845 /* Set up new search table for MIMO */
1846 memcpy(search_tbl, tbl, sz);
1847 search_tbl->is_SGI = !tbl->is_SGI;
1848 rs_set_expected_tpt_table(lq_sta, search_tbl);
1849 /*
1850 * If active table already uses the fastest possible
1851 * modulation (dual stream with short guard interval),
1852 * and it's working well, there's no need to look
1853 * for a better type of modulation!
1854 */
1855 if (tbl->is_SGI) {
1856 s32 tpt = lq_sta->last_tpt / 100;
1857 if (tpt >= search_tbl->expected_tpt[index])
1858 break;
1859 }
1860 search_tbl->current_rate =
1861 rate_n_flags_from_tbl(mvm, search_tbl,
1862 index, is_green);
1863 update_search_tbl_counter = 1;
1864 goto out;
1865 }
1866 tbl->action++;
1867 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1868 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1869
1870 if (tbl->action == start_action)
1871 break;
1872 }
1873 search_tbl->lq_type = LQ_NONE;
1874 return 0;
1875 out:
1876 lq_sta->search_better_tbl = 1;
1877 tbl->action++;
1878 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1879 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1880 if (update_search_tbl_counter)
1881 search_tbl->action = tbl->action;
1882
1883 return 0;
1884}
1885
1886/*
1887 * Check whether we should continue using same modulation mode, or 1577 * Check whether we should continue using same modulation mode, or
1888 * begin search for a new mode, based on: 1578 * begin search for a new mode, based on:
1889 * 1) # tx successes or failures while using this mode 1579 * 1) # tx successes or failures while using this mode
@@ -2289,8 +1979,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2289 scale_action = 0; 1979 scale_action = 0;
2290 1980
2291 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 1981 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >=
2292 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && 1982 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) {
2293 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2294 if (lq_sta->last_bt_traffic > 1983 if (lq_sta->last_bt_traffic >
2295 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { 1984 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
2296 /* 1985 /*
@@ -2307,8 +1996,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2307 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD); 1996 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD);
2308 1997
2309 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 1998 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >=
2310 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && 1999 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && is_mimo(tbl->lq_type)) {
2311 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2312 /* search for a new modulation */ 2000 /* search for a new modulation */
2313 rs_stay_in_table(lq_sta, true); 2001 rs_stay_in_table(lq_sta, true);
2314 goto lq_update; 2002 goto lq_update;
@@ -2368,7 +2056,7 @@ lq_update:
2368 else if (is_mimo2(tbl->lq_type)) 2056 else if (is_mimo2(tbl->lq_type))
2369 rs_move_mimo2_to_other(mvm, lq_sta, sta, index); 2057 rs_move_mimo2_to_other(mvm, lq_sta, sta, index);
2370 else 2058 else
2371 rs_move_mimo3_to_other(mvm, lq_sta, sta, index); 2059 WARN_ON_ONCE(1);
2372 2060
2373 /* If new "search" mode was selected, set up in uCode table */ 2061 /* If new "search" mode was selected, set up in uCode table */
2374 if (lq_sta->search_better_tbl) { 2062 if (lq_sta->search_better_tbl) {
@@ -2533,11 +2221,10 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2533 rate_idx -= IWL_FIRST_OFDM_RATE; 2221 rate_idx -= IWL_FIRST_OFDM_RATE;
2534 /* 6M and 9M shared same MCS index */ 2222 /* 6M and 9M shared same MCS index */
2535 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0; 2223 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
2224 WARN_ON_ONCE(rs_extract_rate(lq_sta->last_rate_n_flags) >=
2225 IWL_RATE_MIMO3_6M_PLCP);
2536 if (rs_extract_rate(lq_sta->last_rate_n_flags) >= 2226 if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2537 IWL_RATE_MIMO3_6M_PLCP) 2227 IWL_RATE_MIMO2_6M_PLCP)
2538 rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);
2539 else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2540 IWL_RATE_MIMO2_6M_PLCP)
2541 rate_idx = rate_idx + MCS_INDEX_PER_STREAM; 2228 rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
2542 info->control.rates[0].flags = IEEE80211_TX_RC_MCS; 2229 info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
2543 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK) 2230 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
@@ -2636,16 +2323,10 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2636 lq_sta->active_mimo2_rate &= ~((u16)0x2); 2323 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2637 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; 2324 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2638 2325
2639 lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1;
2640 lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1;
2641 lq_sta->active_mimo3_rate &= ~((u16)0x2);
2642 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
2643
2644 IWL_DEBUG_RATE(mvm, 2326 IWL_DEBUG_RATE(mvm,
2645 "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n", 2327 "SISO-RATE=%X MIMO2-RATE=%X\n",
2646 lq_sta->active_siso_rate, 2328 lq_sta->active_siso_rate,
2647 lq_sta->active_mimo2_rate, 2329 lq_sta->active_mimo2_rate);
2648 lq_sta->active_mimo3_rate);
2649 2330
2650 /* These values will be overridden later */ 2331 /* These values will be overridden later */
2651 lq_sta->lq.single_stream_ant_msk = 2332 lq_sta->lq.single_stream_ant_msk =
@@ -2689,7 +2370,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2689 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; 2370 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2690 2371
2691 /* Override starting rate (index 0) if needed for debug purposes */ 2372 /* Override starting rate (index 0) if needed for debug purposes */
2692 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2373 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2693 2374
2694 /* Interpret new_rate (rate_n_flags) */ 2375 /* Interpret new_rate (rate_n_flags) */
2695 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, 2376 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
@@ -2736,7 +2417,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2736 } 2417 }
2737 2418
2738 /* Override next rate if needed for debug purposes */ 2419 /* Override next rate if needed for debug purposes */
2739 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2420 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2740 2421
2741 /* Fill next table entry */ 2422 /* Fill next table entry */
2742 lq_cmd->rs_table[index] = 2423 lq_cmd->rs_table[index] =
@@ -2778,7 +2459,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2778 use_ht_possible = 0; 2459 use_ht_possible = 0;
2779 2460
2780 /* Override next rate if needed for debug purposes */ 2461 /* Override next rate if needed for debug purposes */
2781 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2462 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2782 2463
2783 /* Fill next table entry */ 2464 /* Fill next table entry */
2784 lq_cmd->rs_table[index] = cpu_to_le32(new_rate); 2465 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
@@ -2823,7 +2504,7 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
2823 2504
2824#ifdef CONFIG_MAC80211_DEBUGFS 2505#ifdef CONFIG_MAC80211_DEBUGFS
2825static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, 2506static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2826 u32 *rate_n_flags, int index) 2507 u32 *rate_n_flags)
2827{ 2508{
2828 struct iwl_mvm *mvm; 2509 struct iwl_mvm *mvm;
2829 u8 valid_tx_ant; 2510 u8 valid_tx_ant;
@@ -2908,8 +2589,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2908 (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); 2589 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
2909 if (is_Ht(tbl->lq_type)) { 2590 if (is_Ht(tbl->lq_type)) {
2910 desc += sprintf(buff+desc, " %s", 2591 desc += sprintf(buff+desc, " %s",
2911 (is_siso(tbl->lq_type)) ? "SISO" : 2592 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2");
2912 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
2913 desc += sprintf(buff+desc, " %s", 2593 desc += sprintf(buff+desc, " %s",
2914 (tbl->is_ht40) ? "40MHz" : "20MHz"); 2594 (tbl->is_ht40) ? "40MHz" : "20MHz");
2915 desc += sprintf(buff+desc, " %s %s %s\n", 2595 desc += sprintf(buff+desc, " %s %s %s\n",
@@ -3009,32 +2689,6 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
3009 .llseek = default_llseek, 2689 .llseek = default_llseek,
3010}; 2690};
3011 2691
3012static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
3013 char __user *user_buf, size_t count, loff_t *ppos)
3014{
3015 struct iwl_lq_sta *lq_sta = file->private_data;
3016 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
3017 char buff[120];
3018 int desc = 0;
3019
3020 if (is_Ht(tbl->lq_type))
3021 desc += sprintf(buff+desc,
3022 "Bit Rate= %d Mb/s\n",
3023 tbl->expected_tpt[lq_sta->last_txrate_idx]);
3024 else
3025 desc += sprintf(buff+desc,
3026 "Bit Rate= %d Mb/s\n",
3027 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
3028
3029 return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
3030}
3031
3032static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
3033 .read = rs_sta_dbgfs_rate_scale_data_read,
3034 .open = simple_open,
3035 .llseek = default_llseek,
3036};
3037
3038static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir) 2692static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3039{ 2693{
3040 struct iwl_lq_sta *lq_sta = mvm_sta; 2694 struct iwl_lq_sta *lq_sta = mvm_sta;
@@ -3044,9 +2698,6 @@ static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3044 lq_sta->rs_sta_dbgfs_stats_table_file = 2698 lq_sta->rs_sta_dbgfs_stats_table_file =
3045 debugfs_create_file("rate_stats_table", S_IRUSR, dir, 2699 debugfs_create_file("rate_stats_table", S_IRUSR, dir,
3046 lq_sta, &rs_sta_dbgfs_stats_table_ops); 2700 lq_sta, &rs_sta_dbgfs_stats_table_ops);
3047 lq_sta->rs_sta_dbgfs_rate_scale_data_file =
3048 debugfs_create_file("rate_scale_data", S_IRUSR, dir,
3049 lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
3050 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = 2701 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
3051 debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir, 2702 debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
3052 &lq_sta->tx_agg_tid_en); 2703 &lq_sta->tx_agg_tid_en);
@@ -3057,7 +2708,6 @@ static void rs_remove_debugfs(void *mvm, void *mvm_sta)
3057 struct iwl_lq_sta *lq_sta = mvm_sta; 2708 struct iwl_lq_sta *lq_sta = mvm_sta;
3058 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); 2709 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
3059 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); 2710 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
3060 debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
3061 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); 2711 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
3062} 2712}
3063#endif 2713#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 4a99a4d200ac..335cf1682902 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -38,14 +38,8 @@ struct iwl_rs_rate_info {
38 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ 38 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
39 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ 39 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
40 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ 40 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
41 u8 plcp_mimo3; /* uCode API: IWL_RATE_MIMO3_6M_PLCP, etc. */
42 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
43 u8 prev_ieee; /* previous rate in IEEE speeds */
44 u8 next_ieee; /* next rate in IEEE speeds */
45 u8 prev_rs; /* previous rate used in rs algo */ 41 u8 prev_rs; /* previous rate used in rs algo */
46 u8 next_rs; /* next rate used in rs algo */ 42 u8 next_rs; /* next rate used in rs algo */
47 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
48 u8 next_rs_tgg; /* next rate used in TGG rs algo */
49}; 43};
50 44
51#define IWL_RATE_60M_PLCP 3 45#define IWL_RATE_60M_PLCP 3
@@ -120,23 +114,6 @@ enum {
120 IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, 114 IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
121}; 115};
122 116
123/* MAC header values for bit rates */
124enum {
125 IWL_RATE_6M_IEEE = 12,
126 IWL_RATE_9M_IEEE = 18,
127 IWL_RATE_12M_IEEE = 24,
128 IWL_RATE_18M_IEEE = 36,
129 IWL_RATE_24M_IEEE = 48,
130 IWL_RATE_36M_IEEE = 72,
131 IWL_RATE_48M_IEEE = 96,
132 IWL_RATE_54M_IEEE = 108,
133 IWL_RATE_60M_IEEE = 120,
134 IWL_RATE_1M_IEEE = 2,
135 IWL_RATE_2M_IEEE = 4,
136 IWL_RATE_5M_IEEE = 11,
137 IWL_RATE_11M_IEEE = 22,
138};
139
140#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) 117#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
141 118
142#define IWL_INVALID_VALUE -1 119#define IWL_INVALID_VALUE -1
@@ -165,47 +142,22 @@ enum {
165#define IWL_LEGACY_SWITCH_ANTENNA1 0 142#define IWL_LEGACY_SWITCH_ANTENNA1 0
166#define IWL_LEGACY_SWITCH_ANTENNA2 1 143#define IWL_LEGACY_SWITCH_ANTENNA2 1
167#define IWL_LEGACY_SWITCH_SISO 2 144#define IWL_LEGACY_SWITCH_SISO 2
168#define IWL_LEGACY_SWITCH_MIMO2_AB 3 145#define IWL_LEGACY_SWITCH_MIMO2 3
169#define IWL_LEGACY_SWITCH_MIMO2_AC 4
170#define IWL_LEGACY_SWITCH_MIMO2_BC 5
171#define IWL_LEGACY_SWITCH_MIMO3_ABC 6
172 146
173/* possible actions when in siso mode */ 147/* possible actions when in siso mode */
174#define IWL_SISO_SWITCH_ANTENNA1 0 148#define IWL_SISO_SWITCH_ANTENNA1 0
175#define IWL_SISO_SWITCH_ANTENNA2 1 149#define IWL_SISO_SWITCH_ANTENNA2 1
176#define IWL_SISO_SWITCH_MIMO2_AB 2 150#define IWL_SISO_SWITCH_MIMO2 2
177#define IWL_SISO_SWITCH_MIMO2_AC 3 151#define IWL_SISO_SWITCH_GI 3
178#define IWL_SISO_SWITCH_MIMO2_BC 4
179#define IWL_SISO_SWITCH_GI 5
180#define IWL_SISO_SWITCH_MIMO3_ABC 6
181
182 152
183/* possible actions when in mimo mode */ 153/* possible actions when in mimo mode */
184#define IWL_MIMO2_SWITCH_ANTENNA1 0 154#define IWL_MIMO2_SWITCH_ANTENNA1 0
185#define IWL_MIMO2_SWITCH_ANTENNA2 1 155#define IWL_MIMO2_SWITCH_ANTENNA2 1
186#define IWL_MIMO2_SWITCH_SISO_A 2 156#define IWL_MIMO2_SWITCH_SISO_A 2
187#define IWL_MIMO2_SWITCH_SISO_B 3 157#define IWL_MIMO2_SWITCH_SISO_B 3
188#define IWL_MIMO2_SWITCH_SISO_C 4 158#define IWL_MIMO2_SWITCH_GI 4
189#define IWL_MIMO2_SWITCH_GI 5
190#define IWL_MIMO2_SWITCH_MIMO3_ABC 6
191
192
193/* possible actions when in mimo3 mode */
194#define IWL_MIMO3_SWITCH_ANTENNA1 0
195#define IWL_MIMO3_SWITCH_ANTENNA2 1
196#define IWL_MIMO3_SWITCH_SISO_A 2
197#define IWL_MIMO3_SWITCH_SISO_B 3
198#define IWL_MIMO3_SWITCH_SISO_C 4
199#define IWL_MIMO3_SWITCH_MIMO2_AB 5
200#define IWL_MIMO3_SWITCH_MIMO2_AC 6
201#define IWL_MIMO3_SWITCH_MIMO2_BC 7
202#define IWL_MIMO3_SWITCH_GI 8
203
204
205#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
206#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
207 159
208/*FIXME:RS:add possible actions for MIMO3*/ 160#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_GI
209 161
210#define IWL_ACTION_LIMIT 3 /* # possible actions */ 162#define IWL_ACTION_LIMIT 3 /* # possible actions */
211 163
@@ -240,15 +192,13 @@ enum iwl_table_type {
240 LQ_A, 192 LQ_A,
241 LQ_SISO, /* high-throughput types */ 193 LQ_SISO, /* high-throughput types */
242 LQ_MIMO2, 194 LQ_MIMO2,
243 LQ_MIMO3,
244 LQ_MAX, 195 LQ_MAX,
245}; 196};
246 197
247#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) 198#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
248#define is_siso(tbl) ((tbl) == LQ_SISO) 199#define is_siso(tbl) ((tbl) == LQ_SISO)
249#define is_mimo2(tbl) ((tbl) == LQ_MIMO2) 200#define is_mimo2(tbl) ((tbl) == LQ_MIMO2)
250#define is_mimo3(tbl) ((tbl) == LQ_MIMO3) 201#define is_mimo(tbl) is_mimo2(tbl)
251#define is_mimo(tbl) (is_mimo2(tbl) || is_mimo3(tbl))
252#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl)) 202#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
253#define is_a_band(tbl) ((tbl) == LQ_A) 203#define is_a_band(tbl) ((tbl) == LQ_A)
254#define is_g_and(tbl) ((tbl) == LQ_G) 204#define is_g_and(tbl) ((tbl) == LQ_G)
@@ -320,7 +270,6 @@ struct iwl_lq_sta {
320 u16 active_legacy_rate; 270 u16 active_legacy_rate;
321 u16 active_siso_rate; 271 u16 active_siso_rate;
322 u16 active_mimo2_rate; 272 u16 active_mimo2_rate;
323 u16 active_mimo3_rate;
324 s8 max_rate_idx; /* Max rate set by user */ 273 s8 max_rate_idx; /* Max rate set by user */
325 u8 missed_rate_counter; 274 u8 missed_rate_counter;
326 275
@@ -330,7 +279,6 @@ struct iwl_lq_sta {
330#ifdef CONFIG_MAC80211_DEBUGFS 279#ifdef CONFIG_MAC80211_DEBUGFS
331 struct dentry *rs_sta_dbgfs_scale_table_file; 280 struct dentry *rs_sta_dbgfs_scale_table_file;
332 struct dentry *rs_sta_dbgfs_stats_table_file; 281 struct dentry *rs_sta_dbgfs_stats_table_file;
333 struct dentry *rs_sta_dbgfs_rate_scale_data_file;
334 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; 282 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
335 u32 dbg_fixed_rate; 283 u32 dbg_fixed_rate;
336#endif 284#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index ee6547d22287..2a8cb5a60535 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -396,11 +396,62 @@ static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm,
396 memcpy(&mvm->rx_stats, &stats->rx, sizeof(struct mvm_statistics_rx)); 396 memcpy(&mvm->rx_stats, &stats->rx, sizeof(struct mvm_statistics_rx));
397} 397}
398 398
399struct iwl_mvm_stat_data {
400 struct iwl_notif_statistics *stats;
401 struct iwl_mvm *mvm;
402};
403
404static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
405 struct ieee80211_vif *vif)
406{
407 struct iwl_mvm_stat_data *data = _data;
408 struct iwl_notif_statistics *stats = data->stats;
409 struct iwl_mvm *mvm = data->mvm;
410 int sig = -stats->general.beacon_filter_average_energy;
411 int last_event;
412 int thold = vif->bss_conf.cqm_rssi_thold;
413 int hyst = vif->bss_conf.cqm_rssi_hyst;
414 u16 id = le32_to_cpu(stats->rx.general.mac_id);
415 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
416
417 if (mvmvif->id != id)
418 return;
419
420 if (vif->type != NL80211_IFTYPE_STATION)
421 return;
422
423 mvmvif->bf_data.ave_beacon_signal = sig;
424
425 if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
426 return;
427
428 /* CQM Notification */
429 last_event = mvmvif->bf_data.last_cqm_event;
430 if (thold && sig < thold && (last_event == 0 ||
431 sig < last_event - hyst)) {
432 mvmvif->bf_data.last_cqm_event = sig;
433 IWL_DEBUG_RX(mvm, "cqm_iterator cqm low %d\n",
434 sig);
435 ieee80211_cqm_rssi_notify(
436 vif,
437 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
438 GFP_KERNEL);
439 } else if (sig > thold &&
440 (last_event == 0 || sig > last_event + hyst)) {
441 mvmvif->bf_data.last_cqm_event = sig;
442 IWL_DEBUG_RX(mvm, "cqm_iterator cqm high %d\n",
443 sig);
444 ieee80211_cqm_rssi_notify(
445 vif,
446 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
447 GFP_KERNEL);
448 }
449}
450
399/* 451/*
400 * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler 452 * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler
401 * 453 *
402 * TODO: This handler is implemented partially. 454 * TODO: This handler is implemented partially.
403 * It only gets the NIC's temperature.
404 */ 455 */
405int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, 456int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
406 struct iwl_rx_cmd_buffer *rxb, 457 struct iwl_rx_cmd_buffer *rxb,
@@ -409,6 +460,10 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
409 struct iwl_rx_packet *pkt = rxb_addr(rxb); 460 struct iwl_rx_packet *pkt = rxb_addr(rxb);
410 struct iwl_notif_statistics *stats = (void *)&pkt->data; 461 struct iwl_notif_statistics *stats = (void *)&pkt->data;
411 struct mvm_statistics_general_common *common = &stats->general.common; 462 struct mvm_statistics_general_common *common = &stats->general.common;
463 struct iwl_mvm_stat_data data = {
464 .stats = stats,
465 .mvm = mvm,
466 };
412 467
413 if (mvm->temperature != le32_to_cpu(common->temperature)) { 468 if (mvm->temperature != le32_to_cpu(common->temperature)) {
414 mvm->temperature = le32_to_cpu(common->temperature); 469 mvm->temperature = le32_to_cpu(common->temperature);
@@ -416,5 +471,9 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
416 } 471 }
417 iwl_mvm_update_rx_statistics(mvm, stats); 472 iwl_mvm_update_rx_statistics(mvm, stats);
418 473
474 ieee80211_iterate_active_interfaces(mvm->hw,
475 IEEE80211_IFACE_ITER_NORMAL,
476 iwl_mvm_stat_iterator,
477 &data);
419 return 0; 478 return 0;
420} 479}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 9f100363b177..f5329d22840e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -165,7 +165,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
165 WARN_ONCE(!le32_to_cpu(notif->status), 165 WARN_ONCE(!le32_to_cpu(notif->status),
166 "Failed to schedule time event\n"); 166 "Failed to schedule time event\n");
167 167
168 if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) { 168 if (le32_to_cpu(notif->action) & TE_V2_NOTIF_HOST_EVENT_END) {
169 IWL_DEBUG_TE(mvm, 169 IWL_DEBUG_TE(mvm,
170 "TE ended - current time %lu, estimated end %lu\n", 170 "TE ended - current time %lu, estimated end %lu\n",
171 jiffies, te_data->end_jiffies); 171 jiffies, te_data->end_jiffies);
@@ -188,7 +188,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
188 } 188 }
189 189
190 iwl_mvm_te_clear_data(mvm, te_data); 190 iwl_mvm_te_clear_data(mvm, te_data);
191 } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) { 191 } else if (le32_to_cpu(notif->action) & TE_V2_NOTIF_HOST_EVENT_START) {
192 te_data->running = true; 192 te_data->running = true;
193 te_data->end_jiffies = TU_TO_EXP_TIME(te_data->duration); 193 te_data->end_jiffies = TU_TO_EXP_TIME(te_data->duration);
194 194
@@ -255,10 +255,67 @@ static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
255 return true; 255 return true;
256} 256}
257 257
258/* used to convert from time event API v2 to v1 */
259#define TE_V2_DEP_POLICY_MSK (TE_V2_DEP_OTHER | TE_V2_DEP_TSF |\
260 TE_V2_EVENT_SOCIOPATHIC)
261static inline u16 te_v2_get_notify(__le16 policy)
262{
263 return le16_to_cpu(policy) & TE_V2_NOTIF_MSK;
264}
265
266static inline u16 te_v2_get_dep_policy(__le16 policy)
267{
268 return (le16_to_cpu(policy) & TE_V2_DEP_POLICY_MSK) >>
269 TE_V2_PLACEMENT_POS;
270}
271
272static inline u16 te_v2_get_absence(__le16 policy)
273{
274 return (le16_to_cpu(policy) & TE_V2_ABSENCE) >> TE_V2_ABSENCE_POS;
275}
276
277static void iwl_mvm_te_v2_to_v1(const struct iwl_time_event_cmd_v2 *cmd_v2,
278 struct iwl_time_event_cmd_v1 *cmd_v1)
279{
280 cmd_v1->id_and_color = cmd_v2->id_and_color;
281 cmd_v1->action = cmd_v2->action;
282 cmd_v1->id = cmd_v2->id;
283 cmd_v1->apply_time = cmd_v2->apply_time;
284 cmd_v1->max_delay = cmd_v2->max_delay;
285 cmd_v1->depends_on = cmd_v2->depends_on;
286 cmd_v1->interval = cmd_v2->interval;
287 cmd_v1->duration = cmd_v2->duration;
288 if (cmd_v2->repeat == TE_V2_REPEAT_ENDLESS)
289 cmd_v1->repeat = cpu_to_le32(TE_V1_REPEAT_ENDLESS);
290 else
291 cmd_v1->repeat = cpu_to_le32(cmd_v2->repeat);
292 cmd_v1->max_frags = cpu_to_le32(cmd_v2->max_frags);
293 cmd_v1->interval_reciprocal = 0; /* unused */
294
295 cmd_v1->dep_policy = cpu_to_le32(te_v2_get_dep_policy(cmd_v2->policy));
296 cmd_v1->is_present = cpu_to_le32(!te_v2_get_absence(cmd_v2->policy));
297 cmd_v1->notify = cpu_to_le32(te_v2_get_notify(cmd_v2->policy));
298}
299
300static int iwl_mvm_send_time_event_cmd(struct iwl_mvm *mvm,
301 const struct iwl_time_event_cmd_v2 *cmd)
302{
303 struct iwl_time_event_cmd_v1 cmd_v1;
304
305 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2)
306 return iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
307 sizeof(*cmd), cmd);
308
309 iwl_mvm_te_v2_to_v1(cmd, &cmd_v1);
310 return iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
311 sizeof(cmd_v1), &cmd_v1);
312}
313
314
258static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm, 315static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
259 struct ieee80211_vif *vif, 316 struct ieee80211_vif *vif,
260 struct iwl_mvm_time_event_data *te_data, 317 struct iwl_mvm_time_event_data *te_data,
261 struct iwl_time_event_cmd *te_cmd) 318 struct iwl_time_event_cmd_v2 *te_cmd)
262{ 319{
263 static const u8 time_event_response[] = { TIME_EVENT_CMD }; 320 static const u8 time_event_response[] = { TIME_EVENT_CMD };
264 struct iwl_notification_wait wait_time_event; 321 struct iwl_notification_wait wait_time_event;
@@ -294,8 +351,7 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
294 ARRAY_SIZE(time_event_response), 351 ARRAY_SIZE(time_event_response),
295 iwl_mvm_time_event_response, te_data); 352 iwl_mvm_time_event_response, te_data);
296 353
297 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC, 354 ret = iwl_mvm_send_time_event_cmd(mvm, te_cmd);
298 sizeof(*te_cmd), te_cmd);
299 if (ret) { 355 if (ret) {
300 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret); 356 IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
301 iwl_remove_notification(&mvm->notif_wait, &wait_time_event); 357 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
@@ -322,7 +378,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
322{ 378{
323 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 379 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
324 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 380 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
325 struct iwl_time_event_cmd time_cmd = {}; 381 struct iwl_time_event_cmd_v2 time_cmd = {};
326 382
327 lockdep_assert_held(&mvm->mutex); 383 lockdep_assert_held(&mvm->mutex);
328 384
@@ -356,17 +412,14 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
356 time_cmd.apply_time = 412 time_cmd.apply_time =
357 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG)); 413 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG));
358 414
359 time_cmd.dep_policy = TE_INDEPENDENT; 415 time_cmd.max_frags = TE_V2_FRAG_NONE;
360 time_cmd.is_present = cpu_to_le32(1);
361 time_cmd.max_frags = cpu_to_le32(TE_FRAG_NONE);
362 time_cmd.max_delay = cpu_to_le32(500); 416 time_cmd.max_delay = cpu_to_le32(500);
363 /* TODO: why do we need to interval = bi if it is not periodic? */ 417 /* TODO: why do we need to interval = bi if it is not periodic? */
364 time_cmd.interval = cpu_to_le32(1); 418 time_cmd.interval = cpu_to_le32(1);
365 time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1));
366 time_cmd.duration = cpu_to_le32(duration); 419 time_cmd.duration = cpu_to_le32(duration);
367 time_cmd.repeat = cpu_to_le32(1); 420 time_cmd.repeat = 1;
368 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | 421 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
369 TE_NOTIF_HOST_EVENT_END); 422 TE_V2_NOTIF_HOST_EVENT_END);
370 423
371 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 424 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
372} 425}
@@ -380,7 +433,7 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
380 struct iwl_mvm_vif *mvmvif, 433 struct iwl_mvm_vif *mvmvif,
381 struct iwl_mvm_time_event_data *te_data) 434 struct iwl_mvm_time_event_data *te_data)
382{ 435{
383 struct iwl_time_event_cmd time_cmd = {}; 436 struct iwl_time_event_cmd_v2 time_cmd = {};
384 u32 id, uid; 437 u32 id, uid;
385 int ret; 438 int ret;
386 439
@@ -417,8 +470,7 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
417 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 470 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
418 471
419 IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id)); 472 IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id));
420 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC, 473 ret = iwl_mvm_send_time_event_cmd(mvm, &time_cmd);
421 sizeof(time_cmd), &time_cmd);
422 if (WARN_ON(ret)) 474 if (WARN_ON(ret))
423 return; 475 return;
424} 476}
@@ -438,7 +490,7 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
438{ 490{
439 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 491 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
440 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 492 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
441 struct iwl_time_event_cmd time_cmd = {}; 493 struct iwl_time_event_cmd_v2 time_cmd = {};
442 494
443 lockdep_assert_held(&mvm->mutex); 495 lockdep_assert_held(&mvm->mutex);
444 if (te_data->running) { 496 if (te_data->running) {
@@ -469,8 +521,6 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
469 } 521 }
470 522
471 time_cmd.apply_time = cpu_to_le32(0); 523 time_cmd.apply_time = cpu_to_le32(0);
472 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
473 time_cmd.is_present = cpu_to_le32(1);
474 time_cmd.interval = cpu_to_le32(1); 524 time_cmd.interval = cpu_to_le32(1);
475 525
476 /* 526 /*
@@ -479,12 +529,12 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
479 * scheduled. To improve the chances of it being scheduled, allow them 529 * scheduled. To improve the chances of it being scheduled, allow them
480 * to be fragmented, and in addition allow them to be delayed. 530 * to be fragmented, and in addition allow them to be delayed.
481 */ 531 */
482 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20); 532 time_cmd.max_frags = min(MSEC_TO_TU(duration)/50, TE_V2_FRAG_ENDLESS);
483 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); 533 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
484 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); 534 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
485 time_cmd.repeat = cpu_to_le32(1); 535 time_cmd.repeat = 1;
486 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START | 536 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
487 TE_NOTIF_HOST_EVENT_END); 537 TE_V2_NOTIF_HOST_EVENT_END);
488 538
489 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 539 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
490} 540}
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 158669ee4ce5..dc02cb9792af 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -325,15 +325,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
325 int ret; 325 int ret;
326 326
327 iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg); 327 iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
328 if (iwl_trans == NULL) 328 if (IS_ERR(iwl_trans))
329 return -ENOMEM; 329 return PTR_ERR(iwl_trans);
330 330
331 pci_set_drvdata(pdev, iwl_trans); 331 pci_set_drvdata(pdev, iwl_trans);
332 332
333 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); 333 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
334 trans_pcie->drv = iwl_drv_start(iwl_trans, cfg); 334 trans_pcie->drv = iwl_drv_start(iwl_trans, cfg);
335 335
336 if (IS_ERR_OR_NULL(trans_pcie->drv)) { 336 if (IS_ERR(trans_pcie->drv)) {
337 ret = PTR_ERR(trans_pcie->drv); 337 ret = PTR_ERR(trans_pcie->drv);
338 goto out_free_trans; 338 goto out_free_trans;
339 } 339 }
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 68837d4e9fa0..a4c7aeb786d2 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -112,15 +112,16 @@
112 */ 112 */
113static int iwl_rxq_space(const struct iwl_rxq *rxq) 113static int iwl_rxq_space(const struct iwl_rxq *rxq)
114{ 114{
115 int s = rxq->read - rxq->write; 115 /* Make sure RX_QUEUE_SIZE is a power of 2 */
116 116 BUILD_BUG_ON(RX_QUEUE_SIZE & (RX_QUEUE_SIZE - 1));
117 if (s <= 0) 117
118 s += RX_QUEUE_SIZE; 118 /*
119 /* keep some buffer to not confuse full and empty queue */ 119 * There can be up to (RX_QUEUE_SIZE - 1) free slots, to avoid ambiguity
120 s -= 2; 120 * between empty and completely full queues.
121 if (s < 0) 121 * The following is equivalent to modulo by RX_QUEUE_SIZE and is well
122 s = 0; 122 * defined for negative dividends.
123 return s; 123 */
124 return (rxq->read - rxq->write - 1) & (RX_QUEUE_SIZE - 1);
124} 125}
125 126
126/* 127/*
@@ -1128,6 +1129,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
1128 struct iwl_trans *trans = data; 1129 struct iwl_trans *trans = data;
1129 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1130 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1130 u32 inta, inta_mask; 1131 u32 inta, inta_mask;
1132 irqreturn_t ret = IRQ_NONE;
1131 1133
1132 lockdep_assert_held(&trans_pcie->irq_lock); 1134 lockdep_assert_held(&trans_pcie->irq_lock);
1133 1135
@@ -1176,10 +1178,8 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
1176 /* the thread will service interrupts and re-enable them */ 1178 /* the thread will service interrupts and re-enable them */
1177 if (likely(inta)) 1179 if (likely(inta))
1178 return IRQ_WAKE_THREAD; 1180 return IRQ_WAKE_THREAD;
1179 else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 1181
1180 !trans_pcie->inta) 1182 ret = IRQ_HANDLED;
1181 iwl_enable_interrupts(trans);
1182 return IRQ_HANDLED;
1183 1183
1184none: 1184none:
1185 /* re-enable interrupts here since we don't have anything to service. */ 1185 /* re-enable interrupts here since we don't have anything to service. */
@@ -1188,7 +1188,7 @@ none:
1188 !trans_pcie->inta) 1188 !trans_pcie->inta)
1189 iwl_enable_interrupts(trans); 1189 iwl_enable_interrupts(trans);
1190 1190
1191 return IRQ_NONE; 1191 return ret;
1192} 1192}
1193 1193
1194/* interrupt handler using ict table, with this interrupt driver will 1194/* interrupt handler using ict table, with this interrupt driver will
@@ -1207,6 +1207,7 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
1207 u32 val = 0; 1207 u32 val = 0;
1208 u32 read; 1208 u32 read;
1209 unsigned long flags; 1209 unsigned long flags;
1210 irqreturn_t ret = IRQ_NONE;
1210 1211
1211 if (!trans) 1212 if (!trans)
1212 return IRQ_NONE; 1213 return IRQ_NONE;
@@ -1219,7 +1220,7 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
1219 * use legacy interrupt. 1220 * use legacy interrupt.
1220 */ 1221 */
1221 if (unlikely(!trans_pcie->use_ict)) { 1222 if (unlikely(!trans_pcie->use_ict)) {
1222 irqreturn_t ret = iwl_pcie_isr(irq, data); 1223 ret = iwl_pcie_isr(irq, data);
1223 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1224 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1224 return ret; 1225 return ret;
1225 } 1226 }
@@ -1288,17 +1289,9 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
1288 if (likely(inta)) { 1289 if (likely(inta)) {
1289 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1290 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1290 return IRQ_WAKE_THREAD; 1291 return IRQ_WAKE_THREAD;
1291 } else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
1292 !trans_pcie->inta) {
1293 /* Allow interrupt if was disabled by this handler and
1294 * no tasklet was schedules, We should not enable interrupt,
1295 * tasklet will enable it.
1296 */
1297 iwl_enable_interrupts(trans);
1298 } 1292 }
1299 1293
1300 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1294 ret = IRQ_HANDLED;
1301 return IRQ_HANDLED;
1302 1295
1303 none: 1296 none:
1304 /* re-enable interrupts here since we don't have anything to service. 1297 /* re-enable interrupts here since we don't have anything to service.
@@ -1309,5 +1302,5 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
1309 iwl_enable_interrupts(trans); 1302 iwl_enable_interrupts(trans);
1310 1303
1311 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1304 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1312 return IRQ_NONE; 1305 return ret;
1313} 1306}
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index e52d1ce1501c..bad95d28d50d 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1386,9 +1386,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1386 1386
1387 trans = kzalloc(sizeof(struct iwl_trans) + 1387 trans = kzalloc(sizeof(struct iwl_trans) +
1388 sizeof(struct iwl_trans_pcie), GFP_KERNEL); 1388 sizeof(struct iwl_trans_pcie), GFP_KERNEL);
1389 1389 if (!trans) {
1390 if (!trans) 1390 err = -ENOMEM;
1391 return NULL; 1391 goto out;
1392 }
1392 1393
1393 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1394 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1394 1395
@@ -1411,10 +1412,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1411 PCIE_LINK_STATE_CLKPM); 1412 PCIE_LINK_STATE_CLKPM);
1412 } 1413 }
1413 1414
1414 if (pci_enable_device(pdev)) { 1415 err = pci_enable_device(pdev);
1415 err = -ENODEV; 1416 if (err)
1416 goto out_no_pci; 1417 goto out_no_pci;
1417 }
1418 1418
1419 pci_set_master(pdev); 1419 pci_set_master(pdev);
1420 1420
@@ -1483,17 +1483,20 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1483 SLAB_HWCACHE_ALIGN, 1483 SLAB_HWCACHE_ALIGN,
1484 NULL); 1484 NULL);
1485 1485
1486 if (!trans->dev_cmd_pool) 1486 if (!trans->dev_cmd_pool) {
1487 err = -ENOMEM;
1487 goto out_pci_disable_msi; 1488 goto out_pci_disable_msi;
1489 }
1488 1490
1489 trans_pcie->inta_mask = CSR_INI_SET_MASK; 1491 trans_pcie->inta_mask = CSR_INI_SET_MASK;
1490 1492
1491 if (iwl_pcie_alloc_ict(trans)) 1493 if (iwl_pcie_alloc_ict(trans))
1492 goto out_free_cmd_pool; 1494 goto out_free_cmd_pool;
1493 1495
1494 if (request_threaded_irq(pdev->irq, iwl_pcie_isr_ict, 1496 err = request_threaded_irq(pdev->irq, iwl_pcie_isr_ict,
1495 iwl_pcie_irq_handler, 1497 iwl_pcie_irq_handler,
1496 IRQF_SHARED, DRV_NAME, trans)) { 1498 IRQF_SHARED, DRV_NAME, trans);
1499 if (err) {
1497 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); 1500 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq);
1498 goto out_free_ict; 1501 goto out_free_ict;
1499 } 1502 }
@@ -1512,5 +1515,6 @@ out_pci_disable_device:
1512 pci_disable_device(pdev); 1515 pci_disable_device(pdev);
1513out_no_pci: 1516out_no_pci:
1514 kfree(trans); 1517 kfree(trans);
1515 return NULL; 1518out:
1519 return ERR_PTR(err);
1516} 1520}
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 011167c22da8..f45eb29c2ede 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -65,18 +65,30 @@
65 ***************************************************/ 65 ***************************************************/
66static int iwl_queue_space(const struct iwl_queue *q) 66static int iwl_queue_space(const struct iwl_queue *q)
67{ 67{
68 int s = q->read_ptr - q->write_ptr; 68 unsigned int max;
69 69 unsigned int used;
70 if (q->read_ptr > q->write_ptr) 70
71 s -= q->n_bd; 71 /*
72 72 * To avoid ambiguity between empty and completely full queues, there
73 if (s <= 0) 73 * should always be less than q->n_bd elements in the queue.
74 s += q->n_window; 74 * If q->n_window is smaller than q->n_bd, there is no need to reserve
75 /* keep some reserve to not confuse empty and full situations */ 75 * any queue entries for this purpose.
76 s -= 2; 76 */
77 if (s < 0) 77 if (q->n_window < q->n_bd)
78 s = 0; 78 max = q->n_window;
79 return s; 79 else
80 max = q->n_bd - 1;
81
82 /*
83 * q->n_bd is a power of 2, so the following is equivalent to modulo by
84 * q->n_bd and is well defined for negative dividends.
85 */
86 used = (q->write_ptr - q->read_ptr) & (q->n_bd - 1);
87
88 if (WARN_ON(used > max))
89 return 0;
90
91 return max - used;
80} 92}
81 93
82/* 94/*
@@ -826,7 +838,7 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
826 sizeof(struct iwl_txq), GFP_KERNEL); 838 sizeof(struct iwl_txq), GFP_KERNEL);
827 if (!trans_pcie->txq) { 839 if (!trans_pcie->txq) {
828 IWL_ERR(trans, "Not enough memory for txq\n"); 840 IWL_ERR(trans, "Not enough memory for txq\n");
829 ret = ENOMEM; 841 ret = -ENOMEM;
830 goto error; 842 goto error;
831 } 843 }
832 844