xref: /linux/drivers/net/wireless/ath/ath12k/wifi7/hw.c (revision 37a93dd5c49b5fda807fd204edf2547c3493319c)
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 
33 static u8 ath12k_wifi7_hw_qcn9274_mac_from_pdev_id(int pdev_idx)
34 {
35 	return pdev_idx;
36 }
37 
38 static int
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
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 
52 static u8 ath12k_wifi7_hw_get_ring_selector_qcn9274(struct sk_buff *skb)
53 {
54 	return smp_processor_id();
55 }
56 
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
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
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
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 
86 static u8 ath12k_wifi7_hw_get_ring_selector_wcn7850(struct sk_buff *skb)
87 {
88 	return skb_get_queue_mapping(skb);
89 }
90 
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 
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.u.addba_resp.action_code != WLAN_ACTION_ADDBA_RESP)
108 		return false;
109 
110 	return true;
111 }
112 
113 static bool
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 };
162 
163 static const struct ath12k_hw_ops wcn7850_ops = {
164 	.get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id,
165 	.mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850,
166 	.mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850,
167 	.rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_wcn7850,
168 	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850,
169 	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850,
170 	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
171 };
172 
173 static const struct ath12k_hw_ops qcc2072_ops = {
174 	.get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id,
175 	.mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850,
176 	.mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850,
177 	.rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcc2072,
178 	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850,
179 	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850,
180 	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
181 };
182 
183 #define ATH12K_TX_RING_MASK_0 0x1
184 #define ATH12K_TX_RING_MASK_1 0x2
185 #define ATH12K_TX_RING_MASK_2 0x4
186 #define ATH12K_TX_RING_MASK_3 0x8
187 #define ATH12K_TX_RING_MASK_4 0x10
188 
189 #define ATH12K_RX_RING_MASK_0 0x1
190 #define ATH12K_RX_RING_MASK_1 0x2
191 #define ATH12K_RX_RING_MASK_2 0x4
192 #define ATH12K_RX_RING_MASK_3 0x8
193 
194 #define ATH12K_RX_ERR_RING_MASK_0 0x1
195 
196 #define ATH12K_RX_WBM_REL_RING_MASK_0 0x1
197 
198 #define ATH12K_REO_STATUS_RING_MASK_0 0x1
199 
200 #define ATH12K_HOST2RXDMA_RING_MASK_0 0x1
201 
202 #define ATH12K_RX_MON_RING_MASK_0 0x1
203 #define ATH12K_RX_MON_RING_MASK_1 0x2
204 #define ATH12K_RX_MON_RING_MASK_2 0x4
205 
206 #define ATH12K_TX_MON_RING_MASK_0 0x1
207 #define ATH12K_TX_MON_RING_MASK_1 0x2
208 
209 #define ATH12K_RX_MON_STATUS_RING_MASK_0 0x1
210 #define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2
211 #define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4
212 
213 static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_qcn9274 = {
214 	.tx  = {
215 		ATH12K_TX_RING_MASK_0,
216 		ATH12K_TX_RING_MASK_1,
217 		ATH12K_TX_RING_MASK_2,
218 		ATH12K_TX_RING_MASK_3,
219 	},
220 	.rx_mon_dest = {
221 		0, 0, 0, 0,
222 		0, 0, 0, 0,
223 		ATH12K_RX_MON_RING_MASK_0,
224 		ATH12K_RX_MON_RING_MASK_1,
225 		ATH12K_RX_MON_RING_MASK_2,
226 	},
227 	.rx = {
228 		0, 0, 0, 0,
229 		ATH12K_RX_RING_MASK_0,
230 		ATH12K_RX_RING_MASK_1,
231 		ATH12K_RX_RING_MASK_2,
232 		ATH12K_RX_RING_MASK_3,
233 	},
234 	.rx_err = {
235 		0, 0, 0,
236 		ATH12K_RX_ERR_RING_MASK_0,
237 	},
238 	.rx_wbm_rel = {
239 		0, 0, 0,
240 		ATH12K_RX_WBM_REL_RING_MASK_0,
241 	},
242 	.reo_status = {
243 		0, 0, 0,
244 		ATH12K_REO_STATUS_RING_MASK_0,
245 	},
246 	.host2rxdma = {
247 		0, 0, 0,
248 		ATH12K_HOST2RXDMA_RING_MASK_0,
249 	},
250 	.tx_mon_dest = {
251 		0, 0, 0,
252 	},
253 };
254 
255 static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_ipq5332 = {
256 	.tx  = {
257 		ATH12K_TX_RING_MASK_0,
258 		ATH12K_TX_RING_MASK_1,
259 		ATH12K_TX_RING_MASK_2,
260 		ATH12K_TX_RING_MASK_3,
261 	},
262 	.rx_mon_dest = {
263 		0, 0, 0, 0, 0, 0, 0, 0,
264 		ATH12K_RX_MON_RING_MASK_0,
265 	},
266 	.rx = {
267 		0, 0, 0, 0,
268 		ATH12K_RX_RING_MASK_0,
269 		ATH12K_RX_RING_MASK_1,
270 		ATH12K_RX_RING_MASK_2,
271 		ATH12K_RX_RING_MASK_3,
272 	},
273 	.rx_err = {
274 		0, 0, 0,
275 		ATH12K_RX_ERR_RING_MASK_0,
276 	},
277 	.rx_wbm_rel = {
278 		0, 0, 0,
279 		ATH12K_RX_WBM_REL_RING_MASK_0,
280 	},
281 	.reo_status = {
282 		0, 0, 0,
283 		ATH12K_REO_STATUS_RING_MASK_0,
284 	},
285 	.host2rxdma = {
286 		0, 0, 0,
287 		ATH12K_HOST2RXDMA_RING_MASK_0,
288 	},
289 	.tx_mon_dest = {
290 		ATH12K_TX_MON_RING_MASK_0,
291 		ATH12K_TX_MON_RING_MASK_1,
292 	},
293 };
294 
295 static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = {
296 	.tx  = {
297 		ATH12K_TX_RING_MASK_0,
298 		ATH12K_TX_RING_MASK_1,
299 		ATH12K_TX_RING_MASK_2,
300 	},
301 	.rx_mon_dest = {
302 	},
303 	.rx_mon_status = {
304 		0, 0, 0, 0,
305 		ATH12K_RX_MON_STATUS_RING_MASK_0,
306 		ATH12K_RX_MON_STATUS_RING_MASK_1,
307 		ATH12K_RX_MON_STATUS_RING_MASK_2,
308 	},
309 	.rx = {
310 		0, 0, 0,
311 		ATH12K_RX_RING_MASK_0,
312 		ATH12K_RX_RING_MASK_1,
313 		ATH12K_RX_RING_MASK_2,
314 		ATH12K_RX_RING_MASK_3,
315 	},
316 	.rx_err = {
317 		ATH12K_RX_ERR_RING_MASK_0,
318 	},
319 	.rx_wbm_rel = {
320 		ATH12K_RX_WBM_REL_RING_MASK_0,
321 	},
322 	.reo_status = {
323 		ATH12K_REO_STATUS_RING_MASK_0,
324 	},
325 	.host2rxdma = {
326 	},
327 	.tx_mon_dest = {
328 	},
329 };
330 
331 static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = {
332 	.ie1_reg_addr = CE_HOST_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
333 	.ie2_reg_addr = CE_HOST_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
334 	.ie3_reg_addr = CE_HOST_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
335 };
336 
337 static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = {
338 	.base = HAL_IPQ5332_CE_WFSS_REG_BASE,
339 	.size = HAL_IPQ5332_CE_SIZE,
340 	.cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET,
341 };
342 
343 static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
344 	{
345 		.name = "qcn9274 hw1.0",
346 		.hw_rev = ATH12K_HW_QCN9274_HW10,
347 		.fw = {
348 			.dir = "QCN9274/hw1.0",
349 			.board_size = 256 * 1024,
350 			.cal_offset = 128 * 1024,
351 			.m3_loader = ath12k_m3_fw_loader_driver,
352 			.download_aux_ucode = false,
353 		},
354 		.max_radios = 1,
355 		.single_pdev_only = false,
356 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274,
357 		.internal_sleep_clock = false,
358 
359 		.hw_ops = &qcn9274_ops,
360 		.ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274,
361 
362 		.host_ce_config = ath12k_wifi7_host_ce_config_qcn9274,
363 		.ce_count = 16,
364 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274,
365 		.target_ce_count = 12,
366 		.svc_to_ce_map =
367 			ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274,
368 		.svc_to_ce_map_len = 18,
369 
370 		.rxdma1_enable = false,
371 		.num_rxdma_per_pdev = 1,
372 		.num_rxdma_dst_ring = 0,
373 		.rx_mac_buf_ring = false,
374 		.vdev_start_delay = false,
375 
376 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
377 					BIT(NL80211_IFTYPE_AP) |
378 					BIT(NL80211_IFTYPE_MESH_POINT) |
379 					BIT(NL80211_IFTYPE_AP_VLAN),
380 		.supports_monitor = false,
381 
382 		.idle_ps = false,
383 		.download_calib = true,
384 		.supports_suspend = false,
385 		.tcl_ring_retry = true,
386 		.reoq_lut_support = true,
387 		.supports_shadow_regs = false,
388 
389 		.num_tcl_banks = 48,
390 		.max_tx_ring = 4,
391 
392 		.mhi_config = &ath12k_wifi7_mhi_config_qcn9274,
393 
394 		.wmi_init = ath12k_wifi7_wmi_init_qcn9274,
395 
396 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
397 
398 		.rfkill_pin = 0,
399 		.rfkill_cfg = 0,
400 		.rfkill_on_level = 0,
401 
402 		.rddm_size = 0x600000,
403 
404 		.def_num_link = 0,
405 		.max_mlo_peer = 256,
406 
407 		.otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB,
408 
409 		.supports_sta_ps = false,
410 
411 		.acpi_guid = NULL,
412 		.supports_dynamic_smps_6ghz = true,
413 
414 		.iova_mask = 0,
415 
416 		.supports_aspm = false,
417 
418 		.ce_ie_addr = NULL,
419 		.ce_remap = NULL,
420 		.bdf_addr_offset = 0,
421 
422 		.current_cc_support = false,
423 
424 		.dp_primary_link_only = true,
425 	},
426 	{
427 		.name = "wcn7850 hw2.0",
428 		.hw_rev = ATH12K_HW_WCN7850_HW20,
429 
430 		.fw = {
431 			.dir = "WCN7850/hw2.0",
432 			.board_size = 256 * 1024,
433 			.cal_offset = 256 * 1024,
434 			.m3_loader = ath12k_m3_fw_loader_driver,
435 			.download_aux_ucode = false,
436 		},
437 
438 		.max_radios = 1,
439 		.single_pdev_only = true,
440 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850,
441 		.internal_sleep_clock = true,
442 
443 		.hw_ops = &wcn7850_ops,
444 		.ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850,
445 
446 		.host_ce_config = ath12k_wifi7_host_ce_config_wcn7850,
447 		.ce_count = 9,
448 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850,
449 		.target_ce_count = 9,
450 		.svc_to_ce_map =
451 			ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850,
452 		.svc_to_ce_map_len = 14,
453 
454 		.rxdma1_enable = false,
455 		.num_rxdma_per_pdev = 2,
456 		.num_rxdma_dst_ring = 1,
457 		.rx_mac_buf_ring = true,
458 		.vdev_start_delay = true,
459 
460 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
461 				   BIT(NL80211_IFTYPE_AP) |
462 				   BIT(NL80211_IFTYPE_P2P_DEVICE) |
463 				   BIT(NL80211_IFTYPE_P2P_CLIENT) |
464 				   BIT(NL80211_IFTYPE_P2P_GO),
465 		.supports_monitor = true,
466 
467 		.idle_ps = true,
468 		.download_calib = false,
469 		.supports_suspend = true,
470 		.tcl_ring_retry = false,
471 		.reoq_lut_support = false,
472 		.supports_shadow_regs = true,
473 
474 		.num_tcl_banks = 7,
475 		.max_tx_ring = 3,
476 
477 		.mhi_config = &ath12k_wifi7_mhi_config_wcn7850,
478 
479 		.wmi_init = ath12k_wifi7_wmi_init_wcn7850,
480 
481 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
482 					   BIT(CNSS_PCIE_PERST_NO_PULL_V01),
483 
484 		.rfkill_pin = 48,
485 		.rfkill_cfg = 0,
486 		.rfkill_on_level = 1,
487 
488 		.rddm_size = 0x780000,
489 
490 		.def_num_link = 2,
491 		.max_mlo_peer = 32,
492 
493 		.otp_board_id_register = 0,
494 
495 		.supports_sta_ps = true,
496 
497 		.acpi_guid = &wcn7850_uuid,
498 		.supports_dynamic_smps_6ghz = false,
499 
500 		.iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
501 
502 		.supports_aspm = true,
503 
504 		.ce_ie_addr = NULL,
505 		.ce_remap = NULL,
506 		.bdf_addr_offset = 0,
507 
508 		.current_cc_support = true,
509 
510 		.dp_primary_link_only = false,
511 	},
512 	{
513 		.name = "qcn9274 hw2.0",
514 		.hw_rev = ATH12K_HW_QCN9274_HW20,
515 		.fw = {
516 			.dir = "QCN9274/hw2.0",
517 			.board_size = 256 * 1024,
518 			.cal_offset = 128 * 1024,
519 			.m3_loader = ath12k_m3_fw_loader_driver,
520 			.download_aux_ucode = false,
521 		},
522 		.max_radios = 2,
523 		.single_pdev_only = false,
524 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274,
525 		.internal_sleep_clock = false,
526 
527 		.hw_ops = &qcn9274_ops,
528 		.ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274,
529 
530 		.host_ce_config = ath12k_wifi7_host_ce_config_qcn9274,
531 		.ce_count = 16,
532 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274,
533 		.target_ce_count = 12,
534 		.svc_to_ce_map =
535 			ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274,
536 		.svc_to_ce_map_len = 18,
537 
538 		.rxdma1_enable = true,
539 		.num_rxdma_per_pdev = 1,
540 		.num_rxdma_dst_ring = 0,
541 		.rx_mac_buf_ring = false,
542 		.vdev_start_delay = false,
543 
544 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
545 					BIT(NL80211_IFTYPE_AP) |
546 					BIT(NL80211_IFTYPE_MESH_POINT) |
547 					BIT(NL80211_IFTYPE_AP_VLAN),
548 		.supports_monitor = true,
549 
550 		.idle_ps = false,
551 		.download_calib = true,
552 		.supports_suspend = false,
553 		.tcl_ring_retry = true,
554 		.reoq_lut_support = true,
555 		.supports_shadow_regs = false,
556 
557 		.num_tcl_banks = 48,
558 		.max_tx_ring = 4,
559 
560 		.mhi_config = &ath12k_wifi7_mhi_config_qcn9274,
561 
562 		.wmi_init = ath12k_wifi7_wmi_init_qcn9274,
563 
564 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
565 
566 		.rfkill_pin = 0,
567 		.rfkill_cfg = 0,
568 		.rfkill_on_level = 0,
569 
570 		.rddm_size = 0x600000,
571 
572 		.def_num_link = 0,
573 		.max_mlo_peer = 256,
574 
575 		.otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB,
576 
577 		.supports_sta_ps = false,
578 
579 		.acpi_guid = NULL,
580 		.supports_dynamic_smps_6ghz = true,
581 
582 		.iova_mask = 0,
583 
584 		.supports_aspm = false,
585 
586 		.ce_ie_addr = NULL,
587 		.ce_remap = NULL,
588 		.bdf_addr_offset = 0,
589 
590 		.current_cc_support = false,
591 
592 		.dp_primary_link_only = true,
593 	},
594 	{
595 		.name = "ipq5332 hw1.0",
596 		.hw_rev = ATH12K_HW_IPQ5332_HW10,
597 		.fw = {
598 			.dir = "IPQ5332/hw1.0",
599 			.board_size = 256 * 1024,
600 			.cal_offset = 128 * 1024,
601 			.m3_loader = ath12k_m3_fw_loader_remoteproc,
602 			.download_aux_ucode = false,
603 		},
604 		.max_radios = 1,
605 		.single_pdev_only = false,
606 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332,
607 		.internal_sleep_clock = false,
608 
609 		.hw_ops = &qcn9274_ops,
610 		.ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332,
611 
612 		.host_ce_config = ath12k_wifi7_host_ce_config_ipq5332,
613 		.ce_count = 12,
614 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332,
615 		.target_ce_count = 12,
616 		.svc_to_ce_map =
617 			ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332,
618 		.svc_to_ce_map_len = 18,
619 
620 		.rxdma1_enable = false,
621 		.num_rxdma_per_pdev = 1,
622 		.num_rxdma_dst_ring = 0,
623 		.rx_mac_buf_ring = false,
624 		.vdev_start_delay = false,
625 
626 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
627 				   BIT(NL80211_IFTYPE_AP) |
628 				   BIT(NL80211_IFTYPE_MESH_POINT),
629 		.supports_monitor = false,
630 
631 		.idle_ps = false,
632 		.download_calib = true,
633 		.supports_suspend = false,
634 		.tcl_ring_retry = true,
635 		.reoq_lut_support = false,
636 		.supports_shadow_regs = false,
637 
638 		.num_tcl_banks = 48,
639 		.max_tx_ring = 4,
640 
641 		.wmi_init = &ath12k_wifi7_wmi_init_qcn9274,
642 
643 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
644 
645 		.rfkill_pin = 0,
646 		.rfkill_cfg = 0,
647 		.rfkill_on_level = 0,
648 
649 		.rddm_size = 0,
650 
651 		.def_num_link = 0,
652 		.max_mlo_peer = 256,
653 
654 		.otp_board_id_register = 0,
655 
656 		.supports_sta_ps = false,
657 
658 		.acpi_guid = NULL,
659 		.supports_dynamic_smps_6ghz = false,
660 		.iova_mask = 0,
661 		.supports_aspm = false,
662 
663 		.ce_ie_addr = &ath12k_wifi7_ce_ie_addr_ipq5332,
664 		.ce_remap = &ath12k_wifi7_ce_remap_ipq5332,
665 		.bdf_addr_offset = 0xC00000,
666 
667 		.dp_primary_link_only = true,
668 	},
669 	{
670 		.name = "qcc2072 hw1.0",
671 		.hw_rev = ATH12K_HW_QCC2072_HW10,
672 
673 		.fw = {
674 			.dir = "QCC2072/hw1.0",
675 			.board_size = 256 * 1024,
676 			.cal_offset = 256 * 1024,
677 			.m3_loader = ath12k_m3_fw_loader_driver,
678 			.download_aux_ucode = true,
679 		},
680 
681 		.max_radios = 1,
682 		.single_pdev_only = true,
683 		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850,
684 		.internal_sleep_clock = true,
685 
686 		.hw_ops = &qcc2072_ops,
687 		.ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850,
688 
689 		.host_ce_config = ath12k_wifi7_host_ce_config_wcn7850,
690 		.ce_count = 9,
691 		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850,
692 		.target_ce_count = 9,
693 		.svc_to_ce_map =
694 			ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850,
695 		.svc_to_ce_map_len = 14,
696 
697 		.rxdma1_enable = false,
698 		.num_rxdma_per_pdev = 2,
699 		.num_rxdma_dst_ring = 1,
700 		.rx_mac_buf_ring = true,
701 		.vdev_start_delay = true,
702 
703 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
704 				   BIT(NL80211_IFTYPE_AP) |
705 				   BIT(NL80211_IFTYPE_P2P_DEVICE) |
706 				   BIT(NL80211_IFTYPE_P2P_CLIENT) |
707 				   BIT(NL80211_IFTYPE_P2P_GO),
708 		.supports_monitor = true,
709 
710 		.idle_ps = true,
711 		.download_calib = false,
712 		.supports_suspend = true,
713 		.tcl_ring_retry = false,
714 		.reoq_lut_support = false,
715 		.supports_shadow_regs = true,
716 
717 		.num_tcl_banks = 7,
718 		.max_tx_ring = 3,
719 
720 		.mhi_config = &ath12k_wifi7_mhi_config_wcn7850,
721 
722 		.wmi_init = ath12k_wifi7_wmi_init_wcn7850,
723 
724 		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
725 					   BIT(CNSS_PCIE_PERST_NO_PULL_V01) |
726 					   BIT(CNSS_AUX_UC_SUPPORT_V01),
727 
728 		.rfkill_pin = 0,
729 		.rfkill_cfg = 0,
730 		.rfkill_on_level = 0,
731 
732 		.rddm_size = 0x780000,
733 
734 		.def_num_link = 2,
735 		.max_mlo_peer = 32,
736 
737 		.otp_board_id_register = 0,
738 
739 		.supports_sta_ps = true,
740 
741 		.acpi_guid = &wcn7850_uuid,
742 		.supports_dynamic_smps_6ghz = false,
743 
744 		.iova_mask = 0,
745 
746 		.supports_aspm = true,
747 
748 		.ce_ie_addr = NULL,
749 		.ce_remap = NULL,
750 		.bdf_addr_offset = 0,
751 
752 		.current_cc_support = true,
753 
754 		.dp_primary_link_only = false,
755 	},
756 };
757 
758 /* Note: called under rcu_read_lock() */
759 static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
760 				   struct ieee80211_tx_control *control,
761 				   struct sk_buff *skb)
762 {
763 	struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
764 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
765 	struct ieee80211_vif *vif = info->control.vif;
766 	struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
767 	struct ath12k_link_vif *arvif = &ahvif->deflink;
768 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
769 	struct ieee80211_key_conf *key = info->control.hw_key;
770 	struct ieee80211_sta *sta = control->sta;
771 	struct ath12k_link_vif *tmp_arvif;
772 	u32 info_flags = info->flags;
773 	struct sk_buff *msdu_copied;
774 	struct ath12k *ar, *tmp_ar;
775 	struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev;
776 	struct ath12k_dp_link_peer *peer;
777 	unsigned long links_map;
778 	bool is_mcast = false;
779 	bool is_dvlan = false;
780 	struct ethhdr *eth;
781 	bool is_prb_rsp;
782 	u16 mcbc_gsn;
783 	u8 link_id;
784 	int ret;
785 	struct ath12k_dp *tmp_dp;
786 
787 	if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
788 		ieee80211_free_txskb(hw, skb);
789 		return;
790 	}
791 
792 	link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK);
793 	memset(skb_cb, 0, sizeof(*skb_cb));
794 	skb_cb->vif = vif;
795 
796 	if (key) {
797 		skb_cb->cipher = key->cipher;
798 		skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
799 	}
800 
801 	/* handle only for MLO case, use deflink for non MLO case */
802 	if (ieee80211_vif_is_mld(vif)) {
803 		link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags);
804 		if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) {
805 			ieee80211_free_txskb(hw, skb);
806 			return;
807 		}
808 	} else {
809 		if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
810 			link_id = ATH12K_FIRST_SCAN_LINK;
811 		else
812 			link_id = 0;
813 	}
814 
815 	arvif = rcu_dereference(ahvif->link[link_id]);
816 	if (!arvif || !arvif->ar) {
817 		ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission",
818 			    link_id);
819 		ieee80211_free_txskb(hw, skb);
820 		return;
821 	}
822 
823 	ar = arvif->ar;
824 	skb_cb->link_id = link_id;
825 	/*
826 	 * as skb_cb is common currently for dp and mgmt tx processing
827 	 * set this in the common mac op tx function.
828 	 */
829 	skb_cb->ar = ar;
830 	is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control);
831 
832 	if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
833 		eth = (struct ethhdr *)skb->data;
834 		is_mcast = is_multicast_ether_addr(eth->h_dest);
835 
836 		skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP;
837 	} else if (ieee80211_is_mgmt(hdr->frame_control)) {
838 		if (sta && sta->mlo)
839 			skb_cb->flags |= ATH12K_SKB_MLO_STA;
840 
841 		ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp);
842 		if (ret) {
843 			ath12k_warn(ar->ab, "failed to queue management frame %d\n",
844 				    ret);
845 			ieee80211_free_txskb(hw, skb);
846 		}
847 		return;
848 	}
849 
850 	if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
851 		is_mcast = is_multicast_ether_addr(hdr->addr1);
852 
853 	/* This is case only for P2P_GO */
854 	if (vif->type == NL80211_IFTYPE_AP && vif->p2p)
855 		ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp);
856 
857 	dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx);
858 	if (!dp_pdev) {
859 		ieee80211_free_txskb(hw, skb);
860 		return;
861 	}
862 
863 	/* Checking if it is a DVLAN frame */
864 	if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
865 	    !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) &&
866 	    !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) &&
867 	    ieee80211_has_protected(hdr->frame_control))
868 		is_dvlan = true;
869 
870 	if (!vif->valid_links || !is_mcast || is_dvlan ||
871 	    (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) ||
872 	    test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
873 		ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast);
874 		if (unlikely(ret)) {
875 			ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret);
876 			ieee80211_free_txskb(ar->ah->hw, skb);
877 			return;
878 		}
879 	} else {
880 		mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff;
881 
882 		links_map = ahvif->links_map;
883 		for_each_set_bit(link_id, &links_map,
884 				 IEEE80211_MLD_MAX_NUM_LINKS) {
885 			tmp_arvif = rcu_dereference(ahvif->link[link_id]);
886 			if (!tmp_arvif || !tmp_arvif->is_up)
887 				continue;
888 
889 			tmp_ar = tmp_arvif->ar;
890 			tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp,
891 							   tmp_ar->pdev_idx);
892 			if (!tmp_dp_pdev)
893 				continue;
894 			msdu_copied = skb_copy(skb, GFP_ATOMIC);
895 			if (!msdu_copied) {
896 				ath12k_err(ar->ab,
897 					   "skb copy failure link_id 0x%X vdevid 0x%X\n",
898 					   link_id, tmp_arvif->vdev_id);
899 				continue;
900 			}
901 
902 			ath12k_mlo_mcast_update_tx_link_address(vif, link_id,
903 								msdu_copied,
904 								info_flags);
905 
906 			skb_cb = ATH12K_SKB_CB(msdu_copied);
907 			skb_cb->link_id = link_id;
908 			skb_cb->vif = vif;
909 			skb_cb->ar = tmp_ar;
910 
911 			/* For open mode, skip peer find logic */
912 			if (unlikely(!ahvif->dp_vif.key_cipher))
913 				goto skip_peer_find;
914 
915 			tmp_dp = ath12k_ab_to_dp(tmp_ar->ab);
916 			spin_lock_bh(&tmp_dp->dp_lock);
917 			peer = ath12k_dp_link_peer_find_by_addr(tmp_dp,
918 								tmp_arvif->bssid);
919 			if (!peer || !peer->dp_peer) {
920 				spin_unlock_bh(&tmp_dp->dp_lock);
921 				ath12k_warn(tmp_ar->ab,
922 					    "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n",
923 					    tmp_arvif->vdev_id, tmp_arvif->bssid,
924 					    ahvif->links_map);
925 				dev_kfree_skb_any(msdu_copied);
926 				continue;
927 			}
928 
929 			key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx];
930 			if (key) {
931 				skb_cb->cipher = key->cipher;
932 				skb_cb->flags |= ATH12K_SKB_CIPHER_SET;
933 
934 				hdr = (struct ieee80211_hdr *)msdu_copied->data;
935 				if (!ieee80211_has_protected(hdr->frame_control))
936 					hdr->frame_control |=
937 						cpu_to_le16(IEEE80211_FCTL_PROTECTED);
938 			}
939 			spin_unlock_bh(&tmp_dp->dp_lock);
940 
941 skip_peer_find:
942 			ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif,
943 						 msdu_copied, true, mcbc_gsn, is_mcast);
944 			if (unlikely(ret)) {
945 				if (ret == -ENOMEM) {
946 					/* Drops are expected during heavy multicast
947 					 * frame flood. Print with debug log
948 					 * level to avoid lot of console prints
949 					 */
950 					ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
951 						   "failed to transmit frame %d\n",
952 						   ret);
953 				} else {
954 					ath12k_warn(ar->ab,
955 						    "failed to transmit frame %d\n",
956 						    ret);
957 				}
958 
959 				dev_kfree_skb_any(msdu_copied);
960 			}
961 		}
962 		ieee80211_free_txskb(ar->ah->hw, skb);
963 	}
964 }
965 
966 static const struct ieee80211_ops ath12k_ops_wifi7 = {
967 	.tx				= ath12k_wifi7_mac_op_tx,
968 	.wake_tx_queue			= ieee80211_handle_wake_tx_queue,
969 	.start                          = ath12k_mac_op_start,
970 	.stop                           = ath12k_mac_op_stop,
971 	.reconfig_complete              = ath12k_mac_op_reconfig_complete,
972 	.add_interface                  = ath12k_mac_op_add_interface,
973 	.remove_interface		= ath12k_mac_op_remove_interface,
974 	.update_vif_offload		= ath12k_mac_op_update_vif_offload,
975 	.config                         = ath12k_mac_op_config,
976 	.link_info_changed              = ath12k_mac_op_link_info_changed,
977 	.vif_cfg_changed		= ath12k_mac_op_vif_cfg_changed,
978 	.change_vif_links               = ath12k_mac_op_change_vif_links,
979 	.configure_filter		= ath12k_mac_op_configure_filter,
980 	.hw_scan                        = ath12k_mac_op_hw_scan,
981 	.cancel_hw_scan                 = ath12k_mac_op_cancel_hw_scan,
982 	.set_key                        = ath12k_mac_op_set_key,
983 	.set_rekey_data	                = ath12k_mac_op_set_rekey_data,
984 	.sta_state                      = ath12k_mac_op_sta_state,
985 	.sta_set_txpwr			= ath12k_mac_op_sta_set_txpwr,
986 	.link_sta_rc_update		= ath12k_mac_op_link_sta_rc_update,
987 	.conf_tx                        = ath12k_mac_op_conf_tx,
988 	.set_antenna			= ath12k_mac_op_set_antenna,
989 	.get_antenna			= ath12k_mac_op_get_antenna,
990 	.ampdu_action			= ath12k_mac_op_ampdu_action,
991 	.add_chanctx			= ath12k_mac_op_add_chanctx,
992 	.remove_chanctx			= ath12k_mac_op_remove_chanctx,
993 	.change_chanctx			= ath12k_mac_op_change_chanctx,
994 	.assign_vif_chanctx		= ath12k_mac_op_assign_vif_chanctx,
995 	.unassign_vif_chanctx		= ath12k_mac_op_unassign_vif_chanctx,
996 	.switch_vif_chanctx		= ath12k_mac_op_switch_vif_chanctx,
997 	.get_txpower			= ath12k_mac_op_get_txpower,
998 	.set_rts_threshold		= ath12k_mac_op_set_rts_threshold,
999 	.set_frag_threshold		= ath12k_mac_op_set_frag_threshold,
1000 	.set_bitrate_mask		= ath12k_mac_op_set_bitrate_mask,
1001 	.get_survey			= ath12k_mac_op_get_survey,
1002 	.flush				= ath12k_mac_op_flush,
1003 	.sta_statistics			= ath12k_mac_op_sta_statistics,
1004 	.link_sta_statistics		= ath12k_mac_op_link_sta_statistics,
1005 	.remain_on_channel              = ath12k_mac_op_remain_on_channel,
1006 	.cancel_remain_on_channel       = ath12k_mac_op_cancel_remain_on_channel,
1007 	.change_sta_links               = ath12k_mac_op_change_sta_links,
1008 	.can_activate_links             = ath12k_mac_op_can_activate_links,
1009 #ifdef CONFIG_PM
1010 	.suspend			= ath12k_wow_op_suspend,
1011 	.resume				= ath12k_wow_op_resume,
1012 	.set_wakeup			= ath12k_wow_op_set_wakeup,
1013 #endif
1014 #ifdef CONFIG_ATH12K_DEBUGFS
1015 	.vif_add_debugfs                = ath12k_debugfs_op_vif_add,
1016 #endif
1017 	CFG80211_TESTMODE_CMD(ath12k_tm_cmd)
1018 #ifdef CONFIG_ATH12K_DEBUGFS
1019 	.link_sta_add_debugfs           = ath12k_debugfs_link_sta_op_add,
1020 #endif
1021 };
1022 
1023 int ath12k_wifi7_hw_init(struct ath12k_base *ab)
1024 {
1025 	const struct ath12k_hw_params *hw_params = NULL;
1026 	int i;
1027 
1028 	for (i = 0; i < ARRAY_SIZE(ath12k_wifi7_hw_params); i++) {
1029 		hw_params = &ath12k_wifi7_hw_params[i];
1030 
1031 		if (hw_params->hw_rev == ab->hw_rev)
1032 			break;
1033 	}
1034 
1035 	if (i == ARRAY_SIZE(ath12k_wifi7_hw_params)) {
1036 		ath12k_err(ab, "Unsupported Wi-Fi 7 hardware version: 0x%x\n",
1037 			   ab->hw_rev);
1038 		return -EINVAL;
1039 	}
1040 
1041 	ab->hw_params = hw_params;
1042 	ab->ath12k_ops = &ath12k_ops_wifi7;
1043 
1044 	ath12k_wifi7_hal_init(ab);
1045 
1046 	ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name);
1047 
1048 	return 0;
1049 }
1050