History

Merge tag 'iwlwifi-next-for-john-2014-12-02' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

"Grumbach, Emmanuel" <emmanuel.grumbach@intel.com> says: "I deprecate here -8.ucode since -9 has been published long ago. Along with that I have a new activity, we have now better infrastructure for firmware debugging. This will allow to have configurable probes insides the firmware. Luca continues his work on NetDetect, this feature is now complete. All the rest is minor fixes here and there."

John W. Linville committed 11 years ago

Commit ea375112 parents fbf6109 61df75026 files · +1258 −471Browse files

Unified · Split

26 files
  1. drivers/net/wireless/iwlwifi/dvm/commands.h +18 −13
  2. drivers/net/wireless/iwlwifi/dvm/lib.c +24 −23
  3. drivers/net/wireless/iwlwifi/iwl-7000.c +9 −7
  4. drivers/net/wireless/iwlwifi/iwl-8000.c +4 −4
  5. drivers/net/wireless/iwlwifi/iwl-config.h +1 −0
  6. drivers/net/wireless/iwlwifi/iwl-drv.c +177 −18
  7. drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +3 −0
  8. drivers/net/wireless/iwlwifi/iwl-fw-file.h +308 −0
  9. drivers/net/wireless/iwlwifi/iwl-fw.h +69 −178
  10. drivers/net/wireless/iwlwifi/iwl-prph.h +5 −3
  11. drivers/net/wireless/iwlwifi/iwl-trans.h +7 −0
  12. drivers/net/wireless/iwlwifi/mvm/constants.h +2 −2
  13. drivers/net/wireless/iwlwifi/mvm/d3.c +171 −37
  14. drivers/net/wireless/iwlwifi/mvm/debugfs.c +1 −0
  15. drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +1 −5
  16. drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +44 −0
  17. drivers/net/wireless/iwlwifi/mvm/fw-api.h +4 −6
  18. drivers/net/wireless/iwlwifi/mvm/fw.c +45 −1
  19. drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +5 −14
  20. drivers/net/wireless/iwlwifi/mvm/mac80211.c +10 −6
  21. drivers/net/wireless/iwlwifi/mvm/mvm.h +6 −2
  22. drivers/net/wireless/iwlwifi/mvm/nvm.c +23 −8
  23. drivers/net/wireless/iwlwifi/mvm/offloading.c +1 −1
  24. drivers/net/wireless/iwlwifi/mvm/ops.c +15 −16
  25. drivers/net/wireless/iwlwifi/pcie/trans.c +239 −91
  26. drivers/net/wireless/iwlwifi/pcie/tx.c +66 −36
