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