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