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.u.addba_resp.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 };
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() */
ath12k_wifi7_mac_op_tx(struct ieee80211_hw * hw,struct ieee80211_tx_control * control,struct sk_buff * skb)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
ath12k_wifi7_hw_init(struct ath12k_base * ab)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