1 /*
2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**
21 * DOC: defines DP interaction with FW using WMI
22 */
23
24 #include <qdf_status.h>
25 #include "target_if_dp.h"
26 #include <init_deinit_lmac.h>
27 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF
28 #include <wmi_unified_param.h>
29 #include <wlan_objmgr_peer_obj.h>
30 #endif
31
target_if_get_active_mac_phy_number(struct wlan_objmgr_psoc * psoc)32 uint32_t target_if_get_active_mac_phy_number(struct wlan_objmgr_psoc *psoc)
33 {
34 struct target_psoc_info *psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
35 struct target_supported_modes *hw_modes;
36 uint32_t i, phy_bit_map, mac_phy_cnt, max_mac_phy_cnt = 0;
37
38 if (!psoc_info) {
39 target_if_err("invalid psoc info");
40 return 0;
41 }
42 hw_modes = &psoc_info->info.hw_modes;
43 for (i = 0; i < hw_modes->num_modes; i++) {
44 phy_bit_map = hw_modes->phy_bit_map[i];
45 mac_phy_cnt = 0;
46 while (phy_bit_map) {
47 mac_phy_cnt++;
48 phy_bit_map &= (phy_bit_map - 1);
49 }
50 if (mac_phy_cnt > max_mac_phy_cnt)
51 max_mac_phy_cnt = mac_phy_cnt;
52 }
53
54 return max_mac_phy_cnt;
55 }
56
57 void
target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,uint8_t * peer_macaddr,uint8_t vdev_id,bool hash_based,uint8_t ring_num,uint8_t lmac_peer_id_msb)58 target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc *psoc,
59 uint8_t pdev_id, uint8_t *peer_macaddr,
60 uint8_t vdev_id,
61 bool hash_based, uint8_t ring_num,
62 uint8_t lmac_peer_id_msb)
63 {
64 uint32_t value;
65 struct peer_set_params param;
66 struct wmi_unified *pdev_wmi_handle;
67 struct wlan_objmgr_pdev *pdev =
68 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
69 pdev_id, WLAN_PDEV_TARGET_IF_ID);
70
71 if (!pdev) {
72 target_if_err("pdev with id %d is NULL", pdev_id);
73 return;
74 }
75
76 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
77 if (!pdev_wmi_handle) {
78 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
79 target_if_err("pdev wmi handle NULL");
80 return;
81 }
82
83 qdf_mem_zero(¶m, sizeof(param));
84
85 /* TODO: Need bit definitions for ring number and hash based routing
86 * fields in common wmi header file
87 */
88 value = ((hash_based) ? 1 : 0) | (ring_num << 1);
89
90 if (lmac_peer_id_msb)
91 QDF_SET_BITS(value, PEER_ROUTING_LMAC_ID_INDEX,
92 PEER_ROUTING_LMAC_ID_BITS, lmac_peer_id_msb);
93
94 param.param_id = WMI_HOST_PEER_SET_DEFAULT_ROUTING;
95 param.vdev_id = vdev_id;
96 param.param_value = value;
97
98 if (wmi_set_peer_param_send(pdev_wmi_handle, peer_macaddr, ¶m)) {
99 target_if_err("Unable to set default routing for peer "
100 QDF_MAC_ADDR_FMT,
101 QDF_MAC_ADDR_REF(peer_macaddr));
102 }
103 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
104 }
105
106 #ifdef SERIALIZE_QUEUE_SETUP
107 static QDF_STATUS
target_if_rx_reorder_queue_setup(struct scheduler_msg * msg)108 target_if_rx_reorder_queue_setup(struct scheduler_msg *msg)
109 {
110 struct rx_reorder_queue_setup_params param;
111 struct wmi_unified *pdev_wmi_handle;
112 struct reorder_q_setup *q_params;
113 QDF_STATUS status;
114 struct wlan_objmgr_pdev *pdev;
115 struct wlan_objmgr_psoc *psoc;
116
117 if (!(msg->bodyptr)) {
118 target_if_err("rx_reorder: Invalid message body");
119 return QDF_STATUS_E_INVAL;
120 }
121
122 q_params = msg->bodyptr;
123 psoc = (struct wlan_objmgr_psoc *)q_params->psoc;
124
125 pdev = wlan_objmgr_get_pdev_by_id(psoc, q_params->pdev_id,
126 WLAN_PDEV_TARGET_IF_ID);
127
128 if (!pdev) {
129 target_if_err("pdev with id %d is NULL", q_params->pdev_id);
130 return QDF_STATUS_E_INVAL;
131 }
132
133 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
134 if (!pdev_wmi_handle) {
135 target_if_err("pdev wmi handle NULL");
136 status = QDF_STATUS_E_FAILURE;
137 goto out;
138 }
139
140 param.tid = q_params->tid;
141 param.vdev_id = q_params->vdev_id;
142 param.peer_macaddr = q_params->peer_mac;
143 param.hw_qdesc_paddr_lo = q_params->hw_qdesc_paddr & 0xffffffff;
144 param.hw_qdesc_paddr_hi = (uint64_t)q_params->hw_qdesc_paddr >> 32;
145 param.queue_no = q_params->queue_no;
146 param.ba_window_size_valid = q_params->ba_window_size_valid;
147 param.ba_window_size = q_params->ba_window_size;
148
149 status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle,
150 ¶m);
151 out:
152 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
153 qdf_mem_free(q_params);
154
155 return status;
156 }
157
158 static QDF_STATUS
target_if_multi_rx_reorder_queue_setup(struct scheduler_msg * msg)159 target_if_multi_rx_reorder_queue_setup(struct scheduler_msg *msg)
160 {
161 struct multi_rx_reorder_queue_setup_params param = {0};
162 struct wmi_unified *pdev_wmi_handle;
163 struct multi_reorder_q_setup *q_params;
164 QDF_STATUS status;
165 struct wlan_objmgr_pdev *pdev;
166 struct wlan_objmgr_psoc *psoc;
167 int tid;
168
169 if (!(msg->bodyptr)) {
170 target_if_err("rx_reorder: Invalid message body");
171 return QDF_STATUS_E_INVAL;
172 }
173
174 q_params = msg->bodyptr;
175 psoc = (struct wlan_objmgr_psoc *)q_params->psoc;
176
177 pdev = wlan_objmgr_get_pdev_by_id(psoc, q_params->pdev_id,
178 WLAN_PDEV_TARGET_IF_ID);
179 if (!pdev) {
180 target_if_err("pdev with id %d is NULL", q_params->pdev_id);
181 return QDF_STATUS_E_INVAL;
182 }
183
184 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
185 if (!pdev_wmi_handle) {
186 target_if_err("pdev wmi handle NULL");
187 status = QDF_STATUS_E_FAILURE;
188 goto out;
189 }
190
191 param.tid_bitmap = q_params->tid_bitmap;
192 param.vdev_id = q_params->vdev_id;
193 param.peer_macaddr = q_params->peer_mac;
194 param.tid_num = q_params->tid_num;
195
196 for (tid = 0; tid < DP_MAX_TIDS; tid++) {
197 if (!(BIT(tid) & q_params->tid_bitmap))
198 continue;
199 param.queue_params_list[tid].hw_qdesc_paddr =
200 q_params->q_setup_list[tid].hw_qdesc_paddr;
201 param.queue_params_list[tid].queue_no =
202 q_params->q_setup_list[tid].queue_no;
203 param.queue_params_list[tid].ba_window_size_valid =
204 q_params->q_setup_list[tid].ba_window_size_valid;
205 param.queue_params_list[tid].ba_window_size =
206 q_params->q_setup_list[tid].ba_window_size;
207 }
208
209 status = wmi_unified_peer_multi_rx_reorder_queue_setup_send(
210 pdev_wmi_handle, ¶m);
211 out:
212 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
213 qdf_mem_free(q_params);
214
215 return status;
216 }
217
218 QDF_STATUS
target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,uint8_t vdev_id,uint8_t * peer_macaddr,qdf_dma_addr_t hw_qdesc,int tid,uint16_t queue_no,uint8_t ba_window_size_valid,uint16_t ba_window_size)219 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
220 uint8_t pdev_id,
221 uint8_t vdev_id, uint8_t *peer_macaddr,
222 qdf_dma_addr_t hw_qdesc, int tid,
223 uint16_t queue_no,
224 uint8_t ba_window_size_valid,
225 uint16_t ba_window_size)
226 {
227 struct scheduler_msg msg = {0};
228 struct reorder_q_setup *q_params;
229 QDF_STATUS status;
230
231 q_params = qdf_mem_malloc(sizeof(*q_params));
232 if (!q_params)
233 return QDF_STATUS_E_NOMEM;
234
235 q_params->psoc = psoc;
236 q_params->vdev_id = vdev_id;
237 q_params->pdev_id = pdev_id;
238 q_params->hw_qdesc_paddr = hw_qdesc;
239 q_params->tid = tid;
240 q_params->queue_no = queue_no;
241 q_params->ba_window_size_valid = ba_window_size_valid;
242 q_params->ba_window_size = ba_window_size;
243 qdf_mem_copy(q_params->peer_mac, peer_macaddr, QDF_MAC_ADDR_SIZE);
244
245 msg.bodyptr = q_params;
246 msg.callback = target_if_rx_reorder_queue_setup;
247 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
248 QDF_MODULE_ID_TARGET_IF,
249 QDF_MODULE_ID_TARGET_IF, &msg);
250
251 if (status != QDF_STATUS_SUCCESS)
252 qdf_mem_free(q_params);
253
254 return status;
255 }
256
257 QDF_STATUS
target_if_peer_multi_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,struct multi_rx_reorder_queue_setup_params * tid_params)258 target_if_peer_multi_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
259 uint8_t pdev_id,
260 struct multi_rx_reorder_queue_setup_params *tid_params)
261 {
262 struct scheduler_msg msg = {0};
263 struct multi_reorder_q_setup *q_params;
264 QDF_STATUS status;
265 int tid;
266
267 q_params = qdf_mem_malloc(sizeof(*q_params));
268 if (!q_params)
269 return QDF_STATUS_E_NOMEM;
270
271 q_params->psoc = psoc;
272 q_params->vdev_id = tid_params->vdev_id;
273 q_params->pdev_id = pdev_id;
274 q_params->tid_bitmap = tid_params->tid_bitmap;
275 q_params->tid_num = tid_params->tid_num;
276 qdf_mem_copy(q_params->peer_mac, tid_params->peer_macaddr,
277 QDF_MAC_ADDR_SIZE);
278
279 for (tid = 0; tid < DP_MAX_TIDS; tid++) {
280 if (!(BIT(tid) & tid_params->tid_bitmap))
281 continue;
282 q_params->q_setup_list[tid].hw_qdesc_paddr =
283 tid_params->queue_params_list[tid].hw_qdesc_paddr;
284 q_params->q_setup_list[tid].queue_no =
285 tid_params->queue_params_list[tid].queue_no;
286 q_params->q_setup_list[tid].ba_window_size_valid =
287 tid_params->queue_params_list[tid].ba_window_size_valid;
288 q_params->q_setup_list[tid].ba_window_size =
289 tid_params->queue_params_list[tid].ba_window_size;
290 }
291
292 msg.bodyptr = q_params;
293 msg.callback = target_if_multi_rx_reorder_queue_setup;
294 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
295 QDF_MODULE_ID_TARGET_IF,
296 QDF_MODULE_ID_TARGET_IF, &msg);
297
298 if (status != QDF_STATUS_SUCCESS)
299 qdf_mem_free(q_params);
300
301 return status;
302 }
303 #else
304 QDF_STATUS
target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,uint8_t vdev_id,uint8_t * peer_macaddr,qdf_dma_addr_t hw_qdesc,int tid,uint16_t queue_no,uint8_t ba_window_size_valid,uint16_t ba_window_size)305 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
306 uint8_t pdev_id,
307 uint8_t vdev_id, uint8_t *peer_macaddr,
308 qdf_dma_addr_t hw_qdesc, int tid,
309 uint16_t queue_no,
310 uint8_t ba_window_size_valid,
311 uint16_t ba_window_size)
312 {
313 struct rx_reorder_queue_setup_params param;
314 struct wmi_unified *pdev_wmi_handle;
315 QDF_STATUS status;
316 struct wlan_objmgr_pdev *pdev =
317 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
318 pdev_id, WLAN_PDEV_TARGET_IF_ID);
319
320 if (!pdev) {
321 target_if_err("pdev with id %d is NULL", pdev_id);
322 return QDF_STATUS_E_INVAL;
323 }
324
325 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
326 if (!pdev_wmi_handle) {
327 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
328 target_if_err("pdev wmi handle NULL");
329 return QDF_STATUS_E_FAILURE;
330 }
331 param.tid = tid;
332 param.vdev_id = vdev_id;
333 param.peer_macaddr = peer_macaddr;
334 param.hw_qdesc_paddr_lo = hw_qdesc & 0xffffffff;
335 param.hw_qdesc_paddr_hi = (uint64_t)hw_qdesc >> 32;
336 param.queue_no = queue_no;
337 param.ba_window_size_valid = ba_window_size_valid;
338 param.ba_window_size = ba_window_size;
339
340 status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle,
341 ¶m);
342 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
343
344 return status;
345 }
346
347 QDF_STATUS
target_if_peer_multi_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,struct multi_rx_reorder_queue_setup_params * tid_params)348 target_if_peer_multi_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
349 uint8_t pdev_id,
350 struct multi_rx_reorder_queue_setup_params *tid_params)
351 {
352 struct wmi_unified *pdev_wmi_handle;
353 QDF_STATUS status;
354 struct wlan_objmgr_pdev *pdev =
355 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
356 pdev_id, WLAN_PDEV_TARGET_IF_ID);
357 if (!pdev) {
358 target_if_err("pdev with id %d is NULL", pdev_id);
359 return QDF_STATUS_E_INVAL;
360 }
361
362 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
363 if (!pdev_wmi_handle) {
364 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
365 target_if_err("pdev wmi handle NULL");
366 return QDF_STATUS_E_FAILURE;
367 }
368
369 status = wmi_unified_peer_multi_rx_reorder_queue_setup_send(
370 pdev_wmi_handle, tid_params);
371 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
372
373 return status;
374 }
375 #endif
376
377 QDF_STATUS
target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,uint8_t vdev_id,uint8_t * peer_macaddr,uint32_t peer_tid_bitmap)378 target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_psoc *psoc,
379 uint8_t pdev_id,
380 uint8_t vdev_id, uint8_t *peer_macaddr,
381 uint32_t peer_tid_bitmap)
382 {
383 struct rx_reorder_queue_remove_params param;
384 struct wmi_unified *pdev_wmi_handle;
385 QDF_STATUS status;
386 struct wlan_objmgr_pdev *pdev =
387 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
388 pdev_id, WLAN_PDEV_TARGET_IF_ID);
389
390 if (!pdev) {
391 target_if_err("pdev with id %d is NULL", pdev_id);
392 return QDF_STATUS_E_INVAL;
393 }
394
395 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
396 if (!pdev_wmi_handle) {
397 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
398 target_if_err("pdev wmi handle NULL");
399 return QDF_STATUS_E_FAILURE;
400 }
401 param.vdev_id = vdev_id;
402 param.peer_macaddr = peer_macaddr;
403 param.peer_tid_bitmap = peer_tid_bitmap;
404 status = wmi_unified_peer_rx_reorder_queue_remove_send(pdev_wmi_handle,
405 ¶m);
406 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
407
408 return status;
409 }
410
411 QDF_STATUS
target_if_lro_hash_config(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,struct cdp_lro_hash_config * lro_hash_cfg)412 target_if_lro_hash_config(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id,
413 struct cdp_lro_hash_config *lro_hash_cfg)
414 {
415 struct wmi_lro_config_cmd_t wmi_lro_cmd = {0};
416 struct wmi_unified *pdev_wmi_handle;
417 QDF_STATUS status;
418 struct wlan_objmgr_pdev *pdev =
419 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
420 pdev_id, WLAN_PDEV_TARGET_IF_ID);
421
422 if (!pdev) {
423 target_if_err("pdev with id %d is NULL", pdev_id);
424 return QDF_STATUS_E_INVAL;
425 }
426
427 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
428 if (!lro_hash_cfg || !pdev_wmi_handle) {
429 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
430 target_if_err("wmi_handle: 0x%pK, lro_hash_cfg: 0x%pK",
431 pdev_wmi_handle, lro_hash_cfg);
432 return QDF_STATUS_E_FAILURE;
433 }
434
435 wmi_lro_cmd.lro_enable = lro_hash_cfg->lro_enable;
436 wmi_lro_cmd.tcp_flag = lro_hash_cfg->tcp_flag;
437 wmi_lro_cmd.tcp_flag_mask = lro_hash_cfg->tcp_flag_mask;
438 wmi_lro_cmd.pdev_id = pdev_id;
439
440 qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv4,
441 lro_hash_cfg->toeplitz_hash_ipv4,
442 LRO_IPV4_SEED_ARR_SZ * sizeof(uint32_t));
443
444 qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv6,
445 lro_hash_cfg->toeplitz_hash_ipv6,
446 LRO_IPV6_SEED_ARR_SZ * sizeof(uint32_t));
447
448 status = wmi_unified_lro_config_cmd(pdev_wmi_handle,
449 &wmi_lro_cmd);
450 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
451
452 return status;
453 }
454
455 #ifdef WLAN_SUPPORT_PPEDS
456 QDF_STATUS
target_if_peer_set_ppeds_default_routing(struct cdp_ctrl_objmgr_psoc * soc,uint8_t * peer_macaddr,uint16_t service_code,uint8_t priority_valid,uint16_t src_info,uint8_t vdev_id,uint8_t use_ppe,uint8_t ppe_routing_enabled)457 target_if_peer_set_ppeds_default_routing(struct cdp_ctrl_objmgr_psoc *soc,
458 uint8_t *peer_macaddr,
459 uint16_t service_code,
460 uint8_t priority_valid,
461 uint16_t src_info,
462 uint8_t vdev_id, uint8_t use_ppe,
463 uint8_t ppe_routing_enabled)
464 {
465 struct wmi_unified *pdev_wmi_handle;
466 struct wlan_objmgr_pdev *pdev;
467 struct wlan_objmgr_vdev *vdev;
468 struct peer_ppe_ds_param param;
469 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
470
471 struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)soc;
472 if (!psoc) {
473 target_if_err("PSOC is NULL!");
474 return QDF_STATUS_E_NULL_VALUE;
475 }
476 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
477 WLAN_WDS_ID);
478 if (!vdev) {
479 target_if_err("vdev with id %d is NULL", vdev_id);
480 return QDF_STATUS_E_INVAL;
481 }
482
483 pdev = wlan_vdev_get_pdev(vdev);
484
485 if (!pdev) {
486 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
487 target_if_err("pdev is NULL");
488 return QDF_STATUS_E_INVAL;
489 }
490
491 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
492 if (!pdev_wmi_handle) {
493 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
494 target_if_err("pdev_wmi_handle is NULL");
495 return QDF_STATUS_E_INVAL;
496 }
497
498 qdf_mem_zero(¶m, sizeof(param));
499
500 qdf_mem_copy(¶m.peer_macaddr[0], peer_macaddr, QDF_MAC_ADDR_SIZE);
501 param.ppe_routing_enabled = ppe_routing_enabled;
502 param.service_code = service_code;
503 param.priority_valid = priority_valid;
504 param.src_info = src_info;
505 param.vdev_id = vdev_id;
506 param.use_ppe = use_ppe;
507
508 qdf_status = wmi_unified_peer_ppe_ds_param_send(pdev_wmi_handle,
509 ¶m);
510 if (qdf_status != QDF_STATUS_SUCCESS) {
511 target_if_err("Unable to set PPE default routing for peer "
512 QDF_MAC_ADDR_FMT,
513 QDF_MAC_ADDR_REF(peer_macaddr));
514 }
515
516 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
517 return qdf_status;
518 }
519 #endif /* WLAN_SUPPORT_PPEDS */
520
521 #ifdef WDS_CONV_TARGET_IF_OPS_ENABLE
522 QDF_STATUS
target_if_add_wds_entry(struct cdp_ctrl_objmgr_psoc * soc,uint8_t vdev_id,uint8_t * peer_mac,const uint8_t * dest_mac,uint32_t flags,uint8_t type)523 target_if_add_wds_entry(struct cdp_ctrl_objmgr_psoc *soc, uint8_t vdev_id,
524 uint8_t *peer_mac, const uint8_t *dest_mac,
525 uint32_t flags, uint8_t type)
526 {
527 struct peer_add_wds_entry_params wmi_wds_param = {0};
528 struct wmi_unified *pdev_wmi_handle;
529 struct wlan_objmgr_pdev *pdev;
530 struct wlan_objmgr_vdev *vdev;
531 struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)soc;
532 QDF_STATUS status;
533
534 if (type == CDP_TXRX_AST_TYPE_WDS_HM_SEC)
535 return QDF_STATUS_E_FAILURE;
536
537 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
538 WLAN_WDS_ID);
539 if (!vdev) {
540 target_if_err("vdev with id %d is NULL", vdev_id);
541 return QDF_STATUS_E_INVAL;
542 }
543
544 pdev = wlan_vdev_get_pdev(vdev);
545 if (!pdev) {
546 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
547 target_if_err("pdev is NULL");
548 return QDF_STATUS_E_INVAL;
549 }
550
551 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
552 if (!pdev_wmi_handle) {
553 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
554 target_if_err("pdev_wmi_handle is NULL");
555 return QDF_STATUS_E_INVAL;
556 }
557
558 qdf_mem_copy(&wmi_wds_param.dest_addr, dest_mac, QDF_MAC_ADDR_SIZE);
559 qdf_mem_copy(&wmi_wds_param.peer_addr, peer_mac, QDF_MAC_ADDR_SIZE);
560 wmi_wds_param.vdev_id = vdev_id;
561 wmi_wds_param.flags = flags;
562
563 status = wmi_unified_peer_add_wds_entry_cmd(pdev_wmi_handle,
564 &wmi_wds_param);
565 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
566
567 return status;
568 }
569
570 void
target_if_del_wds_entry(struct cdp_ctrl_objmgr_psoc * soc,uint8_t vdev_id,uint8_t * dest_mac,uint8_t type,uint8_t delete_in_fw)571 target_if_del_wds_entry(struct cdp_ctrl_objmgr_psoc *soc, uint8_t vdev_id,
572 uint8_t *dest_mac, uint8_t type, uint8_t delete_in_fw)
573 {
574 struct peer_del_wds_entry_params wmi_wds_param = {0};
575 struct wmi_unified *pdev_wmi_handle;
576 struct wlan_objmgr_pdev *pdev;
577 struct wlan_objmgr_vdev *vdev;
578 struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)soc;
579
580 if (!delete_in_fw || type == CDP_TXRX_AST_TYPE_WDS_HM_SEC) {
581 target_if_err("delete_in_fw: %d type: %d", delete_in_fw, type);
582 return;
583 }
584
585 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
586 WLAN_WDS_ID);
587 if (!vdev) {
588 target_if_err("vdev with id %d is NULL", vdev_id);
589 return;
590 }
591
592 pdev = wlan_vdev_get_pdev(vdev);
593 if (!pdev) {
594 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
595 target_if_err("pdev is NULL");
596 return;
597 }
598
599 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
600 if (!pdev_wmi_handle) {
601 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
602 target_if_err("pdev_wmi_handle is NULL");
603 return;
604 }
605
606 qdf_mem_copy(&wmi_wds_param.dest_addr, dest_mac, QDF_MAC_ADDR_SIZE);
607 wmi_wds_param.vdev_id = vdev_id;
608
609 wmi_unified_peer_del_wds_entry_cmd(pdev_wmi_handle,
610 &wmi_wds_param);
611 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
612 }
613
614 QDF_STATUS
target_if_update_wds_entry(struct cdp_ctrl_objmgr_psoc * soc,uint8_t vdev_id,uint8_t * dest_mac,uint8_t * peer_mac,uint32_t flags)615 target_if_update_wds_entry(struct cdp_ctrl_objmgr_psoc *soc, uint8_t vdev_id,
616 uint8_t *dest_mac, uint8_t *peer_mac,
617 uint32_t flags)
618 {
619 struct peer_update_wds_entry_params wmi_wds_param = {0};
620 struct wmi_unified *pdev_wmi_handle;
621 struct wlan_objmgr_pdev *pdev;
622 struct wlan_objmgr_vdev *vdev;
623 struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)soc;
624 QDF_STATUS status;
625
626 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
627 WLAN_WDS_ID);
628 if (!vdev) {
629 target_if_err("vdev with id %d is NULL", vdev_id);
630 return QDF_STATUS_E_INVAL;
631 }
632
633 pdev = wlan_vdev_get_pdev(vdev);
634 if (!pdev) {
635 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
636 target_if_err("pdev is NULL");
637 return QDF_STATUS_E_INVAL;
638 }
639
640 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
641 if (!pdev_wmi_handle) {
642 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
643 target_if_err("pdev_wmi_handle is NULL");
644 return QDF_STATUS_E_INVAL;
645 }
646
647 qdf_mem_copy(&wmi_wds_param.dest_addr, dest_mac, QDF_MAC_ADDR_SIZE);
648 qdf_mem_copy(&wmi_wds_param.peer_addr, peer_mac, QDF_MAC_ADDR_SIZE);
649 wmi_wds_param.vdev_id = vdev_id;
650 wmi_wds_param.flags = flags;
651
652 status = wmi_unified_update_wds_entry_cmd(pdev_wmi_handle,
653 &wmi_wds_param);
654 wlan_objmgr_vdev_release_ref(vdev, WLAN_WDS_ID);
655
656 return status;
657 }
658 #endif
659
660 #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF
661 /**
662 * map_flush_policy() - Map DP layer flush policy values to target i/f layer
663 * @policy: The DP layer flush policy value
664 *
665 * Return: Peer flush policy
666 */
667 static enum peer_txq_flush_policy
map_flush_policy(enum cdp_peer_txq_flush_policy policy)668 map_flush_policy(enum cdp_peer_txq_flush_policy policy)
669 {
670 switch (policy) {
671 case CDP_PEER_TXQ_FLUSH_POLICY_NONE:
672 return PEER_TXQ_FLUSH_POLICY_NONE;
673 case CDP_PEER_TXQ_FLUSH_POLICY_TWT_SP_END:
674 return PEER_TXQ_FLUSH_POLICY_TWT_SP_END;
675 default:
676 return PEER_TXQ_FLUSH_POLICY_INVALID;
677 }
678 }
679
680 /**
681 * send_peer_txq_flush_conf() - Send flush config for peers TID queues
682 * @psoc: Opaque handle for posc object manager object
683 * @mac: MAC addr of peer for which the tx queue flush is intended
684 * @vdev_id: VDEV identifier
685 * @tid: TID mask for identifying the tx queues to be flushed
686 * @policy: The peer tid queue flush policy
687 *
688 * Return: 0 for success or error code
689 */
send_peer_txq_flush_conf(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t * mac,uint8_t vdev_id,uint32_t tid,enum cdp_peer_txq_flush_policy policy)690 static int send_peer_txq_flush_conf(struct cdp_ctrl_objmgr_psoc *psoc,
691 uint8_t *mac, uint8_t vdev_id,
692 uint32_t tid,
693 enum cdp_peer_txq_flush_policy policy)
694 {
695 struct wlan_objmgr_psoc *obj_soc;
696 struct wmi_unified *wmi_handle;
697 enum peer_txq_flush_policy flush_policy;
698 struct peer_txq_flush_config_params param = {0};
699 QDF_STATUS status;
700
701 obj_soc = (struct wlan_objmgr_psoc *)psoc;
702 wmi_handle = GET_WMI_HDL_FROM_PSOC(obj_soc);
703 if (!wmi_handle) {
704 target_if_err("Invalid wmi handle");
705 return -EINVAL;
706 }
707
708 flush_policy = map_flush_policy(policy);
709 if (flush_policy >= PEER_TXQ_FLUSH_POLICY_INVALID) {
710 target_if_err("Invalid flush policy : %d", policy);
711 return -EINVAL;
712 }
713
714 param.vdev_id = vdev_id;
715 param.tid_mask = tid;
716 param.policy = flush_policy;
717 qdf_mem_copy(param.peer, mac, QDF_MAC_ADDR_SIZE);
718
719 status = wmi_unified_peer_txq_flush_config_send(wmi_handle, ¶m);
720 return qdf_status_to_os_return(status);
721 }
722
723 /**
724 * send_peer_txq_flush_tids() - Send flush command peers TID queues
725 * @psoc: Opaque handle for psoc object manager object
726 * @mac: MAC addr of peer for which the tx queue flush is intended
727 * @vdev_id: VDEV identifier
728 * @tid: TID mask for identifying the tx queues to be flushed
729 *
730 * Return: 0 for success or error code
731 */
send_peer_txq_flush_tids(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t * mac,uint8_t vdev_id,uint32_t tid)732 static int send_peer_txq_flush_tids(struct cdp_ctrl_objmgr_psoc *psoc,
733 uint8_t *mac, uint8_t vdev_id,
734 uint32_t tid)
735 {
736 struct wlan_objmgr_psoc *obj_soc;
737 struct wmi_unified *wmi_handle;
738 struct peer_flush_params param;
739 QDF_STATUS status;
740
741 if (!psoc || !mac) {
742 target_if_err("Invalid params");
743 return -EINVAL;
744 }
745
746 obj_soc = (struct wlan_objmgr_psoc *)psoc;
747 wmi_handle = GET_WMI_HDL_FROM_PSOC(obj_soc);
748 if (!wmi_handle) {
749 target_if_err("Invalid wmi handle");
750 return -EINVAL;
751 }
752
753 param.vdev_id = vdev_id;
754 param.peer_tid_bitmap = tid;
755 qdf_mem_copy(param.peer_mac, mac, QDF_MAC_ADDR_SIZE);
756
757 status = wmi_unified_peer_flush_tids_send(wmi_handle, mac, ¶m);
758 return qdf_status_to_os_return(status);
759 }
760
target_if_peer_txq_flush_config(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t * addr,uint8_t ac,uint32_t tid,enum cdp_peer_txq_flush_policy policy)761 int target_if_peer_txq_flush_config(struct cdp_ctrl_objmgr_psoc *psoc,
762 uint8_t vdev_id, uint8_t *addr,
763 uint8_t ac, uint32_t tid,
764 enum cdp_peer_txq_flush_policy policy)
765 {
766 static uint8_t ac_to_tid[4][2] = { {0, 3}, {1, 2}, {4, 5}, {6, 7} };
767 struct wlan_objmgr_psoc *obj_soc;
768 struct wlan_objmgr_peer *peer;
769 int i, rc;
770
771 if (!psoc || !addr) {
772 target_if_err("Invalid params");
773 return -EINVAL;
774 }
775
776 if (!tid && !ac) {
777 target_if_err("no ac/tid mask setting");
778 return -EINVAL;
779 }
780
781 if (tid && policy == CDP_PEER_TXQ_FLUSH_POLICY_INVALID) {
782 target_if_err("Invalid flush policy");
783 return -EINVAL;
784 }
785 obj_soc = (struct wlan_objmgr_psoc *)psoc;
786
787 peer = wlan_objmgr_get_peer_by_mac(obj_soc, addr, WLAN_DP_ID);
788 if (!peer) {
789 target_if_err("Peer not found in the list");
790 return -EINVAL;
791 }
792 /* If tid mask is provided and policy is immediate use legacy WMI.
793 * If tid mask is provided and policy is other than immediate use
794 * the new WMI command for flush config.
795 * If tid mask is not provided and ac mask is provided, convert to tid,
796 * use the legacy WMI cmd for flushing the queues immediately.
797 */
798 if (tid) {
799 if (policy == CDP_PEER_TXQ_FLUSH_POLICY_IMMEDIATE) {
800 rc = send_peer_txq_flush_tids(psoc, addr, vdev_id, tid);
801 wlan_objmgr_peer_release_ref(peer, WLAN_DP_ID);
802 return rc;
803 }
804 rc = send_peer_txq_flush_conf(psoc, addr, vdev_id, tid, policy);
805 wlan_objmgr_peer_release_ref(peer, WLAN_DP_ID);
806 return rc;
807 }
808
809 if (ac) {
810 tid = 0;
811 for (i = 0; i < 4; ++i) {
812 if (((ac & 0x0f) >> i) & 0x01) {
813 tid |= (1 << ac_to_tid[i][0]) |
814 (1 << ac_to_tid[i][1]);
815 }
816 }
817 rc = send_peer_txq_flush_tids(psoc, addr, vdev_id, tid);
818 wlan_objmgr_peer_release_ref(peer, WLAN_DP_ID);
819 return rc;
820 }
821 /* should not hit this line */
822 return 0;
823 }
824 #endif
825