xref: /linux/drivers/net/wireless/ath/ath12k/wifi7/hw.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5  */
6 
7 #include <linux/types.h>
8 #include <linux/bitops.h>
9 #include <linux/bitfield.h>
10 
11 #include "../debug.h"
12 #include "../core.h"
13 #include "../ce.h"
14 #include "ce.h"
15 #include "../hw.h"
16 #include "hw.h"
17 #include "../mhi.h"
18 #include "mhi.h"
19 #include "dp_rx.h"
20 #include "../peer.h"
21 #include "wmi.h"
22 #include "../wow.h"
23 #include "../debugfs.h"
24 #include "../debugfs_sta.h"
25 #include "../testmode.h"
26 #include "hal.h"
27 #include "dp_tx.h"
28 
29 static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec,
30 					     0x90, 0xd6, 0x02, 0x42,
31 					     0xac, 0x12, 0x00, 0x03);
32 
ath12k_wifi7_hw_qcn9274_mac_from_pdev_id(int pdev_idx)33 static u8 ath12k_wifi7_hw_qcn9274_mac_from_pdev_id(int pdev_idx)
34 {
35 	return pdev_idx;
36 }
37 
38 static int
ath12k_wifi7_hw_mac_id_to_pdev_id_qcn9274(const struct ath12k_hw_params * hw,int mac_id)39 ath12k_wifi7_hw_mac_id_to_pdev_id_qcn9274(const struct ath12k_hw_params *hw,
40 					  int mac_id)
41 {
42 	return mac_id;
43 }
44 
45 static int
ath12k_wifi7_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params * hw,int mac_id)46 ath12k_wifi7_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params *hw,
47 					  int mac_id)
48 {
49 	return 0;
50 }
51 
ath12k_wifi7_hw_get_ring_selector_qcn9274(struct sk_buff * skb)52 static u8 ath12k_wifi7_hw_get_ring_selector_qcn9274(struct sk_buff *skb)
53 {
54 	return smp_processor_id();
55 }
56 
ath12k_wifi7_dp_srng_is_comp_ring_qcn9274(int ring_num)57 static bool ath12k_wifi7_dp_srng_is_comp_ring_qcn9274(int ring_num)
58 {
59 	if (ring_num < 3 || ring_num == 4)
60 		return true;
61 
62 	return false;
63 }
64 
65 static bool
ath12k_wifi7_is_frame_link_agnostic_qcn9274(struct ath12k_link_vif * arvif,struct ieee80211_mgmt * mgmt)66 ath12k_wifi7_is_frame_link_agnostic_qcn9274(struct ath12k_link_vif *arvif,
67 					    struct ieee80211_mgmt *mgmt)
68 {
69 	return ieee80211_is_action(mgmt->frame_control);
70 }
71 
72 static int
ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params * hw,int mac_id)73 ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params *hw,
74 					  int mac_id)
75 {
76 	return 0;
77 }
78 
79 static int
ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850(const struct ath12k_hw_params * hw,int mac_id)80 ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850(const struct ath12k_hw_params *hw,
81 					  int mac_id)
82 {
83 	return mac_id;
84 }
85 
ath12k_wifi7_hw_get_ring_selector_wcn7850(struct sk_buff * skb)86 static u8 ath12k_wifi7_hw_get_ring_selector_wcn7850(struct sk_buff *skb)
87 {
88 	return skb_get_queue_mapping(skb);
89 }
90 
ath12k_wifi7_dp_srng_is_comp_ring_wcn7850(int ring_num)91 static bool ath12k_wifi7_dp_srng_is_comp_ring_wcn7850(int ring_num)
92 {
93 	if (ring_num == 0 || ring_num == 2 || ring_num == 4)
94 		return true;
95 
96 	return false;
97 }
98 
ath12k_is_addba_resp_action_code(struct ieee80211_mgmt * mgmt)99 static bool ath12k_is_addba_resp_action_code(struct ieee80211_mgmt *mgmt)
100 {
101 	if (!ieee80211_is_action(mgmt->frame_control))
102 		return false;
103 
104 	if (mgmt->u.action.category != WLAN_CATEGORY_BACK)
105 		return false;
106 
107 	if (mgmt->u.action.action_code != WLAN_ACTION_ADDBA_RESP)
108 		return false;
109 
110 	return true;
111 }
112 
113 static bool
ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif * arvif,struct ieee80211_mgmt * mgmt)114 ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif,
115 					    struct ieee80211_mgmt *mgmt)
116 {
117 	struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
118 	struct ath12k_hw *ah = ath12k_ar_to_ah(arvif->ar);
119 	struct ath12k_base *ab = arvif->ar->ab;
120 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
121 	struct ath12k_dp_peer *peer;
122 	__le16 fc = mgmt->frame_control;
123 
124 	spin_lock_bh(&dp->dp_lock);
125 	if (!ath12k_dp_link_peer_find_by_addr(dp, mgmt->da)) {
126 		spin_lock_bh(&ah->dp_hw.peer_lock);
127 		peer = ath12k_dp_peer_find_by_addr(&ah->dp_hw, mgmt->da);
128 		if (!peer || (peer && !peer->is_mlo)) {
129 			spin_unlock_bh(&ah->dp_hw.peer_lock);
130 			spin_unlock_bh(&dp->dp_lock);
131 			return false;
132 		}
133 		spin_unlock_bh(&ah->dp_hw.peer_lock);
134 	}
135 	spin_unlock_bh(&dp->dp_lock);
136 
137 	if (vif->type == NL80211_IFTYPE_STATION)
138 		return arvif->is_up &&
139 		       (vif->valid_links == vif->active_links) &&
140 		       !ieee80211_is_probe_req(fc) &&
141 		       !ieee80211_is_auth(fc) &&
142 		       !ieee80211_is_deauth(fc) &&
143 		       !ath12k_is_addba_resp_action_code(mgmt);
144 
145 	if (vif->type == NL80211_IFTYPE_AP)
146 		return !(ieee80211_is_probe_resp(fc) || ieee80211_is_auth(fc) ||
147 			 ieee80211_is_assoc_resp(fc) || ieee80211_is_reassoc_resp(fc) ||
148 			 ath12k_is_addba_resp_action_code(mgmt));
149 
150 	return false;
151 }
152 
153 static const struct ath12k_hw_ops qcn9274_ops = {
154 	.get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id,
155 	.mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_qcn9274,
156 	.mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_qcn9274,
157 	.rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcn9274,
158 	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_qcn9274,
159 	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_qcn9274,
160 	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_qcn9274,
161 	.set_rx_link_id = ath12k_wifi7_dp_rx_set_link_id_qcn9274,
162 };
163 
164 static const struct ath12k_hw_ops wcn7850_ops = {
165 	.get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id,
166 	.mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850,
167 	.mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850,
168 	.rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_wcn7850,
169 	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850,
170 	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850,
171 	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
172 	.set_rx_link_id = ath12k_wifi7_dp_rx_set_link_id_wcn7850,
173 };
174 
175 static const struct ath12k_hw_ops qcc2072_ops = {
176 	.get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id,
177 	.mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850,
178 	.mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850,
179 	.rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcc2072,
180 	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850,
181 	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850,
182 	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
183 	.set_rx_link_id = ath12k_wifi7_dp_rx_set_link_id_wcn7850,
184 };
185 
186 #define ATH12K_TX_RING_MASK_0 0x1
187 #define ATH12K_TX_RING_MASK_1 0x2
188 #define ATH12K_TX_RING_MASK_2 0x4
189 #define ATH12K_TX_RING_MASK_3 0x8
190 #define ATH12K_TX_RING_MASK_4 0x10
191 
192 #define ATH12K_RX_RING_MASK_0 0x1
193 #define ATH12K_RX_RING_MASK_1 0x2
194 #define ATH12K_RX_RING_MASK_2 0x4
195 #define ATH12K_RX_RING_MASK_3 0x8
196 
197 #define ATH12K_RX_ERR_RING_MASK_0 0x1
198 
199 #define ATH12K_RX_WBM_REL_RING_MASK_0 0x1
200 
201 #define ATH12K_REO_STATUS_RING_MASK_0 0x1
202 
203 #define ATH12K_HOST2RXDMA_RING_MASK_0 0x1
204 
205 #define ATH12K_RX_MON_RING_MASK_0 0x1
206 #define ATH12K_RX_MON_RING_MASK_1 0x2
207 #define ATH12K_RX_MON_RING_MASK_2 0x4
208 
209 #define ATH12K_TX_MON_RING_MASK_0 0x1
210 #define ATH12K_TX_MON_RING_MASK_1 0x2
211 
212 #define ATH12K_RX_MON_STATUS_RING_MASK_0 0x1
213 #define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2
214 #define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4
215 
216 static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_qcn9274 = {
217 	.tx  = {
218 		ATH12K_TX_RING_MASK_0,
219 		ATH12K_TX_RING_MASK_1,
220 		ATH12K_TX_RING_MASK_2,
221 		ATH12K_TX_RING_MASK_3,
222 	},
223 	.rx_mon_dest = {
224 		0, 0, 0, 0,
225 		0, 0, 0, 0,
226 		ATH12K_RX_MON_RING_MASK_0,
227 		ATH12K_RX_MON_RING_MASK_1,
228 		ATH12K_RX_MON_RING_MASK_2,
229 	},
230 	.rx = {
231 		0, 0, 0, 0,
232 		ATH12K_RX_RING_MASK_0,
233 		ATH12K_RX_RING_MASK_1,
234 		ATH12K_RX_RING_MASK_2,
235 		ATH12K_RX_RING_MASK_3,
236 	},
237 	.rx_err = {
238 		0, 0, 0,
239 		ATH12K_RX_ERR_RING_MASK_0,
240 	},
241 	.rx_wbm_rel = {
242 		0, 0, 0,
243 		ATH12K_RX_WBM_REL_RING_MASK_0,
244 	},
245 	.reo_status = {
246 		0, 0, 0,
247 		ATH12K_REO_STATUS_RING_MASK_0,
248 	},
249 	.host2rxdma = {
250 		0, 0, 0,
251 		ATH12K_HOST2RXDMA_RING_MASK_0,
252 	},
253 	.tx_mon_dest = {
254 		0, 0, 0,
255 	},
256 };
257 
258 static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_ipq5332 = {
259 	.tx  = {
260 		ATH12K_TX_RING_MASK_0,
261 		ATH12K_TX_RING_MASK_1,
262 		ATH12K_TX_RING_MASK_2,
263 		ATH12K_TX_RING_MASK_3,
264 	},
265 	.rx_mon_dest = {
266 		0, 0, 0, 0, 0, 0, 0, 0,
267 		ATH12K_RX_MON_RING_MASK_0,
268 	},
269 	.rx = {
270 		0, 0, 0, 0,
271 		ATH12K_RX_RING_MASK_0,
272 		ATH12K_RX_RING_MASK_1,
273 		ATH12K_RX_RING_MASK_2,
274 		ATH12K_RX_RING_MASK_3,
275 	},
276 	.rx_err = {
277 		0, 0, 0,
278 		ATH12K_RX_ERR_RING_MASK_0,
279 	},
280 	.rx_wbm_rel = {
281 		0, 0, 0,
282 		ATH12K_RX_WBM_REL_RING_MASK_0,
283 	},
284 	.reo_status = {
285 		0, 0, 0,
286 		ATH12K_REO_STATUS_RING_MASK_0,
287 	},
288 	.host2rxdma = {
289 		0, 0, 0,
290 		ATH12K_HOST2RXDMA_RING_MASK_0,
291 	},
292 	.tx_mon_dest = {
293 		ATH12K_TX_MON_RING_MASK_0,
294 		ATH12K_TX_MON_RING_MASK_1,
295 	},
296 };
297 
298 static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = {
299 	.tx  = {
300 		ATH12K_TX_RING_MASK_0,
301 		ATH12K_TX_RING_MASK_1,
302 		ATH12K_TX_RING_MASK_2,
303 	},
304 	.rx_mon_dest = {
305 	},
306 	.rx_mon_status = {
307 		0, 0, 0, 0,
308 		ATH12K_RX_MON_STATUS_RING_MASK_0,
309 		ATH12K_RX_MON_STATUS_RING_MASK_1,
310 		ATH12K_RX_MON_STATUS_RING_MASK_2,
311 	},
312 	.rx = {
313 		0, 0, 0,
314 		ATH12K_RX_RING_MASK_0,
315 		ATH12K_RX_RING_MASK_1,
316 		ATH12K_RX_RING_MASK_2,
317 		ATH12K_RX_RING_MASK_3,
318 	},
319 	.rx_err = {
320 		ATH12K_RX_ERR_RING_MASK_0,
321 	},
322 	.rx_wbm_rel = {
323 		ATH12K_RX_WBM_REL_RING_MASK_0,
324 	},
325 	.reo_status = {
326 		ATH12K_REO_STATUS_RING_MASK_0,
327 	},
328 	.host2rxdma = {
329 	},
330 	.tx_mon_dest = {
331 	},
332 };
333 
334 static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = {
335 	.ie1_reg_addr = CE_HOST_IPQ5332_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
336 	.ie2_reg_addr = CE_HOST_IPQ5332_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
337 	.ie3_reg_addr = CE_HOST_IPQ5332_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
338 };
339 
340 static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5424 = {
341 	.ie1_reg_addr = CE_HOST_IPQ5424_IE_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
342 	.ie2_reg_addr = CE_HOST_IPQ5424_IE_2_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
343 	.ie3_reg_addr = CE_HOST_IPQ5424_IE_3_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
344 };
345 
346 static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = {
347 	.base = HAL_IPQ5332_CE_WFSS_REG_BASE,
348 	.size = HAL_IPQ5332_CE_SIZE,
349 	.cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET,
350 };
351 
352 static const struct ce_remap ath12k_wifi7_ce_remap_ipq5424 = {
353 	.base = HAL_IPQ5424_CE_WFSS_REG_BASE,
354 	.size = HAL_IPQ5424_CE_SIZE,
355 	.cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET,
356 };
357 
358 static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
359 	{
360 		.name = "qcn9274 hw1.0",
361 		.hw_rev = ATH12K_HW_QCN9274_HW10,
362 		.fw = {
363 			.dir = "QCN9274/hw1.0",
364 			.board_size = 256 * 1024,
365 			.cal_offset = 128 * 1024,
366 			.m3_loader = ath12k_m3_fw_loader_driver,
367 			.download_aux_ucode = false,
368 		},
369 		.max_radios = 1,
370 		.single_pdev_only = false,
371 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274,
372 		.internal_sleep_clock = false,
373 
374 		.hw_ops = &qcn9274_ops,
375 		.ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274,
376 
377 		.host_ce_config = ath12k_wifi7_host_ce_config_qcn9274,
378 		.ce_count = 16,
379 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274,
380 		.target_ce_count = 12,
381 		.svc_to_ce_map =
382 			ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274,
383 		.svc_to_ce_map_len = 18,
384 
385 		.rxdma1_enable = false,
386 		.num_rxdma_per_pdev = 1,
387 		.num_rxdma_dst_ring = 0,
388 		.rx_mac_buf_ring = false,
389 		.vdev_start_delay = false,
390 
391 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
392 					BIT(NL80211_IFTYPE_AP) |
393 					BIT(NL80211_IFTYPE_MESH_POINT) |
394 					BIT(NL80211_IFTYPE_AP_VLAN),
395 		.supports_monitor = false,
396 		.supports_cong_ctrl_max_msdus = true,
397 
398 		.idle_ps = false,
399 		.download_calib = true,
400 		.supports_suspend = false,
401 		.tcl_ring_retry = true,
402 		.reoq_lut_support = true,
403 		.supports_shadow_regs = false,
404 
405 		.num_tcl_banks = 48,
406 		.max_tx_ring = 4,
407 
408 		.mhi_config = &ath12k_wifi7_mhi_config_qcn9274,
409 
410 		.wmi_init = ath12k_wifi7_wmi_init_qcn9274,
411 
412 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
413 
414 		.rfkill_pin = 0,
415 		.rfkill_cfg = 0,
416 		.rfkill_on_level = 0,
417 
418 		.rddm_size = 0x600000,
419 
420 		.def_num_link = 0,
421 		.max_mlo_peer = 256,
422 
423 		.otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB,
424 
425 		.supports_sta_ps = false,
426 
427 		.acpi_guid = NULL,
428 		.supports_dynamic_smps_6ghz = true,
429 
430 		.iova_mask = 0,
431 
432 		.supports_aspm = false,
433 
434 		.ce_ie_addr = NULL,
435 		.ce_remap = NULL,
436 		.bdf_addr_offset = 0,
437 
438 		.current_cc_support = false,
439 
440 		.dp_primary_link_only = true,
441 		.client = {
442 			.max_client_single = 512,
443 			.max_client_dbs = 128,
444 			.max_client_dbs_sbs = 128,
445 		},
446 
447 		.host_alloc_ml_id = true,
448 	},
449 	{
450 		.name = "wcn7850 hw2.0",
451 		.hw_rev = ATH12K_HW_WCN7850_HW20,
452 
453 		.fw = {
454 			.dir = "WCN7850/hw2.0",
455 			.board_size = 256 * 1024,
456 			.cal_offset = 256 * 1024,
457 			.m3_loader = ath12k_m3_fw_loader_driver,
458 			.download_aux_ucode = false,
459 		},
460 
461 		.max_radios = 1,
462 		.single_pdev_only = true,
463 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850,
464 		.internal_sleep_clock = true,
465 
466 		.hw_ops = &wcn7850_ops,
467 		.ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850,
468 
469 		.host_ce_config = ath12k_wifi7_host_ce_config_wcn7850,
470 		.ce_count = 9,
471 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850,
472 		.target_ce_count = 9,
473 		.svc_to_ce_map =
474 			ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850,
475 		.svc_to_ce_map_len = 14,
476 
477 		.rxdma1_enable = false,
478 		.num_rxdma_per_pdev = 2,
479 		.num_rxdma_dst_ring = 1,
480 		.rx_mac_buf_ring = true,
481 		.vdev_start_delay = true,
482 
483 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
484 				   BIT(NL80211_IFTYPE_AP) |
485 				   BIT(NL80211_IFTYPE_P2P_DEVICE) |
486 				   BIT(NL80211_IFTYPE_P2P_CLIENT) |
487 				   BIT(NL80211_IFTYPE_P2P_GO),
488 		.supports_monitor = true,
489 		.supports_cong_ctrl_max_msdus = false,
490 
491 		.idle_ps = true,
492 		.download_calib = false,
493 		.supports_suspend = true,
494 		.tcl_ring_retry = false,
495 		.reoq_lut_support = false,
496 		.supports_shadow_regs = true,
497 
498 		.num_tcl_banks = 7,
499 		.max_tx_ring = 3,
500 
501 		.mhi_config = &ath12k_wifi7_mhi_config_wcn7850,
502 
503 		.wmi_init = ath12k_wifi7_wmi_init_wcn7850,
504 
505 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
506 					   BIT(CNSS_PCIE_PERST_NO_PULL_V01),
507 
508 		.rfkill_pin = 48,
509 		.rfkill_cfg = 0,
510 		.rfkill_on_level = 1,
511 
512 		.rddm_size = 0x780000,
513 
514 		.def_num_link = 2,
515 		.max_mlo_peer = 32,
516 
517 		.otp_board_id_register = 0,
518 
519 		.supports_sta_ps = true,
520 
521 		.acpi_guid = &wcn7850_uuid,
522 		.supports_dynamic_smps_6ghz = false,
523 
524 		.iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
525 
526 		.supports_aspm = true,
527 
528 		.ce_ie_addr = NULL,
529 		.ce_remap = NULL,
530 		.bdf_addr_offset = 0,
531 
532 		.current_cc_support = true,
533 
534 		.dp_primary_link_only = false,
535 		.client = {
536 			.max_client_single = 512,
537 			.max_client_dbs = 128,
538 			.max_client_dbs_sbs = 128,
539 		},
540 
541 		.host_alloc_ml_id = false,
542 	},
543 	{
544 		.name = "qcn9274 hw2.0",
545 		.hw_rev = ATH12K_HW_QCN9274_HW20,
546 		.fw = {
547 			.dir = "QCN9274/hw2.0",
548 			.board_size = 256 * 1024,
549 			.cal_offset = 128 * 1024,
550 			.m3_loader = ath12k_m3_fw_loader_driver,
551 			.download_aux_ucode = false,
552 		},
553 		.max_radios = 2,
554 		.single_pdev_only = false,
555 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274,
556 		.internal_sleep_clock = false,
557 
558 		.hw_ops = &qcn9274_ops,
559 		.ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274,
560 
561 		.host_ce_config = ath12k_wifi7_host_ce_config_qcn9274,
562 		.ce_count = 16,
563 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274,
564 		.target_ce_count = 12,
565 		.svc_to_ce_map =
566 			ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274,
567 		.svc_to_ce_map_len = 18,
568 
569 		.rxdma1_enable = true,
570 		.num_rxdma_per_pdev = 1,
571 		.num_rxdma_dst_ring = 0,
572 		.rx_mac_buf_ring = false,
573 		.vdev_start_delay = false,
574 
575 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
576 					BIT(NL80211_IFTYPE_AP) |
577 					BIT(NL80211_IFTYPE_MESH_POINT) |
578 					BIT(NL80211_IFTYPE_AP_VLAN),
579 		.supports_monitor = true,
580 		.supports_cong_ctrl_max_msdus = true,
581 
582 		.idle_ps = false,
583 		.download_calib = true,
584 		.supports_suspend = false,
585 		.tcl_ring_retry = true,
586 		.reoq_lut_support = true,
587 		.supports_shadow_regs = false,
588 
589 		.num_tcl_banks = 48,
590 		.max_tx_ring = 4,
591 
592 		.mhi_config = &ath12k_wifi7_mhi_config_qcn9274,
593 
594 		.wmi_init = ath12k_wifi7_wmi_init_qcn9274,
595 
596 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
597 
598 		.rfkill_pin = 0,
599 		.rfkill_cfg = 0,
600 		.rfkill_on_level = 0,
601 
602 		.rddm_size = 0x600000,
603 
604 		.def_num_link = 0,
605 		.max_mlo_peer = 256,
606 
607 		.otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB,
608 
609 		.supports_sta_ps = false,
610 
611 		.acpi_guid = NULL,
612 		.supports_dynamic_smps_6ghz = true,
613 
614 		.iova_mask = 0,
615 
616 		.supports_aspm = false,
617 
618 		.ce_ie_addr = NULL,
619 		.ce_remap = NULL,
620 		.bdf_addr_offset = 0,
621 
622 		.current_cc_support = false,
623 
624 		.dp_primary_link_only = true,
625 		.client = {
626 			.max_client_single = 512,
627 			.max_client_dbs = 128,
628 			.max_client_dbs_sbs = 128,
629 		},
630 
631 		.host_alloc_ml_id = true,
632 	},
633 	{
634 		.name = "ipq5332 hw1.0",
635 		.hw_rev = ATH12K_HW_IPQ5332_HW10,
636 		.fw = {
637 			.dir = "IPQ5332/hw1.0",
638 			.board_size = 256 * 1024,
639 			.cal_offset = 128 * 1024,
640 			.m3_loader = ath12k_m3_fw_loader_remoteproc,
641 			.download_aux_ucode = false,
642 		},
643 		.max_radios = 1,
644 		.single_pdev_only = false,
645 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332,
646 		.internal_sleep_clock = false,
647 
648 		.hw_ops = &qcn9274_ops,
649 		.ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332,
650 
651 		.host_ce_config = ath12k_wifi7_host_ce_config_ipq5332,
652 		.ce_count = 12,
653 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332,
654 		.target_ce_count = 12,
655 		.svc_to_ce_map =
656 			ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332,
657 		.svc_to_ce_map_len = 18,
658 
659 		.rxdma1_enable = true,
660 		.num_rxdma_per_pdev = 1,
661 		.num_rxdma_dst_ring = 0,
662 		.rx_mac_buf_ring = false,
663 		.vdev_start_delay = false,
664 
665 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
666 				   BIT(NL80211_IFTYPE_AP) |
667 				   BIT(NL80211_IFTYPE_MESH_POINT),
668 		.supports_monitor = true,
669 		.supports_cong_ctrl_max_msdus = true,
670 
671 		.idle_ps = false,
672 		.download_calib = true,
673 		.supports_suspend = false,
674 		.tcl_ring_retry = true,
675 		.reoq_lut_support = false,
676 		.supports_shadow_regs = false,
677 
678 		.num_tcl_banks = 48,
679 		.max_tx_ring = 4,
680 
681 		.wmi_init = &ath12k_wifi7_wmi_init_qcn9274,
682 
683 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
684 
685 		.rfkill_pin = 0,
686 		.rfkill_cfg = 0,
687 		.rfkill_on_level = 0,
688 
689 		.rddm_size = 0,
690 
691 		.def_num_link = 0,
692 		.max_mlo_peer = 256,
693 
694 		.otp_board_id_register = 0,
695 
696 		.supports_sta_ps = false,
697 
698 		.acpi_guid = NULL,
699 		.supports_dynamic_smps_6ghz = false,
700 		.iova_mask = 0,
701 		.supports_aspm = false,
702 
703 		.ce_ie_addr = &ath12k_wifi7_ce_ie_addr_ipq5332,
704 		.ce_remap = &ath12k_wifi7_ce_remap_ipq5332,
705 		.bdf_addr_offset = 0x1A00000,
706 
707 		.dp_primary_link_only = true,
708 		.client = {
709 			.max_client_single = 256,
710 			.max_client_dbs = 128,
711 			.max_client_dbs_sbs = 128,
712 		},
713 
714 		.host_alloc_ml_id = true,
715 	},
716 	{
717 		.name = "qcc2072 hw1.0",
718 		.hw_rev = ATH12K_HW_QCC2072_HW10,
719 
720 		.fw = {
721 			.dir = "QCC2072/hw1.0",
722 			.board_size = 256 * 1024,
723 			.cal_offset = 256 * 1024,
724 			.m3_loader = ath12k_m3_fw_loader_driver,
725 			.download_aux_ucode = true,
726 		},
727 
728 		.max_radios = 1,
729 		.single_pdev_only = true,
730 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850,
731 		.internal_sleep_clock = true,
732 
733 		.hw_ops = &qcc2072_ops,
734 		.ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850,
735 
736 		.host_ce_config = ath12k_wifi7_host_ce_config_wcn7850,
737 		.ce_count = 9,
738 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850,
739 		.target_ce_count = 9,
740 		.svc_to_ce_map =
741 			ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850,
742 		.svc_to_ce_map_len = 14,
743 
744 		.rxdma1_enable = false,
745 		.num_rxdma_per_pdev = 2,
746 		.num_rxdma_dst_ring = 1,
747 		.rx_mac_buf_ring = true,
748 		.vdev_start_delay = true,
749 
750 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
751 				   BIT(NL80211_IFTYPE_AP) |
752 				   BIT(NL80211_IFTYPE_P2P_DEVICE) |
753 				   BIT(NL80211_IFTYPE_P2P_CLIENT) |
754 				   BIT(NL80211_IFTYPE_P2P_GO),
755 		.supports_monitor = true,
756 		.supports_cong_ctrl_max_msdus = false,
757 
758 		.idle_ps = true,
759 		.download_calib = false,
760 		.supports_suspend = true,
761 		.tcl_ring_retry = false,
762 		.reoq_lut_support = false,
763 		.supports_shadow_regs = true,
764 
765 		.num_tcl_banks = 7,
766 		.max_tx_ring = 3,
767 
768 		.mhi_config = &ath12k_wifi7_mhi_config_wcn7850,
769 
770 		.wmi_init = ath12k_wifi7_wmi_init_wcn7850,
771 
772 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
773 					   BIT(CNSS_PCIE_PERST_NO_PULL_V01) |
774 					   BIT(CNSS_AUX_UC_SUPPORT_V01),
775 
776 		.rfkill_pin = 0,
777 		.rfkill_cfg = 0,
778 		.rfkill_on_level = 0,
779 
780 		.rddm_size = 0x780000,
781 
782 		.def_num_link = 2,
783 		.max_mlo_peer = 32,
784 
785 		.otp_board_id_register = 0,
786 
787 		.supports_sta_ps = true,
788 
789 		.acpi_guid = &wcn7850_uuid,
790 		.supports_dynamic_smps_6ghz = false,
791 
792 		.iova_mask = 0,
793 
794 		.supports_aspm = true,
795 
796 		.ce_ie_addr = NULL,
797 		.ce_remap = NULL,
798 		.bdf_addr_offset = 0,
799 
800 		.current_cc_support = true,
801 
802 		.dp_primary_link_only = false,
803 		.client = {
804 			.max_client_single = 512,
805 			.max_client_dbs = 128,
806 			.max_client_dbs_sbs = 128,
807 		},
808 
809 		.host_alloc_ml_id = false,
810 	},
811 	{
812 		.name = "ipq5424 hw1.0",
813 		.hw_rev = ATH12K_HW_IPQ5424_HW10,
814 		.fw = {
815 			.dir = "IPQ5424/hw1.0",
816 			.board_size = 256 * 1024,
817 			.cal_offset = 128 * 1024,
818 			.m3_loader = ath12k_m3_fw_loader_remoteproc,
819 			.download_aux_ucode = false,
820 		},
821 		.max_radios = 1,
822 		.single_pdev_only = false,
823 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332,
824 		.internal_sleep_clock = false,
825 
826 		.hw_ops = &qcn9274_ops,
827 		.ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332,
828 
829 		.host_ce_config = ath12k_wifi7_host_ce_config_ipq5332,
830 		.ce_count = 12,
831 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332,
832 		.target_ce_count = 12,
833 		.svc_to_ce_map =
834 			ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332,
835 		.svc_to_ce_map_len = 18,
836 
837 		.rxdma1_enable = true,
838 		.num_rxdma_per_pdev = 1,
839 		.num_rxdma_dst_ring = 0,
840 		.rx_mac_buf_ring = false,
841 		.vdev_start_delay = false,
842 
843 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
844 				   BIT(NL80211_IFTYPE_AP) |
845 				   BIT(NL80211_IFTYPE_MESH_POINT),
846 		.supports_monitor = true,
847 		.supports_cong_ctrl_max_msdus = true,
848 
849 		.idle_ps = false,
850 		.download_calib = true,
851 		.supports_suspend = false,
852 		.tcl_ring_retry = true,
853 		.reoq_lut_support = false,
854 		.supports_shadow_regs = false,
855 
856 		.num_tcl_banks = 48,
857 		.max_tx_ring = 4,
858 
859 		.mhi_config = NULL,
860 
861 		.wmi_init = &ath12k_wifi7_wmi_init_qcn9274,
862 
863 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
864 
865 		.rfkill_pin = 0,
866 		.rfkill_cfg = 0,
867 		.rfkill_on_level = 0,
868 
869 		.rddm_size = 0,
870 
871 		.def_num_link = 0,
872 		.max_mlo_peer = 256,
873 
874 		.otp_board_id_register = 0,
875 
876 		.supports_sta_ps = false,
877 
878 		.acpi_guid = NULL,
879 		.supports_dynamic_smps_6ghz = false,
880 		.iova_mask = 0,
881 		.supports_aspm = false,
882 
883 		.ce_ie_addr = &ath12k_wifi7_ce_ie_addr_ipq5424,
884 		.ce_remap = &ath12k_wifi7_ce_remap_ipq5424,
885 		.bdf_addr_offset = 0x940000,
886 
887 		.current_cc_support = false,
888 
889 		.dp_primary_link_only = true,
890 		.client = {
891 			.max_client_single = 512,
892 			.max_client_dbs = 128,
893 			.max_client_dbs_sbs = 128,
894 		},
895 
896 		.host_alloc_ml_id = true,
897 	},
898 };
899 
900 /* Note: called under rcu_read_lock() */
ath12k_wifi7_mac_op_tx(struct ieee80211_hw * hw,struct ieee80211_tx_control * control,struct sk_buff * skb)901 static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
902 				   struct ieee80211_tx_control *control,
903 				   struct sk_buff *skb)
904 {
905 	struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
906 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
907 	struct ieee80211_vif *vif = info->control.vif;
908 	struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
909 	struct ath12k_link_vif *arvif = &ahvif->deflink;
910 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
911 	struct ieee80211_key_conf *key = info->control.hw_key;
912 	struct ieee80211_sta *sta = control->sta;
913 	struct ath12k_link_sta *arsta = NULL;
914 	struct ath12k_link_vif *tmp_arvif;
915 	struct ath12k_sta *ahsta = NULL;
916 	u32 info_flags = info->flags;
917 	struct sk_buff *msdu_copied;
918 	struct ath12k *ar, *tmp_ar;
919 	struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev;
920 	struct ath12k_dp_link_peer *peer;
921 	unsigned long links_map;
922 	bool is_mcast = false;
923 	bool is_dvlan = false;
924 	struct ethhdr *eth;
925 	bool is_prb_rsp;
926 	u16 mcbc_gsn;
927 	u8 cb_flags;
928 	u8 link_id;
929 	int ret;
930 	struct ath12k_dp *tmp_dp;
931 
932 	if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
933 		ieee80211_free_txskb(hw, skb);
934 		return;
935 	}
936 
937 	link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK);
938 	memset(skb_cb, 0, sizeof(*skb_cb));
939 	skb_cb->vif = vif;
940 
941 	if (key) {
942 		skb_cb->cipher = key->cipher;
943 		skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
944 	}
945 
946 	/* handle only for MLO case, use deflink for non MLO case */
947 	if (ieee80211_vif_is_mld(vif)) {
948 		link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags);
949 		if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) {
950 			ieee80211_free_txskb(hw, skb);
951 			return;
952 		}
953 	} else {
954 		if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
955 			link_id = ATH12K_FIRST_SCAN_LINK;
956 		else
957 			link_id = 0;
958 	}
959 
960 	arvif = rcu_dereference(ahvif->link[link_id]);
961 	if (!arvif || !arvif->ar) {
962 		ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission",
963 			    link_id);
964 		ieee80211_free_txskb(hw, skb);
965 		return;
966 	}
967 
968 	ar = arvif->ar;
969 	skb_cb->link_id = link_id;
970 	/*
971 	 * as skb_cb is common currently for dp and mgmt tx processing
972 	 * set this in the common mac op tx function.
973 	 */
974 	skb_cb->ar = ar;
975 	is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
976 
977 	if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
978 		eth = (struct ethhdr *)skb->data;
979 		is_mcast = is_multicast_ether_addr(eth->h_dest);
980 
981 		skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP;
982 	} else if (ieee80211_is_mgmt(hdr->frame_control)) {
983 		if (sta && sta->mlo)
984 			skb_cb->flags |= ATH12K_SKB_MLO_STA;
985 
986 		ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp);
987 		if (ret) {
988 			ath12k_warn(ar->ab, "failed to queue management frame %d\n",
989 				    ret);
990 			ieee80211_free_txskb(hw, skb);
991 		}
992 		return;
993 	}
994 
995 	if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
996 		is_mcast = is_multicast_ether_addr(hdr->addr1);
997 
998 	if (sta) {
999 		ahsta = ath12k_sta_to_ahsta(control->sta);
1000 		if (ahsta && ahsta->enable_4addr)
1001 			arsta = rcu_dereference(ahsta->link[link_id]);
1002 	}
1003 
1004 	/* This is case only for P2P_GO */
1005 	if (vif->type == NL80211_IFTYPE_AP && vif->p2p)
1006 		ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp);
1007 
1008 	dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx);
1009 	if (!dp_pdev) {
1010 		ieee80211_free_txskb(hw, skb);
1011 		return;
1012 	}
1013 
1014 	/* Checking if it is a DVLAN frame */
1015 	if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
1016 	    !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) &&
1017 	    !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) &&
1018 	    ieee80211_has_protected(hdr->frame_control))
1019 		is_dvlan = true;
1020 
1021 	/*
1022 	 * Add a sta pointer check to differentiate multicast encapsulation
1023 	 * offload packets, as the ATH12K_SKB_HW_80211_ENCAP flag is also set
1024 	 * for such packets.
1025 	 */
1026 	if (!vif->valid_links || !is_mcast || is_dvlan ||
1027 	    ((skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && sta) ||
1028 	    test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
1029 		ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, arsta, skb, false, 0, is_mcast);
1030 		if (unlikely(ret)) {
1031 			ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
1032 			ieee80211_free_txskb(ar->ah->hw, skb);
1033 			return;
1034 		}
1035 	} else {
1036 		mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff;
1037 
1038 		links_map = ahvif->links_map;
1039 		cb_flags = skb_cb->flags;
1040 		for_each_set_bit(link_id, &links_map,
1041 				 IEEE80211_MLD_MAX_NUM_LINKS) {
1042 			tmp_arvif = rcu_dereference(ahvif->link[link_id]);
1043 			if (!tmp_arvif || !tmp_arvif->is_up)
1044 				continue;
1045 
1046 			tmp_ar = tmp_arvif->ar;
1047 			if (unlikely(test_bit(ATH12K_FLAG_CRASH_FLUSH, &tmp_ar->ab->dev_flags)))
1048 				continue;
1049 
1050 			tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
1051 			tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_dp,
1052 							   tmp_ar->pdev_idx);
1053 			if (!tmp_dp_pdev)
1054 				continue;
1055 
1056 			if (cb_flags & ATH12K_SKB_HW_80211_ENCAP) {
1057 				/*
1058 				 * skb->data may be modified for the
1059 				 * iova_mask devices. It is better to
1060 				 * use skb_copy() for such devices to
1061 				 * avoid any potential skb corruption
1062 				 * related issues.
1063 				 */
1064 				if (tmp_dp->hw_params->iova_mask) {
1065 					msdu_copied = skb_copy(skb, GFP_ATOMIC);
1066 				} else {
1067 					/*
1068 					 * ath12k_wifi7_dp_tx() should
1069 					 * treat cloned HW-encap Ethernet
1070 					 * multicast frames as read-only.
1071 					 */
1072 					msdu_copied = skb_clone(skb, GFP_ATOMIC);
1073 				}
1074 				if (!msdu_copied) {
1075 					ath12k_err(ar->ab,
1076 						   "skb copy/clone failure link_id 0x%X vdevid 0x%X\n",
1077 						   link_id, tmp_arvif->vdev_id);
1078 					continue;
1079 				}
1080 			} else {
1081 				msdu_copied = skb_copy(skb, GFP_ATOMIC);
1082 				if (!msdu_copied) {
1083 					ath12k_err(ar->ab,
1084 						   "skb copy failure link_id 0x%X vdevid 0x%X\n",
1085 						   link_id, tmp_arvif->vdev_id);
1086 					continue;
1087 				}
1088 
1089 				ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
1090 									msdu_copied,
1091 									info_flags);
1092 			}
1093 
1094 			skb_cb = ATH12K_SKB_CB(msdu_copied);
1095 			skb_cb->link_id = link_id;
1096 			skb_cb->vif = vif;
1097 			skb_cb->ar = tmp_ar;
1098 
1099 			if (ahsta && ahsta->enable_4addr)
1100 				arsta = rcu_dereference(ahsta->link[link_id]);
1101 			else
1102 				arsta = NULL;
1103 
1104 			/* For open mode, skip peer find logic */
1105 			if (unlikely(!ahvif->dp_vif.key_cipher))
1106 				goto skip_peer_find;
1107 
1108 			spin_lock_bh(&tmp_dp->dp_lock);
1109 			peer = ath12k_dp_link_peer_find_by_addr(tmp_dp,
1110 								tmp_arvif->bssid);
1111 			if (!peer || !peer->dp_peer) {
1112 				spin_unlock_bh(&tmp_dp->dp_lock);
1113 				ath12k_warn(tmp_ar->ab,
1114 					    "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n",
1115 					    tmp_arvif->vdev_id, tmp_arvif->bssid,
1116 					    ahvif->links_map);
1117 				dev_kfree_skb_any(msdu_copied);
1118 				continue;
1119 			}
1120 
1121 			key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx];
1122 			if (key) {
1123 				skb_cb->cipher = key->cipher;
1124 				skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
1125 
1126 				if (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP)
1127 					goto skip_fctl_protected_check;
1128 
1129 				hdr = (struct ieee80211_hdr *)msdu_copied->data;
1130 				if (!ieee80211_has_protected(hdr->frame_control))
1131 					hdr->frame_control |=
1132 						cpu_to_le16(IEEE80211_FCTL_PROTECTED);
1133 			}
1134 
1135 skip_fctl_protected_check:
1136 			spin_unlock_bh(&tmp_dp->dp_lock);
1137 
1138 skip_peer_find:
1139 			ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, arsta,
1140 						 msdu_copied, true, mcbc_gsn, is_mcast);
1141 			if (unlikely(ret)) {
1142 				if (ret == -ENOMEM) {
1143 					/* Drops are expected during heavy multicast
1144 					 * frame flood. Print with debug log
1145 					 * level to avoid lot of console prints
1146 					 */
1147 					ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
1148 						   "failed to transmit frame %d\n",
1149 						   ret);
1150 				} else {
1151 					ath12k_warn(ar->ab,
1152 						    "failed to transmit frame %d\n",
1153 						    ret);
1154 				}
1155 
1156 				dev_kfree_skb_any(msdu_copied);
1157 			}
1158 		}
1159 		ieee80211_free_txskb(ar->ah->hw, skb);
1160 	}
1161 }
1162 
1163 static const struct ieee80211_ops ath12k_ops_wifi7 = {
1164 	.tx				= ath12k_wifi7_mac_op_tx,
1165 	.wake_tx_queue			= ieee80211_handle_wake_tx_queue,
1166 	.start                          = ath12k_mac_op_start,
1167 	.stop                           = ath12k_mac_op_stop,
1168 	.reconfig_complete              = ath12k_mac_op_reconfig_complete,
1169 	.add_interface                  = ath12k_mac_op_add_interface,
1170 	.remove_interface		= ath12k_mac_op_remove_interface,
1171 	.update_vif_offload		= ath12k_mac_op_update_vif_offload,
1172 	.config                         = ath12k_mac_op_config,
1173 	.link_info_changed              = ath12k_mac_op_link_info_changed,
1174 	.vif_cfg_changed		= ath12k_mac_op_vif_cfg_changed,
1175 	.change_vif_links               = ath12k_mac_op_change_vif_links,
1176 	.configure_filter		= ath12k_mac_op_configure_filter,
1177 	.hw_scan                        = ath12k_mac_op_hw_scan,
1178 	.cancel_hw_scan                 = ath12k_mac_op_cancel_hw_scan,
1179 	.set_key                        = ath12k_mac_op_set_key,
1180 	.set_rekey_data	                = ath12k_mac_op_set_rekey_data,
1181 	.sta_state                      = ath12k_mac_op_sta_state,
1182 	.sta_set_txpwr			= ath12k_mac_op_sta_set_txpwr,
1183 	.link_sta_rc_update		= ath12k_mac_op_link_sta_rc_update,
1184 	.sta_set_4addr                  = ath12k_mac_op_sta_set_4addr,
1185 	.conf_tx                        = ath12k_mac_op_conf_tx,
1186 	.set_antenna			= ath12k_mac_op_set_antenna,
1187 	.get_antenna			= ath12k_mac_op_get_antenna,
1188 	.ampdu_action			= ath12k_mac_op_ampdu_action,
1189 	.add_chanctx			= ath12k_mac_op_add_chanctx,
1190 	.remove_chanctx			= ath12k_mac_op_remove_chanctx,
1191 	.change_chanctx			= ath12k_mac_op_change_chanctx,
1192 	.assign_vif_chanctx		= ath12k_mac_op_assign_vif_chanctx,
1193 	.unassign_vif_chanctx		= ath12k_mac_op_unassign_vif_chanctx,
1194 	.switch_vif_chanctx		= ath12k_mac_op_switch_vif_chanctx,
1195 	.get_txpower			= ath12k_mac_op_get_txpower,
1196 	.set_rts_threshold		= ath12k_mac_op_set_rts_threshold,
1197 	.set_frag_threshold		= ath12k_mac_op_set_frag_threshold,
1198 	.set_bitrate_mask		= ath12k_mac_op_set_bitrate_mask,
1199 	.get_survey			= ath12k_mac_op_get_survey,
1200 	.flush				= ath12k_mac_op_flush,
1201 	.sta_statistics			= ath12k_mac_op_sta_statistics,
1202 	.link_sta_statistics		= ath12k_mac_op_link_sta_statistics,
1203 	.remain_on_channel              = ath12k_mac_op_remain_on_channel,
1204 	.cancel_remain_on_channel       = ath12k_mac_op_cancel_remain_on_channel,
1205 	.change_sta_links               = ath12k_mac_op_change_sta_links,
1206 	.can_activate_links             = ath12k_mac_op_can_activate_links,
1207 #ifdef CONFIG_PM
1208 	.suspend			= ath12k_wow_op_suspend,
1209 	.resume				= ath12k_wow_op_resume,
1210 	.set_wakeup			= ath12k_wow_op_set_wakeup,
1211 #endif
1212 #ifdef CONFIG_ATH12K_DEBUGFS
1213 	.vif_add_debugfs                = ath12k_debugfs_op_vif_add,
1214 #endif
1215 	CFG80211_TESTMODE_CMD(ath12k_tm_cmd)
1216 #ifdef CONFIG_ATH12K_DEBUGFS
1217 	.link_sta_add_debugfs           = ath12k_debugfs_link_sta_op_add,
1218 #endif
1219 };
1220 
ath12k_wifi7_hw_init(struct ath12k_base * ab)1221 int ath12k_wifi7_hw_init(struct ath12k_base *ab)
1222 {
1223 	const struct ath12k_hw_params *hw_params = NULL;
1224 	int i;
1225 
1226 	for (i = 0; i < ARRAY_SIZE(ath12k_wifi7_hw_params); i++) {
1227 		hw_params = &ath12k_wifi7_hw_params[i];
1228 
1229 		if (hw_params->hw_rev == ab->hw_rev)
1230 			break;
1231 	}
1232 
1233 	if (i == ARRAY_SIZE(ath12k_wifi7_hw_params)) {
1234 		ath12k_err(ab, "Unsupported Wi-Fi 7 hardware version: 0x%x\n",
1235 			   ab->hw_rev);
1236 		return -EINVAL;
1237 	}
1238 
1239 	ab->hw_params = hw_params;
1240 	ab->ath12k_ops = &ath12k_ops_wifi7;
1241 
1242 	ath12k_wifi7_hal_init(ab);
1243 
1244 	ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name);
1245 
1246 	return 0;
1247 }
1248