1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3 * Copyright (C) 2024-2025 Intel Corporation
4 */
5 #include <linux/rtnetlink.h>
6 #include <net/mac80211.h>
7
8 #include "fw/api/rx.h"
9 #include "fw/api/datapath.h"
10 #include "fw/api/commands.h"
11 #include "fw/api/offload.h"
12 #include "fw/api/coex.h"
13 #include "fw/dbg.h"
14 #include "fw/uefi.h"
15
16 #include "mld.h"
17 #include "mlo.h"
18 #include "mac80211.h"
19 #include "led.h"
20 #include "scan.h"
21 #include "tx.h"
22 #include "sta.h"
23 #include "regulatory.h"
24 #include "thermal.h"
25 #include "low_latency.h"
26 #include "hcmd.h"
27 #include "fw/api/location.h"
28
29 #include "iwl-nvm-parse.h"
30
31 #define DRV_DESCRIPTION "Intel(R) MLD wireless driver for Linux"
32 MODULE_DESCRIPTION(DRV_DESCRIPTION);
33 MODULE_LICENSE("GPL");
34 MODULE_IMPORT_NS("IWLWIFI");
35
36 static const struct iwl_op_mode_ops iwl_mld_ops;
37
iwl_mld_init(void)38 static int __init iwl_mld_init(void)
39 {
40 int ret = iwl_opmode_register("iwlmld", &iwl_mld_ops);
41
42 if (ret)
43 pr_err("Unable to register MLD op_mode: %d\n", ret);
44
45 return ret;
46 }
47 module_init(iwl_mld_init);
48
iwl_mld_exit(void)49 static void __exit iwl_mld_exit(void)
50 {
51 iwl_opmode_deregister("iwlmld");
52 }
53 module_exit(iwl_mld_exit);
54
iwl_mld_hw_set_regulatory(struct iwl_mld * mld)55 static void iwl_mld_hw_set_regulatory(struct iwl_mld *mld)
56 {
57 struct wiphy *wiphy = mld->wiphy;
58
59 wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
60 wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
61 }
62
63 VISIBLE_IF_IWLWIFI_KUNIT
iwl_construct_mld(struct iwl_mld * mld,struct iwl_trans * trans,const struct iwl_rf_cfg * cfg,const struct iwl_fw * fw,struct ieee80211_hw * hw,struct dentry * dbgfs_dir)64 void iwl_construct_mld(struct iwl_mld *mld, struct iwl_trans *trans,
65 const struct iwl_rf_cfg *cfg, const struct iwl_fw *fw,
66 struct ieee80211_hw *hw, struct dentry *dbgfs_dir)
67 {
68 mld->dev = trans->dev;
69 mld->trans = trans;
70 mld->cfg = cfg;
71 mld->fw = fw;
72 mld->hw = hw;
73 mld->wiphy = hw->wiphy;
74 mld->debugfs_dir = dbgfs_dir;
75
76 iwl_notification_wait_init(&mld->notif_wait);
77
78 /* Setup async RX handling */
79 spin_lock_init(&mld->async_handlers_lock);
80 INIT_LIST_HEAD(&mld->async_handlers_list);
81 wiphy_work_init(&mld->async_handlers_wk,
82 iwl_mld_async_handlers_wk);
83
84 /* Dynamic Queue Allocation */
85 spin_lock_init(&mld->add_txqs_lock);
86 INIT_LIST_HEAD(&mld->txqs_to_add);
87 wiphy_work_init(&mld->add_txqs_wk, iwl_mld_add_txqs_wk);
88
89 /* Setup RX queues sync wait queue */
90 init_waitqueue_head(&mld->rxq_sync.waitq);
91 }
92 EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_construct_mld);
93
94 static void __acquires(&mld->wiphy->mtx)
iwl_mld_fwrt_dump_start(void * ctx)95 iwl_mld_fwrt_dump_start(void *ctx)
96 {
97 struct iwl_mld *mld = ctx;
98
99 wiphy_lock(mld->wiphy);
100 }
101
102 static void __releases(&mld->wiphy->mtx)
iwl_mld_fwrt_dump_end(void * ctx)103 iwl_mld_fwrt_dump_end(void *ctx)
104 {
105 struct iwl_mld *mld = ctx;
106
107 wiphy_unlock(mld->wiphy);
108 }
109
iwl_mld_d3_debug_enable(void * ctx)110 static bool iwl_mld_d3_debug_enable(void *ctx)
111 {
112 return IWL_MLD_D3_DEBUG;
113 }
114
iwl_mld_fwrt_send_hcmd(void * ctx,struct iwl_host_cmd * host_cmd)115 static int iwl_mld_fwrt_send_hcmd(void *ctx, struct iwl_host_cmd *host_cmd)
116 {
117 struct iwl_mld *mld = (struct iwl_mld *)ctx;
118 int ret;
119
120 wiphy_lock(mld->wiphy);
121 ret = iwl_mld_send_cmd(mld, host_cmd);
122 wiphy_unlock(mld->wiphy);
123
124 return ret;
125 }
126
127 static const struct iwl_fw_runtime_ops iwl_mld_fwrt_ops = {
128 .dump_start = iwl_mld_fwrt_dump_start,
129 .dump_end = iwl_mld_fwrt_dump_end,
130 .send_hcmd = iwl_mld_fwrt_send_hcmd,
131 .d3_debug_enable = iwl_mld_d3_debug_enable,
132 };
133
134 static void
iwl_mld_construct_fw_runtime(struct iwl_mld * mld,struct iwl_trans * trans,const struct iwl_fw * fw,struct dentry * debugfs_dir)135 iwl_mld_construct_fw_runtime(struct iwl_mld *mld, struct iwl_trans *trans,
136 const struct iwl_fw *fw,
137 struct dentry *debugfs_dir)
138 {
139 iwl_fw_runtime_init(&mld->fwrt, trans, fw, &iwl_mld_fwrt_ops, mld,
140 NULL, NULL, debugfs_dir);
141
142 iwl_fw_set_current_image(&mld->fwrt, IWL_UCODE_REGULAR);
143 }
144
145 /* Please keep this array *SORTED* by hex value.
146 * Access is done through binary search
147 */
148 static const struct iwl_hcmd_names iwl_mld_legacy_names[] = {
149 HCMD_NAME(UCODE_ALIVE_NTFY),
150 HCMD_NAME(REPLY_ERROR),
151 HCMD_NAME(INIT_COMPLETE_NOTIF),
152 HCMD_NAME(PHY_CONTEXT_CMD),
153 HCMD_NAME(SCAN_CFG_CMD),
154 HCMD_NAME(SCAN_REQ_UMAC),
155 HCMD_NAME(SCAN_ABORT_UMAC),
156 HCMD_NAME(SCAN_COMPLETE_UMAC),
157 HCMD_NAME(TX_CMD),
158 HCMD_NAME(TXPATH_FLUSH),
159 HCMD_NAME(LEDS_CMD),
160 HCMD_NAME(WNM_80211V_TIMING_MEASUREMENT_NOTIFICATION),
161 HCMD_NAME(WNM_80211V_TIMING_MEASUREMENT_CONFIRM_NOTIFICATION),
162 HCMD_NAME(PHY_CONFIGURATION_CMD),
163 HCMD_NAME(SCAN_OFFLOAD_UPDATE_PROFILES_CMD),
164 HCMD_NAME(POWER_TABLE_CMD),
165 HCMD_NAME(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
166 HCMD_NAME(BEACON_NOTIFICATION),
167 HCMD_NAME(BEACON_TEMPLATE_CMD),
168 HCMD_NAME(TX_ANT_CONFIGURATION_CMD),
169 HCMD_NAME(BT_CONFIG),
170 HCMD_NAME(REDUCE_TX_POWER_CMD),
171 HCMD_NAME(MISSED_BEACONS_NOTIFICATION),
172 HCMD_NAME(MAC_PM_POWER_TABLE),
173 HCMD_NAME(MFUART_LOAD_NOTIFICATION),
174 HCMD_NAME(SCAN_START_NOTIFICATION_UMAC),
175 HCMD_NAME(RSS_CONFIG_CMD),
176 HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
177 HCMD_NAME(REPLY_RX_MPDU_CMD),
178 HCMD_NAME(BA_NOTIF),
179 HCMD_NAME(MCC_UPDATE_CMD),
180 HCMD_NAME(MCC_CHUB_UPDATE_CMD),
181 HCMD_NAME(MCAST_FILTER_CMD),
182 HCMD_NAME(REPLY_BEACON_FILTERING_CMD),
183 HCMD_NAME(PROT_OFFLOAD_CONFIG_CMD),
184 HCMD_NAME(MATCH_FOUND_NOTIFICATION),
185 HCMD_NAME(WOWLAN_PATTERNS),
186 HCMD_NAME(WOWLAN_CONFIGURATION),
187 HCMD_NAME(WOWLAN_TSC_RSC_PARAM),
188 HCMD_NAME(WOWLAN_KEK_KCK_MATERIAL),
189 HCMD_NAME(DEBUG_HOST_COMMAND),
190 HCMD_NAME(LDBG_CONFIG_CMD),
191 };
192
193 /* Please keep this array *SORTED* by hex value.
194 * Access is done through binary search
195 */
196 static const struct iwl_hcmd_names iwl_mld_system_names[] = {
197 HCMD_NAME(SHARED_MEM_CFG_CMD),
198 HCMD_NAME(SOC_CONFIGURATION_CMD),
199 HCMD_NAME(INIT_EXTENDED_CFG_CMD),
200 HCMD_NAME(FW_ERROR_RECOVERY_CMD),
201 HCMD_NAME(RFI_CONFIG_CMD),
202 HCMD_NAME(RFI_GET_FREQ_TABLE_CMD),
203 HCMD_NAME(SYSTEM_STATISTICS_CMD),
204 HCMD_NAME(SYSTEM_STATISTICS_END_NOTIF),
205 };
206
207 /* Please keep this array *SORTED* by hex value.
208 * Access is done through binary search
209 */
210 static const struct iwl_hcmd_names iwl_mld_reg_and_nvm_names[] = {
211 HCMD_NAME(LARI_CONFIG_CHANGE),
212 HCMD_NAME(NVM_GET_INFO),
213 HCMD_NAME(TAS_CONFIG),
214 HCMD_NAME(SAR_OFFSET_MAPPING_TABLE_CMD),
215 HCMD_NAME(MCC_ALLOWED_AP_TYPE_CMD),
216 };
217
218 /* Please keep this array *SORTED* by hex value.
219 * Access is done through binary search
220 */
221 static const struct iwl_hcmd_names iwl_mld_debug_names[] = {
222 HCMD_NAME(HOST_EVENT_CFG),
223 HCMD_NAME(DBGC_SUSPEND_RESUME),
224 };
225
226 /* Please keep this array *SORTED* by hex value.
227 * Access is done through binary search
228 */
229 static const struct iwl_hcmd_names iwl_mld_mac_conf_names[] = {
230 HCMD_NAME(LOW_LATENCY_CMD),
231 HCMD_NAME(SESSION_PROTECTION_CMD),
232 HCMD_NAME(MAC_CONFIG_CMD),
233 HCMD_NAME(LINK_CONFIG_CMD),
234 HCMD_NAME(STA_CONFIG_CMD),
235 HCMD_NAME(AUX_STA_CMD),
236 HCMD_NAME(STA_REMOVE_CMD),
237 HCMD_NAME(ROC_CMD),
238 HCMD_NAME(NAN_CFG_CMD),
239 HCMD_NAME(NAN_DW_END_NOTIF),
240 HCMD_NAME(NAN_JOINED_CLUSTER_NOTIF),
241 HCMD_NAME(MISSED_BEACONS_NOTIF),
242 HCMD_NAME(EMLSR_TRANS_FAIL_NOTIF),
243 HCMD_NAME(ROC_NOTIF),
244 HCMD_NAME(CHANNEL_SWITCH_ERROR_NOTIF),
245 HCMD_NAME(SESSION_PROTECTION_NOTIF),
246 HCMD_NAME(PROBE_RESPONSE_DATA_NOTIF),
247 HCMD_NAME(CHANNEL_SWITCH_START_NOTIF),
248 };
249
250 /* Please keep this array *SORTED* by hex value.
251 * Access is done through binary search
252 */
253 static const struct iwl_hcmd_names iwl_mld_data_path_names[] = {
254 HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
255 HCMD_NAME(WNM_PLATFORM_PTM_REQUEST_CMD),
256 HCMD_NAME(WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD),
257 HCMD_NAME(RFH_QUEUE_CONFIG_CMD),
258 HCMD_NAME(TLC_MNG_CONFIG_CMD),
259 HCMD_NAME(RX_BAID_ALLOCATION_CONFIG_CMD),
260 HCMD_NAME(SCD_QUEUE_CONFIG_CMD),
261 HCMD_NAME(SEC_KEY_CMD),
262 HCMD_NAME(ESR_MODE_NOTIF),
263 HCMD_NAME(MONITOR_NOTIF),
264 HCMD_NAME(TLC_MNG_UPDATE_NOTIF),
265 HCMD_NAME(BEACON_FILTER_IN_NOTIF),
266 HCMD_NAME(PHY_AIR_SNIFFER_NOTIF),
267 HCMD_NAME(MU_GROUP_MGMT_NOTIF),
268 };
269
270 /* Please keep this array *SORTED* by hex value.
271 * Access is done through binary search
272 */
273 static const struct iwl_hcmd_names iwl_mld_scan_names[] = {
274 HCMD_NAME(CHANNEL_SURVEY_NOTIF),
275 };
276
277 /* Please keep this array *SORTED* by hex value.
278 * Access is done through binary search
279 */
280 static const struct iwl_hcmd_names iwl_mld_location_names[] = {
281 HCMD_NAME(TOF_RANGE_REQ_CMD),
282 HCMD_NAME(TOF_RANGE_RESPONSE_NOTIF),
283 };
284
285 /* Please keep this array *SORTED* by hex value.
286 * Access is done through binary search
287 */
288 static const struct iwl_hcmd_names iwl_mld_phy_names[] = {
289 HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE),
290 HCMD_NAME(CTDP_CONFIG_CMD),
291 HCMD_NAME(TEMP_REPORTING_THRESHOLDS_CMD),
292 HCMD_NAME(PER_CHAIN_LIMIT_OFFSET_CMD),
293 HCMD_NAME(CT_KILL_NOTIFICATION),
294 HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE),
295 };
296
297 /* Please keep this array *SORTED* by hex value.
298 * Access is done through binary search
299 */
300 static const struct iwl_hcmd_names iwl_mld_statistics_names[] = {
301 HCMD_NAME(STATISTICS_OPER_NOTIF),
302 HCMD_NAME(STATISTICS_OPER_PART1_NOTIF),
303 };
304
305 /* Please keep this array *SORTED* by hex value.
306 * Access is done through binary search
307 */
308 static const struct iwl_hcmd_names iwl_mld_prot_offload_names[] = {
309 HCMD_NAME(WOWLAN_WAKE_PKT_NOTIFICATION),
310 HCMD_NAME(WOWLAN_INFO_NOTIFICATION),
311 HCMD_NAME(D3_END_NOTIFICATION),
312 };
313
314 /* Please keep this array *SORTED* by hex value.
315 * Access is done through binary search
316 */
317 static const struct iwl_hcmd_names iwl_mld_coex_names[] = {
318 HCMD_NAME(PROFILE_NOTIF),
319 };
320
321 VISIBLE_IF_IWLWIFI_KUNIT
322 const struct iwl_hcmd_arr iwl_mld_groups[] = {
323 [LEGACY_GROUP] = HCMD_ARR(iwl_mld_legacy_names),
324 [LONG_GROUP] = HCMD_ARR(iwl_mld_legacy_names),
325 [SYSTEM_GROUP] = HCMD_ARR(iwl_mld_system_names),
326 [MAC_CONF_GROUP] = HCMD_ARR(iwl_mld_mac_conf_names),
327 [DATA_PATH_GROUP] = HCMD_ARR(iwl_mld_data_path_names),
328 [SCAN_GROUP] = HCMD_ARR(iwl_mld_scan_names),
329 [LOCATION_GROUP] = HCMD_ARR(iwl_mld_location_names),
330 [REGULATORY_AND_NVM_GROUP] = HCMD_ARR(iwl_mld_reg_and_nvm_names),
331 [DEBUG_GROUP] = HCMD_ARR(iwl_mld_debug_names),
332 [PHY_OPS_GROUP] = HCMD_ARR(iwl_mld_phy_names),
333 [STATISTICS_GROUP] = HCMD_ARR(iwl_mld_statistics_names),
334 [PROT_OFFLOAD_GROUP] = HCMD_ARR(iwl_mld_prot_offload_names),
335 [BT_COEX_GROUP] = HCMD_ARR(iwl_mld_coex_names),
336 };
337 EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_groups);
338
339 #if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS)
340 const unsigned int global_iwl_mld_goups_size = ARRAY_SIZE(iwl_mld_groups);
341 EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(global_iwl_mld_goups_size);
342 #endif
343
344 static void
iwl_mld_configure_trans(struct iwl_op_mode * op_mode)345 iwl_mld_configure_trans(struct iwl_op_mode *op_mode)
346 {
347 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
348 static const u8 no_reclaim_cmds[] = {TX_CMD};
349 struct iwl_trans *trans = mld->trans;
350 u32 eckv_value;
351
352 iwl_bios_setup_step(trans, &mld->fwrt);
353 iwl_uefi_get_step_table(trans);
354
355 if (iwl_bios_get_eckv(&mld->fwrt, &eckv_value))
356 IWL_DEBUG_RADIO(mld, "ECKV table doesn't exist in BIOS\n");
357 else
358 trans->conf.ext_32khz_clock_valid = !!eckv_value;
359
360 trans->conf.rx_buf_size = iwl_amsdu_size_to_rxb_size();
361 trans->conf.command_groups = iwl_mld_groups;
362 trans->conf.command_groups_size = ARRAY_SIZE(iwl_mld_groups);
363 trans->conf.fw_reset_handshake = true;
364 trans->conf.queue_alloc_cmd_ver =
365 iwl_fw_lookup_cmd_ver(mld->fw, WIDE_ID(DATA_PATH_GROUP,
366 SCD_QUEUE_CONFIG_CMD),
367 0);
368 trans->conf.cb_data_offs = offsetof(struct ieee80211_tx_info,
369 driver_data[2]);
370 BUILD_BUG_ON(sizeof(no_reclaim_cmds) >
371 sizeof(trans->conf.no_reclaim_cmds));
372 memcpy(trans->conf.no_reclaim_cmds, no_reclaim_cmds,
373 sizeof(no_reclaim_cmds));
374 trans->conf.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
375
376 trans->conf.rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
377 trans->conf.rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_desc);
378 trans->conf.wide_cmd_header = true;
379
380 iwl_trans_op_mode_enter(trans, op_mode);
381 }
382
383 /*
384 *****************************************************
385 * op mode ops functions
386 *****************************************************
387 */
388
389 #define NUM_FW_LOAD_RETRIES 3
390 static struct iwl_op_mode *
iwl_op_mode_mld_start(struct iwl_trans * trans,const struct iwl_rf_cfg * cfg,const struct iwl_fw * fw,struct dentry * dbgfs_dir)391 iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
392 const struct iwl_fw *fw, struct dentry *dbgfs_dir)
393 {
394 struct ieee80211_hw *hw;
395 struct iwl_op_mode *op_mode;
396 struct iwl_mld *mld;
397 int ret;
398
399 /* Allocate and initialize a new hardware device */
400 hw = ieee80211_alloc_hw(sizeof(struct iwl_op_mode) +
401 sizeof(struct iwl_mld),
402 &iwl_mld_hw_ops);
403 if (!hw)
404 return ERR_PTR(-ENOMEM);
405
406 op_mode = hw->priv;
407
408 op_mode->ops = &iwl_mld_ops;
409
410 mld = IWL_OP_MODE_GET_MLD(op_mode);
411
412 iwl_construct_mld(mld, trans, cfg, fw, hw, dbgfs_dir);
413
414 /* we'll verify later it matches between commands */
415 mld->fw_rates_ver_3 = iwl_fw_lookup_cmd_ver(mld->fw, TX_CMD, 0) >= 11;
416
417 iwl_mld_construct_fw_runtime(mld, trans, fw, dbgfs_dir);
418
419 iwl_mld_get_bios_tables(mld);
420 iwl_uefi_get_sgom_table(trans, &mld->fwrt);
421 mld->bios_enable_puncturing = iwl_uefi_get_puncturing(&mld->fwrt);
422
423 iwl_mld_hw_set_regulatory(mld);
424
425 /* Configure transport layer with the opmode specific params */
426 iwl_mld_configure_trans(op_mode);
427
428 /* needed for regulatory init */
429 rtnl_lock();
430 /* Needed for sending commands */
431 wiphy_lock(mld->wiphy);
432
433 for (int i = 0; i < NUM_FW_LOAD_RETRIES; i++) {
434 ret = iwl_mld_load_fw(mld);
435 if (!ret)
436 break;
437 }
438
439 if (!ret) {
440 mld->nvm_data = iwl_get_nvm(mld->trans, mld->fw, 0, 0);
441 if (IS_ERR(mld->nvm_data)) {
442 IWL_ERR(mld, "Failed to read NVM: %d\n", ret);
443 ret = PTR_ERR(mld->nvm_data);
444 }
445 }
446
447 if (ret) {
448 wiphy_unlock(mld->wiphy);
449 rtnl_unlock();
450 goto err;
451 }
452
453 /* We are about to stop the FW. Notifications may require an
454 * operational FW, so handle them all here before we stop.
455 */
456 wiphy_work_flush(mld->wiphy, &mld->async_handlers_wk);
457
458 iwl_mld_stop_fw(mld);
459
460 wiphy_unlock(mld->wiphy);
461 rtnl_unlock();
462
463 ret = iwl_mld_leds_init(mld);
464 if (ret)
465 goto free_nvm;
466
467 ret = iwl_mld_alloc_scan_cmd(mld);
468 if (ret)
469 goto leds_exit;
470
471 ret = iwl_mld_low_latency_init(mld);
472 if (ret)
473 goto free_scan_cmd;
474
475 ret = iwl_mld_register_hw(mld);
476 if (ret)
477 goto low_latency_free;
478
479 iwl_mld_toggle_tx_ant(mld, &mld->mgmt_tx_ant);
480
481 iwl_mld_add_debugfs_files(mld, dbgfs_dir);
482 iwl_mld_thermal_initialize(mld);
483
484 iwl_mld_ptp_init(mld);
485
486 return op_mode;
487
488 low_latency_free:
489 iwl_mld_low_latency_free(mld);
490 free_scan_cmd:
491 kfree(mld->scan.cmd);
492 leds_exit:
493 iwl_mld_leds_exit(mld);
494 free_nvm:
495 kfree(mld->nvm_data);
496 err:
497 iwl_trans_op_mode_leave(mld->trans);
498 ieee80211_free_hw(mld->hw);
499 return ERR_PTR(ret);
500 }
501
502 static void
iwl_op_mode_mld_stop(struct iwl_op_mode * op_mode)503 iwl_op_mode_mld_stop(struct iwl_op_mode *op_mode)
504 {
505 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
506
507 iwl_mld_ptp_remove(mld);
508 iwl_mld_leds_exit(mld);
509
510 iwl_mld_thermal_exit(mld);
511
512 wiphy_lock(mld->wiphy);
513 iwl_mld_low_latency_stop(mld);
514 iwl_mld_deinit_time_sync(mld);
515 wiphy_unlock(mld->wiphy);
516
517 ieee80211_unregister_hw(mld->hw);
518
519 iwl_fw_runtime_free(&mld->fwrt);
520 iwl_mld_low_latency_free(mld);
521
522 iwl_trans_op_mode_leave(mld->trans);
523
524 kfree(mld->nvm_data);
525 kfree(mld->scan.cmd);
526 kfree(mld->channel_survey);
527 kfree(mld->error_recovery_buf);
528 kfree(mld->mcast_filter_cmd);
529
530 ieee80211_free_hw(mld->hw);
531 }
532
iwl_mld_queue_state_change(struct iwl_op_mode * op_mode,int hw_queue,bool queue_full)533 static void iwl_mld_queue_state_change(struct iwl_op_mode *op_mode,
534 int hw_queue, bool queue_full)
535 {
536 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
537 struct ieee80211_txq *txq;
538 struct iwl_mld_sta *mld_sta;
539 struct iwl_mld_txq *mld_txq;
540
541 rcu_read_lock();
542
543 txq = rcu_dereference(mld->fw_id_to_txq[hw_queue]);
544 if (!txq) {
545 rcu_read_unlock();
546
547 if (queue_full) {
548 /* An internal queue is not expected to become full */
549 IWL_WARN(mld,
550 "Internal hw_queue %d is full! stopping all queues\n",
551 hw_queue);
552 /* Stop all queues, as an internal queue is not
553 * mapped to a mac80211 one
554 */
555 ieee80211_stop_queues(mld->hw);
556 } else {
557 ieee80211_wake_queues(mld->hw);
558 }
559
560 return;
561 }
562
563 mld_txq = iwl_mld_txq_from_mac80211(txq);
564 mld_sta = txq->sta ? iwl_mld_sta_from_mac80211(txq->sta) : NULL;
565
566 mld_txq->status.stop_full = queue_full;
567
568 if (!queue_full && mld_sta &&
569 mld_sta->sta_state != IEEE80211_STA_NOTEXIST) {
570 local_bh_disable();
571 iwl_mld_tx_from_txq(mld, txq);
572 local_bh_enable();
573 }
574
575 rcu_read_unlock();
576 }
577
578 static void
iwl_mld_queue_full(struct iwl_op_mode * op_mode,int hw_queue)579 iwl_mld_queue_full(struct iwl_op_mode *op_mode, int hw_queue)
580 {
581 iwl_mld_queue_state_change(op_mode, hw_queue, true);
582 }
583
584 static void
iwl_mld_queue_not_full(struct iwl_op_mode * op_mode,int hw_queue)585 iwl_mld_queue_not_full(struct iwl_op_mode *op_mode, int hw_queue)
586 {
587 iwl_mld_queue_state_change(op_mode, hw_queue, false);
588 }
589
590 static bool
iwl_mld_set_hw_rfkill_state(struct iwl_op_mode * op_mode,bool state)591 iwl_mld_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
592 {
593 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
594
595 iwl_mld_set_hwkill(mld, state);
596
597 return false;
598 }
599
600 static void
iwl_mld_free_skb(struct iwl_op_mode * op_mode,struct sk_buff * skb)601 iwl_mld_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
602 {
603 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
604 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
605
606 iwl_trans_free_tx_cmd(mld->trans, info->driver_data[1]);
607 ieee80211_free_txskb(mld->hw, skb);
608 }
609
iwl_mld_read_error_recovery_buffer(struct iwl_mld * mld)610 static void iwl_mld_read_error_recovery_buffer(struct iwl_mld *mld)
611 {
612 u32 src_size = mld->fw->ucode_capa.error_log_size;
613 u32 src_addr = mld->fw->ucode_capa.error_log_addr;
614 u8 *recovery_buf;
615 int ret;
616
617 /* no recovery buffer size defined in a TLV */
618 if (!src_size)
619 return;
620
621 recovery_buf = kzalloc(src_size, GFP_ATOMIC);
622 if (!recovery_buf)
623 return;
624
625 ret = iwl_trans_read_mem_bytes(mld->trans, src_addr,
626 recovery_buf, src_size);
627 if (ret) {
628 IWL_ERR(mld, "Failed to read error recovery buffer (%d)\n",
629 ret);
630 kfree(recovery_buf);
631 return;
632 }
633
634 mld->error_recovery_buf = recovery_buf;
635 }
636
iwl_mld_restart_nic(struct iwl_mld * mld)637 static void iwl_mld_restart_nic(struct iwl_mld *mld)
638 {
639 iwl_mld_read_error_recovery_buffer(mld);
640
641 mld->fwrt.trans->dbg.restart_required = false;
642
643 ieee80211_restart_hw(mld->hw);
644 }
645
646 static void
iwl_mld_nic_error(struct iwl_op_mode * op_mode,enum iwl_fw_error_type type)647 iwl_mld_nic_error(struct iwl_op_mode *op_mode,
648 enum iwl_fw_error_type type)
649 {
650 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
651 bool trans_dead = iwl_trans_is_dead(mld->trans);
652
653 if (type == IWL_ERR_TYPE_CMD_QUEUE_FULL)
654 IWL_ERR(mld, "Command queue full!\n");
655 else if (!trans_dead && !mld->fw_status.do_not_dump_once)
656 iwl_fwrt_dump_error_logs(&mld->fwrt);
657
658 mld->fw_status.do_not_dump_once = false;
659
660 /* It is necessary to abort any os scan here because mac80211 requires
661 * having the scan cleared before restarting.
662 * We'll reset the scan_status to NONE in restart cleanup in
663 * the next drv_start() call from mac80211. If ieee80211_hw_restart
664 * isn't called scan status will stay busy.
665 */
666 iwl_mld_report_scan_aborted(mld);
667
668 /*
669 * This should be first thing before trying to collect any
670 * data to avoid endless loops if any HW error happens while
671 * collecting debug data.
672 * It might not actually be true that we'll restart, but the
673 * setting doesn't matter if we're going to be unbound either.
674 */
675 if (type != IWL_ERR_TYPE_RESET_HS_TIMEOUT &&
676 mld->fw_status.running)
677 mld->fw_status.in_hw_restart = true;
678 }
679
iwl_mld_dump_error(struct iwl_op_mode * op_mode,struct iwl_fw_error_dump_mode * mode)680 static void iwl_mld_dump_error(struct iwl_op_mode *op_mode,
681 struct iwl_fw_error_dump_mode *mode)
682 {
683 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
684
685 /* if we come in from opmode we have the mutex held */
686 if (mode->context == IWL_ERR_CONTEXT_FROM_OPMODE) {
687 lockdep_assert_wiphy(mld->wiphy);
688 iwl_fw_error_collect(&mld->fwrt);
689 } else {
690 wiphy_lock(mld->wiphy);
691 if (mode->context != IWL_ERR_CONTEXT_ABORT)
692 iwl_fw_error_collect(&mld->fwrt);
693 wiphy_unlock(mld->wiphy);
694 }
695 }
696
iwl_mld_sw_reset(struct iwl_op_mode * op_mode,enum iwl_fw_error_type type)697 static bool iwl_mld_sw_reset(struct iwl_op_mode *op_mode,
698 enum iwl_fw_error_type type)
699 {
700 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
701
702 /* SW reset can happen for TOP error w/o NIC error, so
703 * also abort scan here and set in_hw_restart, when we
704 * had a NIC error both were already done.
705 */
706 iwl_mld_report_scan_aborted(mld);
707 mld->fw_status.in_hw_restart = true;
708
709 /* Do restart only in the following conditions are met:
710 * - we consider the FW as running
711 * - The trigger that brought us here is defined as one that requires
712 * a restart (in the debug TLVs)
713 */
714 if (!mld->fw_status.running || !mld->fwrt.trans->dbg.restart_required)
715 return false;
716
717 iwl_mld_restart_nic(mld);
718 return true;
719 }
720
721 static void
iwl_mld_time_point(struct iwl_op_mode * op_mode,enum iwl_fw_ini_time_point tp_id,union iwl_dbg_tlv_tp_data * tp_data)722 iwl_mld_time_point(struct iwl_op_mode *op_mode,
723 enum iwl_fw_ini_time_point tp_id,
724 union iwl_dbg_tlv_tp_data *tp_data)
725 {
726 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
727
728 iwl_dbg_tlv_time_point(&mld->fwrt, tp_id, tp_data);
729 }
730
731 #ifdef CONFIG_PM_SLEEP
iwl_mld_device_powered_off(struct iwl_op_mode * op_mode)732 static void iwl_mld_device_powered_off(struct iwl_op_mode *op_mode)
733 {
734 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
735
736 wiphy_lock(mld->wiphy);
737 iwl_mld_stop_fw(mld);
738 mld->fw_status.in_d3 = false;
739 wiphy_unlock(mld->wiphy);
740 }
741 #else
iwl_mld_device_powered_off(struct iwl_op_mode * op_mode)742 static void iwl_mld_device_powered_off(struct iwl_op_mode *op_mode)
743 {}
744 #endif
745
iwl_mld_dump(struct iwl_op_mode * op_mode)746 static void iwl_mld_dump(struct iwl_op_mode *op_mode)
747 {
748 struct iwl_mld *mld = IWL_OP_MODE_GET_MLD(op_mode);
749 struct iwl_fw_runtime *fwrt = &mld->fwrt;
750
751 if (!iwl_trans_fw_running(fwrt->trans))
752 return;
753
754 iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER, NULL);
755 }
756
757 static const struct iwl_op_mode_ops iwl_mld_ops = {
758 .start = iwl_op_mode_mld_start,
759 .stop = iwl_op_mode_mld_stop,
760 .rx = iwl_mld_rx,
761 .rx_rss = iwl_mld_rx_rss,
762 .queue_full = iwl_mld_queue_full,
763 .queue_not_full = iwl_mld_queue_not_full,
764 .hw_rf_kill = iwl_mld_set_hw_rfkill_state,
765 .free_skb = iwl_mld_free_skb,
766 .nic_error = iwl_mld_nic_error,
767 .dump_error = iwl_mld_dump_error,
768 .sw_reset = iwl_mld_sw_reset,
769 .time_point = iwl_mld_time_point,
770 .device_powered_off = pm_sleep_ptr(iwl_mld_device_powered_off),
771 .dump = iwl_mld_dump,
772 };
773
774 struct iwl_mld_mod_params iwlmld_mod_params = {
775 .power_scheme = IWL_POWER_SCHEME_BPS,
776 };
777
778 module_param_named(power_scheme, iwlmld_mod_params.power_scheme, int, 0444);
779 MODULE_PARM_DESC(power_scheme,
780 "power management scheme: 1-active, 2-balanced, default: 2");
781