drivers/net/wireless/iwlwifi/dvm/commands.h+18−13
@@ -966,21 +966,21 @@ struct iwl_rem_sta_cmd { · 965 unmodified lines
966966
967967
968968 /* WiFi queues mask */
969−#define IWL_SCD_BK_MSK cpu_to_le32(BIT(0))
970−#define IWL_SCD_BE_MSK cpu_to_le32(BIT(1))
971−#define IWL_SCD_VI_MSK cpu_to_le32(BIT(2))
972−#define IWL_SCD_VO_MSK cpu_to_le32(BIT(3))
973−#define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3))
969+#define IWL_SCD_BK_MSK BIT(0)
970+#define IWL_SCD_BE_MSK BIT(1)
971+#define IWL_SCD_VI_MSK BIT(2)
972+#define IWL_SCD_VO_MSK BIT(3)
973+#define IWL_SCD_MGMT_MSK BIT(3)
974974
975975 /* PAN queues mask */
976−#define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4))
977−#define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5))
978−#define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6))
979−#define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7))
980−#define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7))
981−#define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8))
976+#define IWL_PAN_SCD_BK_MSK BIT(4)
977+#define IWL_PAN_SCD_BE_MSK BIT(5)
978+#define IWL_PAN_SCD_VI_MSK BIT(6)
979+#define IWL_PAN_SCD_VO_MSK BIT(7)
980+#define IWL_PAN_SCD_MGMT_MSK BIT(7)
981+#define IWL_PAN_SCD_MULTICAST_MSK BIT(8)
982982
983−#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00)
983+#define IWL_AGG_TX_QUEUE_MSK 0xffc00
984984
985985 #define IWL_DROP_ALL BIT(1)
986986
@@ -1005,12 +1005,17 @@ struct iwl_rem_sta_cmd { · 18 unmodified lines
10051005 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable.
10061006 * 2: Dump all FIFO
10071007 */
1008−struct iwl_txfifo_flush_cmd {
1008+struct iwl_txfifo_flush_cmd_v3 {
10091009 __le32 queue_control;
10101010 __le16 flush_control;
10111011 __le16 reserved;
10121012 } __packed;
10131013
1014+struct iwl_txfifo_flush_cmd_v2 {
1015+ __le16 queue_control;
1016+ __le16 flush_control;
1017+} __packed;
1018+
10141019 /*
10151020 * REPLY_WEP_KEY = 0x20
10161021 */
drivers/net/wireless/iwlwifi/dvm/lib.c+24−23
@@ -137,37 +137,38 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, · 136 unmodified lines
137137 */
138138 int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk)
139139 {
140− struct iwl_txfifo_flush_cmd flush_cmd;
141− struct iwl_host_cmd cmd = {
142− .id = REPLY_TXFIFO_FLUSH,
143− .len = { sizeof(struct iwl_txfifo_flush_cmd), },
144− .data = { &flush_cmd, },
140+ struct iwl_txfifo_flush_cmd_v3 flush_cmd_v3 = {
141+ .flush_control = cpu_to_le16(IWL_DROP_ALL),
142+ };
143+ struct iwl_txfifo_flush_cmd_v2 flush_cmd_v2 = {
144+ .flush_control = cpu_to_le16(IWL_DROP_ALL),
145145 };
146146
147− memset(&flush_cmd, 0, sizeof(flush_cmd));
147+ u32 queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK |
148+ IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | IWL_SCD_MGMT_MSK;
148149
149− flush_cmd.queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK |
150− IWL_SCD_BE_MSK | IWL_SCD_BK_MSK |
151− IWL_SCD_MGMT_MSK;
152150 if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)))
153− flush_cmd.queue_control |= IWL_PAN_SCD_VO_MSK |
154− IWL_PAN_SCD_VI_MSK |
155− IWL_PAN_SCD_BE_MSK |
156− IWL_PAN_SCD_BK_MSK |
157− IWL_PAN_SCD_MGMT_MSK |
158− IWL_PAN_SCD_MULTICAST_MSK;
151+ queue_control |= IWL_PAN_SCD_VO_MSK | IWL_PAN_SCD_VI_MSK |
152+ IWL_PAN_SCD_BE_MSK | IWL_PAN_SCD_BK_MSK |
153+ IWL_PAN_SCD_MGMT_MSK |
154+ IWL_PAN_SCD_MULTICAST_MSK;
159155
160156 if (priv->nvm_data->sku_cap_11n_enable)
161− flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK;
157+ queue_control |= IWL_AGG_TX_QUEUE_MSK;
162158
163159 if (scd_q_msk)
164− flush_cmd.queue_control = cpu_to_le32(scd_q_msk);
165−
166− IWL_DEBUG_INFO(priv, "queue control: 0x%x\n",
167− flush_cmd.queue_control);
168− flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL);
169−
170− return iwl_dvm_send_cmd(priv, &cmd);
160+ queue_control = scd_q_msk;
161+
162+ IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", queue_control);
163+ flush_cmd_v3.queue_control = cpu_to_le32(queue_control);
164+ flush_cmd_v2.queue_control = cpu_to_le16((u16)queue_control);
165+
166+ if (IWL_UCODE_API(priv->fw->ucode_ver) > 2)
167+ return iwl_dvm_send_cmd_pdu(priv, REPLY_TXFIFO_FLUSH, 0,
168+ sizeof(flush_cmd_v3),
169+ &flush_cmd_v3);
170+ return iwl_dvm_send_cmd_pdu(priv, REPLY_TXFIFO_FLUSH, 0,
171+ sizeof(flush_cmd_v2), &flush_cmd_v2);
171172 }
172173
173174 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
drivers/net/wireless/iwlwifi/iwl-7000.c+9−7
@@ -73,12 +73,12 @@ · 72 unmodified lines
7373 #define IWL3160_UCODE_API_MAX 10
7474
7575 /* Oldest version we won't warn about */
76−#define IWL7260_UCODE_API_OK 9
77−#define IWL3160_UCODE_API_OK 9
76+#define IWL7260_UCODE_API_OK 10
77+#define IWL3160_UCODE_API_OK 10
7878
7979 /* Lowest firmware API version supported */
80−#define IWL7260_UCODE_API_MIN 8
81−#define IWL3160_UCODE_API_MIN 8
80+#define IWL7260_UCODE_API_MIN 9
81+#define IWL3160_UCODE_API_MIN 9
8282
8383 /* NVM versions */
8484 #define IWL7260_NVM_VERSION 0x0a1d
@@ -89,6 +89,8 @@ · 4 unmodified lines
8989 #define IWL3165_TX_POWER_VERSION 0xffff /* meaningless */
9090 #define IWL7265_NVM_VERSION 0x0a1d
9191 #define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
92+#define IWL7265D_NVM_VERSION 0x0c11
93+#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
9294
9395 #define IWL7260_FW_PRE "iwlwifi-7260-"
9496 #define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
@@ -275,7 +277,7 @@ const struct iwl_cfg iwl7265d_2ac_cfg = { · 180 unmodified lines
275277 .fw_name_pre = IWL7265D_FW_PRE,
276278 IWL_DEVICE_7000,
277279 .ht_params = &iwl7265_ht_params,
278− .nvm_ver = IWL7265_NVM_VERSION,
280+ .nvm_ver = IWL7265D_NVM_VERSION,
279281 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
280282 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
281283 };
@@ -285,7 +287,7 @@ const struct iwl_cfg iwl7265d_2n_cfg = { · 3 unmodified lines
285287 .fw_name_pre = IWL7265D_FW_PRE,
286288 IWL_DEVICE_7000,
287289 .ht_params = &iwl7265_ht_params,
288− .nvm_ver = IWL7265_NVM_VERSION,
290+ .nvm_ver = IWL7265D_NVM_VERSION,
289291 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
290292 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
291293 };
@@ -295,7 +297,7 @@ const struct iwl_cfg iwl7265d_n_cfg = { · 3 unmodified lines
295297 .fw_name_pre = IWL7265D_FW_PRE,
296298 IWL_DEVICE_7000,
297299 .ht_params = &iwl7265_ht_params,
298− .nvm_ver = IWL7265_NVM_VERSION,
300+ .nvm_ver = IWL7265D_NVM_VERSION,
299301 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
300302 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
301303 };
drivers/net/wireless/iwlwifi/iwl-8000.c+4−4
@@ -72,10 +72,10 @@ · 71 unmodified lines
7272 #define IWL8000_UCODE_API_MAX 10
7373
7474 /* Oldest version we won't warn about */
75−#define IWL8000_UCODE_API_OK 8
75+#define IWL8000_UCODE_API_OK 10
7676
7777 /* Lowest firmware API version supported */
78−#define IWL8000_UCODE_API_MIN 8
78+#define IWL8000_UCODE_API_MIN 9
7979
8080 /* NVM versions */
8181 #define IWL8000_NVM_VERSION 0x0a1d
@@ -159,8 +159,8 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { · 77 unmodified lines
159159 .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO,
160160 };
161161
162−const struct iwl_cfg iwl4265_2ac_sdio_cfg = {
163− .name = "Intel(R) Dual Band Wireless-AC 4265",
162+const struct iwl_cfg iwl4165_2ac_sdio_cfg = {
163+ .name = "Intel(R) Dual Band Wireless-AC 4165",
164164 .fw_name_pre = IWL8000_FW_PRE,
165165 IWL_DEVICE_8000,
166166 .ht_params = &iwl8000_ht_params,
drivers/net/wireless/iwlwifi/iwl-config.h+1−0
@@ -371,6 +371,7 @@ extern const struct iwl_cfg iwl8260_2n_cfg; · 370 unmodified lines
371371 extern const struct iwl_cfg iwl8260_2ac_cfg;
372372 extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
373373 extern const struct iwl_cfg iwl4265_2ac_sdio_cfg;
374+extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
374375 #endif /* CONFIG_IWLMVM */
375376
376377 #endif /* __IWL_CONFIG_H__ */
drivers/net/wireless/iwlwifi/iwl-drv.c+177−18
@@ -78,9 +78,6 @@ · 77 unmodified lines
7878 #include "iwl-config.h"
7979 #include "iwl-modparams.h"
8080
81−/* private includes */
82−#include "iwl-fw-file.h"
83−
8481 /******************************************************************************
8582 *
8683 * module boiler plate
@@ -187,6 +184,11 @@ static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) · 100 unmodified lines
187184 static void iwl_dealloc_ucode(struct iwl_drv *drv)
188185 {
189186 int i;
187+
188+ kfree(drv->fw.dbg_dest_tlv);
189+ for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++)
190+ kfree(drv->fw.dbg_conf_tlv[i]);
191+
190192 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
191193 iwl_free_fw_img(drv, drv->fw.img + i);
192194 }
@@ -248,6 +250,9 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) · 55 unmodified lines
248250 /*
249251 * Starting 8000B - FW name format has changed. This overwrites the
250252 * previous name and uses the new format.
253+ *
254+ * TODO:
255+ * Once there is only one supported step for 8000 family - delete this!
251256 */
252257 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
253258 char rev_step[2] = {
@@ -258,6 +263,13 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) · 4 unmodified lines
258263 if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP)
259264 rev_step[0] = 0;
260265
266+ /*
267+ * If hw_rev wasn't set yet - default as B-step. If it IS A-step
268+ * we'll reload that FW later instead.
269+ */
270+ if (drv->trans->hw_rev == 0)
271+ rev_step[0] = 'B';
272+
261273 snprintf(drv->firmware_name, sizeof(drv->firmware_name),
262274 "%s%s-%s.ucode", name_pre, rev_step, tag);
263275 }
@@ -301,6 +313,11 @@ struct iwl_firmware_pieces { · 37 unmodified lines
301313
302314 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
303315 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
316+
317+ /* FW debug data parsed for driver usage */
318+ struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
319+ struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
320+ size_t dbg_conf_tlv_len[FW_DBG_MAX];
304321 };
305322
306323 /*
@@ -574,6 +591,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, · 267 unmodified lines
574591 char buildstr[25];
575592 u32 build;
576593 int num_of_cpus;
594+ bool usniffer_images = false;
595+ bool usniffer_req = false;
577596
578597 if (len < sizeof(*ucode)) {
579598 IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
@@ -846,12 +865,79 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, · 266 unmodified lines
846865 capa->n_scan_channels =
847866 le32_to_cpup((__le32 *)tlv_data);
848867 break;
868+ case IWL_UCODE_TLV_FW_DBG_DEST: {
869+ struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
870+
871+ if (pieces->dbg_dest_tlv) {
872+ IWL_ERR(drv,
873+ "dbg destination ignored, already exists\n");
874+ break;
875+ }
876+
877+ pieces->dbg_dest_tlv = dest;
878+ IWL_INFO(drv, "Found debug destination: %s\n",
879+ get_fw_dbg_mode_string(dest->monitor_mode));
880+
881+ drv->fw.dbg_dest_reg_num =
882+ tlv_len - offsetof(struct iwl_fw_dbg_dest_tlv,
883+ reg_ops);
884+ drv->fw.dbg_dest_reg_num /=
885+ sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]);
886+
887+ break;
888+ }
889+ case IWL_UCODE_TLV_FW_DBG_CONF: {
890+ struct iwl_fw_dbg_conf_tlv *conf = (void *)tlv_data;
891+
892+ if (!pieces->dbg_dest_tlv) {
893+ IWL_ERR(drv,
894+ "Ignore dbg config %d - no destination configured\n",
895+ conf->id);
896+ break;
897+ }
898+
899+ if (conf->id >= ARRAY_SIZE(drv->fw.dbg_conf_tlv)) {
900+ IWL_ERR(drv,
901+ "Skip unknown configuration: %d\n",
902+ conf->id);
903+ break;
904+ }
905+
906+ if (pieces->dbg_conf_tlv[conf->id]) {
907+ IWL_ERR(drv,
908+ "Ignore duplicate dbg config %d\n",
909+ conf->id);
910+ break;
911+ }
912+
913+ if (conf->usniffer)
914+ usniffer_req = true;
915+
916+ IWL_INFO(drv, "Found debug configuration: %d\n",
917+ conf->id);
918+
919+ pieces->dbg_conf_tlv[conf->id] = conf;
920+ pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
921+ break;
922+ }
923+ case IWL_UCODE_TLV_SEC_RT_USNIFFER:
924+ usniffer_images = true;
925+ iwl_store_ucode_sec(pieces, tlv_data,
926+ IWL_UCODE_REGULAR_USNIFFER,
927+ tlv_len);
928+ break;
849929 default:
850930 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
851931 break;
852932 }
853933 }
854934
935+ if (usniffer_req && !usniffer_images) {
936+ IWL_ERR(drv,
937+ "user selected to work with usniffer but usniffer image isn't available in ucode package\n");
938+ return -EINVAL;
939+ }
940+
855941 if (len) {
856942 IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len);
857943 iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len);
@@ -989,13 +1075,14 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 131 unmodified lines
9891075 struct iwl_ucode_header *ucode;
9901076 struct iwlwifi_opmode_table *op;
9911077 int err;
992− struct iwl_firmware_pieces pieces;
1078+ struct iwl_firmware_pieces *pieces;
9931079 const unsigned int api_max = drv->cfg->ucode_api_max;
9941080 unsigned int api_ok = drv->cfg->ucode_api_ok;
9951081 const unsigned int api_min = drv->cfg->ucode_api_min;
9961082 u32 api_ver;
9971083 int i;
9981084 bool load_module = false;
1085+ u32 hw_rev = drv->trans->hw_rev;
9991086
10001087 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
10011088 fw->ucode_capa.standard_phy_calibration_size =
@@ -1005,7 +1092,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 3 unmodified lines
10051092 if (!api_ok)
10061093 api_ok = api_max;
10071094
1008− memset(&pieces, 0, sizeof(pieces));
1095+ pieces = kzalloc(sizeof(*pieces), GFP_KERNEL);
1096+ if (!pieces)
1097+ return;
10091098
10101099 if (!ucode_raw) {
10111100 if (drv->fw_index <= api_ok)
@@ -1028,10 +1117,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 16 unmodified lines
10281117 ucode = (struct iwl_ucode_header *)ucode_raw->data;
10291118
10301119 if (ucode->ver)
1031− err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces);
1120+ err = iwl_parse_v1_v2_firmware(drv, ucode_raw, pieces);
10321121 else
1033− err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces,
1034− &fw->ucode_capa);
1122+ err = iwl_parse_tlv_firmware(drv, ucode_raw, pieces,
1123+ &fw->ucode_capa);
10351124
10361125 if (err)
10371126 goto try_again;
@@ -1071,7 +1160,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 33 unmodified lines
10711160 * In mvm uCode there is no difference between data and instructions
10721161 * sections.
10731162 */
1074− if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, drv->cfg))
1163+ if (!fw->mvm_fw && validate_sec_sizes(drv, pieces, drv->cfg))
10751164 goto try_again;
10761165
10771166 /* Allocate ucode buffers for card's bus-master loading ... */
@@ -1080,9 +1169,33 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 2 unmodified lines
10801169 * 1) unmodified from disk
10811170 * 2) backup cache for save/restore during power-downs */
10821171 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
1083− if (iwl_alloc_ucode(drv, &pieces, i))
1172+ if (iwl_alloc_ucode(drv, pieces, i))
10841173 goto out_free_fw;
10851174
1175+ if (pieces->dbg_dest_tlv) {
1176+ drv->fw.dbg_dest_tlv =
1177+ kmemdup(pieces->dbg_dest_tlv,
1178+ sizeof(*pieces->dbg_dest_tlv) +
1179+ sizeof(pieces->dbg_dest_tlv->reg_ops[0]) *
1180+ drv->fw.dbg_dest_reg_num, GFP_KERNEL);
1181+
1182+ if (!drv->fw.dbg_dest_tlv)
1183+ goto out_free_fw;
1184+ }
1185+
1186+ for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) {
1187+ if (pieces->dbg_conf_tlv[i]) {
1188+ drv->fw.dbg_conf_tlv_len[i] =
1189+ pieces->dbg_conf_tlv_len[i];
1190+ drv->fw.dbg_conf_tlv[i] =
1191+ kmemdup(pieces->dbg_conf_tlv[i],
1192+ drv->fw.dbg_conf_tlv_len[i],
1193+ GFP_KERNEL);
1194+ if (!drv->fw.dbg_conf_tlv[i])
1195+ goto out_free_fw;
1196+ }
1197+ }
1198+
10861199 /* Now that we can no longer fail, copy information */
10871200
10881201 /*
@@ -1090,20 +1203,20 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 1 unmodified line
10901203 * for each event, which is of mode 1 (including timestamp) for all
10911204 * new microcodes that include this information.
10921205 */
1093− fw->init_evtlog_ptr = pieces.init_evtlog_ptr;
1094− if (pieces.init_evtlog_size)
1095− fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
1206+ fw->init_evtlog_ptr = pieces->init_evtlog_ptr;
1207+ if (pieces->init_evtlog_size)
1208+ fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12;
10961209 else
10971210 fw->init_evtlog_size =
10981211 drv->cfg->base_params->max_event_log_size;
1099− fw->init_errlog_ptr = pieces.init_errlog_ptr;
1100− fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
1101− if (pieces.inst_evtlog_size)
1102− fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
1212+ fw->init_errlog_ptr = pieces->init_errlog_ptr;
1213+ fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr;
1214+ if (pieces->inst_evtlog_size)
1215+ fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12;
11031216 else
11041217 fw->inst_evtlog_size =
11051218 drv->cfg->base_params->max_event_log_size;
1106− fw->inst_errlog_ptr = pieces.inst_errlog_ptr;
1219+ fw->inst_errlog_ptr = pieces->inst_errlog_ptr;
11071220
11081221 /*
11091222 * figure out the offset of chain noise reset and gain commands
@@ -1162,10 +1275,55 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 52 unmodified lines
11621275 op->name, err);
11631276 #endif
11641277 }
1278+
1279+ /*
1280+ * We may have loaded the wrong FW file in 8000 HW family if it is an
1281+ * A-step card, and if drv->trans->hw_rev wasn't properly read when
1282+ * the FW file had been loaded. (This might happen in SDIO.) In such a
1283+ * case - unload and reload the correct file.
1284+ *
1285+ * TODO:
1286+ * Once there is only one supported step for 8000 family - delete this!
1287+ */
1288+ if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
1289+ CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP &&
1290+ drv->trans->hw_rev != hw_rev) {
1291+ char firmware_name[32];
1292+
1293+ /* Free previous FW resources */
1294+ if (drv->op_mode)
1295+ _iwl_op_mode_stop(drv);
1296+ iwl_dealloc_ucode(drv);
1297+
1298+ /* Build name of correct-step FW */
1299+ snprintf(firmware_name, sizeof(firmware_name),
1300+ strrchr(drv->firmware_name, '-'));
1301+ snprintf(drv->firmware_name, sizeof(drv->firmware_name),
1302+ "%s%s", drv->cfg->fw_name_pre, firmware_name);
1303+
1304+ /* Clear data before loading correct FW */
1305+ list_del(&drv->list);
1306+
1307+ /* Request correct FW file this time */
1308+ IWL_DEBUG_INFO(drv, "attempting to load A-step FW %s\n",
1309+ drv->firmware_name);
1310+ err = request_firmware(&ucode_raw, drv->firmware_name,
1311+ drv->trans->dev);
1312+ if (err) {
1313+ IWL_ERR(drv, "Failed swapping FW!\n");
1314+ goto out_unbind;
1315+ }
1316+
1317+ /* Redo callback function - this time with right FW */
1318+ iwl_req_fw_callback(ucode_raw, context);
1319+ }
1320+
1321+ kfree(pieces);
11651322 return;
11661323
11671324 try_again:
11681325 /* try next, if any */
1326+ kfree(pieces);
11691327 release_firmware(ucode_raw);
11701328 if (iwl_request_firmware(drv, false))
11711329 goto out_unbind;
@@ -1176,6 +1334,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) · 4 unmodified lines
11761334 iwl_dealloc_ucode(drv);
11771335 release_firmware(ucode_raw);
11781336 out_unbind:
1337+ kfree(pieces);
11791338 complete(&drv->request_firmware_complete);
11801339 device_release_driver(drv->trans->dev);
11811340 }
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h+3−0
@@ -81,6 +81,7 @@ · 80 unmodified lines
8181 * @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor
8282 * @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several
8383 * sections like this in a single file.
84+ * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers
8485 */
8586 enum iwl_fw_error_dump_type {
8687 IWL_FW_ERROR_DUMP_SRAM = 0,
@@ -90,6 +91,8 @@ enum iwl_fw_error_dump_type { · 3 unmodified lines
9091 IWL_FW_ERROR_DUMP_DEV_FW_INFO = 4,
9192 IWL_FW_ERROR_DUMP_FW_MONITOR = 5,
9293 IWL_FW_ERROR_DUMP_PRPH = 6,
94+ IWL_FW_ERROR_DUMP_TXF = 7,
95+ IWL_FW_ERROR_DUMP_FH_REGS = 8,
9396
9497 IWL_FW_ERROR_DUMP_MAX,
9598 };
drivers/net/wireless/iwlwifi/iwl-fw-file.h+308−0
@@ -131,6 +131,9 @@ enum iwl_ucode_tlv_type { · 130 unmodified lines
131131 IWL_UCODE_TLV_API_CHANGES_SET = 29,
132132 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
133133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
134+ IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
135+ IWL_UCODE_TLV_FW_DBG_DEST = 38,
136+ IWL_UCODE_TLV_FW_DBG_CONF = 39,
134137 };
135138
136139 struct iwl_ucode_tlv {
@@ -179,4 +182,309 @@ struct iwl_ucode_capa { · 42 unmodified lines
179182 __le32 api_capa;
180183 } __packed;
181184
185+/**
186+ * enum iwl_ucode_tlv_flag - ucode API flags
187+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
188+ * was a separate TLV but moved here to save space.
189+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
190+ * treats good CRC threshold as a boolean
191+ * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
192+ * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
193+ * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
194+ * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: This uCode image supports uAPSD
195+ * @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
196+ * offload profile config command.
197+ * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
198+ * (rather than two) IPv6 addresses
199+ * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
200+ * from the probe request template.
201+ * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
202+ * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
203+ * @IWL_UCODE_TLV_FLAGS_P2P_PM: P2P client supports PM as a stand alone MAC
204+ * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
205+ * P2P client interfaces simultaneously if they are in different bindings.
206+ * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
207+ * P2P client interfaces simultaneously if they are in same bindings.
208+ * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
209+ * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
210+ * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
211+ * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
212+ * @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
213+ */
214+enum iwl_ucode_tlv_flag {
215+ IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
216+ IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
217+ IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
218+ IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
219+ IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
220+ IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
221+ IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
222+ IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
223+ IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15),
224+ IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16),
225+ IWL_UCODE_TLV_FLAGS_P2P_PM = BIT(21),
226+ IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
227+ IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_SCM = BIT(23),
228+ IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
229+ IWL_UCODE_TLV_FLAGS_EBS_SUPPORT = BIT(25),
230+ IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
231+ IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
232+ IWL_UCODE_TLV_FLAGS_GO_UAPSD = BIT(30),
233+};
234+
235+/**
236+ * enum iwl_ucode_tlv_api - ucode api
237+ * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
238+ * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
239+ * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
240+ * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
241+ * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
242+ * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
243+ * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
244+ * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
245+ * longer than the passive one, which is essential for fragmented scan.
246+ */
247+enum iwl_ucode_tlv_api {
248+ IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
249+ IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
250+ IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
251+ IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
252+ IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
253+ IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
254+ IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
255+ IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
256+};
257+
258+/**
259+ * enum iwl_ucode_tlv_capa - ucode capabilities
260+ * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
261+ * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT: supports Location Aware Regulatory
262+ * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan.
263+ * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality
264+ * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
265+ * tx power value into TPC Report action frame and Link Measurement Report
266+ * action frame
267+ * @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports updating current
268+ * channel in DS parameter set element in probe requests.
269+ * @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in
270+ * probe requests.
271+ * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
272+ * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
273+ * which also implies support for the scheduler configuration command
274+ * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
275+ * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
276+ */
277+enum iwl_ucode_tlv_capa {
278+ IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
279+ IWL_UCODE_TLV_CAPA_LAR_SUPPORT = BIT(1),
280+ IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2),
281+ IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6),
282+ IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
283+ IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
284+ IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10),
285+ IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11),
286+ IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
287+ IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13),
288+ IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18),
289+};
290+
291+/* The default calibrate table size if not specified by firmware file */
292+#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
293+#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
294+#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253
295+
296+/* The default max probe length if not specified by the firmware file */
297+#define IWL_DEFAULT_MAX_PROBE_LENGTH 200
298+
299+/*
300+ * For 16.0 uCode and above, there is no differentiation between sections,
301+ * just an offset to the HW address.
302+ */
303+#define IWL_UCODE_SECTION_MAX 12
304+#define IWL_API_ARRAY_SIZE 1
305+#define IWL_CAPABILITIES_ARRAY_SIZE 1
306+#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
307+
308+/* uCode version contains 4 values: Major/Minor/API/Serial */
309+#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
310+#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
311+#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
312+#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
313+
314+/*
315+ * Calibration control struct.
316+ * Sent as part of the phy configuration command.
317+ * @flow_trigger: bitmap for which calibrations to perform according to
318+ * flow triggers.
319+ * @event_trigger: bitmap for which calibrations to perform according to
320+ * event triggers.
321+ */
322+struct iwl_tlv_calib_ctrl {
323+ __le32 flow_trigger;
324+ __le32 event_trigger;
325+} __packed;
326+
327+enum iwl_fw_phy_cfg {
328+ FW_PHY_CFG_RADIO_TYPE_POS = 0,
329+ FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS,
330+ FW_PHY_CFG_RADIO_STEP_POS = 2,
331+ FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS,
332+ FW_PHY_CFG_RADIO_DASH_POS = 4,
333+ FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS,
334+ FW_PHY_CFG_TX_CHAIN_POS = 16,
335+ FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
336+ FW_PHY_CFG_RX_CHAIN_POS = 20,
337+ FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
338+};
339+
340+#define IWL_UCODE_MAX_CS 1
341+
342+/**
343+ * struct iwl_fw_cipher_scheme - a cipher scheme supported by FW.
344+ * @cipher: a cipher suite selector
345+ * @flags: cipher scheme flags (currently reserved for a future use)
346+ * @hdr_len: a size of MPDU security header
347+ * @pn_len: a size of PN
348+ * @pn_off: an offset of pn from the beginning of the security header
349+ * @key_idx_off: an offset of key index byte in the security header
350+ * @key_idx_mask: a bit mask of key_idx bits
351+ * @key_idx_shift: bit shift needed to get key_idx
352+ * @mic_len: mic length in bytes
353+ * @hw_cipher: a HW cipher index used in host commands
354+ */
355+struct iwl_fw_cipher_scheme {
356+ __le32 cipher;
357+ u8 flags;
358+ u8 hdr_len;
359+ u8 pn_len;
360+ u8 pn_off;
361+ u8 key_idx_off;
362+ u8 key_idx_mask;
363+ u8 key_idx_shift;
364+ u8 mic_len;
365+ u8 hw_cipher;
366+} __packed;
367+
368+enum iwl_fw_dbg_reg_operator {
369+ CSR_ASSIGN,
370+ CSR_SETBIT,
371+ CSR_CLEARBIT,
372+
373+ PRPH_ASSIGN,
374+ PRPH_SETBIT,
375+ PRPH_CLEARBIT,
376+};
377+
378+/**
379+ * struct iwl_fw_dbg_reg_op - an operation on a register
380+ *
381+ * @op: %enum iwl_fw_dbg_reg_operator
382+ * @addr: offset of the register
383+ * @val: value
384+ */
385+struct iwl_fw_dbg_reg_op {
386+ u8 op;
387+ u8 reserved[3];
388+ __le32 addr;
389+ __le32 val;
390+} __packed;
391+
392+/**
393+ * enum iwl_fw_dbg_monitor_mode - available monitor recording modes
394+ *
395+ * @SMEM_MODE: monitor stores the data in SMEM
396+ * @EXTERNAL_MODE: monitor stores the data in allocated DRAM
397+ * @MARBH_MODE: monitor stores the data in MARBH buffer
398+ */
399+enum iwl_fw_dbg_monitor_mode {
400+ SMEM_MODE = 0,
401+ EXTERNAL_MODE = 1,
402+ MARBH_MODE = 2,
403+};
404+
405+/**
406+ * struct iwl_fw_dbg_dest_tlv - configures the destination of the debug data
407+ *
408+ * @version: version of the TLV - currently 0
409+ * @monitor_mode: %enum iwl_fw_dbg_monitor_mode
410+ * @base_reg: addr of the base addr register (PRPH)
411+ * @end_reg: addr of the end addr register (PRPH)
412+ * @write_ptr_reg: the addr of the reg of the write pointer
413+ * @wrap_count: the addr of the reg of the wrap_count
414+ * @base_shift: shift right of the base addr reg
415+ * @end_shift: shift right of the end addr reg
416+ * @reg_ops: array of registers operations
417+ *
418+ * This parses IWL_UCODE_TLV_FW_DBG_DEST
419+ */
420+struct iwl_fw_dbg_dest_tlv {
421+ u8 version;
422+ u8 monitor_mode;
423+ u8 reserved[2];
424+ __le32 base_reg;
425+ __le32 end_reg;
426+ __le32 write_ptr_reg;
427+ __le32 wrap_count;
428+ u8 base_shift;
429+ u8 end_shift;
430+ struct iwl_fw_dbg_reg_op reg_ops[0];
431+} __packed;
432+
433+struct iwl_fw_dbg_conf_hcmd {
434+ u8 id;
435+ u8 reserved;
436+ __le16 len;
437+ u8 data[0];
438+} __packed;
439+
440+/**
441+ * struct iwl_fw_dbg_trigger - a TLV that describes a debug configuration
442+ *
443+ * @enabled: is this trigger enabled
444+ * @reserved:
445+ * @len: length, in bytes, of the %trigger field
446+ * @trigger: pointer to a trigger struct
447+ */
448+struct iwl_fw_dbg_trigger {
449+ u8 enabled;
450+ u8 reserved;
451+ u8 len;
452+ u8 trigger[0];
453+} __packed;
454+
455+/**
456+ * enum iwl_fw_dbg_conf - configurations available
457+ *
458+ * @FW_DBG_CUSTOM: take this configuration from alive
459+ * Note that the trigger is NO-OP for this configuration
460+ */
461+enum iwl_fw_dbg_conf {
462+ FW_DBG_CUSTOM = 0,
463+
464+ /* must be last */
465+ FW_DBG_MAX,
466+ FW_DBG_INVALID = 0xff,
467+};
468+
469+/**
470+ * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration
471+ *
472+ * @id: %enum iwl_fw_dbg_conf
473+ * @usniffer: should the uSniffer image be used
474+ * @num_of_hcmds: how many HCMDs to send are present here
475+ * @hcmd: a variable length host command to be sent to apply the configuration.
476+ * If there is more than one HCMD to send, they will appear one after the
477+ * other and be sent in the order that they appear in.
478+ * This parses IWL_UCODE_TLV_FW_DBG_CONF
479+ */
480+struct iwl_fw_dbg_conf_tlv {
481+ u8 id;
482+ u8 usniffer;
483+ u8 reserved;
484+ u8 num_of_hcmds;
485+ struct iwl_fw_dbg_conf_hcmd hcmd;
486+
487+ /* struct iwl_fw_dbg_trigger sits after all variable length hcmds */
488+} __packed;
489+
182490 #endif /* __iwl_fw_file_h__ */
drivers/net/wireless/iwlwifi/iwl-fw.h+69−178
@@ -69,116 +69,6 @@ · 68 unmodified lines
6969
7070 #include "iwl-fw-file.h"
7171
72−/**
73− * enum iwl_ucode_tlv_flag - ucode API flags
74− * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
75− * was a separate TLV but moved here to save space.
76− * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
77− * treats good CRC threshold as a boolean
78− * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
79− * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
80− * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
81− * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: This uCode image supports uAPSD
82− * @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
83− * offload profile config command.
84− * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
85− * (rather than two) IPv6 addresses
86− * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
87− * from the probe request template.
88− * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
89− * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
90− * @IWL_UCODE_TLV_FLAGS_P2P_PM: P2P client supports PM as a stand alone MAC
91− * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
92− * P2P client interfaces simultaneously if they are in different bindings.
93− * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
94− * P2P client interfaces simultaneously if they are in same bindings.
95− * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
96− * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
97− * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
98− * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
99− * @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
100− */
101−enum iwl_ucode_tlv_flag {
102− IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
103− IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
104− IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
105− IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
106− IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
107− IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
108− IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
109− IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
110− IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15),
111− IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16),
112− IWL_UCODE_TLV_FLAGS_P2P_PM = BIT(21),
113− IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
114− IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_SCM = BIT(23),
115− IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
116− IWL_UCODE_TLV_FLAGS_EBS_SUPPORT = BIT(25),
117− IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
118− IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
119− IWL_UCODE_TLV_FLAGS_GO_UAPSD = BIT(30),
120−};
121−
122−/**
123− * enum iwl_ucode_tlv_api - ucode api
124− * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
125− * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
126− * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
127− * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
128− * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
129− * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
130− * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
131− * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
132− * longer than the passive one, which is essential for fragmented scan.
133− */
134−enum iwl_ucode_tlv_api {
135− IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
136− IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
137− IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
138− IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
139− IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
140− IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
141− IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
142− IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
143−};
144−
145−/**
146− * enum iwl_ucode_tlv_capa - ucode capabilities
147− * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
148− * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan.
149− * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality
150− * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
151− * tx power value into TPC Report action frame and Link Measurement Report
152− * action frame
153− * @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports updating current
154− * channel in DS parameter set element in probe requests.
155− * @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in
156− * probe requests.
157− * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
158− * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
159− * which also implies support for the scheduler configuration command
160− * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
161− */
162−enum iwl_ucode_tlv_capa {
163− IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
164− IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2),
165− IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6),
166− IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
167− IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
168− IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10),
169− IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11),
170− IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
171− IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13),
172−};
173−
174−/* The default calibrate table size if not specified by firmware file */
175−#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
176−#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
177−#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253
178−
179−/* The default max probe length if not specified by the firmware file */
180−#define IWL_DEFAULT_MAX_PROBE_LENGTH 200
181−
18272 /**
18373 * enum iwl_ucode_type
18474 *
@@ -187,11 +77,13 @@ enum iwl_ucode_tlv_capa { · 2 unmodified lines
18777 * @IWL_UCODE_REGULAR: Normal runtime ucode
18878 * @IWL_UCODE_INIT: Initial ucode
18979 * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
80+ * @IWL_UCODE_REGULAR_USNIFFER: Normal runtime ucode when using usniffer image
19081 */
19182 enum iwl_ucode_type {
19283 IWL_UCODE_REGULAR,
19384 IWL_UCODE_INIT,
19485 IWL_UCODE_WOWLAN,
86+ IWL_UCODE_REGULAR_USNIFFER,
19587 IWL_UCODE_TYPE_MAX,
19688 };
19789
@@ -206,14 +98,6 @@ enum iwl_ucode_sec { · 8 unmodified lines
20698 IWL_UCODE_SECTION_DATA,
20799 IWL_UCODE_SECTION_INST,
208100 };
209−/*
210− * For 16.0 uCode and above, there is no differentiation between sections,
211− * just an offset to the HW address.
212− */
213−#define IWL_UCODE_SECTION_MAX 12
214−#define IWL_API_ARRAY_SIZE 1
215−#define IWL_CAPABILITIES_ARRAY_SIZE 1
216−#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
217101
218102 struct iwl_ucode_capabilities {
219103 u32 max_probe_length;
@@ -241,66 +125,6 @@ struct iwl_sf_region { · 21 unmodified lines
241125 u32 size;
242126 };
243127
244−/* uCode version contains 4 values: Major/Minor/API/Serial */
245−#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
246−#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
247−#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
248−#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
249−
250−/*
251− * Calibration control struct.
252− * Sent as part of the phy configuration command.
253− * @flow_trigger: bitmap for which calibrations to perform according to
254− * flow triggers.
255− * @event_trigger: bitmap for which calibrations to perform according to
256− * event triggers.
257− */
258−struct iwl_tlv_calib_ctrl {
259− __le32 flow_trigger;
260− __le32 event_trigger;
261−} __packed;
262−
263−enum iwl_fw_phy_cfg {
264− FW_PHY_CFG_RADIO_TYPE_POS = 0,
265− FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS,
266− FW_PHY_CFG_RADIO_STEP_POS = 2,
267− FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS,
268− FW_PHY_CFG_RADIO_DASH_POS = 4,
269− FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS,
270− FW_PHY_CFG_TX_CHAIN_POS = 16,
271− FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
272− FW_PHY_CFG_RX_CHAIN_POS = 20,
273− FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
274−};
275−
276−#define IWL_UCODE_MAX_CS 1
277−
278−/**
279− * struct iwl_fw_cipher_scheme - a cipher scheme supported by FW.
280− * @cipher: a cipher suite selector
281− * @flags: cipher scheme flags (currently reserved for a future use)
282− * @hdr_len: a size of MPDU security header
283− * @pn_len: a size of PN
284− * @pn_off: an offset of pn from the beginning of the security header
285− * @key_idx_off: an offset of key index byte in the security header
286− * @key_idx_mask: a bit mask of key_idx bits
287− * @key_idx_shift: bit shift needed to get key_idx
288− * @mic_len: mic length in bytes
289− * @hw_cipher: a HW cipher index used in host commands
290− */
291−struct iwl_fw_cipher_scheme {
292− __le32 cipher;
293− u8 flags;
294− u8 hdr_len;
295− u8 pn_len;
296− u8 pn_off;
297− u8 key_idx_off;
298− u8 key_idx_mask;
299− u8 key_idx_shift;
300− u8 mic_len;
301− u8 hw_cipher;
302−} __packed;
303−
304128 /**
305129 * struct iwl_fw_cscheme_list - a cipher scheme list
306130 * @size: a number of entries
@@ -327,6 +151,11 @@ struct iwl_fw_cscheme_list { · 20 unmodified lines
327151 * @inst_errlog_ptr: error log offfset for runtime ucode.
328152 * @mvm_fw: indicates this is MVM firmware
329153 * @cipher_scheme: optional external cipher scheme.
154+ * @human_readable: human readable version
155+ * @dbg_dest_tlv: points to the destination TLV for debug
156+ * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
157+ * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries
158+ * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
330159 */
331160 struct iwl_fw {
332161 u32 ucode_ver;
@@ -351,6 +180,68 @@ struct iwl_fw { · 18 unmodified lines
351180
352181 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
353182 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
183+
184+ struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
185+ struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
186+ size_t dbg_conf_tlv_len[FW_DBG_MAX];
187+
188+ u8 dbg_dest_reg_num;
354189 };
355190
191+static inline const char *get_fw_dbg_mode_string(int mode)
192+{
193+ switch (mode) {
194+ case SMEM_MODE:
195+ return "SMEM";
196+ case EXTERNAL_MODE:
197+ return "EXTERNAL_DRAM";
198+ case MARBH_MODE:
199+ return "MARBH";
200+ default:
201+ return "UNKNOWN";
202+ }
203+}
204+
205+static inline const struct iwl_fw_dbg_trigger *
206+iwl_fw_dbg_conf_get_trigger(const struct iwl_fw *fw, u8 id)
207+{
208+ const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
209+ u8 *ptr;
210+ int i;
211+
212+ if (!conf_tlv)
213+ return NULL;
214+
215+ ptr = (void *)&conf_tlv->hcmd;
216+ for (i = 0; i < conf_tlv->num_of_hcmds; i++) {
217+ ptr += sizeof(conf_tlv->hcmd);
218+ ptr += le16_to_cpu(conf_tlv->hcmd.len);
219+ }
220+
221+ return (const struct iwl_fw_dbg_trigger *)ptr;
222+}
223+
224+static inline bool
225+iwl_fw_dbg_conf_enabled(const struct iwl_fw *fw, u8 id)
226+{
227+ const struct iwl_fw_dbg_trigger *trigger =
228+ iwl_fw_dbg_conf_get_trigger(fw, id);
229+
230+ if (!trigger)
231+ return false;
232+
233+ return trigger->enabled;
234+}
235+
236+static inline bool
237+iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
238+{
239+ const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
240+
241+ if (!conf_tlv)
242+ return false;
243+
244+ return conf_tlv->usniffer;
245+}
246+
356247 #endif /* __iwl_fw_h__ */
drivers/net/wireless/iwlwifi/iwl-prph.h+5−3
@@ -322,6 +322,7 @@ enum secure_boot_config_reg { · 321 unmodified lines
322322 LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002,
323323 };
324324
325+#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0 (0xA01E30)
325326 #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30)
326327 #define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34)
327328 enum secure_boot_status_reg {
@@ -333,6 +334,7 @@ enum secure_boot_status_reg { · 5 unmodified lines
333334 LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003,
334335 };
335336
337+#define FH_UCODE_LOAD_STATUS (0x1AF0)
336338 #define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70)
337339 enum secure_load_status_reg {
338340 LMPM_CPU_UCODE_LOADING_STARTED = 0x00000001,
@@ -349,10 +351,10 @@ enum secure_load_status_reg { · 10 unmodified lines
349351
350352 #define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE (0x400000)
351353 #define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE (0x402000)
352−#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x404000)
353−#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x405000)
354+#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000)
355+#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400)
354356
355−#define LMPM_SECURE_TIME_OUT (50000) /* 5 msec */
357+#define LMPM_SECURE_TIME_OUT (100) /* 10 micro */
356358
357359 /* Rx FIFO */
358360 #define RXF_SIZE_ADDR (0xa00c88)
drivers/net/wireless/iwlwifi/iwl-trans.h+7−0
@@ -574,6 +574,9 @@ enum iwl_trans_state { · 573 unmodified lines
574574 * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the
575575 * start of the 802.11 header in the @rx_mpdu_cmd
576576 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI)
577+ * @dbg_dest_tlv: points to the destination TLV for debug
578+ * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
579+ * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
577580 */
578581 struct iwl_trans {
579582 const struct iwl_trans_ops *ops;
@@ -605,6 +608,10 @@ struct iwl_trans { · 25 unmodified lines
605608
606609 u64 dflt_pwr_limit;
607610
611+ const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
612+ const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
613+ u8 dbg_dest_reg_num;
614+
608615 /* pointer to trans specific struct */
609616 /*Ensure that this pointer will always be aligned to sizeof pointer */
610617 char trans_specific[0] __aligned(sizeof(void *));
drivers/net/wireless/iwlwifi/mvm/constants.h+2−2
@@ -94,8 +94,8 @@ · 93 unmodified lines
9494 #define IWL_MVM_BT_COEX_MPLUT 1
9595 #define IWL_MVM_BT_COEX_RRC 1
9696 #define IWL_MVM_BT_COEX_TTC 1
97−#define IWL_MVM_BT_COEX_MPLUT_REG0 0x2e402280
98−#define IWL_MVM_BT_COEX_MPLUT_REG1 0x7711a751
97+#define IWL_MVM_BT_COEX_MPLUT_REG0 0x28412201
98+#define IWL_MVM_BT_COEX_MPLUT_REG1 0x11118451
9999 #define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30
100100 #define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
101101 #define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0
drivers/net/wireless/iwlwifi/mvm/d3.c+171−37
@@ -785,33 +785,19 @@ static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm) · 784 unmodified lines
785785 return iwl_mvm_load_d3_fw(mvm);
786786 }
787787
788−static int
789−iwl_mvm_send_wowlan_config_cmd(struct iwl_mvm *mvm,
790− const struct iwl_wowlan_config_cmd_v3 *cmd)
791−{
792− /* start only with the v2 part of the command */
793− u16 cmd_len = sizeof(cmd->common);
794−
795− if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID)
796− cmd_len = sizeof(*cmd);
797−
798− return iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
799− cmd_len, cmd);
800−}
801−
802788 static int
803789 iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
804790 struct cfg80211_wowlan *wowlan,
805− struct iwl_wowlan_config_cmd_v3 *wowlan_config_cmd,
791+ struct iwl_wowlan_config_cmd *wowlan_config_cmd,
806792 struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
807793 struct ieee80211_sta *ap_sta)
808794 {
809795 int ret;
810796 struct iwl_mvm_sta *mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
811797
812− /* TODO: wowlan_config_cmd->common.wowlan_ba_teardown_tids */
798+ /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
813799
814− wowlan_config_cmd->common.is_11n_connection =
800+ wowlan_config_cmd->is_11n_connection =
815801 ap_sta->ht_cap.ht_supported;
816802
817803 /* Query the last used seqno and set it */
@@ -819,32 +805,32 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm, · 1 unmodified line
819805 if (ret < 0)
820806 return ret;
821807
822− wowlan_config_cmd->common.non_qos_seq = cpu_to_le16(ret);
808+ wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);
823809
824− iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &wowlan_config_cmd->common);
810+ iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, wowlan_config_cmd);
825811
826812 if (wowlan->disconnect)
827− wowlan_config_cmd->common.wakeup_filter |=
813+ wowlan_config_cmd->wakeup_filter |=
828814 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
829815 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
830816 if (wowlan->magic_pkt)
831− wowlan_config_cmd->common.wakeup_filter |=
817+ wowlan_config_cmd->wakeup_filter |=
832818 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
833819 if (wowlan->gtk_rekey_failure)
834− wowlan_config_cmd->common.wakeup_filter |=
820+ wowlan_config_cmd->wakeup_filter |=
835821 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
836822 if (wowlan->eap_identity_req)
837− wowlan_config_cmd->common.wakeup_filter |=
823+ wowlan_config_cmd->wakeup_filter |=
838824 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
839825 if (wowlan->four_way_handshake)
840− wowlan_config_cmd->common.wakeup_filter |=
826+ wowlan_config_cmd->wakeup_filter |=
841827 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
842828 if (wowlan->n_patterns)
843− wowlan_config_cmd->common.wakeup_filter |=
829+ wowlan_config_cmd->wakeup_filter |=
844830 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
845831
846832 if (wowlan->rfkill_release)
847− wowlan_config_cmd->common.wakeup_filter |=
833+ wowlan_config_cmd->wakeup_filter |=
848834 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
849835
850836 if (wowlan->tcp) {
@@ -852,7 +838,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm, · 1 unmodified line
852838 * Set the "link change" (really "link lost") flag as well
853839 * since that implies losing the TCP connection.
854840 */
855− wowlan_config_cmd->common.wakeup_filter |=
841+ wowlan_config_cmd->wakeup_filter |=
856842 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
857843 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
858844 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
@@ -865,7 +851,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm, · 6 unmodified lines
865851 static int
866852 iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
867853 struct cfg80211_wowlan *wowlan,
868− struct iwl_wowlan_config_cmd_v3 *wowlan_config_cmd,
854+ struct iwl_wowlan_config_cmd *wowlan_config_cmd,
869855 struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
870856 struct ieee80211_sta *ap_sta)
871857 {
@@ -947,7 +933,9 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm, · 75 unmodified lines
947933 }
948934 }
949935
950− ret = iwl_mvm_send_wowlan_config_cmd(mvm, wowlan_config_cmd);
936+ ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
937+ sizeof(*wowlan_config_cmd),
938+ wowlan_config_cmd);
951939 if (ret)
952940 goto out;
953941
@@ -972,7 +960,7 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm, · 18 unmodified lines
972960 struct cfg80211_sched_scan_request *nd_config,
973961 struct ieee80211_vif *vif)
974962 {
975− struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {};
963+ struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
976964 int ret;
977965
978966 ret = iwl_mvm_switch_to_d3(mvm);
@@ -981,16 +969,51 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm, · 2 unmodified lines
981969
982970 /* rfkill release can be either for wowlan or netdetect */
983971 if (wowlan->rfkill_release)
984− wowlan_config_cmd.common.wakeup_filter |=
972+ wowlan_config_cmd.wakeup_filter |=
985973 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
986974
987− ret = iwl_mvm_send_wowlan_config_cmd(mvm, &wowlan_config_cmd);
975+ ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
976+ sizeof(wowlan_config_cmd),
977+ &wowlan_config_cmd);
988978 if (ret)
989979 return ret;
990980
991981 ret = iwl_mvm_scan_offload_start(mvm, vif, nd_config, &mvm->nd_ies);
982+ if (ret)
983+ return ret;
992984
993− return ret;
985+ if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels))
986+ return -EBUSY;
987+
988+ /* save the sched scan matchsets... */
989+ if (nd_config->n_match_sets) {
990+ mvm->nd_match_sets = kmemdup(nd_config->match_sets,
991+ sizeof(*nd_config->match_sets) *
992+ nd_config->n_match_sets,
993+ GFP_KERNEL);
994+ if (mvm->nd_match_sets)
995+ mvm->n_nd_match_sets = nd_config->n_match_sets;
996+ }
997+
998+ /* ...and the sched scan channels for later reporting */
999+ mvm->nd_channels = kmemdup(nd_config->channels,
1000+ sizeof(*nd_config->channels) *
1001+ nd_config->n_channels,
1002+ GFP_KERNEL);
1003+ if (mvm->nd_channels)
1004+ mvm->n_nd_channels = nd_config->n_channels;
1005+
1006+ return 0;
1007+}
1008+
1009+static void iwl_mvm_free_nd(struct iwl_mvm *mvm)
1010+{
1011+ kfree(mvm->nd_match_sets);
1012+ mvm->nd_match_sets = NULL;
1013+ mvm->n_nd_match_sets = 0;
1014+ kfree(mvm->nd_channels);
1015+ mvm->nd_channels = NULL;
1016+ mvm->n_nd_channels = 0;
9941017 }
9951018
9961019 static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
@@ -1051,7 +1074,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, · 54 unmodified lines
10511074
10521075 mvm->net_detect = true;
10531076 } else {
1054− struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {};
1077+ struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
10551078
10561079 ap_sta = rcu_dereference_protected(
10571080 mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
@@ -1104,8 +1127,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, · 46 unmodified lines
11041127
11051128 iwl_trans_d3_suspend(mvm->trans, test);
11061129 out:
1107− if (ret < 0)
1130+ if (ret < 0) {
11081131 ieee80211_restart_hw(mvm->hw);
1132+ iwl_mvm_free_nd(mvm);
1133+ }
11091134 out_noreset:
11101135 mutex_unlock(&mvm->mutex);
11111136
@@ -1626,15 +1651,64 @@ out_unlock: · 514 unmodified lines
16261651 return false;
16271652 }
16281653
1654+struct iwl_mvm_nd_query_results {
1655+ u32 matched_profiles;
1656+ struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
1657+};
1658+
1659+static int
1660+iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
1661+ struct iwl_mvm_nd_query_results *results)
1662+{
1663+ struct iwl_scan_offload_profiles_query *query;
1664+ struct iwl_host_cmd cmd = {
1665+ .id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
1666+ .flags = CMD_WANT_SKB,
1667+ };
1668+ int ret, len;
1669+
1670+ ret = iwl_mvm_send_cmd(mvm, &cmd);
1671+ if (ret) {
1672+ IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
1673+ return ret;
1674+ }
1675+
1676+ /* RF-kill already asserted again... */
1677+ if (!cmd.resp_pkt) {
1678+ ret = -ERFKILL;
1679+ goto out_free_resp;
1680+ }
1681+
1682+ len = iwl_rx_packet_payload_len(cmd.resp_pkt);
1683+ if (len < sizeof(*query)) {
1684+ IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
1685+ ret = -EIO;
1686+ goto out_free_resp;
1687+ }
1688+
1689+ query = (void *)cmd.resp_pkt->data;
1690+
1691+ results->matched_profiles = le32_to_cpu(query->matched_profiles);
1692+ memcpy(results->matches, query->matches, sizeof(results->matches));
1693+
1694+out_free_resp:
1695+ iwl_free_resp(&cmd);
1696+ return ret;
1697+}
1698+
16291699 static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
16301700 struct ieee80211_vif *vif)
16311701 {
1702+ struct cfg80211_wowlan_nd_info *net_detect = NULL;
16321703 struct cfg80211_wowlan_wakeup wakeup = {
16331704 .pattern_idx = -1,
16341705 };
16351706 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1707+ struct iwl_mvm_nd_query_results query;
16361708 struct iwl_wowlan_status *fw_status;
1709+ unsigned long matched_profiles;
16371710 u32 reasons = 0;
1711+ int i, j, n_matches, ret;
16381712
16391713 fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
16401714 if (!IS_ERR_OR_NULL(fw_status))
@@ -1643,13 +1717,73 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, · 2 unmodified lines
16431717 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
16441718 wakeup.rfkill_release = true;
16451719
1646− if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
1647− /* TODO: read and check if it was netdetect */
1720+ if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
1721+ goto out;
1722+
1723+ ret = iwl_mvm_netdetect_query_results(mvm, &query);
1724+ if (ret || !query.matched_profiles) {
16481725 wakeup_report = NULL;
1726+ goto out;
1727+ }
1728+
1729+ matched_profiles = query.matched_profiles;
1730+ if (mvm->n_nd_match_sets) {
1731+ n_matches = hweight_long(matched_profiles);
1732+ } else {
1733+ IWL_ERR(mvm, "no net detect match information available\n");
1734+ n_matches = 0;
1735+ }
1736+
1737+ net_detect = kzalloc(sizeof(*net_detect) +
1738+ (n_matches * sizeof(net_detect->matches[0])),
1739+ GFP_KERNEL);
1740+ if (!net_detect || !n_matches)
1741+ goto out_report_nd;
1742+
1743+ for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
1744+ struct iwl_scan_offload_profile_match *fw_match;
1745+ struct cfg80211_wowlan_nd_match *match;
1746+ int n_channels = 0;
1747+
1748+ fw_match = &query.matches[i];
1749+
1750+ for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; j++)
1751+ n_channels += hweight8(fw_match->matching_channels[j]);
1752+
1753+ match = kzalloc(sizeof(*match) +
1754+ (n_channels * sizeof(*match->channels)),
1755+ GFP_KERNEL);
1756+ if (!match)
1757+ goto out_report_nd;
1758+
1759+ net_detect->matches[net_detect->n_matches++] = match;
1760+
1761+ match->ssid.ssid_len = mvm->nd_match_sets[i].ssid.ssid_len;
1762+ memcpy(match->ssid.ssid, mvm->nd_match_sets[i].ssid.ssid,
1763+ match->ssid.ssid_len);
1764+
1765+ if (mvm->n_nd_channels < n_channels)
1766+ continue;
1767+
1768+ for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; j++)
1769+ if (fw_match->matching_channels[j / 8] & (BIT(j % 8)))
1770+ match->channels[match->n_channels++] =
1771+ mvm->nd_channels[j]->center_freq;
16491772 }
16501773
1774+out_report_nd:
1775+ wakeup.net_detect = net_detect;
1776+out:
1777+ iwl_mvm_free_nd(mvm);
1778+
16511779 mutex_unlock(&mvm->mutex);
16521780 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1781+
1782+ if (net_detect) {
1783+ for (i = 0; i < net_detect->n_matches; i++)
1784+ kfree(net_detect->matches[i]);
1785+ kfree(net_detect);
1786+ }
16531787 }
16541788
16551789 static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
drivers/net/wireless/iwlwifi/mvm/debugfs.c+1−0
@@ -1339,6 +1339,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file, · 1338 unmodified lines
13391339 PRINT_MVM_REF(IWL_MVM_REF_NMI);
13401340 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
13411341 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
1342+ PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
13421343
13431344 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
13441345 }
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h+1−5
@@ -241,16 +241,12 @@ enum iwl_wowlan_wakeup_filters { · 240 unmodified lines
241241 IWL_WOWLAN_WAKEUP_BCN_FILTERING = BIT(16),
242242 }; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
243243
244−struct iwl_wowlan_config_cmd_v2 {
244+struct iwl_wowlan_config_cmd {
245245 __le32 wakeup_filter;
246246 __le16 non_qos_seq;
247247 __le16 qos_seq[8];
248248 u8 wowlan_ba_teardown_tids;
249249 u8 is_11n_connection;
250−} __packed; /* WOWLAN_CONFIG_API_S_VER_2 */
251−
252−struct iwl_wowlan_config_cmd_v3 {
253− struct iwl_wowlan_config_cmd_v2 common;
254250 u8 offloading_tid;
255251 u8 reserved[3];
256252 } __packed; /* WOWLAN_CONFIG_API_S_VER_3 */
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h+44−0
@@ -1047,4 +1047,48 @@ struct iwl_umac_scan_complete { · 1046 unmodified lines
10471047 __le32 reserved;
10481048 } __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */
10491049
1050+#define SCAN_OFFLOAD_MATCHING_CHANNELS_LEN 5
1051+/**
1052+ * struct iwl_scan_offload_profile_match - match information
1053+ * @bssid: matched bssid
1054+ * @channel: channel where the match occurred
1055+ * @energy:
1056+ * @matching_feature:
1057+ * @matching_channels: bitmap of channels that matched, referencing
1058+ * the channels passed in tue scan offload request
1059+ */
1060+struct iwl_scan_offload_profile_match {
1061+ u8 bssid[ETH_ALEN];
1062+ __le16 reserved;
1063+ u8 channel;
1064+ u8 energy;
1065+ u8 matching_feature;
1066+ u8 matching_channels[SCAN_OFFLOAD_MATCHING_CHANNELS_LEN];
1067+} __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_1 */
1068+
1069+/**
1070+ * struct iwl_scan_offload_profiles_query - match results query response
1071+ * @matched_profiles: bitmap of matched profiles, referencing the
1072+ * matches passed in the scan offload request
1073+ * @last_scan_age: age of the last offloaded scan
1074+ * @n_scans_done: number of offloaded scans done
1075+ * @gp2_d0u: GP2 when D0U occurred
1076+ * @gp2_invoked: GP2 when scan offload was invoked
1077+ * @resume_while_scanning: not used
1078+ * @self_recovery: obsolete
1079+ * @reserved: reserved
1080+ * @matches: array of match information, one for each match
1081+ */
1082+struct iwl_scan_offload_profiles_query {
1083+ __le32 matched_profiles;
1084+ __le32 last_scan_age;
1085+ __le32 n_scans_done;
1086+ __le32 gp2_d0u;
1087+ __le32 gp2_invoked;
1088+ u8 resume_while_scanning;
1089+ u8 self_recovery;
1090+ __le16 reserved;
1091+ struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
1092+} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
1093+
10501094 #endif
drivers/net/wireless/iwlwifi/mvm/fw-api.h+4−6
@@ -249,11 +249,9 @@ enum { · 248 unmodified lines
249249 WOWLAN_TX_POWER_PER_DB = 0xe6,
250250
251251 /* and for NetDetect */
252− NET_DETECT_CONFIG_CMD = 0x54,
253− NET_DETECT_PROFILES_QUERY_CMD = 0x56,
254− NET_DETECT_PROFILES_CMD = 0x57,
255− NET_DETECT_HOTSPOTS_CMD = 0x58,
256− NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
252+ SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56,
253+ SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD = 0x58,
254+ SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD = 0x59,
257255
258256 REPLY_MAX = 0xff,
259257 };
@@ -1617,7 +1615,7 @@ enum iwl_sf_scenario { · 1357 unmodified lines
16171615 #define SF_NUM_TIMEOUT_TYPES 2 /* Aging timer and Idle timer */
16181616
16191617 /* smart FIFO default values */
1620−#define SF_W_MARK_SISO 4096
1618+#define SF_W_MARK_SISO 6144
16211619 #define SF_W_MARK_MIMO2 8192
16221620 #define SF_W_MARK_MIMO3 6144
16231621 #define SF_W_MARK_LEGACY 4096
drivers/net/wireless/iwlwifi/mvm/fw.c+45−1
@@ -186,7 +186,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, · 185 unmodified lines
186186 static const u8 alive_cmd[] = { MVM_ALIVE };
187187 struct iwl_sf_region st_fwrd_space;
188188
189− fw = iwl_get_ucode_image(mvm, ucode_type);
189+ if (ucode_type == IWL_UCODE_REGULAR &&
190+ iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_CUSTOM) &&
191+ iwl_fw_dbg_conf_enabled(mvm->fw, FW_DBG_CUSTOM))
192+ fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
193+ else
194+ fw = iwl_get_ucode_image(mvm, ucode_type);
190195 if (WARN_ON(!fw))
191196 return -EINVAL;
192197 mvm->cur_ucode = ucode_type;
@@ -394,6 +399,42 @@ out: · 201 unmodified lines
394399 return ret;
395400 }
396401
402+static int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm,
403+ enum iwl_fw_dbg_conf conf_id)
404+{
405+ u8 *ptr;
406+ int ret;
407+ int i;
408+
409+ if (WARN_ONCE(conf_id >= ARRAY_SIZE(mvm->fw->dbg_conf_tlv),
410+ "Invalid configuration %d\n", conf_id))
411+ return -EINVAL;
412+
413+ if (!mvm->fw->dbg_conf_tlv[conf_id])
414+ return -EINVAL;
415+
416+ if (mvm->fw_dbg_conf != FW_DBG_INVALID)
417+ IWL_WARN(mvm, "FW already configured (%d) - re-configuring\n",
418+ mvm->fw_dbg_conf);
419+
420+ /* Send all HCMDs for configuring the FW debug */
421+ ptr = (void *)&mvm->fw->dbg_conf_tlv[conf_id]->hcmd;
422+ for (i = 0; i < mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds; i++) {
423+ struct iwl_fw_dbg_conf_hcmd *cmd = (void *)ptr;
424+
425+ ret = iwl_mvm_send_cmd_pdu(mvm, cmd->id, 0,
426+ le16_to_cpu(cmd->len), cmd->data);
427+ if (ret)
428+ return ret;
429+
430+ ptr += sizeof(*cmd);
431+ ptr += le16_to_cpu(cmd->len);
432+ }
433+
434+ mvm->fw_dbg_conf = conf_id;
435+ return ret;
436+}
437+
397438 int iwl_mvm_up(struct iwl_mvm *mvm)
398439 {
399440 int ret, i;
@@ -445,6 +486,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm) · 45 unmodified lines
445486 if (ret)
446487 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
447488
489+ mvm->fw_dbg_conf = FW_DBG_INVALID;
490+ iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM);
491+
448492 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
449493 if (ret)
450494 goto error;
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c+5−14
@@ -1304,31 +1304,22 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, · 1303 unmodified lines
13041304 struct iwl_device_cmd *cmd)
13051305 {
13061306 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1307+ struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
13071308 struct iwl_mvm_tx_resp *beacon_notify_hdr;
13081309 struct ieee80211_vif *csa_vif;
13091310 struct ieee80211_vif *tx_blocked_vif;
1310− u64 tsf;
13111311 u16 status;
13121312
13131313 lockdep_assert_held(&mvm->mutex);
13141314
1315− if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_CAPA_EXTENDED_BEACON) {
1316− struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
1317−
1318− beacon_notify_hdr = &beacon->beacon_notify_hdr;
1319− tsf = le64_to_cpu(beacon->tsf);
1320− mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
1321− } else {
1322− struct iwl_beacon_notif *beacon = (void *)pkt->data;
1323−
1324− beacon_notify_hdr = &beacon->beacon_notify_hdr;
1325− tsf = le64_to_cpu(beacon->tsf);
1326− }
1315+ beacon_notify_hdr = &beacon->beacon_notify_hdr;
1316+ mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
13271317
13281318 status = le16_to_cpu(beacon_notify_hdr->status.status) & TX_STATUS_MSK;
13291319 IWL_DEBUG_RX(mvm,
13301320 "beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n",
1331− status, beacon_notify_hdr->failure_frame, tsf,
1321+ status, beacon_notify_hdr->failure_frame,
1322+ le64_to_cpu(beacon->tsf),
13321323 mvm->ap_last_beacon_gp2,
13331324 le32_to_cpu(beacon_notify_hdr->initial_rate));
13341325
drivers/net/wireless/iwlwifi/mvm/mac80211.c+10−6
@@ -337,7 +337,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) · 336 unmodified lines
337337 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
338338
339339 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT &&
340− IWL_UCODE_API(mvm->fw->ucode_ver) >= 9 &&
341340 !iwlwifi_mod_params.uapsd_disable) {
342341 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
343342 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
@@ -370,8 +369,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) · 26 unmodified lines
370369 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD)
371370 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
372371
373− if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_CSA_FLOW)
374− hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
372+ hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
375373
376374 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
377375 hw->wiphy->n_iface_combinations =
@@ -2577,9 +2575,15 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, · 2199 unmodified lines
25772575
25782576 switch (vif->type) {
25792577 case NL80211_IFTYPE_STATION:
2580− /* Use aux roc framework (HS20) */
2581− ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
2582− vif, duration);
2578+ if (mvm->fw->ucode_capa.capa[0] &
2579+ IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT) {
2580+ /* Use aux roc framework (HS20) */
2581+ ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
2582+ vif, duration);
2583+ goto out_unlock;
2584+ }
2585+ IWL_ERR(mvm, "hotspot not supported\n");
2586+ ret = -EINVAL;
25832587 goto out_unlock;
25842588 case NL80211_IFTYPE_P2P_DEVICE:
25852589 /* handle below */
drivers/net/wireless/iwlwifi/mvm/mvm.h+6−2
@@ -295,7 +295,6 @@ enum iwl_bt_force_ant_mode { · 294 unmodified lines
295295 * struct iwl_mvm_vif_bf_data - beacon filtering related data
296296 * @bf_enabled: indicates if beacon filtering is enabled
297297 * @ba_enabled: indicated if beacon abort is enabled
298−* @last_beacon_signal: last beacon rssi signal in dbm
299298 * @ave_beacon_signal: average beacon signal
300299 * @last_cqm_event: rssi of the last cqm event
301300 * @bt_coex_min_thold: minimum threshold for BT coex
@@ -671,6 +670,7 @@ struct iwl_mvm { · 369 unmodified lines
671670 /* -1 for always, 0 for never, >0 for that many times */
672671 s8 restart_fw;
673672 struct work_struct fw_error_dump_wk;
673+ enum iwl_fw_dbg_conf fw_dbg_conf;
674674
675675 #ifdef CONFIG_IWLWIFI_LEDS
676676 struct led_classdev led;
@@ -685,6 +685,10 @@ struct iwl_mvm { · 8 unmodified lines
685685 /* sched scan settings for net detect */
686686 struct cfg80211_sched_scan_request *nd_config;
687687 struct ieee80211_scan_ies nd_ies;
688+ struct cfg80211_match_set *nd_match_sets;
689+ int n_nd_match_sets;
690+ struct ieee80211_channel **nd_channels;
691+ int n_nd_channels;
688692 bool net_detect;
689693 #ifdef CONFIG_IWLWIFI_DEBUGFS
690694 u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */
@@ -1143,7 +1147,7 @@ iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif) · 452 unmodified lines
11431147 }
11441148 #endif
11451149 void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
1146− struct iwl_wowlan_config_cmd_v2 *cmd);
1150+ struct iwl_wowlan_config_cmd *cmd);
11471151 int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
11481152 struct ieee80211_vif *vif,
11491153 bool disable_offloading,
drivers/net/wireless/iwlwifi/mvm/nvm.c+23−8
@@ -339,11 +339,15 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) · 338 unmodified lines
339339 } *file_sec;
340340 const u8 *eof, *temp;
341341 int max_section_size;
342+ const __le32 *dword_buff;
342343
343344 #define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
344345 #define NVM_WORD2_ID(x) (x >> 12)
345346 #define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8))
346347 #define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4)
348+#define NVM_HEADER_0 (0x2A504C54)
349+#define NVM_HEADER_1 (0x4E564D2A)
350+#define NVM_HEADER_SIZE (4 * sizeof(u32))
347351
348352 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
349353
@@ -372,12 +376,6 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) · 22 unmodified lines
372376 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n",
373377 mvm->nvm_file_name, fw_entry->size);
374378
375− if (fw_entry->size < sizeof(*file_sec)) {
376− IWL_ERR(mvm, "NVM file too small\n");
377− ret = -EINVAL;
378− goto out;
379− }
380−
381379 if (fw_entry->size > MAX_NVM_FILE_LEN) {
382380 IWL_ERR(mvm, "NVM file too large\n");
383381 ret = -EINVAL;
@@ -385,8 +383,25 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) · 1 unmodified line
385383 }
386384
387385 eof = fw_entry->data + fw_entry->size;
388−
389− file_sec = (void *)fw_entry->data;
386+ dword_buff = (__le32 *)fw_entry->data;
387+
388+ /* some NVM file will contain a header.
389+ * The header is identified by 2 dwords header as follow:
390+ * dword[0] = 0x2A504C54
391+ * dword[1] = 0x4E564D2A
392+ *
393+ * This header must be skipped when providing the NVM data to the FW.
394+ */
395+ if (fw_entry->size > NVM_HEADER_SIZE &&
396+ dword_buff[0] == cpu_to_le32(NVM_HEADER_0) &&
397+ dword_buff[1] == cpu_to_le32(NVM_HEADER_1)) {
398+ file_sec = (void *)(fw_entry->data + NVM_HEADER_SIZE);
399+ IWL_INFO(mvm, "NVM Version %08X\n", le32_to_cpu(dword_buff[2]));
400+ IWL_INFO(mvm, "NVM Manufacturing date %08X\n",
401+ le32_to_cpu(dword_buff[3]));
402+ } else {
403+ file_sec = (void *)fw_entry->data;
404+ }
390405
391406 while (true) {
392407 if (file_sec->data > eof) {
drivers/net/wireless/iwlwifi/mvm/offloading.c+1−1
@@ -67,7 +67,7 @@ · 66 unmodified lines
6767 #include "mvm.h"
6868
6969 void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
70− struct iwl_wowlan_config_cmd_v2 *cmd)
70+ struct iwl_wowlan_config_cmd *cmd)
7171 {
7272 int i;
7373
drivers/net/wireless/iwlwifi/mvm/ops.c+15−16
@@ -325,11 +325,9 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = { · 324 unmodified lines
325325 CMD(WOWLAN_KEK_KCK_MATERIAL),
326326 CMD(WOWLAN_GET_STATUSES),
327327 CMD(WOWLAN_TX_POWER_PER_DB),
328− CMD(NET_DETECT_CONFIG_CMD),
329− CMD(NET_DETECT_PROFILES_QUERY_CMD),
330− CMD(NET_DETECT_PROFILES_CMD),
331− CMD(NET_DETECT_HOTSPOTS_CMD),
332− CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
328+ CMD(SCAN_OFFLOAD_PROFILES_QUERY_CMD),
329+ CMD(SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD),
330+ CMD(SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD),
333331 CMD(CARD_STATE_NOTIFICATION),
334332 CMD(MISSED_BEACONS_NOTIFICATION),
335333 CMD(BT_COEX_PRIO_TABLE),
@@ -498,6 +496,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, · 162 unmodified lines
498496
499497 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
500498 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
499+ trans->dbg_dest_tlv = mvm->fw->dbg_dest_tlv;
500+ trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num;
501+ memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv,
502+ sizeof(trans->dbg_conf_tlv));
501503
502504 /* set up notification wait support */
503505 iwl_notification_wait_init(&mvm->notif_wait);
@@ -1002,7 +1004,7 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac, · 498 unmodified lines
10021004 }
10031005
10041006 static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
1005− struct iwl_wowlan_config_cmd_v3 *cmd,
1007+ struct iwl_wowlan_config_cmd *cmd,
10061008 struct iwl_d0i3_iter_data *iter_data)
10071009 {
10081010 struct ieee80211_sta *ap_sta;
@@ -1018,14 +1020,14 @@ static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm, · 9 unmodified lines
10181020 goto out;
10191021
10201022 mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
1021− cmd->common.is_11n_connection = ap_sta->ht_cap.ht_supported;
1023+ cmd->is_11n_connection = ap_sta->ht_cap.ht_supported;
10221024 cmd->offloading_tid = iter_data->offloading_tid;
10231025
10241026 /*
10251027 * The d0i3 uCode takes care of the nonqos counters,
10261028 * so configure only the qos seq ones.
10271029 */
1028− iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &cmd->common);
1030+ iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, cmd);
10291031 out:
10301032 rcu_read_unlock();
10311033 }
@@ -1037,14 +1039,11 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) · 5 unmodified lines
10371039 struct iwl_d0i3_iter_data d0i3_iter_data = {
10381040 .mvm = mvm,
10391041 };
1040− struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {
1041− .common = {
1042− .wakeup_filter =
1043− cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME |
1044− IWL_WOWLAN_WAKEUP_BEACON_MISS |
1045− IWL_WOWLAN_WAKEUP_LINK_CHANGE |
1046− IWL_WOWLAN_WAKEUP_BCN_FILTERING),
1047− },
1042+ struct iwl_wowlan_config_cmd wowlan_config_cmd = {
1043+ .wakeup_filter = cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME |
1044+ IWL_WOWLAN_WAKEUP_BEACON_MISS |
1045+ IWL_WOWLAN_WAKEUP_LINK_CHANGE |
1046+ IWL_WOWLAN_WAKEUP_BCN_FILTERING),
10481047 };
10491048 struct iwl_d3_manager_config d3_cfg_cmd = {
10501049 .min_sleep_time = cpu_to_le32(1000),
drivers/net/wireless/iwlwifi/pcie/trans.c+239−91
@@ -78,6 +78,7 @@ · 77 unmodified lines
7878 #include "iwl-agn-hw.h"
7979 #include "iwl-fw-error-dump.h"
8080 #include "internal.h"
81+#include "iwl-fh.h"
8182
8283 /* extended range in FW SRAM */
8384 #define IWL_FW_MEM_EXTENDED_START 0x40000
@@ -665,14 +666,14 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, · 581 unmodified lines
665666 return ret;
666667 }
667668
668−static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans,
669− const struct fw_img *image,
670− int cpu,
671− int *first_ucode_section)
669+static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
670+ const struct fw_img *image,
671+ int cpu,
672+ int *first_ucode_section)
672673 {
673674 int shift_param;
674− int i, ret = 0;
675− u32 last_read_idx = 0;
675+ int i, ret = 0, sec_num = 0x1;
676+ u32 val, last_read_idx = 0;
676677
677678 if (cpu == 1) {
678679 shift_param = 0;
@@ -693,21 +694,16 @@ static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans, · 14 unmodified lines
693694 break;
694695 }
695696
696− if (i == (*first_ucode_section) + 1)
697− /* set CPU to started */
698− iwl_set_bits_prph(trans,
699− CSR_UCODE_LOAD_STATUS_ADDR,
700− LMPM_CPU_HDRS_LOADING_COMPLETED
701− << shift_param);
702−
703697 ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
704698 if (ret)
705699 return ret;
700+
701+ /* Notify the ucode of the loaded section number and status */
702+ val = iwl_read_direct32(trans, FH_UCODE_LOAD_STATUS);
703+ val = val | (sec_num << shift_param);
704+ iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, val);
705+ sec_num = (sec_num << 1) | 0x1;
706706 }
707− /* image loading complete */
708− iwl_set_bits_prph(trans,
709− CSR_UCODE_LOAD_STATUS_ADDR,
710− LMPM_CPU_UCODE_LOADING_COMPLETED << shift_param);
711707
712708 *first_ucode_section = last_read_idx;
713709
@@ -760,46 +756,78 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans, · 46 unmodified lines
760756 return 0;
761757 }
762758
763−static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
764− const struct fw_img *image)
759+static void iwl_pcie_apply_destination(struct iwl_trans *trans)
765760 {
766761 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
767− int ret = 0;
768− int first_ucode_section;
762+ const struct iwl_fw_dbg_dest_tlv *dest = trans->dbg_dest_tlv;
763+ int i;
769764
770− IWL_DEBUG_FW(trans,
771− "working with %s CPU\n",
772− image->is_dual_cpus ? "Dual" : "Single");
765+ if (dest->version)
766+ IWL_ERR(trans,
767+ "DBG DEST version is %d - expect issues\n",
768+ dest->version);
773769
774− /* configure the ucode to be ready to get the secured image */
775− if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) {
776− /* set secure boot inspector addresses */
777− iwl_write_prph(trans,
778− LMPM_SECURE_INSPECTOR_CODE_ADDR,
779− LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE);
770+ IWL_INFO(trans, "Applying debug destination %s\n",
771+ get_fw_dbg_mode_string(dest->monitor_mode));
780772
781− iwl_write_prph(trans,
782− LMPM_SECURE_INSPECTOR_DATA_ADDR,
783− LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE);
773+ if (dest->monitor_mode == EXTERNAL_MODE)
774+ iwl_pcie_alloc_fw_monitor(trans);
775+ else
776+ IWL_WARN(trans, "PCI should have external buffer debug\n");
784777
785− /* set CPU1 header address */
786− iwl_write_prph(trans,
787− LMPM_SECURE_UCODE_LOAD_CPU1_HDR_ADDR,
788− LMPM_SECURE_CPU1_HDR_MEM_SPACE);
778+ for (i = 0; i < trans->dbg_dest_reg_num; i++) {
779+ u32 addr = le32_to_cpu(dest->reg_ops[i].addr);
780+ u32 val = le32_to_cpu(dest->reg_ops[i].val);
789781
790− /* load to FW the binary Secured sections of CPU1 */
791− ret = iwl_pcie_load_cpu_secured_sections(trans, image, 1,
792− &first_ucode_section);
793− if (ret)
794− return ret;
782+ switch (dest->reg_ops[i].op) {
783+ case CSR_ASSIGN:
784+ iwl_write32(trans, addr, val);
785+ break;
786+ case CSR_SETBIT:
787+ iwl_set_bit(trans, addr, BIT(val));
788+ break;
789+ case CSR_CLEARBIT:
790+ iwl_clear_bit(trans, addr, BIT(val));
791+ break;
792+ case PRPH_ASSIGN:
793+ iwl_write_prph(trans, addr, val);
794+ break;
795+ case PRPH_SETBIT:
796+ iwl_set_bits_prph(trans, addr, BIT(val));
797+ break;
798+ case PRPH_CLEARBIT:
799+ iwl_clear_bits_prph(trans, addr, BIT(val));
800+ break;
801+ default:
802+ IWL_ERR(trans, "FW debug - unknown OP %d\n",
803+ dest->reg_ops[i].op);
804+ break;
805+ }
806+ }
795807
796− } else {
797− /* load to FW the binary Non secured sections of CPU1 */
798− ret = iwl_pcie_load_cpu_sections(trans, image, 1,
799− &first_ucode_section);
800− if (ret)
801− return ret;
808+ if (dest->monitor_mode == EXTERNAL_MODE && trans_pcie->fw_mon_size) {
809+ iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
810+ trans_pcie->fw_mon_phys >> dest->base_shift);
811+ iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
812+ (trans_pcie->fw_mon_phys +
813+ trans_pcie->fw_mon_size) >> dest->end_shift);
802814 }
815+}
816+
817+static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
818+ const struct fw_img *image)
819+{
820+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
821+ int ret = 0;
822+ int first_ucode_section;
823+
824+ IWL_DEBUG_FW(trans, "working with %s CPU\n",
825+ image->is_dual_cpus ? "Dual" : "Single");
826+
827+ /* load to FW the binary non secured sections of CPU1 */
828+ ret = iwl_pcie_load_cpu_sections(trans, image, 1, &first_ucode_section);
829+ if (ret)
830+ return ret;
803831
804832 if (image->is_dual_cpus) {
805833 /* set CPU2 header address */
@@ -808,14 +836,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, · 2 unmodified lines
808836 LMPM_SECURE_CPU2_HDR_MEM_SPACE);
809837
810838 /* load to FW the binary sections of CPU2 */
811− if (iwl_has_secure_boot(trans->hw_rev,
812− trans->cfg->device_family))
813− ret = iwl_pcie_load_cpu_secured_sections(
814− trans, image, 2,
815− &first_ucode_section);
816− else
817− ret = iwl_pcie_load_cpu_sections(trans, image, 2,
818− &first_ucode_section);
839+ ret = iwl_pcie_load_cpu_sections(trans, image, 2,
840+ &first_ucode_section);
819841 if (ret)
820842 return ret;
821843 }
@@ -832,6 +854,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, · 10 unmodified lines
832854 (trans_pcie->fw_mon_phys +
833855 trans_pcie->fw_mon_size) >> 4);
834856 }
857+ } else if (trans->dbg_dest_tlv) {
858+ iwl_pcie_apply_destination(trans);
835859 }
836860
837861 /* release CPU reset */
@@ -840,18 +864,50 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, · 2 unmodified lines
840864 else
841865 iwl_write32(trans, CSR_RESET, 0);
842866
843− if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) {
844− /* wait for image verification to complete */
845− ret = iwl_poll_prph_bit(trans,
846− LMPM_SECURE_BOOT_CPU1_STATUS_ADDR,
847− LMPM_SECURE_BOOT_STATUS_SUCCESS,
848− LMPM_SECURE_BOOT_STATUS_SUCCESS,
849− LMPM_SECURE_TIME_OUT);
867+ return 0;
868+}
850869
851− if (ret < 0) {
852− IWL_ERR(trans, "Time out on secure boot process\n");
853− return ret;
854− }
870+static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
871+ const struct fw_img *image)
872+{
873+ int ret = 0;
874+ int first_ucode_section;
875+ u32 reg;
876+
877+ IWL_DEBUG_FW(trans, "working with %s CPU\n",
878+ image->is_dual_cpus ? "Dual" : "Single");
879+
880+ /* configure the ucode to be ready to get the secured image */
881+ /* release CPU reset */
882+ iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
883+
884+ /* load to FW the binary Secured sections of CPU1 */
885+ ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1,
886+ &first_ucode_section);
887+ if (ret)
888+ return ret;
889+
890+ /* load to FW the binary sections of CPU2 */
891+ ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2,
892+ &first_ucode_section);
893+ if (ret)
894+ return ret;
895+
896+ /* Notify FW loading is done */
897+ iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
898+
899+ /* wait for image verification to complete */
900+ ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
901+ LMPM_SECURE_BOOT_STATUS_SUCCESS,
902+ LMPM_SECURE_BOOT_STATUS_SUCCESS,
903+ LMPM_SECURE_TIME_OUT);
904+ if (ret < 0) {
905+ reg = iwl_read_prph(trans,
906+ LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0);
907+
908+ IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n",
909+ reg);
910+ return ret;
855911 }
856912
857913 return 0;
@@ -903,7 +959,11 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, · 45 unmodified lines
903959 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
904960
905961 /* Load the given image to the HW */
906− return iwl_pcie_load_given_ucode(trans, fw);
962+ if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
963+ (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP))
964+ return iwl_pcie_load_given_ucode_8000b(trans, fw);
965+ else
966+ return iwl_pcie_load_given_ucode(trans, fw);
907967 }
908968
909969 static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
@@ -994,6 +1054,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) · 84 unmodified lines
9941054 clear_bit(STATUS_RFKILL, &trans->status);
9951055 if (hw_rfkill != was_hw_rfkill)
9961056 iwl_trans_pcie_rf_kill(trans, hw_rfkill);
1057+
1058+ /* re-take ownership to prevent other users from stealing the deivce */
1059+ iwl_pcie_prepare_card_hw(trans);
9971060 }
9981061
9991062 void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
@@ -1968,6 +2031,31 @@ static u32 iwl_trans_pcie_dump_csr(struct iwl_trans *trans, · 968 unmodified lines
19682031 return csr_len;
19692032 }
19702033
2034+static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans,
2035+ struct iwl_fw_error_dump_data **data)
2036+{
2037+ u32 fh_regs_len = FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND;
2038+ unsigned long flags;
2039+ __le32 *val;
2040+ int i;
2041+
2042+ if (!iwl_trans_grab_nic_access(trans, false, &flags))
2043+ return 0;
2044+
2045+ (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FH_REGS);
2046+ (*data)->len = cpu_to_le32(fh_regs_len);
2047+ val = (void *)(*data)->data;
2048+
2049+ for (i = FH_MEM_LOWER_BOUND; i < FH_MEM_UPPER_BOUND; i += sizeof(u32))
2050+ *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i));
2051+
2052+ iwl_trans_release_nic_access(trans, &flags);
2053+
2054+ *data = iwl_fw_error_next_data(*data);
2055+
2056+ return sizeof(**data) + fh_regs_len;
2057+}
2058+
19712059 static
19722060 struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
19732061 {
@@ -1977,6 +2065,7 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans) · 3 unmodified lines
19772065 struct iwl_fw_error_dump_txcmd *txcmd;
19782066 struct iwl_trans_dump_data *dump_data;
19792067 u32 len;
2068+ u32 monitor_len;
19802069 int i, ptr;
19812070
19822071 /* transport dump header */
@@ -1999,10 +2088,34 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans) · 16 unmodified lines
19992088 num_bytes_in_chunk;
20002089 }
20012090
2091+ /* FH registers */
2092+ len += sizeof(*data) + (FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND);
2093+
20022094 /* FW monitor */
2003− if (trans_pcie->fw_mon_page)
2095+ if (trans_pcie->fw_mon_page) {
20042096 len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
2005− trans_pcie->fw_mon_size;
2097+ trans_pcie->fw_mon_size;
2098+ monitor_len = trans_pcie->fw_mon_size;
2099+ } else if (trans->dbg_dest_tlv) {
2100+ u32 base, end;
2101+
2102+ base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
2103+ end = le32_to_cpu(trans->dbg_dest_tlv->end_reg);
2104+
2105+ base = iwl_read_prph(trans, base) <<
2106+ trans->dbg_dest_tlv->base_shift;
2107+ end = iwl_read_prph(trans, end) <<
2108+ trans->dbg_dest_tlv->end_shift;
2109+
2110+ /* Make "end" point to the actual end */
2111+ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
2112+ end += (1 << trans->dbg_dest_tlv->end_shift);
2113+ monitor_len = end - base;
2114+ len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
2115+ monitor_len;
2116+ } else {
2117+ monitor_len = 0;
2118+ }
20062119
20072120 dump_data = vzalloc(len);
20082121 if (!dump_data)
@@ -2039,36 +2152,71 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans) · 30 unmodified lines
20392152
20402153 len += iwl_trans_pcie_dump_prph(trans, &data);
20412154 len += iwl_trans_pcie_dump_csr(trans, &data);
2155+ len += iwl_trans_pcie_fh_regs_dump(trans, &data);
20422156 /* data is already pointing to the next section */
20432157
2044− if (trans_pcie->fw_mon_page) {
2158+ if ((trans_pcie->fw_mon_page &&
2159+ trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
2160+ trans->dbg_dest_tlv) {
20452161 struct iwl_fw_error_dump_fw_mon *fw_mon_data;
2162+ u32 base, write_ptr, wrap_cnt;
2163+
2164+ /* If there was a dest TLV - use the values from there */
2165+ if (trans->dbg_dest_tlv) {
2166+ write_ptr =
2167+ le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
2168+ wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
2169+ base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
2170+ } else {
2171+ base = MON_BUFF_BASE_ADDR;
2172+ write_ptr = MON_BUFF_WRPTR;
2173+ wrap_cnt = MON_BUFF_CYCLE_CNT;
2174+ }
20462175
20472176 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
2048− data->len = cpu_to_le32(trans_pcie->fw_mon_size +
2049− sizeof(*fw_mon_data));
20502177 fw_mon_data = (void *)data->data;
20512178 fw_mon_data->fw_mon_wr_ptr =
2052− cpu_to_le32(iwl_read_prph(trans, MON_BUFF_WRPTR));
2179+ cpu_to_le32(iwl_read_prph(trans, write_ptr));
20532180 fw_mon_data->fw_mon_cycle_cnt =
2054− cpu_to_le32(iwl_read_prph(trans, MON_BUFF_CYCLE_CNT));
2181+ cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
20552182 fw_mon_data->fw_mon_base_ptr =
2056− cpu_to_le32(iwl_read_prph(trans, MON_BUFF_BASE_ADDR));
2057−
2058− /*
2059− * The firmware is now asserted, it won't write anything to
2060− * the buffer. CPU can take ownership to fetch the data.
2061− * The buffer will be handed back to the device before the
2062− * firmware will be restarted.
2063− */
2064− dma_sync_single_for_cpu(trans->dev, trans_pcie->fw_mon_phys,
2065− trans_pcie->fw_mon_size,
2066− DMA_FROM_DEVICE);
2067− memcpy(fw_mon_data->data, page_address(trans_pcie->fw_mon_page),
2068− trans_pcie->fw_mon_size);
2069−
2070− len += sizeof(*data) + sizeof(*fw_mon_data) +
2071− trans_pcie->fw_mon_size;
2183+ cpu_to_le32(iwl_read_prph(trans, base));
2184+
2185+ len += sizeof(*data) + sizeof(*fw_mon_data);
2186+ if (trans_pcie->fw_mon_page) {
2187+ data->len = cpu_to_le32(trans_pcie->fw_mon_size +
2188+ sizeof(*fw_mon_data));
2189+
2190+ /*
2191+ * The firmware is now asserted, it won't write anything
2192+ * to the buffer. CPU can take ownership to fetch the
2193+ * data. The buffer will be handed back to the device
2194+ * before the firmware will be restarted.
2195+ */
2196+ dma_sync_single_for_cpu(trans->dev,
2197+ trans_pcie->fw_mon_phys,
2198+ trans_pcie->fw_mon_size,
2199+ DMA_FROM_DEVICE);
2200+ memcpy(fw_mon_data->data,
2201+ page_address(trans_pcie->fw_mon_page),
2202+ trans_pcie->fw_mon_size);
2203+
2204+ len += trans_pcie->fw_mon_size;
2205+ } else {
2206+ /* If we are here then the buffer is internal */
2207+
2208+ /*
2209+ * Update pointers to reflect actual values after
2210+ * shifting
2211+ */
2212+ base = iwl_read_prph(trans, base) <<
2213+ trans->dbg_dest_tlv->base_shift;
2214+ iwl_trans_read_mem(trans, base, fw_mon_data->data,
2215+ monitor_len / sizeof(u32));
2216+ data->len = cpu_to_le32(sizeof(*fw_mon_data) +
2217+ monitor_len);
2218+ len += monitor_len;
2219+ }
20722220 }
20732221
20742222 dump_data->len = len;
drivers/net/wireless/iwlwifi/pcie/tx.c+66−36
@@ -989,6 +989,65 @@ out: · 988 unmodified lines
989989 spin_unlock_bh(&txq->lock);
990990 }
991991
992+static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans)
993+{
994+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
995+ int ret;
996+
997+ lockdep_assert_held(&trans_pcie->reg_lock);
998+
999+ if (trans_pcie->cmd_in_flight)
1000+ return 0;
1001+
1002+ trans_pcie->cmd_in_flight = true;
1003+
1004+ /*
1005+ * wake up the NIC to make sure that the firmware will see the host
1006+ * command - we will let the NIC sleep once all the host commands
1007+ * returned. This needs to be done only on NICs that have
1008+ * apmg_wake_up_wa set.
1009+ */
1010+ if (trans->cfg->base_params->apmg_wake_up_wa) {
1011+ __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1012+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1013+ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
1014+ udelay(2);
1015+
1016+ ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
1017+ CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1018+ (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1019+ CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1020+ 15000);
1021+ if (ret < 0) {
1022+ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1023+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1024+ trans_pcie->cmd_in_flight = false;
1025+ IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1026+ return -EIO;
1027+ }
1028+ }
1029+
1030+ return 0;
1031+}
1032+
1033+static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
1034+{
1035+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1036+
1037+ lockdep_assert_held(&trans_pcie->reg_lock);
1038+
1039+ if (WARN_ON(!trans_pcie->cmd_in_flight))
1040+ return 0;
1041+
1042+ trans_pcie->cmd_in_flight = false;
1043+
1044+ if (trans->cfg->base_params->apmg_wake_up_wa)
1045+ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1046+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1047+
1048+ return 0;
1049+}
1050+
9921051 /*
9931052 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd
9941053 *
@@ -1024,14 +1083,9 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) · 29 unmodified lines
10241083 }
10251084 }
10261085
1027− if (trans->cfg->base_params->apmg_wake_up_wa &&
1028− q->read_ptr == q->write_ptr) {
1086+ if (q->read_ptr == q->write_ptr) {
10291087 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1030− WARN_ON(!trans_pcie->cmd_in_flight);
1031− trans_pcie->cmd_in_flight = false;
1032− __iwl_trans_pcie_clear_bit(trans,
1033− CSR_GP_CNTRL,
1034− CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1088+ iwl_pcie_clear_cmd_in_flight(trans);
10351089 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
10361090 }
10371091
@@ -1419,35 +1473,11 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, · 381 unmodified lines
14191473 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
14201474
14211475 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1422−
1423− /*
1424− * wake up the NIC to make sure that the firmware will see the host
1425− * command - we will let the NIC sleep once all the host commands
1426− * returned. This needs to be done only on NICs that have
1427− * apmg_wake_up_wa set.
1428− */
1429− if (trans->cfg->base_params->apmg_wake_up_wa &&
1430− !trans_pcie->cmd_in_flight) {
1431− trans_pcie->cmd_in_flight = true;
1432− __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1433− CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1434− if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
1435− udelay(2);
1436−
1437− ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
1438− CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1439− (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1440− CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1441− 15000);
1442− if (ret < 0) {
1443− __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1444− CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1445− spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1446− trans_pcie->cmd_in_flight = false;
1447− IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1448− idx = -EIO;
1449− goto out;
1450− }
1476+ ret = iwl_pcie_set_cmd_in_flight(trans);
1477+ if (ret < 0) {
1478+ idx = ret;
1479+ spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1480+ goto out;
14511481 }
14521482
14531483 /* Increment and update queue's write index */