1 /*
2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 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: wma_dev_if.c
22 * This file contains vdev & peer related operations.
23 */
24
25 /* Header files */
26
27 #include "wma.h"
28 #include "wma_api.h"
29 #include "cds_api.h"
30 #include "wmi_unified_api.h"
31 #include "wlan_qct_sys.h"
32 #include "wni_api.h"
33 #include "ani_global.h"
34 #include "wmi_unified.h"
35 #include "wni_cfg.h"
36
37 #include "qdf_nbuf.h"
38 #include "qdf_types.h"
39 #include "qdf_mem.h"
40
41 #include "wma_types.h"
42 #include "lim_api.h"
43 #include "lim_session_utils.h"
44 #include "wma_pasn_peer_api.h"
45
46 #include "cds_utils.h"
47
48 #if !defined(REMOVE_PKT_LOG)
49 #include "pktlog_ac.h"
50 #endif /* REMOVE_PKT_LOG */
51
52 #include "dbglog_host.h"
53 #include "csr_api.h"
54
55 #include "wma_internal.h"
56
57 #include "wma_ocb.h"
58 #include "cdp_txrx_cfg.h"
59 #include "cdp_txrx_flow_ctrl_legacy.h"
60 #include <cdp_txrx_peer_ops.h>
61 #include <cdp_txrx_cfg.h>
62 #include <cdp_txrx_cmn.h>
63 #include <cdp_txrx_misc.h>
64 #include <cdp_txrx_ctrl.h>
65
66 #include "wlan_policy_mgr_api.h"
67 #include "wma_nan_datapath.h"
68 #include "wifi_pos_pasn_api.h"
69 #if defined(CONFIG_HL_SUPPORT)
70 #include "wlan_tgt_def_config_hl.h"
71 #else
72 #include "wlan_tgt_def_config.h"
73 #endif
74 #include <wlan_dfs_tgt_api.h>
75 #include <cdp_txrx_handle.h>
76 #include "wlan_pmo_ucfg_api.h"
77 #include "wlan_reg_services_api.h"
78 #include <include/wlan_vdev_mlme.h>
79 #include "wma_he.h"
80 #include "wma_eht.h"
81 #include "wlan_roam_debug.h"
82 #include "wlan_ocb_ucfg_api.h"
83 #include "init_deinit_lmac.h"
84 #include <target_if.h>
85 #include "wlan_policy_mgr_ucfg.h"
86 #include "wlan_mlme_public_struct.h"
87 #include "wlan_mlme_api.h"
88 #include "wlan_mlme_main.h"
89 #include "wlan_mlme_ucfg_api.h"
90 #include "wlan_mlme_twt_api.h"
91 #include <wlan_dfs_utils_api.h>
92 #include "../../core/src/vdev_mgr_ops.h"
93 #include "wlan_utility.h"
94 #include "wlan_coex_ucfg_api.h"
95 #include <wlan_cp_stats_mc_ucfg_api.h>
96 #include "wmi_unified_vdev_api.h"
97 #include <wlan_cm_api.h>
98 #include <../../core/src/wlan_cm_vdev_api.h>
99 #include "wlan_nan_api.h"
100 #include "wlan_mlo_mgr_peer.h"
101 #include "wifi_pos_api.h"
102 #include "wifi_pos_pasn_api.h"
103 #ifdef DCS_INTERFERENCE_DETECTION
104 #include <wlan_dcs_ucfg_api.h>
105 #endif
106
107 #ifdef FEATURE_STA_MODE_VOTE_LINK
108 #include "wlan_ipa_ucfg_api.h"
109 #endif
110
111 #include "son_api.h"
112 #include "wlan_vdev_mgr_tgt_if_tx_defs.h"
113 #include "wlan_mlo_mgr_roam.h"
114 #include "target_if_vdev_mgr_tx_ops.h"
115 #include "wlan_fwol_ucfg_api.h"
116 #include "wlan_vdev_mgr_utils_api.h"
117 #include "target_if.h"
118 #include <wlan_psoc_mlme_api.h>
119
120 /*
121 * FW only supports 8 clients in SAP/GO mode for D3 WoW feature
122 * and hence host needs to hold a wake lock after 9th client connects
123 * and release the wake lock when 9th client disconnects
124 */
125 #define SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK (9)
126 #define SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK (8)
127
wma_find_vdev_id_by_addr(tp_wma_handle wma,uint8_t * addr,uint8_t * vdev_id)128 QDF_STATUS wma_find_vdev_id_by_addr(tp_wma_handle wma, uint8_t *addr,
129 uint8_t *vdev_id)
130 {
131 uint8_t i;
132 struct wlan_objmgr_vdev *vdev;
133
134 for (i = 0; i < wma->max_bssid; i++) {
135 vdev = wma->interfaces[i].vdev;
136 if (!vdev)
137 continue;
138
139 if (qdf_is_macaddr_equal(
140 (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev),
141 (struct qdf_mac_addr *)addr) == true) {
142 *vdev_id = i;
143 return QDF_STATUS_SUCCESS;
144 }
145
146 if (qdf_is_macaddr_equal((struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev),
147 (struct qdf_mac_addr *)addr) == true) {
148 *vdev_id = i;
149 return QDF_STATUS_SUCCESS;
150 }
151 }
152
153 return QDF_STATUS_E_FAILURE;
154 }
155
156
157 /**
158 * wma_is_vdev_in_ap_mode() - check that vdev is in ap mode or not
159 * @wma: wma handle
160 * @vdev_id: vdev id
161 *
162 * Helper function to know whether given vdev id
163 * is in AP mode or not.
164 *
165 * Return: True/False
166 */
wma_is_vdev_in_ap_mode(tp_wma_handle wma,uint8_t vdev_id)167 bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id)
168 {
169 struct wma_txrx_node *intf = wma->interfaces;
170
171 if (vdev_id >= wma->max_bssid) {
172 wma_err("Invalid vdev_id %hu", vdev_id);
173 QDF_ASSERT(0);
174 return false;
175 }
176
177 if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
178 ((intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) ||
179 (intf[vdev_id].sub_type == 0)))
180 return true;
181
182 return false;
183 }
184
wma_get_vdev_bssid(struct wlan_objmgr_vdev * vdev)185 uint8_t *wma_get_vdev_bssid(struct wlan_objmgr_vdev *vdev)
186 {
187 struct vdev_mlme_obj *mlme_obj;
188
189 if (!vdev) {
190 wma_err("vdev is NULL");
191 return NULL;
192 }
193
194 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
195 if (!mlme_obj) {
196 wma_err("Failed to get mlme_obj");
197 return NULL;
198 }
199
200 return mlme_obj->mgmt.generic.bssid;
201 }
202
wma_find_vdev_id_by_bssid(tp_wma_handle wma,uint8_t * bssid,uint8_t * vdev_id)203 QDF_STATUS wma_find_vdev_id_by_bssid(tp_wma_handle wma, uint8_t *bssid,
204 uint8_t *vdev_id)
205 {
206 int i;
207 uint8_t *bssid_addr;
208
209 for (i = 0; i < wma->max_bssid; i++) {
210 if (!wma->interfaces[i].vdev)
211 continue;
212 bssid_addr = wma_get_vdev_bssid(wma->interfaces[i].vdev);
213 if (!bssid_addr)
214 continue;
215
216 if (qdf_is_macaddr_equal(
217 (struct qdf_mac_addr *)bssid_addr,
218 (struct qdf_mac_addr *)bssid) == true) {
219 *vdev_id = i;
220 return QDF_STATUS_SUCCESS;
221 }
222 }
223
224 return QDF_STATUS_E_FAILURE;
225 }
226
227 /**
228 * wma_find_req_on_timer_expiry() - find request by address
229 * @wma: wma handle
230 * @req: pointer to the target request
231 *
232 * On timer expiry, the pointer to the req message is received from the
233 * timer callback. Lookup the wma_hold_req_queue for the request with the
234 * same address and return success if found.
235 *
236 * Return: QDF_STATUS
237 */
wma_find_req_on_timer_expiry(tp_wma_handle wma,struct wma_target_req * req)238 static QDF_STATUS wma_find_req_on_timer_expiry(tp_wma_handle wma,
239 struct wma_target_req *req)
240 {
241 struct wma_target_req *req_msg = NULL;
242 bool found = false;
243 qdf_list_node_t *cur_node = NULL, *next_node = NULL;
244 QDF_STATUS status;
245
246 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
247 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
248 &next_node)) {
249 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
250 wma_err("unable to get msg node from request queue");
251 return QDF_STATUS_E_FAILURE;
252 }
253
254 do {
255 cur_node = next_node;
256 req_msg = qdf_container_of(cur_node,
257 struct wma_target_req, node);
258 if (req_msg != req)
259 continue;
260
261 found = true;
262 status = qdf_list_remove_node(&wma->wma_hold_req_queue,
263 cur_node);
264 if (QDF_STATUS_SUCCESS != status) {
265 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
266 wma_debug("Failed to remove request for req %pK", req);
267 return QDF_STATUS_E_FAILURE;
268 }
269 break;
270 } while (QDF_STATUS_SUCCESS ==
271 qdf_list_peek_next(&wma->wma_hold_req_queue,
272 cur_node, &next_node));
273
274 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
275 if (!found) {
276 wma_err("target request not found for req %pK", req);
277 return QDF_STATUS_E_INVAL;
278 }
279
280 wma_debug("target request found for vdev id: %d type %d",
281 req_msg->vdev_id, req_msg->type);
282
283 return QDF_STATUS_SUCCESS;
284 }
285
286 /**
287 * wma_find_req() - find target request for vdev id
288 * @wma: wma handle
289 * @vdev_id: vdev id
290 * @type: request type
291 * @peer_addr: Peer mac address
292 *
293 * Find target request for given vdev id & type of request.
294 * Remove that request from active list.
295 *
296 * Return: return target request if found or NULL.
297 */
wma_find_req(tp_wma_handle wma,uint8_t vdev_id,uint8_t type,struct qdf_mac_addr * peer_addr)298 static struct wma_target_req *wma_find_req(tp_wma_handle wma,
299 uint8_t vdev_id, uint8_t type,
300 struct qdf_mac_addr *peer_addr)
301 {
302 struct wma_target_req *req_msg = NULL;
303 bool found = false;
304 qdf_list_node_t *node1 = NULL, *node2 = NULL;
305 QDF_STATUS status;
306
307 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
308 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
309 &node2)) {
310 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
311 wma_err("unable to get msg node from request queue");
312 return NULL;
313 }
314
315 do {
316 node1 = node2;
317 req_msg = qdf_container_of(node1, struct wma_target_req, node);
318 if (req_msg->vdev_id != vdev_id)
319 continue;
320 if (req_msg->type != type)
321 continue;
322
323 found = true;
324 if (type == WMA_PEER_CREATE_RESPONSE &&
325 peer_addr &&
326 !qdf_is_macaddr_equal(&req_msg->addr, peer_addr))
327 found = false;
328
329 status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
330 if (QDF_STATUS_SUCCESS != status) {
331 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
332 wma_debug("Failed to remove request for vdev_id %d type %d",
333 vdev_id, type);
334 return NULL;
335 }
336 break;
337 } while (QDF_STATUS_SUCCESS ==
338 qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
339 &node2));
340
341 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
342 if (!found) {
343 wma_err("target request not found for vdev_id %d type %d",
344 vdev_id, type);
345 return NULL;
346 }
347
348 wma_debug("target request found for vdev id: %d type %d",
349 vdev_id, type);
350
351 return req_msg;
352 }
353
wma_find_remove_req_msgtype(tp_wma_handle wma,uint8_t vdev_id,uint32_t msg_type)354 struct wma_target_req *wma_find_remove_req_msgtype(tp_wma_handle wma,
355 uint8_t vdev_id,
356 uint32_t msg_type)
357 {
358 struct wma_target_req *req_msg = NULL;
359 bool found = false;
360 qdf_list_node_t *node1 = NULL, *node2 = NULL;
361 QDF_STATUS status;
362
363 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
364 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
365 &node2)) {
366 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
367 wma_debug("unable to get msg node from request queue for vdev_id %d type %d",
368 vdev_id, msg_type);
369 return NULL;
370 }
371
372 do {
373 node1 = node2;
374 req_msg = qdf_container_of(node1, struct wma_target_req, node);
375 if (req_msg->vdev_id != vdev_id)
376 continue;
377 if (req_msg->msg_type != msg_type)
378 continue;
379
380 found = true;
381 status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
382 if (QDF_STATUS_SUCCESS != status) {
383 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
384 wma_debug("Failed to remove request. vdev_id %d type %d",
385 vdev_id, msg_type);
386 return NULL;
387 }
388 break;
389 } while (QDF_STATUS_SUCCESS ==
390 qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
391 &node2));
392
393 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
394 if (!found) {
395 wma_debug("target request not found for vdev_id %d type %d",
396 vdev_id, msg_type);
397 return NULL;
398 }
399
400 wma_debug("target request found for vdev id: %d type %d",
401 vdev_id, msg_type);
402
403 return req_msg;
404 }
405
wma_vdev_detach_callback(struct vdev_delete_response * rsp)406 QDF_STATUS wma_vdev_detach_callback(struct vdev_delete_response *rsp)
407 {
408 tp_wma_handle wma;
409 struct wma_txrx_node *iface = NULL;
410
411 wma = cds_get_context(QDF_MODULE_ID_WMA);
412 if (!wma)
413 return QDF_STATUS_E_FAILURE;
414
415 /* Sanitize the vdev id*/
416 if (rsp->vdev_id >= wma->max_bssid) {
417 wma_err("vdev delete response with invalid vdev_id :%d",
418 rsp->vdev_id);
419 QDF_BUG(0);
420 return QDF_STATUS_E_FAILURE;
421 }
422
423 iface = &wma->interfaces[rsp->vdev_id];
424
425 wma_debug("vdev del response received for VDEV_%d", rsp->vdev_id);
426 iface->del_staself_req = NULL;
427
428 if (iface->roam_scan_stats_req) {
429 struct sir_roam_scan_stats *roam_scan_stats_req =
430 iface->roam_scan_stats_req;
431
432 iface->roam_scan_stats_req = NULL;
433 qdf_mem_free(roam_scan_stats_req);
434 }
435
436 wma_vdev_deinit(iface);
437 qdf_mem_zero(iface, sizeof(*iface));
438 wma_vdev_init(iface);
439
440 mlme_vdev_del_resp(rsp->vdev_id);
441
442 return QDF_STATUS_SUCCESS;
443 }
444
445 static void
wma_cdp_vdev_detach(ol_txrx_soc_handle soc,tp_wma_handle wma_handle,uint8_t vdev_id)446 wma_cdp_vdev_detach(ol_txrx_soc_handle soc, tp_wma_handle wma_handle,
447 uint8_t vdev_id)
448 {
449 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
450 struct wlan_objmgr_vdev *vdev = iface->vdev;
451
452 if (!vdev) {
453 wma_err("vdev is NULL");
454 return;
455 }
456
457 if (soc && wlan_vdev_get_id(vdev) != WLAN_INVALID_VDEV_ID)
458 cdp_vdev_detach(soc, vdev_id, NULL, NULL);
459 }
460
461 /**
462 * wma_release_vdev_ref() - Release vdev object reference count
463 * @iface: wma interface txrx node
464 *
465 * Purpose of this function is to release vdev object reference count
466 * from wma interface txrx node.
467 *
468 * Return: None
469 */
470 static void
wma_release_vdev_ref(struct wma_txrx_node * iface)471 wma_release_vdev_ref(struct wma_txrx_node *iface)
472 {
473 struct wlan_objmgr_vdev *vdev;
474
475 vdev = iface->vdev;
476 if (!vdev) {
477 wma_debug("vdev context is NULL");
478 return;
479 }
480 wma_debug("vdev state: %d", vdev->obj_state);
481 if (vdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
482 wma_debug("no vdev delete");
483 return;
484 }
485 iface->vdev_active = false;
486 iface->vdev = NULL;
487 if (vdev)
488 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
489 }
490
491 /**
492 * wma_handle_monitor_mode_vdev_detach() - Stop and down monitor mode vdev
493 * @wma: wma handle
494 * @vdev_id: used to get wma interface txrx node
495 *
496 * Monitor mode is unconneted mode, so do explicit vdev stop and down
497 *
498 * Return: None
499 */
wma_handle_monitor_mode_vdev_detach(tp_wma_handle wma,uint8_t vdev_id)500 static void wma_handle_monitor_mode_vdev_detach(tp_wma_handle wma,
501 uint8_t vdev_id)
502 {
503 struct wma_txrx_node *iface;
504
505 iface = &wma->interfaces[vdev_id];
506 wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
507 WLAN_VDEV_SM_EV_DOWN,
508 0, NULL);
509 iface->vdev_active = false;
510 }
511
512 /**
513 * wma_handle_vdev_detach() - wma vdev detach handler
514 * @wma_handle: pointer to wma handle
515 * @del_vdev_req_param: pointer to del req param
516 *
517 * Return: none.
518 */
wma_handle_vdev_detach(tp_wma_handle wma_handle,struct del_vdev_params * del_vdev_req_param)519 static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
520 struct del_vdev_params *del_vdev_req_param)
521 {
522 QDF_STATUS status = QDF_STATUS_SUCCESS;
523 uint8_t vdev_id = del_vdev_req_param->vdev_id;
524 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
525 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
526 struct wmi_mgmt_params mgmt_params = {};
527
528 if (!soc) {
529 status = QDF_STATUS_E_FAILURE;
530 goto rel_ref;
531 }
532
533 if ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) ||
534 (policy_mgr_is_sta_mon_concurrency(wma_handle->psoc) &&
535 wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_MONITOR_MODE))
536 wma_handle_monitor_mode_vdev_detach(wma_handle, vdev_id);
537
538 rel_ref:
539 wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
540 if (qdf_is_recovering())
541 wlan_mgmt_txrx_vdev_drain(iface->vdev,
542 wma_mgmt_frame_fill_peer_cb,
543 &mgmt_params);
544 wma_debug("Releasing wma reference for vdev:%d", vdev_id);
545 wma_release_vdev_ref(iface);
546 return status;
547 }
548
549 /**
550 * wma_self_peer_remove() - Self peer remove handler
551 * @wma_handle: wma handle
552 * @del_vdev_req: vdev id
553 *
554 * Return: success if peer delete command sent to firmware, else failure.
555 */
wma_self_peer_remove(tp_wma_handle wma_handle,struct del_vdev_params * del_vdev_req)556 static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle,
557 struct del_vdev_params *del_vdev_req)
558 {
559 QDF_STATUS qdf_status;
560 uint8_t vdev_id = del_vdev_req->vdev_id;
561 struct wma_target_req *msg = NULL;
562 struct del_sta_self_rsp_params *sta_self_wmi_rsp = NULL;
563
564 wma_debug("P2P Device: removing self peer "QDF_MAC_ADDR_FMT,
565 QDF_MAC_ADDR_REF(del_vdev_req->self_mac_addr));
566
567 if (wmi_service_enabled(wma_handle->wmi_handle,
568 wmi_service_sync_delete_cmds)) {
569 sta_self_wmi_rsp =
570 qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params));
571 if (!sta_self_wmi_rsp) {
572 qdf_status = QDF_STATUS_E_NOMEM;
573 goto error;
574 }
575
576 sta_self_wmi_rsp->self_sta_param = del_vdev_req;
577 msg = wma_fill_hold_req(wma_handle, vdev_id,
578 WMA_DELETE_STA_REQ,
579 WMA_DEL_P2P_SELF_STA_RSP_START,
580 sta_self_wmi_rsp,
581 WMA_DELETE_STA_TIMEOUT);
582 if (!msg) {
583 wma_err("Failed to allocate request for vdev_id %d",
584 vdev_id);
585 wma_remove_req(wma_handle, vdev_id,
586 WMA_DEL_P2P_SELF_STA_RSP_START);
587 qdf_mem_free(sta_self_wmi_rsp);
588 qdf_status = QDF_STATUS_E_FAILURE;
589 goto error;
590 }
591 }
592
593 qdf_status = wma_remove_peer(wma_handle, del_vdev_req->self_mac_addr,
594 vdev_id, false);
595 if (QDF_IS_STATUS_ERROR(qdf_status)) {
596 wma_err("wma_remove_peer is failed");
597 wma_remove_req(wma_handle, vdev_id,
598 WMA_DEL_P2P_SELF_STA_RSP_START);
599 if (sta_self_wmi_rsp)
600 qdf_mem_free(sta_self_wmi_rsp);
601
602 goto error;
603 }
604
605 error:
606 return qdf_status;
607 }
608
609 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
wma_p2p_self_peer_remove(struct wlan_objmgr_vdev * vdev)610 QDF_STATUS wma_p2p_self_peer_remove(struct wlan_objmgr_vdev *vdev)
611 {
612 struct del_vdev_params *del_self_peer_req;
613 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
614 QDF_STATUS status;
615
616 if (!wma_handle)
617 return QDF_STATUS_E_INVAL;
618
619 del_self_peer_req = qdf_mem_malloc(sizeof(*del_self_peer_req));
620 if (!del_self_peer_req)
621 return QDF_STATUS_E_NOMEM;
622
623 del_self_peer_req->vdev = vdev;
624 del_self_peer_req->vdev_id = wlan_vdev_get_id(vdev);
625 qdf_mem_copy(del_self_peer_req->self_mac_addr,
626 wlan_vdev_mlme_get_macaddr(vdev),
627 QDF_MAC_ADDR_SIZE);
628
629 status = wma_self_peer_remove(wma_handle, del_self_peer_req);
630
631 return status;
632 }
633 #endif
634
wma_remove_objmgr_peer(tp_wma_handle wma,struct wlan_objmgr_vdev * obj_vdev,uint8_t * peer_addr)635 void wma_remove_objmgr_peer(tp_wma_handle wma,
636 struct wlan_objmgr_vdev *obj_vdev,
637 uint8_t *peer_addr)
638 {
639 struct wlan_objmgr_psoc *psoc;
640 struct wlan_objmgr_peer *obj_peer;
641 struct wlan_objmgr_pdev *obj_pdev;
642 uint8_t pdev_id = 0;
643
644 psoc = wma->psoc;
645 if (!psoc) {
646 wma_err("PSOC is NULL");
647 return;
648 }
649
650 obj_pdev = wlan_vdev_get_pdev(obj_vdev);
651 pdev_id = wlan_objmgr_pdev_get_pdev_id(obj_pdev);
652 obj_peer = wlan_objmgr_get_peer(psoc, pdev_id, peer_addr,
653 WLAN_LEGACY_WMA_ID);
654 if (obj_peer) {
655 wlan_objmgr_peer_obj_delete(obj_peer);
656 /* Unref to decrement ref happened in find_peer */
657 wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID);
658 } else {
659 wma_nofl_err("Peer "QDF_MAC_ADDR_FMT" not found",
660 QDF_MAC_ADDR_REF(peer_addr));
661 }
662
663 }
664
wma_check_for_deferred_peer_delete(tp_wma_handle wma_handle,struct del_vdev_params * pdel_vdev_req_param)665 static QDF_STATUS wma_check_for_deferred_peer_delete(tp_wma_handle wma_handle,
666 struct del_vdev_params
667 *pdel_vdev_req_param)
668 {
669 QDF_STATUS status = QDF_STATUS_SUCCESS;
670 uint8_t vdev_id = pdel_vdev_req_param->vdev_id;
671 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
672 uint32_t vdev_stop_type;
673
674 if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) {
675 status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
676 if (QDF_IS_STATUS_ERROR(status)) {
677 wma_err("Failed to get wma req msg_type for vdev_id: %d",
678 vdev_id);
679 status = QDF_STATUS_E_INVAL;
680 return status;
681 }
682
683 if (vdev_stop_type != WMA_DELETE_BSS_REQ) {
684 status = QDF_STATUS_E_INVAL;
685 return status;
686 }
687
688 wma_debug("BSS is not yet stopped. Deferring vdev(vdev id %x) deletion",
689 vdev_id);
690 iface->del_staself_req = pdel_vdev_req_param;
691 iface->is_del_sta_deferred = true;
692 }
693
694 return status;
695 }
696
697 static QDF_STATUS
wma_vdev_self_peer_delete(tp_wma_handle wma_handle,struct del_vdev_params * pdel_vdev_req_param)698 wma_vdev_self_peer_delete(tp_wma_handle wma_handle,
699 struct del_vdev_params *pdel_vdev_req_param)
700 {
701 QDF_STATUS status = QDF_STATUS_SUCCESS;
702 uint8_t vdev_id = pdel_vdev_req_param->vdev_id;
703 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
704
705 if (mlme_vdev_uses_self_peer(iface->type, iface->sub_type)) {
706 status = wma_self_peer_remove(wma_handle, pdel_vdev_req_param);
707 if (QDF_IS_STATUS_ERROR(status)) {
708 wma_err("can't remove selfpeer, send rsp session: %d",
709 vdev_id);
710 wma_handle_vdev_detach(wma_handle, pdel_vdev_req_param);
711 mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param);
712 cds_trigger_recovery(QDF_SELF_PEER_DEL_FAILED);
713 return status;
714 }
715 } else if (iface->type == WMI_VDEV_TYPE_STA ||
716 iface->type == WMI_VDEV_TYPE_NAN) {
717 wma_remove_objmgr_peer(wma_handle, iface->vdev,
718 pdel_vdev_req_param->self_mac_addr);
719 }
720
721 return status;
722 }
723
wma_vdev_detach(struct del_vdev_params * pdel_vdev_req_param)724 QDF_STATUS wma_vdev_detach(struct del_vdev_params *pdel_vdev_req_param)
725 {
726 QDF_STATUS status = QDF_STATUS_SUCCESS;
727 uint8_t vdev_id;
728 struct wma_txrx_node *iface = NULL;
729 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
730
731 if (!wma_handle)
732 return QDF_STATUS_E_INVAL;
733
734 vdev_id = wlan_vdev_get_id(pdel_vdev_req_param->vdev);
735 iface = &wma_handle->interfaces[vdev_id];
736 if (!iface->vdev) {
737 wma_err("vdev %d is NULL", vdev_id);
738 return status;
739 }
740
741 status = wma_check_for_deferred_peer_delete(wma_handle,
742 pdel_vdev_req_param);
743 if (QDF_IS_STATUS_ERROR(status))
744 goto send_fail_rsp;
745
746 if (iface->is_del_sta_deferred)
747 return status;
748
749 iface->is_del_sta_deferred = false;
750 iface->del_staself_req = NULL;
751
752 status = wma_vdev_self_peer_delete(wma_handle, pdel_vdev_req_param);
753 if (QDF_IS_STATUS_ERROR(status)) {
754 wma_err("Failed to send self peer delete:%d", status);
755 status = QDF_STATUS_E_INVAL;
756 return status;
757 }
758
759 if (iface->type != WMI_VDEV_TYPE_MONITOR)
760 iface->vdev_active = false;
761
762 if (!mlme_vdev_uses_self_peer(iface->type, iface->sub_type) ||
763 !wmi_service_enabled(wma_handle->wmi_handle,
764 wmi_service_sync_delete_cmds)) {
765 status = wma_handle_vdev_detach(wma_handle,
766 pdel_vdev_req_param);
767 pdel_vdev_req_param->status = status;
768 mlme_vdev_self_peer_delete_resp(pdel_vdev_req_param);
769 }
770
771 return status;
772
773 send_fail_rsp:
774 wma_err("rcvd del_self_sta without del_bss; vdev_id:%d", vdev_id);
775 cds_trigger_recovery(QDF_DEL_SELF_STA_FAILED);
776 status = QDF_STATUS_E_FAILURE;
777 return status;
778 }
779
780 /**
781 * wma_send_start_resp() - send vdev start response to upper layer
782 * @wma: wma handle
783 * @add_bss_rsp: add bss params
784 * @rsp: response params
785 *
786 * Return: none
787 */
wma_send_start_resp(tp_wma_handle wma,struct add_bss_rsp * add_bss_rsp,struct vdev_start_response * rsp)788 static void wma_send_start_resp(tp_wma_handle wma,
789 struct add_bss_rsp *add_bss_rsp,
790 struct vdev_start_response *rsp)
791 {
792 struct wma_txrx_node *iface = &wma->interfaces[rsp->vdev_id];
793 QDF_STATUS status;
794
795 if (QDF_IS_STATUS_SUCCESS(rsp->status) &&
796 QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) {
797 status =
798 wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
799 WLAN_VDEV_SM_EV_START_RESP,
800 sizeof(*add_bss_rsp),
801 add_bss_rsp);
802 if (QDF_IS_STATUS_SUCCESS(status))
803 return;
804
805 add_bss_rsp->status = status;
806 }
807
808 /* Send vdev stop if vdev start was success */
809 if (QDF_IS_STATUS_ERROR(add_bss_rsp->status) &&
810 QDF_IS_STATUS_SUCCESS(rsp->status)) {
811 wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
812 WLAN_VDEV_SM_EV_DOWN,
813 sizeof(*add_bss_rsp),
814 add_bss_rsp);
815 return;
816 }
817
818 wma_remove_bss_peer_on_failure(wma, rsp->vdev_id);
819
820 wma_debug("Sending add bss rsp to umac(vdev %d status %d)",
821 rsp->vdev_id, add_bss_rsp->status);
822 lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp);
823 }
824
825 /**
826 * wma_vdev_start_rsp() - send vdev start response to upper layer
827 * @wma: wma handle
828 * @vdev: vdev
829 * @rsp: response params
830 *
831 * Return: none
832 */
wma_vdev_start_rsp(tp_wma_handle wma,struct wlan_objmgr_vdev * vdev,struct vdev_start_response * rsp)833 static void wma_vdev_start_rsp(tp_wma_handle wma, struct wlan_objmgr_vdev *vdev,
834 struct vdev_start_response *rsp)
835 {
836 struct beacon_info *bcn;
837 enum QDF_OPMODE opmode;
838 struct add_bss_rsp *add_bss_rsp;
839
840 opmode = wlan_vdev_mlme_get_opmode(vdev);
841
842 add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp));
843 if (!add_bss_rsp)
844 return;
845
846 add_bss_rsp->vdev_id = rsp->vdev_id;
847 add_bss_rsp->status = rsp->status;
848 add_bss_rsp->chain_mask = rsp->chain_mask;
849 add_bss_rsp->smps_mode = host_map_smps_mode(rsp->smps_mode);
850
851 if (rsp->status)
852 goto send_fail_resp;
853
854 if (opmode == QDF_P2P_GO_MODE || opmode == QDF_SAP_MODE) {
855 wma->interfaces[rsp->vdev_id].beacon =
856 qdf_mem_malloc(sizeof(struct beacon_info));
857
858 bcn = wma->interfaces[rsp->vdev_id].beacon;
859 if (!bcn) {
860 add_bss_rsp->status = QDF_STATUS_E_NOMEM;
861 goto send_fail_resp;
862 }
863 bcn->buf = qdf_nbuf_alloc(NULL, SIR_MAX_BEACON_SIZE, 0,
864 sizeof(uint32_t), 0);
865 if (!bcn->buf) {
866 qdf_mem_free(bcn);
867 add_bss_rsp->status = QDF_STATUS_E_FAILURE;
868 goto send_fail_resp;
869 }
870 bcn->seq_no = MIN_SW_SEQ;
871 qdf_spinlock_create(&bcn->lock);
872 qdf_atomic_set(&wma->interfaces[rsp->vdev_id].bss_status,
873 WMA_BSS_STATUS_STARTED);
874 wma_debug("AP mode (type %d subtype %d) BSS is started",
875 wma->interfaces[rsp->vdev_id].type,
876 wma->interfaces[rsp->vdev_id].sub_type);
877 }
878
879 send_fail_resp:
880 wma_send_start_resp(wma, add_bss_rsp, rsp);
881 }
882
883 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
884 /**
885 * wma_find_mcc_ap() - finds if device is operating AP in MCC mode or not
886 * @wma: wma handle.
887 * @vdev_id: vdev ID of device for which MCC has to be checked
888 * @add: flag indicating if current device is added or deleted
889 *
890 * This function parses through all the interfaces in wma and finds if
891 * any of those devces are in MCC mode with AP. If such a vdev is found
892 * involved AP vdevs are sent WDA_UPDATE_Q2Q_IE_IND msg to update their
893 * beacon template to include Q2Q IE.
894 *
895 * Return: none
896 */
wma_find_mcc_ap(tp_wma_handle wma,uint8_t vdev_id,bool add)897 static void wma_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id, bool add)
898 {
899 uint8_t i;
900 uint16_t prev_ch_freq = 0;
901 bool is_ap = false;
902 bool result = false;
903 uint8_t *ap_vdev_ids = NULL;
904 uint8_t num_ch = 0;
905
906 ap_vdev_ids = qdf_mem_malloc(wma->max_bssid);
907 if (!ap_vdev_ids)
908 return;
909
910 for (i = 0; i < wma->max_bssid; i++) {
911 ap_vdev_ids[i] = -1;
912 if (add == false && i == vdev_id)
913 continue;
914
915 if (wma_is_vdev_up(vdev_id) || (i == vdev_id && add)) {
916 if (wma->interfaces[i].type == WMI_VDEV_TYPE_AP) {
917 is_ap = true;
918 ap_vdev_ids[i] = i;
919 }
920
921 if (wma->interfaces[i].ch_freq != prev_ch_freq) {
922 num_ch++;
923 prev_ch_freq = wma->interfaces[i].ch_freq;
924 }
925 }
926 }
927
928 if (is_ap && (num_ch > 1))
929 result = true;
930 else
931 result = false;
932
933 wma_send_msg(wma, WMA_UPDATE_Q2Q_IE_IND, (void *)ap_vdev_ids, result);
934 }
935 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
936
937 /**
938 * wma_handle_hidden_ssid_restart() - handle hidden ssid restart
939 * @wma: wma handle
940 * @iface: interface pointer
941 *
942 * Return: none
943 */
wma_handle_hidden_ssid_restart(tp_wma_handle wma,struct wma_txrx_node * iface)944 static void wma_handle_hidden_ssid_restart(tp_wma_handle wma,
945 struct wma_txrx_node *iface)
946 {
947 wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
948 WLAN_VDEV_SM_EV_RESTART_RESP,
949 0, NULL);
950 }
951
952 #ifdef WLAN_FEATURE_11BE
953 /**
954 * wma_get_peer_phymode() - get phy mode and eht puncture
955 * @nw_type: wlan type
956 * @old_peer_phymode: old peer phy mode
957 * @vdev_chan: vdev channel
958 * @is_eht: is eht mode
959 * @puncture_bitmap: eht puncture bitmap
960 *
961 * Return: new wlan phy mode
962 */
963 static enum wlan_phymode
wma_get_peer_phymode(tSirNwType nw_type,enum wlan_phymode old_peer_phymode,struct wlan_channel * vdev_chan,bool * is_eht,uint16_t * puncture_bitmap)964 wma_get_peer_phymode(tSirNwType nw_type, enum wlan_phymode old_peer_phymode,
965 struct wlan_channel *vdev_chan, bool *is_eht,
966 uint16_t *puncture_bitmap)
967 {
968 enum wlan_phymode new_phymode;
969
970 new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER,
971 IS_WLAN_PHYMODE_HT(old_peer_phymode),
972 vdev_chan->ch_width,
973 IS_WLAN_PHYMODE_VHT(old_peer_phymode),
974 IS_WLAN_PHYMODE_HE(old_peer_phymode),
975 IS_WLAN_PHYMODE_EHT(old_peer_phymode));
976 *is_eht = IS_WLAN_PHYMODE_EHT(new_phymode);
977 if (*is_eht)
978 *puncture_bitmap = vdev_chan->puncture_bitmap;
979
980 return new_phymode;
981 }
982 #else
983 static enum wlan_phymode
wma_get_peer_phymode(tSirNwType nw_type,enum wlan_phymode old_peer_phymode,struct wlan_channel * vdev_chan,bool * is_eht,uint16_t * puncture_bitmap)984 wma_get_peer_phymode(tSirNwType nw_type, enum wlan_phymode old_peer_phymode,
985 struct wlan_channel *vdev_chan, bool *is_eht,
986 uint16_t *puncture_bitmap)
987 {
988 enum wlan_phymode new_phymode;
989
990 new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER,
991 IS_WLAN_PHYMODE_HT(old_peer_phymode),
992 vdev_chan->ch_width,
993 IS_WLAN_PHYMODE_VHT(old_peer_phymode),
994 IS_WLAN_PHYMODE_HE(old_peer_phymode),
995 0);
996
997 return new_phymode;
998 }
999 #endif
1000
wma_peer_send_phymode(struct wlan_objmgr_vdev * vdev,void * object,void * arg)1001 static void wma_peer_send_phymode(struct wlan_objmgr_vdev *vdev,
1002 void *object, void *arg)
1003 {
1004 struct wlan_objmgr_peer *peer = object;
1005 enum wlan_phymode old_peer_phymode;
1006 struct wlan_channel *vdev_chan;
1007 enum wlan_phymode new_phymode;
1008 tSirNwType nw_type;
1009 uint32_t fw_phymode;
1010 uint32_t max_ch_width_supported;
1011 tp_wma_handle wma;
1012 uint8_t *peer_mac_addr;
1013 uint8_t vdev_id;
1014 bool is_eht = false;
1015 uint16_t puncture_bitmap = 0;
1016 uint16_t new_puncture_bitmap = 0;
1017 uint32_t bw_puncture = 0;
1018 enum phy_ch_width new_bw;
1019
1020 if (wlan_peer_get_peer_type(peer) == WLAN_PEER_SELF)
1021 return;
1022
1023 wma = cds_get_context(QDF_MODULE_ID_WMA);
1024 if(!wma)
1025 return;
1026
1027 old_peer_phymode = wlan_peer_get_phymode(peer);
1028 vdev_chan = wlan_vdev_mlme_get_des_chan(vdev);
1029
1030 peer_mac_addr = wlan_peer_get_macaddr(peer);
1031
1032 if (WLAN_REG_IS_24GHZ_CH_FREQ(vdev_chan->ch_freq)) {
1033 if (vdev_chan->ch_phymode == WLAN_PHYMODE_11B ||
1034 old_peer_phymode == WLAN_PHYMODE_11B)
1035 nw_type = eSIR_11B_NW_TYPE;
1036 else
1037 nw_type = eSIR_11G_NW_TYPE;
1038 } else {
1039 nw_type = eSIR_11A_NW_TYPE;
1040 }
1041
1042 new_phymode = wma_get_peer_phymode(nw_type, old_peer_phymode,
1043 vdev_chan, &is_eht,
1044 &puncture_bitmap);
1045
1046 if (!is_eht && new_phymode == old_peer_phymode) {
1047 wma_debug("Ignore update as old %d and new %d phymode are same for mac "QDF_MAC_ADDR_FMT,
1048 old_peer_phymode, new_phymode,
1049 QDF_MAC_ADDR_REF(peer_mac_addr));
1050 return;
1051 }
1052 wlan_peer_set_phymode(peer, new_phymode);
1053
1054 fw_phymode = wmi_host_to_fw_phymode(new_phymode);
1055 vdev_id = wlan_vdev_get_id(vdev);
1056
1057 max_ch_width_supported =
1058 wmi_get_ch_width_from_phy_mode(wma->wmi_handle,
1059 fw_phymode);
1060 new_bw =
1061 target_if_wmi_chan_width_to_phy_ch_width(max_ch_width_supported);
1062
1063 if (is_eht) {
1064 wlan_reg_extract_puncture_by_bw(vdev_chan->ch_width,
1065 puncture_bitmap,
1066 vdev_chan->ch_freq,
1067 vdev_chan->ch_freq_seg2,
1068 new_bw,
1069 &new_puncture_bitmap);
1070 QDF_SET_BITS(bw_puncture, 0, 8, new_bw);
1071 QDF_SET_BITS(bw_puncture, 8, 16, new_puncture_bitmap);
1072 wlan_util_vdev_peer_set_param_send(vdev, peer_mac_addr,
1073 WLAN_MLME_PEER_BW_PUNCTURE,
1074 bw_puncture);
1075 } else {
1076 wma_set_peer_param(wma, peer_mac_addr, WMI_HOST_PEER_CHWIDTH,
1077 max_ch_width_supported, vdev_id);
1078 }
1079
1080 wma_set_peer_param(wma, peer_mac_addr, WMI_HOST_PEER_PHYMODE,
1081 fw_phymode, vdev_id);
1082 wma_debug("FW phymode %d old phymode %d new phymode %d bw %d punct: 0x%x macaddr " QDF_MAC_ADDR_FMT,
1083 fw_phymode, old_peer_phymode, new_phymode,
1084 max_ch_width_supported, new_puncture_bitmap,
1085 QDF_MAC_ADDR_REF(peer_mac_addr));
1086 }
1087
1088 static
wma_update_rate_flags_after_vdev_restart(tp_wma_handle wma,struct wma_txrx_node * iface)1089 void wma_update_rate_flags_after_vdev_restart(tp_wma_handle wma,
1090 struct wma_txrx_node *iface)
1091 {
1092 struct vdev_mlme_obj *vdev_mlme;
1093 uint32_t rate_flags = 0;
1094 enum wlan_phymode bss_phymode;
1095 struct wlan_channel *des_chan;
1096
1097 if (iface->type != WMI_VDEV_TYPE_STA)
1098 return;
1099
1100 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
1101 if (!vdev_mlme)
1102 return;
1103
1104 des_chan = wlan_vdev_mlme_get_des_chan(iface->vdev);
1105 bss_phymode = des_chan->ch_phymode;
1106
1107 if (wma_is_eht_phymode_supported(bss_phymode)) {
1108 rate_flags = wma_get_eht_rate_flags(des_chan->ch_width);
1109 } else if (IS_WLAN_PHYMODE_HE(bss_phymode)) {
1110 rate_flags = wma_get_he_rate_flags(des_chan->ch_width);
1111 } else if (IS_WLAN_PHYMODE_VHT(bss_phymode)) {
1112 rate_flags = wma_get_vht_rate_flags(des_chan->ch_width);
1113 } else if (IS_WLAN_PHYMODE_HT(bss_phymode)) {
1114 rate_flags = wma_get_ht_rate_flags(des_chan->ch_width);
1115 } else {
1116 rate_flags = TX_RATE_LEGACY;
1117 }
1118
1119 vdev_mlme->mgmt.rate_info.rate_flags = rate_flags;
1120
1121 wma_debug("bss phymode %d rate_flags %x, ch_width %d",
1122 bss_phymode, rate_flags, des_chan->ch_width);
1123
1124 ucfg_mc_cp_stats_set_rate_flags(iface->vdev, rate_flags);
1125 }
1126
wma_handle_channel_switch_resp(tp_wma_handle wma,struct vdev_start_response * rsp)1127 QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma,
1128 struct vdev_start_response *rsp)
1129 {
1130 enum wlan_vdev_sm_evt event;
1131 struct wma_txrx_node *iface;
1132
1133 iface = &wma->interfaces[rsp->vdev_id];
1134 wma_debug("Send channel switch resp vdev %d status %d",
1135 rsp->vdev_id, rsp->status);
1136
1137 /* Indicate channel switch failure to LIM */
1138 if (QDF_IS_STATUS_ERROR(rsp->status) &&
1139 (iface->type == WMI_VDEV_TYPE_MONITOR ||
1140 wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) ||
1141 mlme_is_chan_switch_in_progress(iface->vdev))) {
1142 mlme_set_chan_switch_in_progress(iface->vdev, false);
1143 lim_process_switch_channel_rsp(wma->mac_context, rsp);
1144 return QDF_STATUS_SUCCESS;
1145 }
1146
1147 if (QDF_IS_STATUS_SUCCESS(rsp->status) &&
1148 rsp->resp_type == WMI_VDEV_RESTART_RESP_EVENT) {
1149 wlan_objmgr_iterate_peerobj_list(iface->vdev,
1150 wma_peer_send_phymode, NULL,
1151 WLAN_LEGACY_WMA_ID);
1152 wma_update_rate_flags_after_vdev_restart(wma, iface);
1153 }
1154
1155 if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id) ||
1156 mlme_is_chan_switch_in_progress(iface->vdev))
1157 event = WLAN_VDEV_SM_EV_RESTART_RESP;
1158 else
1159 event = WLAN_VDEV_SM_EV_START_RESP;
1160 wlan_vdev_mlme_sm_deliver_evt(iface->vdev, event,
1161 sizeof(rsp), rsp);
1162
1163 return QDF_STATUS_SUCCESS;
1164 }
1165
1166 #ifdef DCS_INTERFERENCE_DETECTION
1167 /**
1168 * wma_dcs_clear_vdev_starting() - clear vdev starting within dcs information
1169 * @mac_ctx: mac context
1170 * @vdev_id: vdev id
1171 *
1172 * This function is used to clear vdev starting within dcs information
1173 *
1174 * Return: None
1175 */
wma_dcs_clear_vdev_starting(struct mac_context * mac_ctx,uint32_t vdev_id)1176 static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx,
1177 uint32_t vdev_id)
1178 {
1179 mac_ctx->sap.dcs_info.is_vdev_starting[vdev_id] = false;
1180 }
1181
1182 /**
1183 * wma_dcs_wlan_interference_mitigation_enable() - enable wlan
1184 * interference mitigation
1185 * @mac_ctx: mac context
1186 * @mac_id: mac id
1187 * @rsp: vdev start response
1188 *
1189 * This function is used to enable wlan interference mitigation through
1190 * send dcs command
1191 *
1192 * Return: None
1193 */
wma_dcs_wlan_interference_mitigation_enable(struct mac_context * mac_ctx,uint32_t mac_id,struct vdev_start_response * rsp)1194 static void wma_dcs_wlan_interference_mitigation_enable(
1195 struct mac_context *mac_ctx,
1196 uint32_t mac_id,
1197 struct vdev_start_response *rsp)
1198 {
1199 int vdev_index;
1200 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
1201 uint32_t count;
1202 bool wlan_interference_mitigation_enable =
1203 mac_ctx->sap.dcs_info.
1204 wlan_interference_mitigation_enable[rsp->vdev_id];
1205
1206 count = policy_mgr_get_sap_go_count_on_mac(
1207 mac_ctx->psoc, list, mac_id);
1208
1209 for (vdev_index = 0; vdev_index < count; vdev_index++) {
1210 if (mac_ctx->sap.dcs_info.is_vdev_starting[list[vdev_index]]) {
1211 wma_err("vdev %d: does not finish restart",
1212 list[vdev_index]);
1213 return;
1214 }
1215 wlan_interference_mitigation_enable =
1216 wlan_interference_mitigation_enable ||
1217 mac_ctx->sap.dcs_info.
1218 wlan_interference_mitigation_enable[list[vdev_index]];
1219 }
1220
1221 if (wlan_interference_mitigation_enable)
1222 ucfg_config_dcs_event_data(mac_ctx->psoc, mac_id, true);
1223
1224 if (rsp->resp_type == WMI_HOST_VDEV_START_RESP_EVENT) {
1225 ucfg_config_dcs_enable(mac_ctx->psoc, mac_id,
1226 WLAN_HOST_DCS_WLANIM);
1227 ucfg_wlan_dcs_cmd(mac_ctx->psoc, mac_id, true);
1228 }
1229 }
1230 #else
wma_dcs_wlan_interference_mitigation_enable(struct mac_context * mac_ctx,uint32_t mac_id,struct vdev_start_response * rsp)1231 static void wma_dcs_wlan_interference_mitigation_enable(
1232 struct mac_context *mac_ctx,
1233 uint32_t mac_id,
1234 struct vdev_start_response *rsp)
1235 {
1236 }
1237
1238
wma_dcs_clear_vdev_starting(struct mac_context * mac_ctx,uint32_t vdev_id)1239 static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx,
1240 uint32_t vdev_id)
1241 {
1242 }
1243 #endif
1244
1245 /*
1246 * wma_get_ratemask_type() - convert user input ratemask type to FW type
1247 * @type: User input ratemask type maintained in HDD
1248 * @fwtype: Value return arg for fw ratemask type value
1249 *
1250 * Return: FW configurable ratemask type
1251 */
wma_get_ratemask_type(enum wlan_mlme_ratemask_type type,uint8_t * fwtype)1252 static QDF_STATUS wma_get_ratemask_type(enum wlan_mlme_ratemask_type type,
1253 uint8_t *fwtype)
1254 {
1255 switch (type) {
1256 case WLAN_MLME_RATEMASK_TYPE_CCK:
1257 *fwtype = WMI_RATEMASK_TYPE_CCK;
1258 break;
1259 case WLAN_MLME_RATEMASK_TYPE_HT:
1260 *fwtype = WMI_RATEMASK_TYPE_HT;
1261 break;
1262 case WLAN_MLME_RATEMASK_TYPE_VHT:
1263 *fwtype = WMI_RATEMASK_TYPE_VHT;
1264 break;
1265 case WLAN_MLME_RATEMASK_TYPE_HE:
1266 *fwtype = WMI_RATEMASK_TYPE_HE;
1267 break;
1268 default:
1269 return QDF_STATUS_E_INVAL;
1270 }
1271
1272 return QDF_STATUS_SUCCESS;
1273 }
1274
wma_vdev_start_resp_handler(struct vdev_mlme_obj * vdev_mlme,struct vdev_start_response * rsp)1275 QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme,
1276 struct vdev_start_response *rsp)
1277 {
1278 tp_wma_handle wma;
1279 struct wma_txrx_node *iface;
1280 target_resource_config *wlan_res_cfg;
1281 struct wlan_objmgr_psoc *psoc;
1282 struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1283 QDF_STATUS status;
1284 enum vdev_assoc_type assoc_type = VDEV_ASSOC;
1285 struct vdev_mlme_obj *mlme_obj;
1286 struct wlan_mlme_psoc_ext_obj *mlme_psoc_obj;
1287 const struct wlan_mlme_ratemask *ratemask_cfg;
1288 struct config_ratemask_params rparams = {0};
1289
1290 wma = cds_get_context(QDF_MODULE_ID_WMA);
1291 if (!wma)
1292 return QDF_STATUS_E_FAILURE;
1293
1294 psoc = wma->psoc;
1295 if (!psoc) {
1296 wma_err("psoc is NULL");
1297 return QDF_STATUS_E_FAILURE;
1298 }
1299
1300 mlme_psoc_obj = mlme_get_psoc_ext_obj(psoc);
1301 if (!mlme_psoc_obj) {
1302 wma_err("Failed to get mlme_psoc");
1303 return QDF_STATUS_E_FAILURE;
1304 }
1305
1306 ratemask_cfg = &mlme_psoc_obj->cfg.ratemask_cfg;
1307
1308 if (!mac_ctx) {
1309 wma_err("Failed to get mac_ctx");
1310 return QDF_STATUS_E_FAILURE;
1311 }
1312
1313 wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
1314 if (!wlan_res_cfg) {
1315 wma_err("Wlan resource config is NULL");
1316 return QDF_STATUS_E_FAILURE;
1317 }
1318
1319 if (rsp->vdev_id >= wma->max_bssid) {
1320 wma_err("Invalid vdev id received from firmware");
1321 return QDF_STATUS_E_FAILURE;
1322 }
1323
1324 if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id))
1325 tgt_dfs_radar_enable(wma->pdev, 0, 0, true);
1326
1327 iface = &wma->interfaces[rsp->vdev_id];
1328 if (!iface->vdev) {
1329 wma_err("Invalid vdev");
1330 return QDF_STATUS_E_FAILURE;
1331 }
1332
1333 if (rsp->status == QDF_STATUS_SUCCESS) {
1334 wma->interfaces[rsp->vdev_id].tx_streams =
1335 rsp->cfgd_tx_streams;
1336
1337 if (wlan_res_cfg->use_pdev_id) {
1338 if (rsp->mac_id == OL_TXRX_PDEV_ID) {
1339 wma_err("soc level id received for mac id");
1340 return -QDF_STATUS_E_INVAL;
1341 }
1342 wma->interfaces[rsp->vdev_id].mac_id =
1343 WMA_PDEV_TO_MAC_MAP(rsp->mac_id);
1344 } else {
1345 wma->interfaces[rsp->vdev_id].mac_id =
1346 rsp->mac_id;
1347 }
1348
1349 wma_debug("vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d",
1350 rsp->vdev_id,
1351 rsp->cfgd_tx_streams,
1352 rsp->cfgd_rx_streams,
1353 rsp->chain_mask,
1354 wma->interfaces[rsp->vdev_id].mac_id);
1355
1356 /* Fill bss_chan after vdev start */
1357 qdf_mem_copy(iface->vdev->vdev_mlme.bss_chan,
1358 iface->vdev->vdev_mlme.des_chan,
1359 sizeof(struct wlan_channel));
1360 }
1361
1362 if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) {
1363 wma_dcs_clear_vdev_starting(mac_ctx, rsp->vdev_id);
1364 wma_dcs_wlan_interference_mitigation_enable(mac_ctx,
1365 iface->mac_id, rsp);
1366 }
1367
1368 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1369 if (rsp->status == QDF_STATUS_SUCCESS
1370 && mac_ctx->sap.sap_channel_avoidance)
1371 wma_find_mcc_ap(wma, rsp->vdev_id, true);
1372 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1373
1374 if (wma_get_hidden_ssid_restart_in_progress(iface) &&
1375 wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) {
1376 wma_handle_hidden_ssid_restart(wma, iface);
1377 return QDF_STATUS_SUCCESS;
1378 }
1379
1380 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
1381 if (!mlme_obj)
1382 return QDF_STATUS_E_INVAL;
1383
1384 mlme_obj->mgmt.generic.tx_pwrlimit = rsp->max_allowed_tx_power;
1385 wma_debug("Max allowed tx power: %d", rsp->max_allowed_tx_power);
1386
1387 if (iface->type == WMI_VDEV_TYPE_STA)
1388 assoc_type = mlme_get_assoc_type(vdev_mlme->vdev);
1389
1390 if (mlme_is_chan_switch_in_progress(iface->vdev) ||
1391 iface->type == WMI_VDEV_TYPE_MONITOR ||
1392 (iface->type == WMI_VDEV_TYPE_STA &&
1393 (assoc_type == VDEV_ASSOC || assoc_type == VDEV_REASSOC))) {
1394 status = wma_handle_channel_switch_resp(wma,
1395 rsp);
1396 if (QDF_IS_STATUS_ERROR(status))
1397 return QDF_STATUS_E_FAILURE;
1398 } else if (iface->type == WMI_VDEV_TYPE_OCB) {
1399 mlme_obj->proto.sta.assoc_id = iface->aid;
1400 if (vdev_mgr_up_send(mlme_obj) != QDF_STATUS_SUCCESS) {
1401 wma_err("failed to send vdev up");
1402 return QDF_STATUS_E_FAILURE;
1403 }
1404 ucfg_ocb_config_channel(wma->pdev);
1405 } else {
1406 struct qdf_mac_addr bss_peer;
1407
1408 status =
1409 wlan_vdev_get_bss_peer_mac(iface->vdev, &bss_peer);
1410 if (QDF_IS_STATUS_ERROR(status)) {
1411 wma_err("Failed to get bssid");
1412 return QDF_STATUS_E_INVAL;
1413 }
1414 qdf_mem_copy(mlme_obj->mgmt.generic.bssid, bss_peer.bytes,
1415 QDF_MAC_ADDR_SIZE);
1416 wma_vdev_start_rsp(wma, vdev_mlme->vdev, rsp);
1417 }
1418 if (iface->type == WMI_VDEV_TYPE_AP && wma_is_vdev_up(rsp->vdev_id))
1419 wma_set_sap_keepalive(wma, rsp->vdev_id);
1420
1421 /* Send ratemask to firmware */
1422 if ((ratemask_cfg->type > WLAN_MLME_RATEMASK_TYPE_NO_MASK) &&
1423 (ratemask_cfg->type < WLAN_MLME_RATEMASK_TYPE_MAX)) {
1424 struct wmi_unified *wmi_handle = wma->wmi_handle;
1425
1426 if (wmi_validate_handle(wmi_handle))
1427 return QDF_STATUS_E_INVAL;
1428
1429 rparams.vdev_id = rsp->vdev_id;
1430 status = wma_get_ratemask_type(ratemask_cfg->type,
1431 &rparams.type);
1432
1433 if (QDF_IS_STATUS_ERROR(status)) {
1434 wma_err(FL("unable to map ratemask"));
1435 /* don't fail, default rates will still work */
1436 return QDF_STATUS_SUCCESS;
1437 }
1438
1439 rparams.lower32 = ratemask_cfg->lower32;
1440 rparams.higher32 = ratemask_cfg->higher32;
1441 rparams.lower32_2 = ratemask_cfg->lower32_2;
1442 rparams.higher32_2 = ratemask_cfg->higher32_2;
1443
1444 status = wmi_unified_vdev_config_ratemask_cmd_send(wmi_handle,
1445 &rparams);
1446 /* Only log failure. Do not abort */
1447 if (QDF_IS_STATUS_ERROR(status))
1448 wma_err(FL("failed to send ratemask"));
1449 }
1450
1451 return QDF_STATUS_SUCCESS;
1452 }
1453
wma_is_vdev_valid(uint32_t vdev_id)1454 bool wma_is_vdev_valid(uint32_t vdev_id)
1455 {
1456 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1457
1458 if (!wma_handle)
1459 return false;
1460
1461 /* No of interface are allocated based on max_bssid value */
1462 if (vdev_id >= wma_handle->max_bssid) {
1463 wma_debug("vdev_id: %d is invalid, max_bssid: %d",
1464 vdev_id, wma_handle->max_bssid);
1465 return false;
1466 }
1467
1468 return wma_handle->interfaces[vdev_id].vdev_active;
1469 }
1470
1471 /**
1472 * wma_vdev_set_param() - set per vdev params in fw
1473 * @wmi_handle: wmi handle
1474 * @if_id: vdev id
1475 * @param_id: parameter id
1476 * @param_value: parameter value
1477 *
1478 * Return: QDF_STATUS_SUCCESS for success or error code
1479 */
1480 QDF_STATUS
wma_vdev_set_param(wmi_unified_t wmi_handle,uint32_t if_id,uint32_t param_id,uint32_t param_value)1481 wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id,
1482 uint32_t param_id, uint32_t param_value)
1483 {
1484 struct vdev_set_params param = {0};
1485
1486 if (!wma_is_vdev_valid(if_id)) {
1487 wma_err("vdev_id: %d is not active reject the req: param id %d val %d",
1488 if_id, param_id, param_value);
1489 return QDF_STATUS_E_INVAL;
1490 }
1491
1492 param.vdev_id = if_id;
1493 param.param_id = param_id;
1494 param.param_value = param_value;
1495
1496 return wmi_unified_vdev_set_param_send(wmi_handle, ¶m);
1497 }
1498
1499 /**
1500 * wma_set_peer_param() - set peer parameter in fw
1501 * @wma_ctx: wma handle
1502 * @peer_addr: peer mac address
1503 * @param_id: parameter id
1504 * @param_value: parameter value
1505 * @vdev_id: vdev id
1506 *
1507 * Return: QDF_STATUS_SUCCESS for success or error code
1508 */
wma_set_peer_param(void * wma_ctx,uint8_t * peer_addr,uint32_t param_id,uint32_t param_value,uint32_t vdev_id)1509 QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
1510 uint32_t param_id, uint32_t param_value,
1511 uint32_t vdev_id)
1512 {
1513 tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx;
1514 struct peer_set_params param = {0};
1515 QDF_STATUS status;
1516
1517 param.vdev_id = vdev_id;
1518 param.param_value = param_value;
1519 param.param_id = param_id;
1520
1521 status = wmi_set_peer_param_send(wma_handle->wmi_handle,
1522 peer_addr,
1523 ¶m);
1524 if (QDF_IS_STATUS_ERROR(status))
1525 wma_err("vdev_id: %d peer set failed, id %d, val %d",
1526 vdev_id, param_id, param_value);
1527 return status;
1528 }
1529
1530 /**
1531 * wma_peer_unmap_conf_send - send peer unmap conf cmnd to fw
1532 * @wma: wma handle
1533 * @msg: peer unmap conf params
1534 *
1535 * Return: QDF_STATUS
1536 */
wma_peer_unmap_conf_send(tp_wma_handle wma,struct send_peer_unmap_conf_params * msg)1537 QDF_STATUS wma_peer_unmap_conf_send(tp_wma_handle wma,
1538 struct send_peer_unmap_conf_params *msg)
1539 {
1540 QDF_STATUS qdf_status;
1541
1542 if (!msg) {
1543 wma_err("null input params");
1544 return QDF_STATUS_E_INVAL;
1545 }
1546
1547 qdf_status = wmi_unified_peer_unmap_conf_send(
1548 wma->wmi_handle,
1549 msg->vdev_id,
1550 msg->peer_id_cnt,
1551 msg->peer_id_list);
1552
1553 if (qdf_status != QDF_STATUS_SUCCESS)
1554 wma_err("peer_unmap_conf_send failed %d", qdf_status);
1555
1556 qdf_mem_free(msg->peer_id_list);
1557 msg->peer_id_list = NULL;
1558
1559 return qdf_status;
1560 }
1561
1562 /**
1563 * wma_peer_unmap_conf_cb - send peer unmap conf cmnd to fw
1564 * @vdev_id: vdev id
1565 * @peer_id_cnt: no of peer id
1566 * @peer_id_list: list of peer ids
1567 *
1568 * Return: QDF_STATUS
1569 */
wma_peer_unmap_conf_cb(uint8_t vdev_id,uint32_t peer_id_cnt,uint16_t * peer_id_list)1570 QDF_STATUS wma_peer_unmap_conf_cb(uint8_t vdev_id,
1571 uint32_t peer_id_cnt,
1572 uint16_t *peer_id_list)
1573 {
1574 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
1575 QDF_STATUS qdf_status;
1576
1577 if (!wma)
1578 return QDF_STATUS_E_INVAL;
1579
1580 wma_debug("peer_id_cnt: %d", peer_id_cnt);
1581 qdf_status = wmi_unified_peer_unmap_conf_send(
1582 wma->wmi_handle,
1583 vdev_id, peer_id_cnt,
1584 peer_id_list);
1585
1586 if (qdf_status == QDF_STATUS_E_BUSY) {
1587 QDF_STATUS retcode;
1588 struct scheduler_msg msg = {0};
1589 struct send_peer_unmap_conf_params *peer_unmap_conf_req;
1590 void *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1591
1592 wma_debug("post unmap_conf cmd to MC thread");
1593
1594 if (!mac_ctx)
1595 return QDF_STATUS_E_FAILURE;
1596
1597 peer_unmap_conf_req = qdf_mem_malloc(sizeof(
1598 struct send_peer_unmap_conf_params));
1599
1600 if (!peer_unmap_conf_req)
1601 return QDF_STATUS_E_NOMEM;
1602
1603 peer_unmap_conf_req->vdev_id = vdev_id;
1604 peer_unmap_conf_req->peer_id_cnt = peer_id_cnt;
1605 peer_unmap_conf_req->peer_id_list = qdf_mem_malloc(
1606 sizeof(uint16_t) * peer_id_cnt);
1607 if (!peer_unmap_conf_req->peer_id_list) {
1608 qdf_mem_free(peer_unmap_conf_req);
1609 peer_unmap_conf_req = NULL;
1610 return QDF_STATUS_E_NOMEM;
1611 }
1612 qdf_mem_copy(peer_unmap_conf_req->peer_id_list,
1613 peer_id_list, sizeof(uint16_t) * peer_id_cnt);
1614
1615 msg.type = WMA_SEND_PEER_UNMAP_CONF;
1616 msg.reserved = 0;
1617 msg.bodyptr = peer_unmap_conf_req;
1618 msg.bodyval = 0;
1619
1620 retcode = wma_post_ctrl_msg(mac_ctx, &msg);
1621 if (retcode != QDF_STATUS_SUCCESS) {
1622 wma_err("wma_post_ctrl_msg failed");
1623 qdf_mem_free(peer_unmap_conf_req->peer_id_list);
1624 qdf_mem_free(peer_unmap_conf_req);
1625 return QDF_STATUS_E_FAILURE;
1626 }
1627 }
1628
1629 return qdf_status;
1630 }
1631
wma_objmgr_peer_exist(tp_wma_handle wma,uint8_t * peer_addr,uint8_t * peer_vdev_id)1632 bool wma_objmgr_peer_exist(tp_wma_handle wma,
1633 uint8_t *peer_addr, uint8_t *peer_vdev_id)
1634 {
1635 struct wlan_objmgr_peer *peer;
1636
1637 if (!peer_addr ||
1638 qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr))
1639 return false;
1640
1641 peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_addr,
1642 WLAN_LEGACY_WMA_ID);
1643 if (!peer)
1644 return false;
1645
1646 if (peer_vdev_id)
1647 *peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
1648
1649 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1650
1651 return true;
1652 }
1653
1654 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
wma_peer_tbl_trans_add_entry(struct wlan_objmgr_peer * peer,bool is_create,struct cdp_peer_setup_info * peer_info)1655 void wma_peer_tbl_trans_add_entry(struct wlan_objmgr_peer *peer, bool is_create,
1656 struct cdp_peer_setup_info *peer_info)
1657 {
1658 QDF_STATUS status;
1659 struct wlan_objmgr_vdev *vdev;
1660 struct wlan_objmgr_psoc *psoc;
1661 struct wlan_peer_tbl_trans_entry *peer_trans_entry;
1662 uint8_t *peer_mac, *peer_mld;
1663
1664 vdev = wlan_peer_get_vdev(peer);
1665 if (!vdev)
1666 return;
1667
1668 psoc = wlan_vdev_get_psoc(vdev);
1669 if (!psoc)
1670 return;
1671
1672 peer_trans_entry = qdf_mem_malloc(sizeof(*peer_trans_entry));
1673 if (!peer_trans_entry)
1674 return;
1675
1676 peer_trans_entry->ts = qdf_get_log_timestamp();
1677 peer_trans_entry->vdev_id = wlan_vdev_get_id(vdev);
1678 peer_trans_entry->opmode = wlan_vdev_mlme_get_opmode(vdev);
1679
1680 peer_mac = wlan_peer_get_macaddr(peer);
1681 peer_mld = wlan_peer_mlme_get_mldaddr(peer);
1682 qdf_ether_addr_copy(&peer_trans_entry->peer_addr.bytes[0], peer_mac);
1683 if (peer_mld) {
1684 qdf_ether_addr_copy(&peer_trans_entry->peer_mld_addr.bytes[0],
1685 peer_mld);
1686 }
1687
1688 peer_trans_entry->is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev);
1689 peer_trans_entry->is_mlo_link = wlan_vdev_mlme_is_mlo_link_vdev(vdev);
1690
1691 if (wlan_cm_is_vdev_roam_sync_inprogress(vdev)) {
1692 peer_trans_entry->peer_flags |= WLAN_PEER_TBL_TRANS_ROAM;
1693 peer_trans_entry->auth_status =
1694 wlan_cm_check_mlo_roam_auth_status(vdev);
1695 peer_trans_entry->num_roam_links = mlo_mgr_num_roam_links(vdev);
1696 } else if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
1697 peer_trans_entry->peer_flags |= WLAN_PEER_TBL_TRANS_LINK_SWITCH;
1698 } else if (is_create) {
1699 peer_trans_entry->peer_flags |= WLAN_PEER_TBL_TRANS_CONNECT;
1700 } else {
1701 peer_trans_entry->peer_flags |= WLAN_PEER_TBL_TRANS_DISCONNECT;
1702 }
1703
1704 if (is_create) {
1705 peer_trans_entry->peer_flags |= WLAN_PEER_TBL_TRANS_CREATE;
1706 peer_trans_entry->is_primary = peer_info->is_primary_link;
1707 peer_trans_entry->is_first_link = peer_info->is_first_link;
1708 } else {
1709 peer_trans_entry->peer_flags |= WLAN_PEER_TBL_TRANS_DESTROY;
1710 }
1711
1712 status = wlan_mlme_psoc_peer_tbl_trans_add_entry(psoc,
1713 peer_trans_entry);
1714 if (QDF_IS_STATUS_ERROR(status))
1715 qdf_mem_free(peer_trans_entry);
1716 }
1717 #endif
1718
1719 /**
1720 * wma_remove_peer() - remove peer information from host driver and fw
1721 * @wma: wma handle
1722 * @mac_addr: peer mac address, to be removed
1723 * @vdev_id: vdev id
1724 * @no_fw_peer_delete: If true dont send peer delete to firmware
1725 *
1726 * Return: QDF_STATUS
1727 */
wma_remove_peer(tp_wma_handle wma,uint8_t * mac_addr,uint8_t vdev_id,bool no_fw_peer_delete)1728 QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr,
1729 uint8_t vdev_id, bool no_fw_peer_delete)
1730 {
1731 #define PEER_ALL_TID_BITMASK 0xffffffff
1732 uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK;
1733 uint8_t peer_addr[QDF_MAC_ADDR_SIZE] = {0};
1734 struct peer_flush_params param = {0};
1735 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1736 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1737 uint32_t bitmap = 1 << CDP_PEER_DELETE_NO_SPECIAL;
1738 bool peer_unmap_conf_support_enabled;
1739 uint8_t peer_vdev_id;
1740 struct peer_delete_cmd_params del_param = {0};
1741 struct wma_txrx_node *iface;
1742 struct wlan_objmgr_peer *peer;
1743
1744 if (vdev_id >= WLAN_MAX_VDEVS) {
1745 wma_err("Invalid vdev_id %d", vdev_id);
1746 QDF_BUG(0);
1747 return QDF_STATUS_E_INVAL;
1748 }
1749
1750 qdf_mem_copy(peer_addr, mac_addr, QDF_MAC_ADDR_SIZE);
1751
1752 iface = &wma->interfaces[vdev_id];
1753 if (!iface->peer_count) {
1754 wma_err("Can't remove peer with peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d",
1755 QDF_MAC_ADDR_REF(peer_addr), vdev_id,
1756 iface->peer_count);
1757 QDF_ASSERT(0);
1758 return QDF_STATUS_E_INVAL;
1759 }
1760
1761 if (!soc) {
1762 QDF_BUG(0);
1763 return QDF_STATUS_E_INVAL;
1764 }
1765
1766 peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_addr,
1767 WLAN_LEGACY_WMA_ID);
1768 if (!peer) {
1769 wma_err("peer doesn't exist peer_addr "QDF_MAC_ADDR_FMT" vdevid %d peer_count %d",
1770 QDF_MAC_ADDR_REF(peer_addr), vdev_id,
1771 iface->peer_count);
1772 return QDF_STATUS_E_INVAL;
1773 }
1774
1775 peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
1776 if (peer_vdev_id != vdev_id) {
1777 wma_err("peer "QDF_MAC_ADDR_FMT" is on vdev id %d but delete req on vdevid %d peer_count %d",
1778 QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id,
1779 iface->peer_count);
1780 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1781 return QDF_STATUS_E_INVAL;
1782 }
1783
1784 wma_peer_tbl_trans_add_entry(peer, false, NULL);
1785 peer_unmap_conf_support_enabled =
1786 cdp_cfg_get_peer_unmap_conf_support(soc);
1787
1788 cdp_peer_teardown(soc, vdev_id, peer_addr);
1789
1790 if (no_fw_peer_delete)
1791 goto peer_detach;
1792
1793 /* Flush all TIDs except MGMT TID for this peer in Target */
1794 peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID);
1795 param.peer_tid_bitmap = peer_tid_bitmap;
1796 param.vdev_id = vdev_id;
1797 if (!wmi_service_enabled(wma->wmi_handle,
1798 wmi_service_peer_delete_no_peer_flush_tids_cmd))
1799 wmi_unified_peer_flush_tids_send(wma->wmi_handle, peer_addr,
1800 ¶m);
1801
1802 /* peer->ref_cnt is not visible in WMA */
1803 wlan_roam_debug_log(vdev_id, DEBUG_PEER_DELETE_SEND,
1804 DEBUG_INVALID_PEER_ID, peer_addr, NULL,
1805 0, 0);
1806
1807 del_param.vdev_id = vdev_id;
1808 del_param.is_mlo_link_switch =
1809 wlan_vdev_mlme_is_mlo_link_switch_in_progress(iface->vdev);
1810 qdf_status = wmi_unified_peer_delete_send(wma->wmi_handle, peer_addr,
1811 &del_param);
1812 if (QDF_IS_STATUS_ERROR(qdf_status)) {
1813 wma_err("Peer delete could not be sent to firmware %d",
1814 qdf_status);
1815 /* Clear default bit and set to NOT_START_UNMAP */
1816 bitmap = 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER;
1817 qdf_status = QDF_STATUS_E_FAILURE;
1818 }
1819
1820 peer_detach:
1821 wma_debug("vdevid %d is detaching with peer_addr "QDF_MAC_ADDR_FMT" peer_count %d",
1822 vdev_id, QDF_MAC_ADDR_REF(peer_addr), iface->peer_count);
1823 if (no_fw_peer_delete &&
1824 is_cdp_peer_detach_force_delete_supported(soc)) {
1825 if (!peer_unmap_conf_support_enabled) {
1826 wma_debug("LFR3: trigger force delete for peer "QDF_MAC_ADDR_FMT,
1827 QDF_MAC_ADDR_REF(peer_addr));
1828 cdp_peer_detach_force_delete(soc, vdev_id, peer_addr);
1829 } else {
1830 cdp_peer_delete_sync(soc, vdev_id, peer_addr,
1831 wma_peer_unmap_conf_cb,
1832 bitmap);
1833 }
1834 } else {
1835 if (no_fw_peer_delete)
1836 wma_debug("LFR3: Delete the peer "QDF_MAC_ADDR_FMT,
1837 QDF_MAC_ADDR_REF(peer_addr));
1838
1839 if (peer_unmap_conf_support_enabled)
1840 cdp_peer_delete_sync(soc, vdev_id, peer_addr,
1841 wma_peer_unmap_conf_cb,
1842 bitmap);
1843 else
1844 cdp_peer_delete(soc, vdev_id, peer_addr, bitmap);
1845 }
1846
1847 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1848 wlan_release_peer_key_wakelock(wma->pdev, peer_addr);
1849 wma_remove_objmgr_peer(wma, iface->vdev, peer_addr);
1850
1851 iface->peer_count--;
1852 #undef PEER_ALL_TID_BITMASK
1853
1854 return qdf_status;
1855 }
1856
1857 /**
1858 * wma_get_obj_mgr_peer_type() - Determine the type of peer(eg. STA/AP)
1859 * @wma: wma handle
1860 * @vdev_id: vdev id
1861 * @peer_addr: peer mac address
1862 * @wma_peer_type: wma peer type
1863 *
1864 * Return: Peer type
1865 */
wma_get_obj_mgr_peer_type(tp_wma_handle wma,uint8_t vdev_id,uint8_t * peer_addr,uint32_t wma_peer_type)1866 static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id,
1867 uint8_t *peer_addr, uint32_t wma_peer_type)
1868
1869 {
1870 uint32_t obj_peer_type = 0;
1871 struct wlan_objmgr_vdev *vdev;
1872 uint8_t *addr;
1873 uint8_t *mld_addr;
1874
1875 vdev = wma->interfaces[vdev_id].vdev;
1876 if (!vdev) {
1877 wma_err("Couldn't find vdev for VDEV_%d", vdev_id);
1878 return obj_peer_type;
1879 }
1880 addr = wlan_vdev_mlme_get_macaddr(vdev);
1881 mld_addr = wlan_vdev_mlme_get_mldaddr(vdev);
1882
1883 if (wma_peer_type == WMI_PEER_TYPE_TDLS)
1884 return WLAN_PEER_TDLS;
1885
1886 if (wma_peer_type == WMI_PEER_TYPE_PASN)
1887 return WLAN_PEER_RTT_PASN;
1888
1889 if (!qdf_mem_cmp(addr, peer_addr, QDF_MAC_ADDR_SIZE) ||
1890 !qdf_mem_cmp(mld_addr, peer_addr, QDF_MAC_ADDR_SIZE)) {
1891 obj_peer_type = WLAN_PEER_SELF;
1892 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA) {
1893 if (wma->interfaces[vdev_id].sub_type ==
1894 WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT)
1895 obj_peer_type = WLAN_PEER_P2P_GO;
1896 else
1897 obj_peer_type = WLAN_PEER_AP;
1898 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_AP) {
1899 obj_peer_type = WLAN_PEER_STA;
1900 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_IBSS) {
1901 obj_peer_type = WLAN_PEER_IBSS;
1902 } else if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_NDI) {
1903 obj_peer_type = WLAN_PEER_NDP;
1904 } else {
1905 wma_err("Couldn't find peertype for type %d and sub type %d",
1906 wma->interfaces[vdev_id].type,
1907 wma->interfaces[vdev_id].sub_type);
1908 }
1909
1910 return obj_peer_type;
1911
1912 }
1913
1914 #ifdef WLAN_FEATURE_11BE_MLO
1915 static QDF_STATUS
wma_create_peer_validate_mld_address(tp_wma_handle wma,uint8_t * peer_mld_addr,struct wlan_objmgr_vdev * vdev)1916 wma_create_peer_validate_mld_address(tp_wma_handle wma,
1917 uint8_t *peer_mld_addr,
1918 struct wlan_objmgr_vdev *vdev)
1919 {
1920 uint8_t peer_vdev_id, vdev_id;
1921 struct wlan_objmgr_vdev *dup_vdev;
1922 QDF_STATUS status = QDF_STATUS_SUCCESS;
1923 struct wlan_objmgr_psoc *psoc = wma->psoc;
1924
1925 vdev_id = wlan_vdev_get_id(vdev);
1926 /* Check if the @peer_mld_addr matches any other
1927 * peer's link address.
1928 * We may find a match if one of the peers added
1929 * has same MLD and link, in such case check if
1930 * both are in same ML dev context.
1931 */
1932 if (wma_objmgr_peer_exist(wma, peer_mld_addr, &peer_vdev_id)) {
1933 if (peer_vdev_id != vdev_id) {
1934 dup_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
1935 psoc, peer_vdev_id,
1936 WLAN_LEGACY_WMA_ID);
1937 if (!dup_vdev)
1938 return QDF_STATUS_E_INVAL;
1939
1940 /* If ML dev context is NULL then the matching
1941 * peer exist on non ML VDEV, so reject the peer.
1942 */
1943 if (!dup_vdev->mlo_dev_ctx) {
1944 wlan_objmgr_vdev_release_ref(
1945 dup_vdev, WLAN_LEGACY_WMA_ID);
1946 return QDF_STATUS_E_ALREADY;
1947 } else if (dup_vdev->mlo_dev_ctx != vdev->mlo_dev_ctx) {
1948 wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d",
1949 QDF_MAC_ADDR_REF(peer_mld_addr),
1950 peer_vdev_id, vdev_id);
1951 wlan_objmgr_vdev_release_ref(
1952 dup_vdev, WLAN_LEGACY_WMA_ID);
1953 status = QDF_STATUS_E_ALREADY;
1954 } else {
1955 wlan_objmgr_vdev_release_ref(
1956 dup_vdev, WLAN_LEGACY_WMA_ID);
1957 wma_debug("Allow ML peer on same ML dev context");
1958 status = QDF_STATUS_SUCCESS;
1959 }
1960 } else {
1961 wma_debug("ML Peer exists on same VDEV %d", vdev_id);
1962 status = QDF_STATUS_E_ALREADY;
1963 }
1964 } else if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_mld_addr,
1965 &vdev_id)) {
1966 /* Reject if MLD exists on different ML dev context,
1967 */
1968 wma_debug("ML Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context",
1969 QDF_MAC_ADDR_REF(peer_mld_addr));
1970 status = QDF_STATUS_E_ALREADY;
1971 }
1972
1973 return status;
1974 }
1975 #else
1976 static QDF_STATUS
wma_create_peer_validate_mld_address(tp_wma_handle wma,uint8_t * peer_mld_addr,struct wlan_objmgr_vdev * vdev)1977 wma_create_peer_validate_mld_address(tp_wma_handle wma,
1978 uint8_t *peer_mld_addr,
1979 struct wlan_objmgr_vdev *vdev)
1980 {
1981 return QDF_STATUS_SUCCESS;
1982 }
1983 #endif
1984
wma_create_objmgr_peer(tp_wma_handle wma,uint8_t vdev_id,uint8_t * peer_addr,uint32_t wma_peer_type,uint8_t * peer_mld_addr)1985 struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
1986 uint8_t vdev_id,
1987 uint8_t *peer_addr,
1988 uint32_t wma_peer_type,
1989 uint8_t *peer_mld_addr)
1990 {
1991 QDF_STATUS status;
1992 uint8_t peer_vdev_id;
1993 uint32_t obj_peer_type;
1994 struct wlan_objmgr_vdev *obj_vdev;
1995 struct wlan_objmgr_peer *obj_peer = NULL;
1996 struct wlan_objmgr_psoc *psoc = wma->psoc;
1997
1998 obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1999 WLAN_LEGACY_WMA_ID);
2000
2001 if (!obj_vdev) {
2002 wma_err("Invalid obj vdev. Unable to create peer");
2003 return NULL;
2004 }
2005
2006 /*
2007 * Check if peer with same MAC exist on any Vdev, If so avoid
2008 * adding this peer.
2009 */
2010 if (wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) {
2011 wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d",
2012 QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id);
2013 goto vdev_ref;
2014 }
2015
2016 /* Reject if same MAC exists on different ML dev context */
2017 if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_addr,
2018 &vdev_id)) {
2019 wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context",
2020 QDF_MAC_ADDR_REF(peer_addr));
2021 goto vdev_ref;
2022 }
2023
2024 status = wma_create_peer_validate_mld_address(wma, peer_mld_addr,
2025 obj_vdev);
2026 if (QDF_IS_STATUS_ERROR(status)) {
2027 wma_debug("MLD " QDF_MAC_ADDR_FMT " matches with peer on different MLD context",
2028 QDF_MAC_ADDR_REF(peer_mld_addr));
2029 goto vdev_ref;
2030 }
2031
2032 obj_peer_type = wma_get_obj_mgr_peer_type(wma, vdev_id, peer_addr,
2033 wma_peer_type);
2034 if (!obj_peer_type) {
2035 wma_err("Invalid obj peer type. Unable to create peer %d",
2036 obj_peer_type);
2037 goto vdev_ref;
2038 }
2039
2040 /* Create obj_mgr peer */
2041 obj_peer = wlan_objmgr_peer_obj_create(obj_vdev, obj_peer_type,
2042 peer_addr);
2043
2044 vdev_ref:
2045 wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID);
2046
2047 return obj_peer;
2048
2049 }
2050
2051 /**
2052 * wma_increment_peer_count() - Increment the vdev peer
2053 * count
2054 * @wma: wma handle
2055 * @vdev_id: vdev id
2056 *
2057 * Return: None
2058 */
2059 static void
wma_increment_peer_count(tp_wma_handle wma,uint8_t vdev_id)2060 wma_increment_peer_count(tp_wma_handle wma, uint8_t vdev_id)
2061 {
2062 wma->interfaces[vdev_id].peer_count++;
2063 }
2064
2065 /**
2066 * wma_update_mlo_peer_create() - update mlo parameter for peer creation
2067 * @param: peer create param
2068 * @mlo_enable: mlo enable or not
2069 *
2070 * Return: Void
2071 */
2072 #ifdef WLAN_FEATURE_11BE_MLO
wma_update_mlo_peer_create(struct peer_create_params * param,bool mlo_enable)2073 static void wma_update_mlo_peer_create(struct peer_create_params *param,
2074 bool mlo_enable)
2075 {
2076 param->mlo_enabled = mlo_enable;
2077 }
2078 #else
wma_update_mlo_peer_create(struct peer_create_params * param,bool mlo_enable)2079 static void wma_update_mlo_peer_create(struct peer_create_params *param,
2080 bool mlo_enable)
2081 {
2082 }
2083 #endif
2084
2085 /**
2086 * wma_add_peer() - send peer create command to fw
2087 * @wma: wma handle
2088 * @peer_addr: peer mac addr
2089 * @peer_type: peer type
2090 * @vdev_id: vdev id
2091 * @peer_mld_addr: peer mld addr
2092 * @is_assoc_peer: is assoc peer or not
2093 *
2094 * Return: QDF status
2095 */
2096 static
wma_add_peer(tp_wma_handle wma,uint8_t peer_addr[QDF_MAC_ADDR_SIZE],uint32_t peer_type,uint8_t vdev_id,uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE],bool is_assoc_peer)2097 QDF_STATUS wma_add_peer(tp_wma_handle wma,
2098 uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
2099 uint32_t peer_type, uint8_t vdev_id,
2100 uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE],
2101 bool is_assoc_peer)
2102 {
2103 struct peer_create_params param = {0};
2104 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
2105 struct wlan_objmgr_psoc *psoc = wma->psoc;
2106 target_resource_config *wlan_res_cfg;
2107 struct wlan_objmgr_peer *obj_peer = NULL;
2108 QDF_STATUS status;
2109
2110 if (!psoc) {
2111 wma_err("psoc is NULL");
2112 return QDF_STATUS_E_INVAL;
2113 }
2114
2115 wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
2116 if (!wlan_res_cfg) {
2117 wma_err("psoc target res cfg is null");
2118 return QDF_STATUS_E_INVAL;
2119 }
2120
2121 if (wma->interfaces[vdev_id].peer_count >=
2122 wlan_res_cfg->num_peers) {
2123 wma_err("the peer count exceeds the limit %d",
2124 wma->interfaces[vdev_id].peer_count);
2125 return QDF_STATUS_E_FAILURE;
2126 }
2127
2128 if (!dp_soc)
2129 return QDF_STATUS_E_FAILURE;
2130
2131 if (qdf_is_macaddr_group((struct qdf_mac_addr *)peer_addr) ||
2132 qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr)) {
2133 wma_err("Invalid peer address received reject it");
2134 return QDF_STATUS_E_FAILURE;
2135 }
2136
2137 obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type,
2138 peer_mld_addr);
2139 if (!obj_peer)
2140 return QDF_STATUS_E_FAILURE;
2141
2142 /* The peer object should be created before sending the WMI peer
2143 * create command to firmware. This is to prevent a race condition
2144 * where the HTT peer map event is received before the peer object
2145 * is created in the data path
2146 */
2147 if (peer_mld_addr &&
2148 !qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_mld_addr)) {
2149 wlan_peer_mlme_flag_ext_set(obj_peer, WLAN_PEER_FEXT_MLO);
2150 wma_debug("peer " QDF_MAC_ADDR_FMT "is_assoc_peer%d mld mac " QDF_MAC_ADDR_FMT,
2151 QDF_MAC_ADDR_REF(peer_addr), is_assoc_peer,
2152 QDF_MAC_ADDR_REF(peer_mld_addr));
2153 wlan_peer_mlme_set_mldaddr(obj_peer, peer_mld_addr);
2154 wlan_peer_mlme_set_assoc_peer(obj_peer, is_assoc_peer);
2155 wma_update_mlo_peer_create(¶m, true);
2156 }
2157 status = cdp_peer_create(dp_soc, vdev_id, peer_addr);
2158 if (QDF_IS_STATUS_ERROR(status)) {
2159 wma_err("Unable to attach peer "QDF_MAC_ADDR_FMT,
2160 QDF_MAC_ADDR_REF(peer_addr));
2161 wlan_objmgr_peer_obj_delete(obj_peer);
2162 return QDF_STATUS_E_FAILURE;
2163 }
2164
2165 if (peer_type == WMI_PEER_TYPE_TDLS)
2166 cdp_peer_set_peer_as_tdls(dp_soc, vdev_id, peer_addr, true);
2167
2168 if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) ||
2169 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id)) {
2170 wma_debug("LFR3: Created peer "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count %d",
2171 QDF_MAC_ADDR_REF(peer_addr), vdev_id,
2172 wma->interfaces[vdev_id].peer_count + 1);
2173 return QDF_STATUS_SUCCESS;
2174 }
2175 param.peer_addr = peer_addr;
2176 param.peer_type = peer_type;
2177 param.vdev_id = vdev_id;
2178 if (wmi_unified_peer_create_send(wma->wmi_handle,
2179 ¶m) != QDF_STATUS_SUCCESS) {
2180 wma_err("Unable to create peer in Target");
2181 if (cdp_cfg_get_peer_unmap_conf_support(dp_soc))
2182 cdp_peer_delete_sync(
2183 dp_soc, vdev_id, peer_addr,
2184 wma_peer_unmap_conf_cb,
2185 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER);
2186 else
2187 cdp_peer_delete(
2188 dp_soc, vdev_id, peer_addr,
2189 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER);
2190 wlan_objmgr_peer_obj_delete(obj_peer);
2191
2192 return QDF_STATUS_E_FAILURE;
2193 }
2194
2195 wma_debug("Created peer peer_addr "QDF_MAC_ADDR_FMT" vdev_id %d, peer_count - %d",
2196 QDF_MAC_ADDR_REF(peer_addr), vdev_id,
2197 wma->interfaces[vdev_id].peer_count + 1);
2198
2199 wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND,
2200 DEBUG_INVALID_PEER_ID, peer_addr, NULL, 0, 0);
2201
2202 return QDF_STATUS_SUCCESS;
2203 }
2204
2205 #ifdef WLAN_FEATURE_11BE_MLO
wma_peer_setup_fill_info(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_peer * peer,struct cdp_peer_setup_info * peer_info)2206 static void wma_peer_setup_fill_info(struct wlan_objmgr_psoc *psoc,
2207 struct wlan_objmgr_peer *peer,
2208 struct cdp_peer_setup_info *peer_info)
2209 {
2210 uint8_t vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
2211
2212 peer_info->mld_peer_mac = wlan_peer_mlme_get_mldaddr(peer);
2213 if (MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id) &&
2214 wlan_vdev_mlme_get_is_mlo_link(psoc, vdev_id)) {
2215 peer_info->is_first_link = true;
2216 peer_info->is_primary_link = false;
2217 } else if (wlan_cm_is_roam_sync_in_progress(psoc, vdev_id) &&
2218 wlan_vdev_mlme_get_is_mlo_vdev(psoc, vdev_id)) {
2219 if (mlo_get_single_link_ml_roaming(psoc, vdev_id)) {
2220 peer_info->is_first_link = true;
2221 peer_info->is_primary_link = true;
2222 } else {
2223 peer_info->is_first_link = false;
2224 peer_info->is_primary_link = true;
2225 }
2226 } else {
2227 peer_info->is_first_link = wlan_peer_mlme_is_assoc_peer(peer);
2228 peer_info->is_primary_link = peer_info->is_first_link;
2229 }
2230 }
2231
2232 /**
2233 * wma_cdp_peer_setup() - provide mlo information to cdp_peer_setup
2234 * @dp_soc: dp soc
2235 * @vdev_id: vdev id
2236 * @peer: Object manager peer pointer
2237 * @peer_info: Peer setup info
2238 *
2239 * Return: VOID
2240 */
wma_cdp_peer_setup(ol_txrx_soc_handle dp_soc,uint8_t vdev_id,struct wlan_objmgr_peer * peer,struct cdp_peer_setup_info * peer_info)2241 static void wma_cdp_peer_setup(ol_txrx_soc_handle dp_soc,
2242 uint8_t vdev_id, struct wlan_objmgr_peer *peer,
2243 struct cdp_peer_setup_info *peer_info)
2244 {
2245 uint8_t *mld_mac, *peer_addr;
2246
2247 peer_addr = wlan_peer_get_macaddr(peer);
2248 mld_mac = peer_info->mld_peer_mac;
2249
2250 if (!mld_mac || qdf_is_macaddr_zero((struct qdf_mac_addr *)mld_mac)) {
2251 cdp_peer_setup(dp_soc, vdev_id, peer_addr, NULL);
2252 return;
2253 }
2254
2255 cdp_peer_setup(dp_soc, vdev_id, peer_addr, peer_info);
2256 }
2257 #else
2258 static inline void
wma_peer_setup_fill_info(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_peer * peer,struct cdp_peer_setup_info * peer_info)2259 wma_peer_setup_fill_info(struct wlan_objmgr_psoc *psoc,
2260 struct wlan_objmgr_peer *peer,
2261 struct cdp_peer_setup_info *peer_info)
2262 {
2263 peer_info->mld_peer_mac = NULL;
2264 peer_info->is_first_link = false;
2265 peer_info->is_primary_link = false;
2266 }
2267
wma_cdp_peer_setup(ol_txrx_soc_handle dp_soc,uint8_t vdev_id,struct wlan_objmgr_peer * peer,struct cdp_peer_setup_info * peer_info)2268 static void wma_cdp_peer_setup(ol_txrx_soc_handle dp_soc,
2269 uint8_t vdev_id, struct wlan_objmgr_peer *peer,
2270 struct cdp_peer_setup_info *peer_info)
2271 {
2272 uint8_t *peer_addr;
2273
2274 peer_addr = wlan_peer_get_macaddr(peer);
2275 cdp_peer_setup(dp_soc, vdev_id, peer_addr, NULL);
2276 }
2277 #endif
2278
wma_create_peer(tp_wma_handle wma,uint8_t peer_addr[QDF_MAC_ADDR_SIZE],uint32_t peer_type,uint8_t vdev_id,uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE],bool is_assoc_peer)2279 QDF_STATUS wma_create_peer(tp_wma_handle wma,
2280 uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
2281 uint32_t peer_type, uint8_t vdev_id,
2282 uint8_t peer_mld_addr[QDF_MAC_ADDR_SIZE],
2283 bool is_assoc_peer)
2284 {
2285 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
2286 QDF_STATUS status;
2287 struct wlan_objmgr_peer *obj_peer;
2288 struct cdp_peer_setup_info peer_info = {0};
2289
2290 if (!dp_soc)
2291 return QDF_STATUS_E_FAILURE;
2292 status = wma_add_peer(wma, peer_addr, peer_type, vdev_id,
2293 peer_mld_addr, is_assoc_peer);
2294 if (QDF_IS_STATUS_ERROR(status))
2295 return status;
2296
2297 obj_peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_addr,
2298 WLAN_LEGACY_WMA_ID);
2299 if (!obj_peer)
2300 return QDF_STATUS_E_FAILURE;
2301
2302 wma_increment_peer_count(wma, vdev_id);
2303
2304 wma_peer_setup_fill_info(wma->psoc, obj_peer, &peer_info);
2305 wma_peer_tbl_trans_add_entry(obj_peer, true, &peer_info);
2306 wma_cdp_peer_setup(dp_soc, vdev_id, obj_peer, &peer_info);
2307 wlan_objmgr_peer_release_ref(obj_peer, WLAN_LEGACY_WMA_ID);
2308
2309 return QDF_STATUS_SUCCESS;
2310 }
2311
2312 /**
2313 * wma_create_sta_mode_bss_peer() - send peer create command to fw
2314 * and start peer create response timer
2315 * @wma: wma handle
2316 * @peer_addr: peer mac address
2317 * @peer_type: peer type
2318 * @vdev_id: vdev id
2319 * @mld_addr: peer mld address
2320 * @is_assoc_peer: is assoc peer or not
2321 *
2322 * Return: QDF_STATUS
2323 */
2324 static QDF_STATUS
wma_create_sta_mode_bss_peer(tp_wma_handle wma,uint8_t peer_addr[QDF_MAC_ADDR_SIZE],uint32_t peer_type,uint8_t vdev_id,uint8_t mld_addr[QDF_MAC_ADDR_SIZE],bool is_assoc_peer)2325 wma_create_sta_mode_bss_peer(tp_wma_handle wma,
2326 uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
2327 uint32_t peer_type, uint8_t vdev_id,
2328 uint8_t mld_addr[QDF_MAC_ADDR_SIZE],
2329 bool is_assoc_peer)
2330 {
2331 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
2332 struct wma_target_req *msg = NULL;
2333 struct peer_create_rsp_params *peer_create_rsp = NULL;
2334 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2335 bool is_tgt_peer_conf_supported = false;
2336
2337 if (!mac) {
2338 wma_err("vdev%d: Mac context is null", vdev_id);
2339 return status;
2340 }
2341
2342 /*
2343 * If fw doesn't advertise peer create confirm event support,
2344 * use the legacy peer create API
2345 */
2346 is_tgt_peer_conf_supported =
2347 wlan_psoc_nif_fw_ext_cap_get(wma->psoc,
2348 WLAN_SOC_F_PEER_CREATE_RESP);
2349 if (!is_tgt_peer_conf_supported) {
2350 status = wma_create_peer(wma, peer_addr, peer_type, vdev_id,
2351 mld_addr, is_assoc_peer);
2352 goto end;
2353 }
2354
2355 peer_create_rsp = qdf_mem_malloc(sizeof(*peer_create_rsp));
2356 if (!peer_create_rsp)
2357 goto end;
2358
2359 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
2360 WMA_PEER_CREATE_RESPONSE_TIMEOUT);
2361
2362 status = wma_add_peer(wma, peer_addr, peer_type, vdev_id,
2363 mld_addr, is_assoc_peer);
2364 if (QDF_IS_STATUS_ERROR(status)) {
2365 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
2366 goto end;
2367 }
2368
2369 wma_increment_peer_count(wma, vdev_id);
2370 qdf_mem_copy(peer_create_rsp->peer_mac.bytes, peer_addr,
2371 QDF_MAC_ADDR_SIZE);
2372
2373 msg = wma_fill_hold_req(wma, vdev_id, WMA_PEER_CREATE_REQ,
2374 WMA_PEER_CREATE_RESPONSE,
2375 (void *)peer_create_rsp,
2376 WMA_PEER_CREATE_RESPONSE_TIMEOUT);
2377 if (!msg) {
2378 wma_err("vdev:%d failed to fill peer create req", vdev_id);
2379 wma_remove_peer_req(wma, vdev_id, WMA_PEER_CREATE_RESPONSE,
2380 (struct qdf_mac_addr *)peer_addr);
2381 wma_remove_peer(wma, peer_addr, vdev_id, false);
2382 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
2383 status = QDF_STATUS_E_FAILURE;
2384 goto end;
2385 }
2386
2387 return status;
2388
2389 end:
2390 qdf_mem_free(peer_create_rsp);
2391 lim_send_peer_create_resp(mac, vdev_id, status, peer_addr);
2392
2393 return status;
2394 }
2395
2396 /**
2397 * wma_remove_bss_peer() - remove BSS peer
2398 * @wma: pointer to WMA handle
2399 * @vdev_id: vdev id on which delete BSS request was received
2400 * @vdev_stop_resp: pointer to Delete BSS response
2401 * @type: request type
2402 *
2403 * This function is called on receiving vdev stop response from FW or
2404 * vdev stop response timeout. In case of NDI, use vdev's self MAC
2405 * for removing the peer. In case of STA/SAP use bssid passed as part of
2406 * delete STA parameter.
2407 *
2408 * Return: 0 on success, ERROR code on failure
2409 */
wma_remove_bss_peer(tp_wma_handle wma,uint32_t vdev_id,struct del_bss_resp * vdev_stop_resp,uint8_t type)2410 static int wma_remove_bss_peer(tp_wma_handle wma, uint32_t vdev_id,
2411 struct del_bss_resp *vdev_stop_resp,
2412 uint8_t type)
2413 {
2414 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2415 uint8_t *mac_addr = NULL;
2416 struct wma_target_req *del_req;
2417 int ret_value = 0;
2418 QDF_STATUS qdf_status;
2419 struct qdf_mac_addr bssid;
2420
2421 if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id)) {
2422 mac_addr = cdp_get_vdev_mac_addr(soc, vdev_id);
2423 if (!mac_addr) {
2424 wma_err("mac_addr is NULL for vdev_id = %d", vdev_id);
2425 return -EINVAL;
2426 }
2427 } else {
2428 qdf_status = wlan_vdev_get_bss_peer_mac(
2429 wma->interfaces[vdev_id].vdev,
2430 &bssid);
2431 if (QDF_IS_STATUS_ERROR(qdf_status)) {
2432 wma_err("Failed to get bssid for vdev_id: %d", vdev_id);
2433 return -EINVAL;
2434 }
2435 mac_addr = bssid.bytes;
2436 }
2437
2438 qdf_status = wma_remove_peer(wma, mac_addr, vdev_id, false);
2439
2440 if (QDF_IS_STATUS_ERROR(qdf_status)) {
2441 wma_err("wma_remove_peer failed vdev_id:%d", vdev_id);
2442 return -EINVAL;
2443 }
2444
2445 if (cds_is_driver_recovering())
2446 return -EINVAL;
2447
2448 if (wmi_service_enabled(wma->wmi_handle,
2449 wmi_service_sync_delete_cmds)) {
2450 wma_debug("Wait for the peer delete. vdev_id %d", vdev_id);
2451 del_req = wma_fill_hold_req(wma, vdev_id,
2452 WMA_DELETE_STA_REQ,
2453 type,
2454 vdev_stop_resp,
2455 WMA_DELETE_STA_TIMEOUT);
2456 if (!del_req) {
2457 wma_err("Failed to allocate request. vdev_id %d", vdev_id);
2458 vdev_stop_resp->status = QDF_STATUS_E_NOMEM;
2459 ret_value = -EINVAL;
2460 }
2461 }
2462
2463 return ret_value;
2464 }
2465
2466 #ifdef FEATURE_WLAN_APF
2467 /*
2468 * get_fw_active_apf_mode() - convert HDD APF mode to FW configurable APF
2469 * mode
2470 * @mode: APF mode maintained in HDD
2471 *
2472 * Return: FW configurable BP mode
2473 */
2474 static enum wmi_host_active_apf_mode
get_fw_active_apf_mode(enum active_apf_mode mode)2475 get_fw_active_apf_mode(enum active_apf_mode mode)
2476 {
2477 switch (mode) {
2478 case ACTIVE_APF_DISABLED:
2479 return WMI_HOST_ACTIVE_APF_DISABLED;
2480 case ACTIVE_APF_ENABLED:
2481 return WMI_HOST_ACTIVE_APF_ENABLED;
2482 case ACTIVE_APF_ADAPTIVE:
2483 return WMI_HOST_ACTIVE_APF_ADAPTIVE;
2484 default:
2485 wma_err("Invalid Active APF Mode %d; Using 'disabled'", mode);
2486 return WMI_HOST_ACTIVE_APF_DISABLED;
2487 }
2488 }
2489
2490 /**
2491 * wma_config_active_apf_mode() - Config active APF mode in FW
2492 * @wma: the WMA handle
2493 * @vdev_id: the Id of the vdev for which the configuration should be applied
2494 *
2495 * Return: QDF status
2496 */
wma_config_active_apf_mode(t_wma_handle * wma,uint8_t vdev_id)2497 static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id)
2498 {
2499 enum wmi_host_active_apf_mode uc_mode, mcbc_mode;
2500
2501 uc_mode = get_fw_active_apf_mode(wma->active_uc_apf_mode);
2502 mcbc_mode = get_fw_active_apf_mode(wma->active_mc_bc_apf_mode);
2503
2504 wma_debug("Configuring Active APF Mode UC:%d MC/BC:%d for vdev %u",
2505 uc_mode, mcbc_mode, vdev_id);
2506
2507 return wmi_unified_set_active_apf_mode_cmd(wma->wmi_handle, vdev_id,
2508 uc_mode, mcbc_mode);
2509 }
2510 #else /* FEATURE_WLAN_APF */
wma_config_active_apf_mode(t_wma_handle * wma,uint8_t vdev_id)2511 static QDF_STATUS wma_config_active_apf_mode(t_wma_handle *wma, uint8_t vdev_id)
2512 {
2513 return QDF_STATUS_SUCCESS;
2514 }
2515 #endif /* FEATURE_WLAN_APF */
2516
2517 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2518 /**
2519 * wma_check_and_find_mcc_ap() - finds if device is operating AP
2520 * in MCC mode or not
2521 * @wma: wma handle.
2522 * @vdev_id: vdev ID of device for which MCC has to be checked
2523 *
2524 * This function internally calls wma_find_mcc_ap finds if
2525 * device is operating AP in MCC mode or not
2526 *
2527 * Return: none
2528 */
2529 static void
wma_check_and_find_mcc_ap(tp_wma_handle wma,uint8_t vdev_id)2530 wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
2531 {
2532 struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
2533
2534 if (!mac_ctx)
2535 return;
2536
2537 if (mac_ctx->sap.sap_channel_avoidance)
2538 wma_find_mcc_ap(wma, vdev_id, false);
2539 }
2540 #else
2541 static inline void
wma_check_and_find_mcc_ap(tp_wma_handle wma,uint8_t vdev_id)2542 wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
2543 {}
2544 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2545
wma_send_del_bss_response(tp_wma_handle wma,struct del_bss_resp * resp)2546 void wma_send_del_bss_response(tp_wma_handle wma, struct del_bss_resp *resp)
2547 {
2548 struct wma_txrx_node *iface;
2549 struct beacon_info *bcn;
2550 uint8_t vdev_id;
2551 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2552
2553 if (!resp) {
2554 wma_err("req is NULL");
2555 return;
2556 }
2557
2558 vdev_id = resp->vdev_id;
2559 iface = &wma->interfaces[vdev_id];
2560
2561 if (!iface->vdev) {
2562 wma_err("vdev id %d iface->vdev is NULL", vdev_id);
2563 if (resp)
2564 qdf_mem_free(resp);
2565 return;
2566 }
2567
2568 cdp_fc_vdev_flush(soc, vdev_id);
2569 wma_debug("vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
2570 vdev_id);
2571 cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
2572 wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST);
2573 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
2574 wma_debug("(type %d subtype %d) BSS is stopped",
2575 iface->type, iface->sub_type);
2576
2577 bcn = wma->interfaces[vdev_id].beacon;
2578 if (bcn) {
2579 wma_debug("Freeing beacon struct %pK, template memory %pK",
2580 bcn, bcn->buf);
2581 if (bcn->dma_mapped)
2582 qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf,
2583 QDF_DMA_TO_DEVICE);
2584 qdf_nbuf_free(bcn->buf);
2585 qdf_mem_free(bcn);
2586 wma->interfaces[vdev_id].beacon = NULL;
2587 }
2588
2589 /* Timeout status means its WMA generated DEL BSS REQ when ADD
2590 * BSS REQ was timed out to stop the VDEV in this case no need
2591 * to send response to UMAC
2592 */
2593 if (resp->status == QDF_STATUS_FW_MSG_TIMEDOUT) {
2594 qdf_mem_free(resp);
2595 wma_err("DEL BSS from ADD BSS timeout do not send resp to UMAC (vdev id %x)",
2596 vdev_id);
2597 } else {
2598 resp->status = QDF_STATUS_SUCCESS;
2599 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
2600 (void *)resp, 0);
2601 }
2602
2603 if (iface->del_staself_req && iface->is_del_sta_deferred) {
2604 iface->is_del_sta_deferred = false;
2605 wma_nofl_alert("scheduling deferred deletion (vdev id %x)",
2606 vdev_id);
2607 wma_vdev_detach(iface->del_staself_req);
2608 }
2609 }
2610
2611 QDF_STATUS
wma_send_vdev_down(tp_wma_handle wma,struct del_bss_resp * resp)2612 wma_send_vdev_down(tp_wma_handle wma, struct del_bss_resp *resp)
2613 {
2614 uint8_t vdev_id;
2615 struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id];
2616 uint32_t vdev_stop_type;
2617 QDF_STATUS status;
2618
2619 if (!resp) {
2620 wma_err("resp is NULL");
2621 return QDF_STATUS_E_NULL_VALUE;
2622 }
2623
2624 vdev_id = resp->vdev_id;
2625 status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
2626 if (QDF_IS_STATUS_ERROR(status)) {
2627 wma_err("Failed to get vdev stop type");
2628 qdf_mem_free(resp);
2629 return status;
2630 }
2631
2632 if (vdev_stop_type != WMA_DELETE_BSS_HO_FAIL_REQ) {
2633 status = wma_send_vdev_down_to_fw(wma, vdev_id);
2634 if (QDF_IS_STATUS_ERROR(status))
2635 wma_err("Failed to send vdev down cmd: vdev %d", vdev_id);
2636 else
2637 wma_check_and_find_mcc_ap(wma, vdev_id);
2638 }
2639
2640 wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
2641 WLAN_VDEV_SM_EV_DOWN_COMPLETE,
2642 sizeof(*resp), resp);
2643 return status;
2644 }
2645
2646 /**
2647 * wma_send_vdev_down_req() - handle vdev down req
2648 * @wma: wma handle
2649 * @resp: pointer to vde del bss response
2650 *
2651 * Return: none
2652 */
2653
wma_send_vdev_down_req(tp_wma_handle wma,struct del_bss_resp * resp)2654 static void wma_send_vdev_down_req(tp_wma_handle wma,
2655 struct del_bss_resp *resp)
2656 {
2657 struct wma_txrx_node *iface = &wma->interfaces[resp->vdev_id];
2658 enum QDF_OPMODE mode;
2659
2660 mode = wlan_vdev_mlme_get_opmode(iface->vdev);
2661 if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) {
2662 /* initiate MLME Down req from CM for STA/CLI */
2663 wlan_cm_bss_peer_delete_rsp(iface->vdev, resp->status);
2664 qdf_mem_free(resp);
2665 return;
2666 }
2667
2668 wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
2669 WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
2670 sizeof(*resp), resp);
2671 }
2672
2673 #ifdef WLAN_FEATURE_11BE_MLO
wma_delete_peer_mlo(struct wlan_objmgr_psoc * psoc,uint8_t * macaddr)2674 void wma_delete_peer_mlo(struct wlan_objmgr_psoc *psoc, uint8_t *macaddr)
2675 {
2676 struct wlan_objmgr_peer *peer = NULL;
2677
2678 peer = wlan_objmgr_get_peer_by_mac(psoc, macaddr, WLAN_LEGACY_WMA_ID);
2679 if (peer) {
2680 wlan_mlo_link_peer_delete(peer);
2681 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
2682 }
2683 }
2684 #endif /* WLAN_FEATURE_11BE_MLO */
2685
2686 static QDF_STATUS
wma_delete_peer_on_vdev_stop(tp_wma_handle wma,uint8_t vdev_id)2687 wma_delete_peer_on_vdev_stop(tp_wma_handle wma, uint8_t vdev_id)
2688 {
2689 uint32_t vdev_stop_type;
2690 struct del_bss_resp *vdev_stop_resp;
2691 struct wma_txrx_node *iface;
2692 QDF_STATUS status;
2693 struct qdf_mac_addr bssid;
2694
2695 iface = &wma->interfaces[vdev_id];
2696 status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid);
2697 if (QDF_IS_STATUS_ERROR(status)) {
2698 wma_err("Failed to get bssid");
2699 return QDF_STATUS_E_INVAL;
2700 }
2701
2702 status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
2703 if (QDF_IS_STATUS_ERROR(status)) {
2704 wma_err("Failed to get wma req msg type for vdev id %d",
2705 vdev_id);
2706 return QDF_STATUS_E_INVAL;
2707 }
2708
2709 wma_delete_peer_mlo(wma->psoc, bssid.bytes);
2710
2711 vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp));
2712 if (!vdev_stop_resp)
2713 return QDF_STATUS_E_NOMEM;
2714
2715 if (vdev_stop_type == WMA_DELETE_BSS_HO_FAIL_REQ) {
2716 status = wma_remove_peer(wma, bssid.bytes,
2717 vdev_id, true);
2718 if (QDF_IS_STATUS_ERROR(status))
2719 goto free_params;
2720
2721 vdev_stop_resp->status = status;
2722 vdev_stop_resp->vdev_id = vdev_id;
2723 wma_send_vdev_down_req(wma, vdev_stop_resp);
2724 } else if (vdev_stop_type == WMA_DELETE_BSS_REQ ||
2725 vdev_stop_type == WMA_SET_LINK_STATE) {
2726 uint8_t type;
2727
2728 /* CCA is required only for sta interface */
2729 if (iface->type == WMI_VDEV_TYPE_STA)
2730 wma_get_cca_stats(wma, vdev_id);
2731 if (vdev_stop_type == WMA_DELETE_BSS_REQ)
2732 type = WMA_DELETE_PEER_RSP;
2733 else
2734 type = WMA_SET_LINK_PEER_RSP;
2735
2736 vdev_stop_resp->vdev_id = vdev_id;
2737 vdev_stop_resp->status = status;
2738 status = wma_remove_bss_peer(wma, vdev_id,
2739 vdev_stop_resp, type);
2740 if (status) {
2741 wma_err("Del bss failed vdev:%d", vdev_id);
2742 wma_send_vdev_down_req(wma, vdev_stop_resp);
2743 return status;
2744 }
2745
2746 if (wmi_service_enabled(wma->wmi_handle,
2747 wmi_service_sync_delete_cmds))
2748 return status;
2749
2750 wma_send_vdev_down_req(wma, vdev_stop_resp);
2751 }
2752
2753 return status;
2754
2755 free_params:
2756 qdf_mem_free(vdev_stop_resp);
2757 return status;
2758 }
2759
2760 QDF_STATUS
cm_send_bss_peer_delete_req(struct wlan_objmgr_vdev * vdev)2761 cm_send_bss_peer_delete_req(struct wlan_objmgr_vdev *vdev)
2762 {
2763 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
2764 uint8_t vdev_id = wlan_vdev_get_id(vdev);
2765
2766 if (!wma)
2767 return QDF_STATUS_E_INVAL;
2768
2769 if (wlan_vdev_mlme_is_init_state(vdev) == QDF_STATUS_SUCCESS) {
2770 wma_remove_bss_peer_on_failure(wma, vdev_id);
2771 return QDF_STATUS_SUCCESS;
2772 }
2773
2774 return wma_delete_peer_on_vdev_stop(wma, vdev_id);
2775 }
2776
2777 QDF_STATUS
__wma_handle_vdev_stop_rsp(struct vdev_stop_response * resp_event)2778 __wma_handle_vdev_stop_rsp(struct vdev_stop_response *resp_event)
2779 {
2780 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
2781 struct wma_txrx_node *iface;
2782 QDF_STATUS status;
2783 struct qdf_mac_addr bssid;
2784 enum QDF_OPMODE mode;
2785
2786 if (!wma)
2787 return QDF_STATUS_E_INVAL;
2788
2789 /* Ignore stop_response in Monitor mode */
2790 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
2791 return QDF_STATUS_SUCCESS;
2792
2793 iface = &wma->interfaces[resp_event->vdev_id];
2794
2795 /* vdev in stopped state, no more waiting for key */
2796 iface->is_waiting_for_key = false;
2797
2798 /*
2799 * Reset the rmfEnabled as there might be MGMT action frames
2800 * sent on this vdev before the next session is established.
2801 */
2802 if (iface->rmfEnabled) {
2803 iface->rmfEnabled = 0;
2804 wma_debug("Reset rmfEnabled for vdev %d",
2805 resp_event->vdev_id);
2806 }
2807
2808 mode = wlan_vdev_mlme_get_opmode(iface->vdev);
2809 if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) {
2810 status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid);
2811 if (QDF_IS_STATUS_ERROR(status)) {
2812 wma_debug("Failed to get bssid, peer might have got deleted already");
2813 return wlan_cm_bss_peer_delete_rsp(iface->vdev, status);
2814 }
2815 /* initiate CM to delete bss peer */
2816 return wlan_cm_bss_peer_delete_ind(iface->vdev, &bssid);
2817 } else if (mode == QDF_SAP_MODE) {
2818 wlan_son_deliver_vdev_stop(iface->vdev);
2819 }
2820
2821 return wma_delete_peer_on_vdev_stop(wma, resp_event->vdev_id);
2822 }
2823
2824 /**
2825 * wma_handle_vdev_stop_rsp() - handle vdev stop resp
2826 * @wma: wma handle
2827 * @resp_event: fw resp
2828 *
2829 * Return: QDF_STATUS
2830 */
2831 static QDF_STATUS
wma_handle_vdev_stop_rsp(tp_wma_handle wma,struct vdev_stop_response * resp_event)2832 wma_handle_vdev_stop_rsp(tp_wma_handle wma,
2833 struct vdev_stop_response *resp_event)
2834 {
2835 struct wma_txrx_node *iface;
2836
2837 iface = &wma->interfaces[resp_event->vdev_id];
2838 return wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
2839 WLAN_VDEV_SM_EV_STOP_RESP,
2840 sizeof(*resp_event), resp_event);
2841 }
2842
wma_vdev_stop_resp_handler(struct vdev_mlme_obj * vdev_mlme,struct vdev_stop_response * rsp)2843 QDF_STATUS wma_vdev_stop_resp_handler(struct vdev_mlme_obj *vdev_mlme,
2844 struct vdev_stop_response *rsp)
2845 {
2846 tp_wma_handle wma;
2847 struct wma_txrx_node *iface = NULL;
2848 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2849
2850 wma = cds_get_context(QDF_MODULE_ID_WMA);
2851 if (!wma)
2852 return status;
2853
2854 iface = &wma->interfaces[vdev_mlme->vdev->vdev_objmgr.vdev_id];
2855
2856 if (rsp->vdev_id >= wma->max_bssid) {
2857 wma_err("Invalid vdev_id %d from FW", rsp->vdev_id);
2858 return QDF_STATUS_E_INVAL;
2859 }
2860
2861 status = wma_handle_vdev_stop_rsp(wma, rsp);
2862
2863 return status;
2864 }
2865
wma_cleanup_vdev(struct wlan_objmgr_vdev * vdev)2866 void wma_cleanup_vdev(struct wlan_objmgr_vdev *vdev)
2867 {
2868 tp_wma_handle wma_handle;
2869 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2870 uint8_t vdev_id = wlan_vdev_get_id(vdev);
2871 struct vdev_mlme_obj *vdev_mlme;
2872
2873 if (!soc)
2874 return;
2875
2876 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
2877 if (!wma_handle)
2878 return;
2879
2880 if (!wma_handle->interfaces[vdev_id].vdev) {
2881 wma_err("vdev is NULL");
2882 return;
2883 }
2884
2885 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
2886 if (!vdev_mlme) {
2887 wma_err("Failed to get vdev mlme obj for vdev id %d", vdev_id);
2888 return;
2889 }
2890
2891 wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
2892 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
2893 wma_handle->interfaces[vdev_id].vdev = NULL;
2894 wma_handle->interfaces[vdev_id].vdev_active = false;
2895 }
2896
wma_vdev_self_peer_create(struct vdev_mlme_obj * vdev_mlme)2897 QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme)
2898 {
2899 struct wlan_objmgr_peer *obj_peer;
2900 QDF_STATUS status = QDF_STATUS_SUCCESS;
2901 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev;
2902 tp_wma_handle wma_handle;
2903 uint8_t peer_vdev_id, *self_peer_macaddr;
2904
2905 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
2906 if (!wma_handle)
2907 return QDF_STATUS_E_FAILURE;
2908
2909 if (mlme_vdev_uses_self_peer(vdev_mlme->mgmt.generic.type,
2910 vdev_mlme->mgmt.generic.subtype)) {
2911 status = wma_create_peer(wma_handle,
2912 vdev->vdev_mlme.macaddr,
2913 WMI_PEER_TYPE_DEFAULT,
2914 wlan_vdev_get_id(vdev),
2915 NULL, false);
2916 if (QDF_IS_STATUS_ERROR(status))
2917 wma_err("Failed to create peer %d", status);
2918 } else if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA ||
2919 vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_NAN) {
2920 if (!qdf_is_macaddr_zero(
2921 (struct qdf_mac_addr *)vdev->vdev_mlme.mldaddr))
2922 self_peer_macaddr = vdev->vdev_mlme.mldaddr;
2923 else
2924 self_peer_macaddr = vdev->vdev_mlme.macaddr;
2925
2926 /**
2927 * Self peer is used for the frames exchanged before
2928 * association. For ML STA, Self peer create will be triggered
2929 * for both the VDEVs, but one self peer is enough. So in case
2930 * of ML, use MLD address for the self peer and ignore self peer
2931 * creation for the partner link vdev.
2932 */
2933 if (wma_objmgr_peer_exist(wma_handle, self_peer_macaddr,
2934 &peer_vdev_id))
2935 return QDF_STATUS_SUCCESS;
2936
2937 obj_peer = wma_create_objmgr_peer(wma_handle,
2938 wlan_vdev_get_id(vdev),
2939 self_peer_macaddr,
2940 WMI_PEER_TYPE_DEFAULT,
2941 vdev->vdev_mlme.macaddr);
2942 if (!obj_peer) {
2943 wma_err("Failed to create obj mgr peer for self");
2944 status = QDF_STATUS_E_INVAL;
2945 }
2946 }
2947
2948 return status;
2949 }
2950
2951 #ifdef MULTI_CLIENT_LL_SUPPORT
2952 #define MAX_VDEV_LATENCY_PARAMS 10
2953 /* params being sent:
2954 * 1.wmi_vdev_param_set_multi_client_ll_feature_config
2955 * 2.wmi_vdev_param_set_normal_latency_flags_config
2956 * 3.wmi_vdev_param_set_xr_latency_flags_config
2957 * 4.wmi_vdev_param_set_low_latency_flags_config
2958 * 5.wmi_vdev_param_set_ultra_low_latency_flags_config
2959 * 6.wmi_vdev_param_set_normal_latency_ul_dl_config
2960 * 7.wmi_vdev_param_set_xr_latency_ul_dl_config
2961 * 8.wmi_vdev_param_set_low_latency_ul_dl_config
2962 * 9.wmi_vdev_param_set_ultra_low_latency_ul_dl_config
2963 * 10.wmi_vdev_param_set_default_ll_config
2964 */
2965
2966 /**
2967 * wma_set_vdev_latency_level_param() - Set per vdev latency level params in FW
2968 * @wma_handle: wma handle
2969 * @mac: mac context
2970 * @vdev_id: vdev id
2971 *
2972 * Return: QDF_STATUS
2973 */
wma_set_vdev_latency_level_param(tp_wma_handle wma_handle,struct mac_context * mac,uint8_t vdev_id)2974 static QDF_STATUS wma_set_vdev_latency_level_param(tp_wma_handle wma_handle,
2975 struct mac_context *mac,
2976 uint8_t vdev_id)
2977 {
2978 QDF_STATUS status = QDF_STATUS_SUCCESS;
2979 bool multi_client_ll_ini_support, multi_client_ll_caps;
2980 uint32_t latency_flags;
2981 static uint32_t ll[4] = {100, 60, 40, 20};
2982 uint32_t ul_latency, dl_latency, ul_dl_latency;
2983 uint8_t default_latency_level;
2984 struct dev_set_param setparam[MAX_VDEV_LATENCY_PARAMS];
2985 uint8_t index = 0;
2986
2987 multi_client_ll_ini_support =
2988 mac->mlme_cfg->wlm_config.multi_client_ll_support;
2989 multi_client_ll_caps =
2990 wlan_mlme_get_wlm_multi_client_ll_caps(mac->psoc);
2991 wma_debug("INI support: %d, fw capability:%d",
2992 multi_client_ll_ini_support, multi_client_ll_caps);
2993 /*
2994 * Multi-Client arbiter functionality is enabled only if both INI is
2995 * set, and Service bit is configured.
2996 */
2997 if (!(multi_client_ll_ini_support && multi_client_ll_caps))
2998 return status;
2999 status = mlme_check_index_setparam(
3000 setparam,
3001 wmi_vdev_param_set_multi_client_ll_feature_config,
3002 multi_client_ll_ini_support, index++,
3003 MAX_VDEV_LATENCY_PARAMS);
3004 if (QDF_IS_STATUS_ERROR(status)) {
3005 wma_err("failed to configure low latency feature");
3006 return status;
3007 }
3008
3009 /* wlm latency level index:0 - normal, 1 - xr, 2 - low, 3 - ultralow */
3010 wma_debug("Setting vdev params for latency level flags");
3011
3012 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[0];
3013 status = mlme_check_index_setparam(
3014 setparam,
3015 wmi_vdev_param_set_normal_latency_flags_config,
3016 latency_flags, index++,
3017 MAX_VDEV_LATENCY_PARAMS);
3018 if (QDF_IS_STATUS_ERROR(status)) {
3019 wma_err("failed to configure normal latency feature");
3020 return status;
3021 }
3022
3023 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[1];
3024 status = mlme_check_index_setparam(
3025 setparam,
3026 wmi_vdev_param_set_xr_latency_flags_config,
3027 latency_flags, index++,
3028 MAX_VDEV_LATENCY_PARAMS);
3029 if (QDF_IS_STATUS_ERROR(status)) {
3030 wma_err("failed to configure xr latency feature");
3031 return status;
3032 }
3033
3034 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[2];
3035 status = mlme_check_index_setparam(
3036 setparam,
3037 wmi_vdev_param_set_low_latency_flags_config,
3038 latency_flags, index++,
3039 MAX_VDEV_LATENCY_PARAMS);
3040 if (QDF_IS_STATUS_ERROR(status)) {
3041 wma_err("failed to configure low latency feature");
3042 return status;
3043 }
3044
3045 latency_flags = mac->mlme_cfg->wlm_config.latency_flags[3];
3046 status = mlme_check_index_setparam(
3047 setparam,
3048 wmi_vdev_param_set_ultra_low_latency_flags_config,
3049 latency_flags, index++, MAX_VDEV_LATENCY_PARAMS);
3050 if (QDF_IS_STATUS_ERROR(status)) {
3051 wma_err("failed to configure ultra low latency feature");
3052 return status;
3053 }
3054
3055 wma_debug("Setting vdev params for Latency level UL/DL flags");
3056 /*
3057 * Latency level UL/DL
3058 * 0-15 bits: UL and 16-31 bits: DL
3059 */
3060 dl_latency = ll[0];
3061 ul_latency = ll[0];
3062 ul_dl_latency = dl_latency << 16 | ul_latency;
3063 status = mlme_check_index_setparam(
3064 setparam,
3065 wmi_vdev_param_set_normal_latency_ul_dl_config,
3066 ul_dl_latency, index++,
3067 MAX_VDEV_LATENCY_PARAMS);
3068 if (QDF_IS_STATUS_ERROR(status)) {
3069 wma_err("failed to configure normal latency ul dl flag");
3070 return status;
3071 }
3072
3073 dl_latency = ll[1];
3074 ul_latency = ll[1];
3075 ul_dl_latency = dl_latency << 16 | ul_latency;
3076 status = mlme_check_index_setparam(
3077 setparam,
3078 wmi_vdev_param_set_xr_latency_ul_dl_config,
3079 ul_dl_latency, index++,
3080 MAX_VDEV_LATENCY_PARAMS);
3081 if (QDF_IS_STATUS_ERROR(status)) {
3082 wma_err("failed to configure normal latency ul dl flag");
3083 return status;
3084 }
3085
3086 dl_latency = ll[2];
3087 ul_latency = ll[2];
3088 ul_dl_latency = dl_latency << 16 | ul_latency;
3089 status = mlme_check_index_setparam(
3090 setparam,
3091 wmi_vdev_param_set_low_latency_ul_dl_config,
3092 ul_dl_latency, index++,
3093 MAX_VDEV_LATENCY_PARAMS);
3094 if (QDF_IS_STATUS_ERROR(status)) {
3095 wma_err("failed to configure normal latency ul dl flag");
3096 return status;
3097 }
3098
3099 dl_latency = ll[3];
3100 ul_latency = ll[3];
3101 ul_dl_latency = dl_latency << 16 | ul_latency;
3102 status = mlme_check_index_setparam(
3103 setparam,
3104 wmi_vdev_param_set_ultra_low_latency_ul_dl_config,
3105 ul_dl_latency, index++,
3106 MAX_VDEV_LATENCY_PARAMS);
3107 if (QDF_IS_STATUS_ERROR(status)) {
3108 wma_err("failed to configure normal latency ul dl flag");
3109 return status;
3110 }
3111
3112 default_latency_level = mac->mlme_cfg->wlm_config.latency_level;
3113 status = mlme_check_index_setparam(
3114 setparam,
3115 wmi_vdev_param_set_default_ll_config,
3116 default_latency_level, index++,
3117 MAX_VDEV_LATENCY_PARAMS);
3118 if (QDF_IS_STATUS_ERROR(status)) {
3119 wma_err("failed to configure low latency feature");
3120 return status;
3121 }
3122
3123 status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
3124 vdev_id, setparam, index);
3125 if (QDF_IS_STATUS_ERROR(status))
3126 wma_err("Failed to configure vdev latency level params");
3127 return status;
3128 }
3129 #else
wma_set_vdev_latency_level_param(tp_wma_handle wma_handle,struct mac_context * mac,uint8_t vdev_id)3130 static QDF_STATUS wma_set_vdev_latency_level_param(tp_wma_handle wma_handle,
3131 struct mac_context *mac,
3132 uint8_t vdev_id)
3133 {
3134 return QDF_STATUS_E_FAILURE;
3135 }
3136 #endif
3137
wma_post_vdev_create_setup(struct wlan_objmgr_vdev * vdev)3138 QDF_STATUS wma_post_vdev_create_setup(struct wlan_objmgr_vdev *vdev)
3139 {
3140 QDF_STATUS status = QDF_STATUS_SUCCESS;
3141 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3142 bool mcc_adapt_sch = false;
3143 QDF_STATUS ret;
3144 uint8_t vdev_id;
3145 struct wlan_mlme_qos *qos_aggr;
3146 struct vdev_mlme_obj *vdev_mlme;
3147 tp_wma_handle wma_handle;
3148 uint8_t enable_sifs_burst = 0;
3149
3150 if (!mac)
3151 return QDF_STATUS_E_FAILURE;
3152
3153 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
3154 if (!wma_handle)
3155 return QDF_STATUS_E_FAILURE;
3156
3157 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_WMA_ID) !=
3158 QDF_STATUS_SUCCESS)
3159 return QDF_STATUS_E_FAILURE;
3160
3161 vdev_id = wlan_vdev_get_id(vdev);
3162 wma_handle->interfaces[vdev_id].vdev = vdev;
3163 wma_handle->interfaces[vdev_id].vdev_active = true;
3164
3165 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
3166 if (!vdev_mlme) {
3167 wma_err("Failed to get vdev mlme obj!");
3168 goto end;
3169 }
3170
3171 wma_vdev_update_pause_bitmap(vdev_id, 0);
3172
3173 wma_handle->interfaces[vdev_id].type =
3174 vdev_mlme->mgmt.generic.type;
3175 wma_handle->interfaces[vdev_id].sub_type =
3176 vdev_mlme->mgmt.generic.subtype;
3177
3178 qos_aggr = &mac->mlme_cfg->qos_mlme_params;
3179 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA) {
3180 wma_set_sta_keep_alive(
3181 wma_handle, vdev_id,
3182 SIR_KEEP_ALIVE_NULL_PKT,
3183 mac->mlme_cfg->sta.sta_keep_alive_period,
3184 NULL, NULL, NULL);
3185
3186 /* offload STA SA query related params to fwr */
3187 if (wmi_service_enabled(wma_handle->wmi_handle,
3188 wmi_service_sta_pmf_offload)) {
3189 wma_set_sta_sa_query_param(wma_handle, vdev_id);
3190 }
3191
3192 status = wma_set_sw_retry_threshold(qos_aggr);
3193 if (QDF_IS_STATUS_ERROR(status))
3194 wma_err("failed to set sw retry threshold (status = %d)",
3195 status);
3196
3197 status = wma_set_sw_retry_threshold_per_ac(wma_handle, vdev_id,
3198 qos_aggr);
3199 if (QDF_IS_STATUS_ERROR(status))
3200 wma_err("failed to set sw retry threshold per ac(status = %d)",
3201 status);
3202 }
3203
3204 status = wma_vdev_create_set_param(vdev);
3205 if (QDF_IS_STATUS_ERROR(status)) {
3206 wma_err("Failed to setup Vdev create set param for vdev: %d",
3207 vdev_id);
3208 return status;
3209 }
3210
3211 if (policy_mgr_get_dynamic_mcc_adaptive_sch(mac->psoc,
3212 &mcc_adapt_sch) ==
3213 QDF_STATUS_SUCCESS) {
3214 wma_debug("setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d",
3215 mcc_adapt_sch);
3216 ret =
3217 wma_set_enable_disable_mcc_adaptive_scheduler(mcc_adapt_sch);
3218 if (QDF_IS_STATUS_ERROR(ret)) {
3219 wma_err("Failed to set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED");
3220 }
3221 } else {
3222 wma_err("Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, leaving unchanged");
3223 }
3224
3225 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA &&
3226 ucfg_pmo_is_apf_enabled(wma_handle->psoc)) {
3227 ret = wma_config_active_apf_mode(wma_handle,
3228 vdev_id);
3229 if (QDF_IS_STATUS_ERROR(ret))
3230 wma_err("Failed to configure active APF mode");
3231 }
3232
3233 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA &&
3234 vdev_mlme->mgmt.generic.subtype == 0)
3235 wma_set_vdev_latency_level_param(wma_handle, mac, vdev_id);
3236
3237 switch (vdev_mlme->mgmt.generic.type) {
3238 case WMI_VDEV_TYPE_AP:
3239 if (vdev_mlme->mgmt.generic.subtype !=
3240 WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE)
3241 break;
3242
3243 fallthrough;
3244 case WMI_VDEV_TYPE_STA:
3245 case WMI_VDEV_TYPE_NAN:
3246 case WMI_VDEV_TYPE_OCB:
3247 case WMI_VDEV_TYPE_MONITOR:
3248 status = ucfg_get_enable_sifs_burst(wma_handle->psoc,
3249 &enable_sifs_burst);
3250 if (QDF_IS_STATUS_ERROR(status))
3251 wma_err("Failed to get sifs burst value, use default");
3252
3253 status = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
3254 WMI_PDEV_PARAM_BURST_ENABLE,
3255 enable_sifs_burst);
3256
3257 if (QDF_IS_STATUS_ERROR(status))
3258 wma_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d",
3259 status);
3260 break;
3261 default:
3262 break;
3263 }
3264
3265 wma_vdev_set_data_tx_callback(vdev);
3266
3267 return QDF_STATUS_SUCCESS;
3268
3269 end:
3270 wma_cleanup_vdev(vdev);
3271 return QDF_STATUS_E_FAILURE;
3272 }
3273
wma_vdev_set_data_tx_callback(struct wlan_objmgr_vdev * vdev)3274 QDF_STATUS wma_vdev_set_data_tx_callback(struct wlan_objmgr_vdev *vdev)
3275 {
3276 u_int8_t vdev_id;
3277 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
3278 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
3279
3280 if (!vdev || !wma_handle || !soc) {
3281 wma_err("null vdev, wma_handle or soc");
3282 return QDF_STATUS_E_FAILURE;
3283 }
3284
3285 vdev_id = wlan_vdev_get_id(vdev);
3286 cdp_data_tx_cb_set(soc, vdev_id,
3287 wma_data_tx_ack_comp_hdlr,
3288 wma_handle);
3289
3290 return QDF_STATUS_SUCCESS;
3291 }
3292
wma_get_bcn_rate_code(uint16_t rate)3293 enum mlme_bcn_tx_rate_code wma_get_bcn_rate_code(uint16_t rate)
3294 {
3295 /* rate in multiples of 100 Kbps */
3296 switch (rate) {
3297 case WMA_BEACON_TX_RATE_1_M:
3298 return MLME_BCN_TX_RATE_CODE_1_M;
3299 case WMA_BEACON_TX_RATE_2_M:
3300 return MLME_BCN_TX_RATE_CODE_2_M;
3301 case WMA_BEACON_TX_RATE_5_5_M:
3302 return MLME_BCN_TX_RATE_CODE_5_5_M;
3303 case WMA_BEACON_TX_RATE_11_M:
3304 return MLME_BCN_TX_RATE_CODE_11M;
3305 case WMA_BEACON_TX_RATE_6_M:
3306 return MLME_BCN_TX_RATE_CODE_6_M;
3307 case WMA_BEACON_TX_RATE_9_M:
3308 return MLME_BCN_TX_RATE_CODE_9_M;
3309 case WMA_BEACON_TX_RATE_12_M:
3310 return MLME_BCN_TX_RATE_CODE_12_M;
3311 case WMA_BEACON_TX_RATE_18_M:
3312 return MLME_BCN_TX_RATE_CODE_18_M;
3313 case WMA_BEACON_TX_RATE_24_M:
3314 return MLME_BCN_TX_RATE_CODE_24_M;
3315 case WMA_BEACON_TX_RATE_36_M:
3316 return MLME_BCN_TX_RATE_CODE_36_M;
3317 case WMA_BEACON_TX_RATE_48_M:
3318 return MLME_BCN_TX_RATE_CODE_48_M;
3319 case WMA_BEACON_TX_RATE_54_M:
3320 return MLME_BCN_TX_RATE_CODE_54_M;
3321 default:
3322 return MLME_BCN_TX_RATE_CODE_1_M;
3323 }
3324 }
3325
3326 #ifdef WLAN_BCN_RATECODE_ENABLE
3327 /**
3328 * wma_update_beacon_tx_rate_code() - Update bcn_tx_rate_code
3329 * @mlme_obj: pointer to mlme object
3330 *
3331 * Return: none
3332 */
wma_update_beacon_tx_rate_code(struct vdev_mlme_obj * mlme_obj)3333 static void wma_update_beacon_tx_rate_code(struct vdev_mlme_obj *mlme_obj)
3334 {
3335 uint8_t preamble, nss, rix;
3336 uint32_t rate_code;
3337
3338 rate_code = mlme_obj->mgmt.rate_info.bcn_tx_rate;
3339
3340 rix = rate_code & RATECODE_V1_RIX_MASK;
3341 nss = (rate_code >> RATECODE_V1_NSS_OFFSET) & RATECODE_V1_NSS_MASK;
3342 preamble = rate_code >> RATECODE_V1_PREAMBLE_OFFSET;
3343
3344 mlme_obj->mgmt.rate_info.bcn_tx_rate_code =
3345 wlan_mlme_assemble_rate_code(preamble, nss, rix);
3346 }
3347 #else
wma_update_beacon_tx_rate_code(struct vdev_mlme_obj * mlme_obj)3348 static void wma_update_beacon_tx_rate_code(struct vdev_mlme_obj *mlme_obj)
3349 {
3350 }
3351 #endif
3352
wma_vdev_pre_start(uint8_t vdev_id,bool restart)3353 QDF_STATUS wma_vdev_pre_start(uint8_t vdev_id, bool restart)
3354 {
3355 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
3356 struct wma_txrx_node *intr;
3357 struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
3358 struct wlan_mlme_nss_chains *ini_cfg;
3359 struct vdev_mlme_obj *mlme_obj;
3360 struct wlan_objmgr_vdev *vdev;
3361 struct wlan_channel *des_chan;
3362 QDF_STATUS status;
3363 enum coex_btc_chain_mode btc_chain_mode;
3364 struct wlan_mlme_qos *qos_aggr;
3365 uint8_t amsdu_val;
3366
3367 if (!wma || !mac_ctx)
3368 return QDF_STATUS_E_FAILURE;
3369
3370 intr = wma->interfaces;
3371 if (!intr) {
3372 wma_err("Invalid interface");
3373 return QDF_STATUS_E_FAILURE;
3374 }
3375 if (vdev_id >= WLAN_MAX_VDEVS) {
3376 wma_err("Invalid vdev id");
3377 return QDF_STATUS_E_INVAL;
3378 }
3379 vdev = intr[vdev_id].vdev;
3380 if (!vdev) {
3381 wma_err("Invalid vdev");
3382 return QDF_STATUS_E_FAILURE;
3383 }
3384
3385 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
3386 if (!mlme_obj) {
3387 wma_err("vdev component object is NULL");
3388 return QDF_STATUS_E_FAILURE;
3389 }
3390 des_chan = vdev->vdev_mlme.des_chan;
3391
3392 ini_cfg = mlme_get_ini_vdev_config(vdev);
3393 if (!ini_cfg) {
3394 wma_err("nss chain ini config NULL");
3395 return QDF_STATUS_E_FAILURE;
3396 }
3397
3398 intr[vdev_id].config.gtx_info.gtxRTMask[0] =
3399 CFG_TGT_DEFAULT_GTX_HT_MASK;
3400 intr[vdev_id].config.gtx_info.gtxRTMask[1] =
3401 CFG_TGT_DEFAULT_GTX_VHT_MASK;
3402
3403 intr[vdev_id].config.gtx_info.gtxUsrcfg =
3404 mac_ctx->mlme_cfg->sta.tgt_gtx_usr_cfg;
3405
3406 intr[vdev_id].config.gtx_info.gtxPERThreshold =
3407 CFG_TGT_DEFAULT_GTX_PER_THRESHOLD;
3408 intr[vdev_id].config.gtx_info.gtxPERMargin =
3409 CFG_TGT_DEFAULT_GTX_PER_MARGIN;
3410 intr[vdev_id].config.gtx_info.gtxTPCstep =
3411 CFG_TGT_DEFAULT_GTX_TPC_STEP;
3412 intr[vdev_id].config.gtx_info.gtxTPCMin =
3413 CFG_TGT_DEFAULT_GTX_TPC_MIN;
3414 intr[vdev_id].config.gtx_info.gtxBWMask =
3415 CFG_TGT_DEFAULT_GTX_BW_MASK;
3416 intr[vdev_id].chan_width = des_chan->ch_width;
3417 intr[vdev_id].ch_freq = des_chan->ch_freq;
3418 intr[vdev_id].ch_flagext = des_chan->ch_flagext;
3419
3420 /*
3421 * If the channel has DFS set, flip on radar reporting.
3422 *
3423 * It may be that this should only be done for hostap operation
3424 * as this flag may be interpreted (at some point in the future)
3425 * by the firmware as "oh, and please do radar DETECTION."
3426 *
3427 * If that is ever the case we would insert the decision whether to
3428 * enable the firmware flag here.
3429 */
3430 if (QDF_GLOBAL_MONITOR_MODE != cds_get_conparam() &&
3431 utils_is_dfs_chan_for_freq(wma->pdev, des_chan->ch_freq))
3432 mlme_obj->mgmt.generic.disable_hw_ack = true;
3433
3434 if (mlme_obj->mgmt.rate_info.bcn_tx_rate) {
3435 wma_debug("beacon tx rate [%u * 100 Kbps]",
3436 mlme_obj->mgmt.rate_info.bcn_tx_rate);
3437 /*
3438 * beacon_tx_rate is in multiples of 100 Kbps.
3439 * Convert the data rate to hw rate code.
3440 */
3441 mlme_obj->mgmt.rate_info.bcn_tx_rate =
3442 wma_get_bcn_rate_code(mlme_obj->mgmt.rate_info.bcn_tx_rate);
3443 wma_update_beacon_tx_rate_code(mlme_obj);
3444 }
3445
3446 if (!restart) {
3447 wma_debug("vdev_id: %d, unpausing tx_ll_queue at VDEV_START",
3448 vdev_id);
3449
3450 cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
3451 vdev_id, 0xffffffff, 0);
3452 wma_vdev_update_pause_bitmap(vdev_id, 0);
3453 }
3454
3455 /* Send the dynamic nss chain params before vdev start to fw */
3456 if (wma->dynamic_nss_chains_support && !restart)
3457 wma_vdev_nss_chain_params_send(vdev_id, ini_cfg);
3458
3459 status = ucfg_coex_psoc_get_btc_chain_mode(wma->psoc, &btc_chain_mode);
3460 if (QDF_IS_STATUS_ERROR(status)) {
3461 wma_err("Failed to get btc chain mode");
3462 return QDF_STATUS_E_FAILURE;
3463 }
3464
3465 if (btc_chain_mode != WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED) {
3466 status = ucfg_coex_send_btc_chain_mode(vdev, btc_chain_mode);
3467 if (QDF_IS_STATUS_ERROR(status)) {
3468 wma_err("Failed to send btc chain mode %d",
3469 btc_chain_mode);
3470 return QDF_STATUS_E_FAILURE;
3471 }
3472 }
3473
3474 qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params;
3475 status = wma_set_tx_rx_aggr_size(vdev_id, qos_aggr->tx_aggregation_size,
3476 qos_aggr->rx_aggregation_size,
3477 WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU);
3478 if (QDF_IS_STATUS_ERROR(status))
3479 wma_err("failed to set aggregation sizes(status = %d)", status);
3480
3481 if (mac_ctx->is_usr_cfg_amsdu_enabled) {
3482 status = wlan_mlme_get_max_amsdu_num(wma->psoc, &amsdu_val);
3483 if (QDF_IS_STATUS_ERROR(status)) {
3484 wma_err("failed to get amsdu aggr.size(status = %d)",
3485 status);
3486 } else {
3487 status = wma_set_tx_rx_aggr_size(
3488 vdev_id, amsdu_val, amsdu_val,
3489 WMI_VDEV_CUSTOM_AGGR_TYPE_AMSDU);
3490 if (QDF_IS_STATUS_ERROR(status))
3491 wma_err("failed to set amsdu aggr.size(status = %d)",
3492 status);
3493 }
3494 }
3495
3496 if (mlme_obj->mgmt.generic.type == WMI_VDEV_TYPE_STA) {
3497 status = wma_set_tx_rx_aggr_size_per_ac(wma, vdev_id, qos_aggr,
3498 WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU);
3499
3500 if (QDF_IS_STATUS_ERROR(status))
3501 wma_err("failed to set aggr size per ac(status = %d)",
3502 status);
3503 }
3504
3505 return QDF_STATUS_SUCCESS;
3506 }
3507
3508 /**
3509 * wma_peer_assoc_conf_handler() - peer assoc conf handler
3510 * @handle: wma handle
3511 * @cmd_param_info: event buffer
3512 * @len: buffer length
3513 *
3514 * Return: 0 for success or error code
3515 */
wma_peer_assoc_conf_handler(void * handle,uint8_t * cmd_param_info,uint32_t len)3516 int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info,
3517 uint32_t len)
3518 {
3519 tp_wma_handle wma = (tp_wma_handle) handle;
3520 WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *param_buf;
3521 wmi_peer_assoc_conf_event_fixed_param *event;
3522 struct wma_target_req *req_msg;
3523 uint8_t macaddr[QDF_MAC_ADDR_SIZE];
3524 int status = 0;
3525
3526 param_buf = (WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *) cmd_param_info;
3527 if (!param_buf) {
3528 wma_err("Invalid peer assoc conf event buffer");
3529 return -EINVAL;
3530 }
3531
3532 event = param_buf->fixed_param;
3533 if (!event) {
3534 wma_err("Invalid peer assoc conf event buffer");
3535 return -EINVAL;
3536 }
3537
3538 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
3539 wma_debug("peer assoc conf for vdev:%d mac="QDF_MAC_ADDR_FMT,
3540 event->vdev_id, QDF_MAC_ADDR_REF(macaddr));
3541
3542 req_msg = wma_find_req(wma, event->vdev_id,
3543 WMA_PEER_ASSOC_CNF_START, NULL);
3544
3545 if (!req_msg) {
3546 wma_err("Failed to lookup request message for vdev %d",
3547 event->vdev_id);
3548 return -EINVAL;
3549 }
3550
3551 qdf_mc_timer_stop(&req_msg->event_timeout);
3552
3553 if (req_msg->msg_type == WMA_ADD_STA_REQ) {
3554 tpAddStaParams params = (tpAddStaParams)req_msg->user_data;
3555
3556 if (!params) {
3557 wma_err("add STA params is NULL for vdev %d",
3558 event->vdev_id);
3559 status = -EINVAL;
3560 goto free_req_msg;
3561 }
3562
3563 /* peer assoc conf event means the cmd succeeds */
3564 params->status = event->status;
3565 wma_debug("Send ADD_STA_RSP: statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d",
3566 params->staType, params->smesessionId,
3567 params->assocId, QDF_MAC_ADDR_REF(params->bssId),
3568 params->status);
3569 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
3570 (void *)params, 0);
3571 } else if (req_msg->msg_type == WMA_ADD_BSS_REQ) {
3572 wma_send_add_bss_resp(wma, event->vdev_id, event->status);
3573 } else {
3574 wma_err("Unhandled request message type: %d", req_msg->msg_type);
3575 }
3576
3577 free_req_msg:
3578 qdf_mc_timer_destroy(&req_msg->event_timeout);
3579 qdf_mem_free(req_msg);
3580
3581 return status;
3582 }
3583
wma_peer_create_confirm_handler(void * handle,uint8_t * evt_param_info,uint32_t len)3584 int wma_peer_create_confirm_handler(void *handle, uint8_t *evt_param_info,
3585 uint32_t len)
3586 {
3587 tp_wma_handle wma = (tp_wma_handle)handle;
3588 wmi_peer_create_conf_event_fixed_param *peer_create_rsp;
3589 WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *param_buf;
3590 struct wma_target_req *req_msg = NULL;
3591 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3592 struct peer_create_rsp_params *rsp_data;
3593 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
3594 struct qdf_mac_addr peer_mac;
3595 QDF_STATUS status = QDF_STATUS_E_FAILURE;
3596 int ret = -EINVAL;
3597 uint8_t req_msg_type;
3598 struct wlan_objmgr_peer *peer;
3599 struct cdp_peer_setup_info peer_info = {0};
3600
3601 param_buf = (WMI_PEER_CREATE_CONF_EVENTID_param_tlvs *)evt_param_info;
3602 if (!param_buf) {
3603 wma_err("Invalid peer create conf evt buffer");
3604 return -EINVAL;
3605 }
3606
3607 peer_create_rsp = param_buf->fixed_param;
3608
3609 WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_create_rsp->peer_macaddr,
3610 peer_mac.bytes);
3611 if (qdf_is_macaddr_zero(&peer_mac) ||
3612 qdf_is_macaddr_broadcast(&peer_mac) ||
3613 qdf_is_macaddr_group(&peer_mac)) {
3614 wma_err("Invalid bssid");
3615 return -EINVAL;
3616 }
3617
3618 wma_debug("vdev:%d Peer create confirm for bssid: " QDF_MAC_ADDR_FMT,
3619 peer_create_rsp->vdev_id, QDF_MAC_ADDR_REF(peer_mac.bytes));
3620 req_msg = wma_find_remove_req_msgtype(wma, peer_create_rsp->vdev_id,
3621 WMA_PEER_CREATE_REQ);
3622 if (!req_msg) {
3623 wma_debug("vdev:%d Failed to lookup peer create request msg",
3624 peer_create_rsp->vdev_id);
3625 return -EINVAL;
3626 }
3627
3628 rsp_data = (struct peer_create_rsp_params *)req_msg->user_data;
3629 req_msg_type = req_msg->type;
3630
3631 qdf_mc_timer_stop(&req_msg->event_timeout);
3632 qdf_mc_timer_destroy(&req_msg->event_timeout);
3633 qdf_mem_free(rsp_data);
3634 qdf_mem_free(req_msg);
3635
3636 if (req_msg_type == WMA_PASN_PEER_CREATE_RESPONSE) {
3637 wma_pasn_handle_peer_create_conf(wma, &peer_mac,
3638 peer_create_rsp->status,
3639 peer_create_rsp->vdev_id);
3640 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
3641 return 0;
3642 }
3643
3644 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
3645 if (!peer_create_rsp->status) {
3646 if (!dp_soc) {
3647 wma_err("DP SOC context is NULL");
3648 goto fail;
3649 }
3650
3651 peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_mac.bytes,
3652 WLAN_LEGACY_WMA_ID);
3653 if (!peer) {
3654 status = QDF_STATUS_E_FAILURE;
3655 goto fail;
3656 }
3657
3658 wma_peer_setup_fill_info(wma->psoc, peer, &peer_info);
3659 wma_peer_tbl_trans_add_entry(peer, true, &peer_info);
3660 wma_cdp_peer_setup(dp_soc, peer_create_rsp->vdev_id,
3661 peer, &peer_info);
3662 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
3663
3664 status = QDF_STATUS_SUCCESS;
3665 ret = 0;
3666 }
3667
3668 fail:
3669 if (QDF_IS_STATUS_ERROR(status))
3670 wma_remove_peer(wma, peer_mac.bytes, peer_create_rsp->vdev_id,
3671 (peer_create_rsp->status > 0) ? true : false);
3672
3673 if (mac)
3674 lim_send_peer_create_resp(mac, peer_create_rsp->vdev_id, status,
3675 peer_mac.bytes);
3676
3677 return ret;
3678 }
3679
3680 #ifdef FEATURE_WDS
3681 /*
3682 * wma_cdp_cp_peer_del_response - handle peer delete response
3683 * @psoc: psoc object pointer
3684 * @mac_addr: Mac address of the peer
3685 * @vdev_id: id of virtual device object
3686 *
3687 * when peer map v2 is enabled, cdp_peer_teardown() does not remove the AST from
3688 * hash table. Call cdp_cp_peer_del_response() when peer delete response is
3689 * received from fw to delete the AST entry from the AST hash.
3690 *
3691 * Return: None
3692 */
3693 static void
wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc * psoc,uint8_t * peer_mac,uint8_t vdev_id)3694 wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc *psoc,
3695 uint8_t *peer_mac, uint8_t vdev_id)
3696 {
3697 ol_txrx_soc_handle soc_txrx_handle;
3698
3699 soc_txrx_handle = wlan_psoc_get_dp_handle(psoc);
3700 cdp_cp_peer_del_response(soc_txrx_handle, vdev_id, peer_mac);
3701 }
3702 #else
3703 static void
wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc * psoc,uint8_t * peer_mac,uint8_t vdev_id)3704 wma_cdp_cp_peer_del_response(struct wlan_objmgr_psoc *psoc,
3705 uint8_t *peer_mac, uint8_t vdev_id)
3706 {
3707 }
3708 #endif
3709
3710 /**
3711 * wma_peer_delete_handler() - peer delete response handler
3712 * @handle: wma handle
3713 * @cmd_param_info: event buffer
3714 * @len: buffer length
3715 *
3716 * Return: 0 for success or error code
3717 */
wma_peer_delete_handler(void * handle,uint8_t * cmd_param_info,uint32_t len)3718 int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
3719 uint32_t len)
3720 {
3721 tp_wma_handle wma = (tp_wma_handle) handle;
3722 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
3723 wmi_peer_delete_cmd_fixed_param *event;
3724 struct wma_target_req *req_msg;
3725 tDeleteStaParams *del_sta;
3726 uint8_t macaddr[QDF_MAC_ADDR_SIZE];
3727 int status = 0;
3728 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3729
3730 if (!mac) {
3731 wma_err("mac context is null");
3732 return -EINVAL;
3733 }
3734 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info;
3735 if (!param_buf) {
3736 wma_err("Invalid vdev delete event buffer");
3737 return -EINVAL;
3738 }
3739
3740 event = (wmi_peer_delete_cmd_fixed_param *)param_buf->fixed_param;
3741 if (!event) {
3742 wma_err("Invalid vdev delete event buffer");
3743 return -EINVAL;
3744 }
3745
3746 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
3747 wma_debug("Peer Delete Response, vdev %d Peer "QDF_MAC_ADDR_FMT,
3748 event->vdev_id, QDF_MAC_ADDR_REF(macaddr));
3749 wlan_roam_debug_log(event->vdev_id, DEBUG_PEER_DELETE_RESP,
3750 DEBUG_INVALID_PEER_ID, macaddr, NULL, 0, 0);
3751 req_msg = wma_find_remove_req_msgtype(wma, event->vdev_id,
3752 WMA_DELETE_STA_REQ);
3753 if (!req_msg) {
3754 wma_debug("Peer Delete response is not handled");
3755 return -EINVAL;
3756 }
3757
3758 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
3759
3760 /* Cleanup timeout handler */
3761 qdf_mc_timer_stop(&req_msg->event_timeout);
3762 qdf_mc_timer_destroy(&req_msg->event_timeout);
3763
3764 if (req_msg->type == WMA_DELETE_STA_RSP_START) {
3765 del_sta = req_msg->user_data;
3766 if (del_sta->respReqd) {
3767 wma_debug("Sending peer del rsp to umac");
3768 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
3769 (void *)del_sta, QDF_STATUS_SUCCESS);
3770 } else {
3771 qdf_mem_free(del_sta);
3772 }
3773 } else if (req_msg->type == WMA_DEL_P2P_SELF_STA_RSP_START) {
3774 struct del_sta_self_rsp_params *data;
3775
3776 data = (struct del_sta_self_rsp_params *)req_msg->user_data;
3777 wma_debug("Calling vdev detach handler");
3778 wma_handle_vdev_detach(wma, data->self_sta_param);
3779 mlme_vdev_self_peer_delete_resp(data->self_sta_param);
3780 qdf_mem_free(data);
3781 } else if (req_msg->type == WMA_SET_LINK_PEER_RSP ||
3782 req_msg->type == WMA_DELETE_PEER_RSP) {
3783 wma_send_vdev_down_req(wma, req_msg->user_data);
3784 } else if (req_msg->type == WMA_DELETE_STA_CONNECT_RSP) {
3785 wma_debug("wma delete peer completed vdev %d",
3786 req_msg->vdev_id);
3787 lim_cm_send_connect_rsp(mac, NULL, req_msg->user_data,
3788 CM_GENERIC_FAILURE,
3789 QDF_STATUS_E_FAILURE, 0, false);
3790 cm_free_join_req(req_msg->user_data);
3791 }
3792
3793 wma_cdp_cp_peer_del_response(wma->psoc, macaddr, event->vdev_id);
3794 qdf_mem_free(req_msg);
3795
3796 return status;
3797 }
3798
3799 static
wma_trigger_recovery_assert_on_fw_timeout(uint16_t wma_msg,enum qdf_hang_reason reason)3800 void wma_trigger_recovery_assert_on_fw_timeout(uint16_t wma_msg,
3801 enum qdf_hang_reason reason)
3802 {
3803 wma_err("%s timed out, triggering recovery",
3804 mac_trace_get_wma_msg_string(wma_msg));
3805 qdf_trigger_self_recovery(NULL, reason);
3806 }
3807
wma_crash_on_fw_timeout(bool crash_enabled)3808 static inline bool wma_crash_on_fw_timeout(bool crash_enabled)
3809 {
3810 /* Discard FW timeouts and dont crash during SSR */
3811 if (cds_is_driver_recovering())
3812 return false;
3813
3814 /* Firmware is down send failure response */
3815 if (cds_is_fw_down())
3816 return false;
3817
3818 if (cds_is_driver_unloading())
3819 return false;
3820
3821 return crash_enabled;
3822 }
3823
3824 /**
3825 * wma_hold_req_timer() - wma hold request timeout function
3826 * @data: target request params
3827 *
3828 * Return: none
3829 */
wma_hold_req_timer(void * data)3830 void wma_hold_req_timer(void *data)
3831 {
3832 tp_wma_handle wma;
3833 struct wma_target_req *tgt_req = (struct wma_target_req *)data;
3834 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
3835 QDF_STATUS status;
3836
3837 wma = cds_get_context(QDF_MODULE_ID_WMA);
3838 if (!wma)
3839 return;
3840
3841 status = wma_find_req_on_timer_expiry(wma, tgt_req);
3842
3843 if (QDF_IS_STATUS_ERROR(status)) {
3844 /*
3845 * if find request failed, then firmware rsp should have
3846 * consumed the buffer. Do not free.
3847 */
3848 wma_debug("Failed to lookup request message - %pK", tgt_req);
3849 return;
3850 }
3851 wma_alert("request %d is timed out for vdev_id - %d",
3852 tgt_req->msg_type, tgt_req->vdev_id);
3853
3854 if (tgt_req->msg_type == WMA_ADD_STA_REQ) {
3855 tpAddStaParams params = (tpAddStaParams) tgt_req->user_data;
3856
3857 params->status = QDF_STATUS_E_TIMEOUT;
3858 wma_alert("WMA_ADD_STA_REQ timed out");
3859 wma_debug("Sending add sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)",
3860 QDF_MAC_ADDR_REF(params->staMac), params->status);
3861 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3862 wma_trigger_recovery_assert_on_fw_timeout(
3863 WMA_ADD_STA_REQ,
3864 QDF_AP_STA_CONNECT_REQ_TIMEOUT);
3865 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
3866 (void *)params, 0);
3867 } else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) {
3868
3869 wma_alert("WMA_ADD_BSS_REQ timed out");
3870 wma_debug("Sending add bss rsp to umac (vdev %d, status:%d)",
3871 tgt_req->vdev_id, QDF_STATUS_E_TIMEOUT);
3872
3873 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3874 wma_trigger_recovery_assert_on_fw_timeout(
3875 WMA_ADD_BSS_REQ,
3876 QDF_STA_AP_CONNECT_REQ_TIMEOUT);
3877
3878 wma_send_add_bss_resp(wma, tgt_req->vdev_id,
3879 QDF_STATUS_E_TIMEOUT);
3880 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3881 (tgt_req->type == WMA_DELETE_STA_RSP_START)) {
3882 tpDeleteStaParams params =
3883 (tpDeleteStaParams) tgt_req->user_data;
3884 params->status = QDF_STATUS_E_TIMEOUT;
3885 wma_err("WMA_DEL_STA_REQ timed out");
3886 wma_debug("Sending del sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)",
3887 QDF_MAC_ADDR_REF(params->staMac), params->status);
3888
3889 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3890 wma_trigger_recovery_assert_on_fw_timeout(
3891 WMA_DELETE_STA_REQ,
3892 QDF_PEER_DELETION_TIMEDOUT);
3893 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
3894 (void *)params, 0);
3895 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3896 (tgt_req->type == WMA_DEL_P2P_SELF_STA_RSP_START)) {
3897 struct del_sta_self_rsp_params *del_sta;
3898
3899 del_sta = (struct del_sta_self_rsp_params *)tgt_req->user_data;
3900
3901 del_sta->self_sta_param->status = QDF_STATUS_E_TIMEOUT;
3902 wma_alert("wma delete sta p2p request timed out");
3903
3904 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3905 wma_trigger_recovery_assert_on_fw_timeout(
3906 WMA_DELETE_STA_REQ,
3907 QDF_PEER_DELETION_TIMEDOUT);
3908 wma_handle_vdev_detach(wma, del_sta->self_sta_param);
3909 mlme_vdev_self_peer_delete_resp(del_sta->self_sta_param);
3910 qdf_mem_free(tgt_req->user_data);
3911 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3912 (tgt_req->type == WMA_SET_LINK_PEER_RSP ||
3913 tgt_req->type == WMA_DELETE_PEER_RSP)) {
3914 struct del_bss_resp *params =
3915 (struct del_bss_resp *)tgt_req->user_data;
3916
3917 params->status = QDF_STATUS_E_TIMEOUT;
3918 wma_err("wma delete peer for del bss req timed out");
3919
3920 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3921 wma_trigger_recovery_assert_on_fw_timeout(
3922 WMA_DELETE_STA_REQ,
3923 QDF_PEER_DELETION_TIMEDOUT);
3924 wma_send_vdev_down_req(wma, params);
3925 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3926 (tgt_req->type == WMA_DELETE_STA_CONNECT_RSP)) {
3927 wma_err("wma delete peer timed out vdev %d",
3928 tgt_req->vdev_id);
3929
3930 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3931 wma_trigger_recovery_assert_on_fw_timeout(
3932 WMA_DELETE_STA_REQ,
3933 QDF_PEER_DELETION_TIMEDOUT);
3934 if (!mac) {
3935 wma_err("mac: Null Pointer Error");
3936 goto timer_destroy;
3937 }
3938 lim_cm_send_connect_rsp(mac, NULL, tgt_req->user_data,
3939 CM_GENERIC_FAILURE,
3940 QDF_STATUS_E_FAILURE, 0, false);
3941 cm_free_join_req(tgt_req->user_data);
3942 } else if ((tgt_req->msg_type == SIR_HAL_PDEV_SET_HW_MODE) &&
3943 (tgt_req->type == WMA_PDEV_SET_HW_MODE_RESP)) {
3944 struct sir_set_hw_mode_resp *params =
3945 qdf_mem_malloc(sizeof(*params));
3946
3947 wma_err("set hw mode req timed out");
3948
3949 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3950 wma_trigger_recovery_assert_on_fw_timeout(
3951 SIR_HAL_PDEV_SET_HW_MODE,
3952 QDF_MAC_HW_MODE_CHANGE_TIMEOUT);
3953 if (!params)
3954 goto timer_destroy;
3955
3956 params->status = SET_HW_MODE_STATUS_ECANCELED;
3957 params->cfgd_hw_mode_index = 0;
3958 params->num_vdev_mac_entries = 0;
3959 wma_send_msg_high_priority(wma, SIR_HAL_PDEV_SET_HW_MODE_RESP,
3960 params, 0);
3961 } else if ((tgt_req->msg_type == SIR_HAL_PDEV_DUAL_MAC_CFG_REQ) &&
3962 (tgt_req->type == WMA_PDEV_MAC_CFG_RESP)) {
3963 struct sir_dual_mac_config_resp *resp =
3964 qdf_mem_malloc(sizeof(*resp));
3965
3966 wma_err("set dual mac config timeout");
3967 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3968 wma_trigger_recovery_assert_on_fw_timeout(
3969 SIR_HAL_PDEV_DUAL_MAC_CFG_REQ,
3970 QDF_MAC_HW_MODE_CONFIG_TIMEOUT);
3971 if (!resp)
3972 goto timer_destroy;
3973
3974 resp->status = SET_HW_MODE_STATUS_ECANCELED;
3975 wma_send_msg_high_priority(wma, SIR_HAL_PDEV_MAC_CFG_RESP,
3976 resp, 0);
3977 } else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) &&
3978 (tgt_req->type == WMA_PEER_CREATE_RESPONSE)) {
3979 struct peer_create_rsp_params *peer_create_rsp;
3980 struct qdf_mac_addr *peer_mac;
3981
3982 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
3983 wma_trigger_recovery_assert_on_fw_timeout(
3984 WMA_PEER_CREATE_RESPONSE,
3985 WMA_PEER_CREATE_RESPONSE_TIMEOUT);
3986
3987 peer_create_rsp =
3988 (struct peer_create_rsp_params *)tgt_req->user_data;
3989 peer_mac = &peer_create_rsp->peer_mac;
3990 wma_remove_peer(wma, peer_mac->bytes,
3991 tgt_req->vdev_id, false);
3992 if (!mac) {
3993 qdf_mem_free(tgt_req->user_data);
3994 goto timer_destroy;
3995 }
3996
3997 lim_send_peer_create_resp(mac, tgt_req->vdev_id,
3998 QDF_STATUS_E_TIMEOUT,
3999 (uint8_t *)tgt_req->user_data);
4000 qdf_mem_free(tgt_req->user_data);
4001 } else if ((tgt_req->msg_type == WMA_PEER_CREATE_REQ) &&
4002 (tgt_req->type == WMA_PASN_PEER_CREATE_RESPONSE)) {
4003 struct peer_create_rsp_params *peer_create_rsp;
4004 struct qdf_mac_addr *peer_mac;
4005
4006 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
4007 wma_trigger_recovery_assert_on_fw_timeout(
4008 WMA_PEER_CREATE_RESPONSE,
4009 WMA_PEER_CREATE_RESPONSE_TIMEOUT);
4010
4011 peer_create_rsp =
4012 (struct peer_create_rsp_params *)tgt_req->user_data;
4013 peer_mac = &peer_create_rsp->peer_mac;
4014
4015 wma_pasn_handle_peer_create_conf(
4016 wma, peer_mac, QDF_STATUS_E_TIMEOUT,
4017 tgt_req->vdev_id);
4018 qdf_mem_free(tgt_req->user_data);
4019 } else if (tgt_req->msg_type == WMA_PASN_PEER_DELETE_REQUEST &&
4020 tgt_req->type == WMA_PASN_PEER_DELETE_RESPONSE) {
4021 wma_err("PASN Peer delete all resp not received. vdev:%d",
4022 tgt_req->vdev_id);
4023 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash))
4024 wma_trigger_recovery_assert_on_fw_timeout(
4025 WMA_PASN_PEER_DELETE_RESPONSE,
4026 WMA_PEER_DELETE_RESPONSE_TIMEOUT);
4027
4028 wma_resume_vdev_delete(wma, tgt_req->vdev_id);
4029 } else {
4030 wma_err("Unhandled timeout for msg_type:%d and type:%d",
4031 tgt_req->msg_type, tgt_req->type);
4032 QDF_BUG(0);
4033 }
4034
4035 timer_destroy:
4036 qdf_mc_timer_destroy(&tgt_req->event_timeout);
4037 qdf_mem_free(tgt_req);
4038 }
4039
4040 /**
4041 * wma_fill_hold_req() - fill wma request
4042 * @wma: wma handle
4043 * @vdev_id: vdev id
4044 * @msg_type: message type
4045 * @type: request type
4046 * @params: request params
4047 * @timeout: timeout value
4048 *
4049 * Return: wma_target_req ptr
4050 */
wma_fill_hold_req(tp_wma_handle wma,uint8_t vdev_id,uint32_t msg_type,uint8_t type,void * params,uint32_t timeout)4051 struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma,
4052 uint8_t vdev_id,
4053 uint32_t msg_type, uint8_t type,
4054 void *params, uint32_t timeout)
4055 {
4056 struct wma_target_req *req;
4057 QDF_STATUS status;
4058
4059 req = qdf_mem_malloc(sizeof(*req));
4060 if (!req)
4061 return NULL;
4062
4063 wma_debug("vdev_id %d msg %d type %d", vdev_id, msg_type, type);
4064 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
4065 req->vdev_id = vdev_id;
4066 req->msg_type = msg_type;
4067 req->type = type;
4068 req->user_data = params;
4069 status = qdf_list_insert_back(&wma->wma_hold_req_queue, &req->node);
4070 if (QDF_STATUS_SUCCESS != status) {
4071 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
4072 wma_err("Failed add request in queue");
4073 qdf_mem_free(req);
4074 return NULL;
4075 }
4076 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
4077 qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW,
4078 wma_hold_req_timer, req);
4079 qdf_mc_timer_start(&req->event_timeout, timeout);
4080 return req;
4081 }
4082
wma_remove_peer_req(tp_wma_handle wma,uint8_t vdev_id,uint8_t type,struct qdf_mac_addr * peer_addr)4083 void wma_remove_peer_req(tp_wma_handle wma, uint8_t vdev_id,
4084 uint8_t type, struct qdf_mac_addr *peer_addr)
4085 {
4086 struct wma_target_req *req_msg;
4087
4088 wma_debug("Remove req for vdev: %d type: %d", vdev_id, type);
4089 req_msg = wma_find_req(wma, vdev_id, type, peer_addr);
4090 if (!req_msg) {
4091 wma_err("target req not found for vdev: %d type: %d",
4092 vdev_id, type);
4093 return;
4094 }
4095
4096 qdf_mc_timer_stop(&req_msg->event_timeout);
4097 qdf_mc_timer_destroy(&req_msg->event_timeout);
4098 qdf_mem_free(req_msg);
4099 }
4100
4101 /**
4102 * wma_remove_req() - remove request
4103 * @wma: wma handle
4104 * @vdev_id: vdev id
4105 * @type: type
4106 *
4107 * Return: none
4108 */
wma_remove_req(tp_wma_handle wma,uint8_t vdev_id,uint8_t type)4109 void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id,
4110 uint8_t type)
4111 {
4112 struct wma_target_req *req_msg;
4113
4114 wma_debug("Remove req for vdev: %d type: %d", vdev_id, type);
4115 req_msg = wma_find_req(wma, vdev_id, type, NULL);
4116 if (!req_msg) {
4117 wma_err("target req not found for vdev: %d type: %d",
4118 vdev_id, type);
4119 return;
4120 }
4121
4122 qdf_mc_timer_stop(&req_msg->event_timeout);
4123 qdf_mc_timer_destroy(&req_msg->event_timeout);
4124 qdf_mem_free(req_msg);
4125 }
4126
4127 #define MAX_VDEV_SET_BSS_PARAMS 5
4128 /* params being sent:
4129 * 1.wmi_vdev_param_beacon_interval
4130 * 2.wmi_vdev_param_dtim_period
4131 * 3.wmi_vdev_param_tx_pwrlimit
4132 * 4.wmi_vdev_param_slot_time
4133 * 5.wmi_vdev_param_protection_mode
4134 */
4135
4136 /**
4137 * wma_vdev_set_bss_params() - BSS set params functions
4138 * @wma: wma handle
4139 * @vdev_id: vdev id
4140 * @beaconInterval: beacon interval
4141 * @dtimPeriod: DTIM period
4142 * @shortSlotTimeSupported: short slot time
4143 * @llbCoexist: llbCoexist
4144 * @maxTxPower: max tx power
4145 * @bss_max_idle_period: BSS max idle period
4146 *
4147 * Return: QDF_STATUS
4148 */
4149 static QDF_STATUS
wma_vdev_set_bss_params(tp_wma_handle wma,int vdev_id,tSirMacBeaconInterval beaconInterval,uint8_t dtimPeriod,uint8_t shortSlotTimeSupported,uint8_t llbCoexist,int8_t maxTxPower,uint16_t bss_max_idle_period)4150 wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id,
4151 tSirMacBeaconInterval beaconInterval,
4152 uint8_t dtimPeriod, uint8_t shortSlotTimeSupported,
4153 uint8_t llbCoexist, int8_t maxTxPower,
4154 uint16_t bss_max_idle_period)
4155 {
4156 uint32_t slot_time;
4157 struct wma_txrx_node *intr = wma->interfaces;
4158 struct dev_set_param setparam[MAX_VDEV_SET_BSS_PARAMS];
4159 uint8_t index = 0;
4160 enum ieee80211_protmode prot_mode;
4161 QDF_STATUS ret;
4162
4163 ret = QDF_STATUS_E_FAILURE;
4164 /* Beacon Interval setting */
4165 ret = mlme_check_index_setparam(setparam,
4166 wmi_vdev_param_beacon_interval,
4167 beaconInterval, index++,
4168 MAX_VDEV_SET_BSS_PARAMS);
4169 if (QDF_IS_STATUS_ERROR(ret)) {
4170 wma_debug("failed to send wmi_vdev_param_beacon_interval to fw");
4171 goto error;
4172 }
4173
4174 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id,
4175 &intr[vdev_id].config.gtx_info);
4176 if (QDF_IS_STATUS_ERROR(ret)) {
4177 wma_err("failed to set vdev gtx cfg");
4178 goto error;
4179 }
4180 ret = mlme_check_index_setparam(setparam, wmi_vdev_param_dtim_period,
4181 dtimPeriod, index++,
4182 MAX_VDEV_SET_BSS_PARAMS);
4183 if (QDF_IS_STATUS_ERROR(ret)) {
4184 wma_debug("failed to send wmi_vdev_param_dtim_period fw");
4185 goto error;
4186 }
4187 intr[vdev_id].dtimPeriod = dtimPeriod;
4188
4189 if (!wlan_reg_is_ext_tpc_supported(wma->psoc)) {
4190 if (!maxTxPower)
4191 wma_warn("Setting Tx power limit to 0");
4192
4193 wma_nofl_debug("TXP[W][set_bss_params]: %d", maxTxPower);
4194
4195 if (maxTxPower != INVALID_TXPOWER) {
4196 ret = mlme_check_index_setparam(
4197 setparam,
4198 wmi_vdev_param_tx_pwrlimit,
4199 maxTxPower, index++,
4200 MAX_VDEV_SET_BSS_PARAMS);
4201 if (QDF_IS_STATUS_ERROR(ret)) {
4202 wma_debug("failed to send wmi_vdev_param_tx_pwrlimit to fw");
4203 goto error;
4204 }
4205 } else {
4206 wma_err("Invalid max Tx power");
4207 }
4208 }
4209 /* Slot time */
4210 if (shortSlotTimeSupported)
4211 slot_time = WMI_VDEV_SLOT_TIME_SHORT;
4212 else
4213 slot_time = WMI_VDEV_SLOT_TIME_LONG;
4214 ret = mlme_check_index_setparam(setparam, wmi_vdev_param_slot_time,
4215 slot_time, index++,
4216 MAX_VDEV_SET_BSS_PARAMS);
4217 if (QDF_IS_STATUS_ERROR(ret)) {
4218 wma_debug("failed to send wmi_vdev_param_slot_time to fw");
4219 goto error;
4220 }
4221 /* Initialize protection mode in case of coexistence */
4222 prot_mode = llbCoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE;
4223 ret = mlme_check_index_setparam(setparam,
4224 wmi_vdev_param_protection_mode,
4225 prot_mode, index++,
4226 MAX_VDEV_SET_BSS_PARAMS);
4227 if (QDF_IS_STATUS_ERROR(ret)) {
4228 wma_debug("failed to send wmi_vdev_param_protection_mode to fw");
4229 goto error;
4230 }
4231 ret = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
4232 vdev_id, setparam, index);
4233 if (QDF_IS_STATUS_ERROR(ret)) {
4234 wma_err("Failed to set BEACON/DTIM_PERIOD/PWRLIMIT/SLOTTIME/PROTECTION params");
4235 goto error;
4236 }
4237 mlme_set_max_reg_power(intr[vdev_id].vdev, maxTxPower);
4238 if (bss_max_idle_period)
4239 wma_set_sta_keep_alive(
4240 wma, vdev_id,
4241 SIR_KEEP_ALIVE_NULL_PKT,
4242 bss_max_idle_period,
4243 NULL, NULL, NULL);
4244 error:
4245 return ret;
4246 }
4247
wma_set_mgmt_frame_protection(tp_wma_handle wma)4248 static void wma_set_mgmt_frame_protection(tp_wma_handle wma)
4249 {
4250 struct pdev_params param = {0};
4251 QDF_STATUS ret;
4252
4253 /*
4254 * when 802.11w PMF is enabled for hw encr/decr
4255 * use hw MFP Qos bits 0x10
4256 */
4257 param.param_id = wmi_pdev_param_pmf_qos;
4258 param.param_value = true;
4259 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
4260 ¶m, WMA_WILDCARD_PDEV_ID);
4261 if (QDF_IS_STATUS_ERROR(ret)) {
4262 wma_err("Failed to set QOS MFP/PMF (%d)", ret);
4263 } else {
4264 wma_debug("QOS MFP/PMF set");
4265 }
4266 }
4267
4268 /**
4269 * wma_set_peer_pmf_status() - Get the peer and update PMF capability of it
4270 * @wma: wma handle
4271 * @peer_mac: peer mac addr
4272 * @is_pmf_enabled: Carries the status whether PMF is enabled or not
4273 *
4274 * Return: QDF_STATUS
4275 */
4276 static QDF_STATUS
wma_set_peer_pmf_status(tp_wma_handle wma,uint8_t * peer_mac,bool is_pmf_enabled)4277 wma_set_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac,
4278 bool is_pmf_enabled)
4279 {
4280 struct wlan_objmgr_peer *peer;
4281
4282 peer = wlan_objmgr_get_peer(wma->psoc,
4283 wlan_objmgr_pdev_get_pdev_id(wma->pdev),
4284 peer_mac, WLAN_LEGACY_WMA_ID);
4285 if (!peer) {
4286 wma_err("Peer of peer_mac "QDF_MAC_ADDR_FMT" not found",
4287 QDF_MAC_ADDR_REF(peer_mac));
4288 return QDF_STATUS_E_INVAL;
4289 }
4290 mlme_set_peer_pmf_status(peer, is_pmf_enabled);
4291 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
4292 wma_debug("set is_pmf_enabled %d for "QDF_MAC_ADDR_FMT,
4293 is_pmf_enabled, QDF_MAC_ADDR_REF(peer_mac));
4294
4295 return QDF_STATUS_SUCCESS;
4296 }
4297
wma_pre_vdev_start_setup(uint8_t vdev_id,struct bss_params * add_bss)4298 QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id,
4299 struct bss_params *add_bss)
4300 {
4301 QDF_STATUS status;
4302 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4303 struct wma_txrx_node *iface;
4304 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4305 struct vdev_mlme_obj *mlme_obj;
4306 uint8_t *mac_addr;
4307
4308 if (!soc || !wma)
4309 return QDF_STATUS_E_FAILURE;
4310
4311 iface = &wma->interfaces[vdev_id];
4312
4313 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
4314 if (!mlme_obj) {
4315 wma_err("vdev component object is NULL");
4316 return QDF_STATUS_E_FAILURE;
4317 }
4318
4319 wma_set_bss_rate_flags(wma, vdev_id, add_bss);
4320 if (wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_NDI_MODE ||
4321 wlan_vdev_mlme_get_opmode(iface->vdev) == QDF_IBSS_MODE)
4322 mac_addr = mlme_obj->mgmt.generic.bssid;
4323 else
4324 mac_addr = wlan_vdev_mlme_get_macaddr(iface->vdev);
4325
4326 status = wma_create_peer(wma, mac_addr,
4327 WMI_PEER_TYPE_DEFAULT, vdev_id,
4328 NULL, false);
4329 if (status != QDF_STATUS_SUCCESS) {
4330 wma_err("Failed to create peer");
4331 return status;
4332 }
4333
4334 if (!cdp_find_peer_exist(soc, OL_TXRX_PDEV_ID, mac_addr)) {
4335 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4336 QDF_MAC_ADDR_REF(mac_addr));
4337 return QDF_STATUS_E_FAILURE;
4338 }
4339
4340 iface->rmfEnabled = add_bss->rmfEnabled;
4341 if (add_bss->rmfEnabled)
4342 wma_set_mgmt_frame_protection(wma);
4343
4344 return status;
4345 }
4346
wma_post_vdev_start_setup(uint8_t vdev_id)4347 QDF_STATUS wma_post_vdev_start_setup(uint8_t vdev_id)
4348 {
4349 QDF_STATUS status = QDF_STATUS_SUCCESS;
4350 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4351 struct wma_txrx_node *intr;
4352 struct vdev_mlme_obj *mlme_obj;
4353 struct wlan_objmgr_vdev *vdev;
4354 uint8_t bss_power = 0;
4355
4356 if (!wma)
4357 return QDF_STATUS_E_FAILURE;
4358
4359 intr = &wma->interfaces[vdev_id];
4360 if (!intr) {
4361 wma_err("Invalid interface");
4362 return QDF_STATUS_E_FAILURE;
4363 }
4364 vdev = intr->vdev;
4365 if (!vdev) {
4366 wma_err("vdev is NULL");
4367 return QDF_STATUS_E_FAILURE;
4368 }
4369 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_NDI_MODE ||
4370 wlan_vdev_mlme_get_opmode(vdev) == QDF_IBSS_MODE) {
4371 /* Initialize protection mode to no protection */
4372 wma_vdev_set_param(wma->wmi_handle, vdev_id,
4373 wmi_vdev_param_protection_mode,
4374 IEEE80211_PROT_NONE);
4375 return status;
4376 }
4377 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
4378 if (!mlme_obj) {
4379 wma_err("vdev component object is NULL");
4380 return QDF_STATUS_E_FAILURE;
4381 }
4382
4383 /* Fill bss_chan after vdev start */
4384 qdf_mem_copy(vdev->vdev_mlme.bss_chan,
4385 vdev->vdev_mlme.des_chan,
4386 sizeof(struct wlan_channel));
4387
4388 if (!wlan_reg_is_ext_tpc_supported(wma->psoc))
4389 bss_power = wlan_reg_get_channel_reg_power_for_freq(
4390 wma->pdev, vdev->vdev_mlme.bss_chan->ch_freq);
4391
4392 if (wma_vdev_set_bss_params(wma, vdev_id,
4393 mlme_obj->proto.generic.beacon_interval,
4394 mlme_obj->proto.generic.dtim_period,
4395 mlme_obj->proto.generic.slot_time,
4396 mlme_obj->proto.generic.protection_mode,
4397 bss_power, 0)) {
4398 wma_err("Failed to set wma_vdev_set_bss_params");
4399 }
4400
4401 wma_vdev_set_he_bss_params(wma, vdev_id,
4402 &mlme_obj->proto.he_ops_info);
4403 #if defined(WLAN_FEATURE_11BE)
4404 wma_vdev_set_eht_bss_params(wma, vdev_id,
4405 &mlme_obj->proto.eht_ops_info);
4406 #endif
4407
4408 return status;
4409 }
4410
wma_update_iface_params(tp_wma_handle wma,struct bss_params * add_bss)4411 static QDF_STATUS wma_update_iface_params(tp_wma_handle wma,
4412 struct bss_params *add_bss)
4413 {
4414 struct wma_txrx_node *iface;
4415 uint8_t vdev_id;
4416
4417 vdev_id = add_bss->staContext.smesessionId;
4418 iface = &wma->interfaces[vdev_id];
4419 wma_set_bss_rate_flags(wma, vdev_id, add_bss);
4420
4421 if (iface->addBssStaContext)
4422 qdf_mem_free(iface->addBssStaContext);
4423 iface->addBssStaContext = qdf_mem_malloc(sizeof(tAddStaParams));
4424 if (!iface->addBssStaContext)
4425 return QDF_STATUS_E_RESOURCES;
4426
4427 *iface->addBssStaContext = add_bss->staContext;
4428 /* Save parameters later needed by WMA_ADD_STA_REQ */
4429 iface->rmfEnabled = add_bss->rmfEnabled;
4430 if (add_bss->rmfEnabled)
4431 wma_set_peer_pmf_status(wma, add_bss->bssId, true);
4432 iface->beaconInterval = add_bss->beaconInterval;
4433 iface->llbCoexist = add_bss->llbCoexist;
4434 iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported;
4435 iface->nwType = add_bss->nwType;
4436 iface->bss_max_idle_period = add_bss->bss_max_idle_period;
4437
4438 return QDF_STATUS_SUCCESS;
4439 }
4440
4441 static inline
wma_cdp_find_peer_by_addr(uint8_t * peer_addr)4442 bool wma_cdp_find_peer_by_addr(uint8_t *peer_addr)
4443 {
4444 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4445 uint8_t pdev_id = OL_TXRX_PDEV_ID;
4446
4447 if (!soc || pdev_id == OL_TXRX_INVALID_PDEV_ID) {
4448 wma_err("Failed to get pdev/soc");
4449 return NULL;
4450 }
4451
4452 return cdp_find_peer_exist(soc, pdev_id, peer_addr);
4453 }
4454
4455 static
wma_save_bss_params(tp_wma_handle wma,struct bss_params * add_bss)4456 QDF_STATUS wma_save_bss_params(tp_wma_handle wma, struct bss_params *add_bss)
4457 {
4458 QDF_STATUS status;
4459
4460 wma_vdev_set_he_config(wma, add_bss->staContext.smesessionId, add_bss);
4461 if (!wma_cdp_find_peer_by_addr(add_bss->bssId))
4462 status = QDF_STATUS_E_FAILURE;
4463 else
4464 status = QDF_STATUS_SUCCESS;
4465 qdf_mem_copy(add_bss->staContext.staMac, add_bss->bssId,
4466 sizeof(add_bss->staContext.staMac));
4467
4468 wma_debug("update_bss %d nw_type %d bssid "QDF_MAC_ADDR_FMT" status %d",
4469 add_bss->updateBss, add_bss->nwType,
4470 QDF_MAC_ADDR_REF(add_bss->bssId),
4471 status);
4472
4473 return status;
4474 }
4475
wma_pre_assoc_req(struct bss_params * add_bss)4476 QDF_STATUS wma_pre_assoc_req(struct bss_params *add_bss)
4477 {
4478 QDF_STATUS status;
4479 tp_wma_handle wma;
4480
4481 wma = cds_get_context(QDF_MODULE_ID_WMA);
4482 if (!wma)
4483 return QDF_STATUS_E_INVAL;
4484
4485 status = wma_update_iface_params(wma, add_bss);
4486 if (QDF_IS_STATUS_ERROR(status))
4487 return status;
4488
4489 status = wma_save_bss_params(wma, add_bss);
4490
4491 return status;
4492 }
4493
wma_add_bss_lfr3(tp_wma_handle wma,struct bss_params * add_bss)4494 void wma_add_bss_lfr3(tp_wma_handle wma, struct bss_params *add_bss)
4495 {
4496 QDF_STATUS status;
4497
4498 status = wma_update_iface_params(wma, add_bss);
4499 if (QDF_IS_STATUS_ERROR(status))
4500 return;
4501
4502 if (!wma_cdp_find_peer_by_addr(add_bss->bssId)) {
4503 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4504 QDF_MAC_ADDR_REF(add_bss->bssId));
4505 return;
4506 }
4507 wma_debug("LFR3: bssid "QDF_MAC_ADDR_FMT,
4508 QDF_MAC_ADDR_REF(add_bss->bssId));
4509 }
4510
4511
4512 #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
4513 static
wma_set_cdp_vdev_pause_reason(tp_wma_handle wma,uint8_t vdev_id)4514 QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id)
4515 {
4516 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4517
4518 cdp_fc_vdev_pause(soc, vdev_id,
4519 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED, 0);
4520
4521 return QDF_STATUS_SUCCESS;
4522 }
4523 #else
4524 static inline
wma_set_cdp_vdev_pause_reason(tp_wma_handle wma,uint8_t vdev_id)4525 QDF_STATUS wma_set_cdp_vdev_pause_reason(tp_wma_handle wma, uint8_t vdev_id)
4526 {
4527 return QDF_STATUS_SUCCESS;
4528 }
4529 #endif
4530
wma_send_add_bss_resp(tp_wma_handle wma,uint8_t vdev_id,QDF_STATUS status)4531 void wma_send_add_bss_resp(tp_wma_handle wma, uint8_t vdev_id,
4532 QDF_STATUS status)
4533 {
4534 struct add_bss_rsp *add_bss_rsp;
4535
4536 add_bss_rsp = qdf_mem_malloc(sizeof(*add_bss_rsp));
4537 if (!add_bss_rsp)
4538 return;
4539
4540 add_bss_rsp->vdev_id = vdev_id;
4541 add_bss_rsp->status = status;
4542 lim_handle_add_bss_rsp(wma->mac_context, add_bss_rsp);
4543 }
4544
4545 #ifdef WLAN_FEATURE_HOST_ROAM
wma_add_bss_lfr2_vdev_start(struct wlan_objmgr_vdev * vdev,struct bss_params * add_bss)4546 QDF_STATUS wma_add_bss_lfr2_vdev_start(struct wlan_objmgr_vdev *vdev,
4547 struct bss_params *add_bss)
4548 {
4549 tp_wma_handle wma;
4550 QDF_STATUS status;
4551 struct vdev_mlme_obj *mlme_obj;
4552 uint8_t vdev_id;
4553 bool peer_exist = false;
4554
4555 wma = cds_get_context(QDF_MODULE_ID_WMA);
4556 if (!wma || !vdev) {
4557 wma_err("Invalid wma or vdev");
4558 return QDF_STATUS_E_INVAL;
4559 }
4560
4561 vdev_id = vdev->vdev_objmgr.vdev_id;
4562 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
4563 if (!mlme_obj) {
4564 wma_err("vdev component object is NULL");
4565 return QDF_STATUS_E_FAILURE;
4566 }
4567
4568 status = wma_update_iface_params(wma, add_bss);
4569 if (QDF_IS_STATUS_ERROR(status))
4570 goto send_fail_resp;
4571
4572 peer_exist = wma_cdp_find_peer_by_addr(mlme_obj->mgmt.generic.bssid);
4573 if (!peer_exist) {
4574 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4575 QDF_MAC_ADDR_REF(mlme_obj->mgmt.generic.bssid));
4576 goto send_fail_resp;
4577 }
4578
4579 status = wma_vdev_pre_start(vdev_id, false);
4580 if (QDF_IS_STATUS_ERROR(status)) {
4581 wma_err("failed, status: %d", status);
4582 goto peer_cleanup;
4583 }
4584 status = vdev_mgr_start_send(mlme_obj, false);
4585 if (QDF_IS_STATUS_ERROR(status)) {
4586 wma_err("failed, status: %d", status);
4587 goto peer_cleanup;
4588 }
4589 status = wma_set_cdp_vdev_pause_reason(wma, vdev_id);
4590 if (QDF_IS_STATUS_ERROR(status))
4591 goto peer_cleanup;
4592
4593 /* ADD_BSS_RESP will be deferred to completion of VDEV_START */
4594 return QDF_STATUS_SUCCESS;
4595
4596 peer_cleanup:
4597 if (peer_exist)
4598 wma_remove_peer(wma, mlme_obj->mgmt.generic.bssid, vdev_id,
4599 false);
4600
4601 send_fail_resp:
4602 wma_send_add_bss_resp(wma, vdev_id, QDF_STATUS_E_FAILURE);
4603
4604 return QDF_STATUS_SUCCESS;
4605 }
4606 #endif
4607
wma_set_vdev_bw(uint8_t vdev_id,uint8_t bw)4608 QDF_STATUS wma_set_vdev_bw(uint8_t vdev_id, uint8_t bw)
4609 {
4610 QDF_STATUS status;
4611 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4612
4613 if (!wma)
4614 return QDF_STATUS_E_INVAL;
4615
4616 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
4617 wmi_vdev_param_chwidth, bw);
4618 if (QDF_IS_STATUS_ERROR(status))
4619 wma_err("failed to set vdev bw, status: %d", status);
4620
4621 return status;
4622 }
4623
wma_send_peer_assoc_req(struct bss_params * add_bss)4624 QDF_STATUS wma_send_peer_assoc_req(struct bss_params *add_bss)
4625 {
4626 struct wma_target_req *msg;
4627 tp_wma_handle wma;
4628 uint8_t vdev_id;
4629 bool peer_exist;
4630 QDF_STATUS status;
4631 struct wma_txrx_node *iface;
4632 int pps_val = 0;
4633 struct vdev_mlme_obj *mlme_obj;
4634 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
4635 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4636
4637 wma = cds_get_context(QDF_MODULE_ID_WMA);
4638 if (!wma || !mac || !soc)
4639 return QDF_STATUS_E_INVAL;
4640
4641 vdev_id = add_bss->staContext.smesessionId;
4642
4643 iface = &wma->interfaces[vdev_id];
4644 status = wma_update_iface_params(wma, add_bss);
4645 if (QDF_IS_STATUS_ERROR(status))
4646 goto send_resp;
4647
4648 peer_exist = wma_cdp_find_peer_by_addr(add_bss->bssId);
4649 if (add_bss->nonRoamReassoc && peer_exist)
4650 goto send_resp;
4651
4652 if (!add_bss->updateBss)
4653 goto send_resp;
4654
4655 if (!peer_exist) {
4656 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
4657 QDF_MAC_ADDR_REF(add_bss->bssId));
4658 status = QDF_STATUS_E_FAILURE;
4659 goto send_resp;
4660 }
4661
4662
4663 if (add_bss->staContext.encryptType == eSIR_ED_NONE) {
4664 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into auth",
4665 QDF_MAC_ADDR_REF(add_bss->bssId));
4666 cdp_peer_state_update(soc, add_bss->bssId,
4667 OL_TXRX_PEER_STATE_AUTH);
4668 } else {
4669 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into conn",
4670 QDF_MAC_ADDR_REF(add_bss->bssId));
4671 cdp_peer_state_update(soc, add_bss->bssId,
4672 OL_TXRX_PEER_STATE_CONN);
4673 status = wma_set_cdp_vdev_pause_reason(wma, vdev_id);
4674 if (QDF_IS_STATUS_ERROR(status))
4675 goto send_resp;
4676 }
4677
4678 wmi_unified_send_txbf(wma, &add_bss->staContext);
4679
4680 pps_val = ((mac->mlme_cfg->sta.enable_5g_ebt << 31) &
4681 0xffff0000) | (PKT_PWR_SAVE_5G_EBT & 0xffff);
4682 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
4683 wmi_vdev_param_packet_powersave,
4684 pps_val);
4685 if (QDF_IS_STATUS_ERROR(status))
4686 wma_err("Failed to send wmi packet power save cmd");
4687 else
4688 wma_debug("Sent packet power save %x", pps_val);
4689
4690 add_bss->staContext.no_ptk_4_way = add_bss->no_ptk_4_way;
4691
4692 status = wma_send_peer_assoc(wma, add_bss->nwType,
4693 &add_bss->staContext);
4694 if (QDF_IS_STATUS_ERROR(status)) {
4695 wma_err("Failed to send peer assoc status:%d", status);
4696 goto send_resp;
4697 }
4698
4699 /* we just had peer assoc, so install key will be done later */
4700 if (add_bss->staContext.encryptType != eSIR_ED_NONE)
4701 iface->is_waiting_for_key = true;
4702
4703 if (add_bss->rmfEnabled)
4704 wma_set_mgmt_frame_protection(wma);
4705
4706 if (wlan_reg_is_ext_tpc_supported(wma->psoc))
4707 add_bss->maxTxPower = 0;
4708
4709 if (wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId,
4710 add_bss->beaconInterval,
4711 add_bss->dtimPeriod,
4712 add_bss->shortSlotTimeSupported,
4713 add_bss->llbCoexist,
4714 add_bss->maxTxPower,
4715 add_bss->bss_max_idle_period)) {
4716 wma_err("Failed to set bss params");
4717 }
4718
4719 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(iface->vdev);
4720 if (!mlme_obj) {
4721 wma_err("Failed to mlme obj");
4722 status = QDF_STATUS_E_FAILURE;
4723 goto send_resp;
4724 }
4725 /*
4726 * Store the bssid in interface table, bssid will
4727 * be used during group key setting sta mode.
4728 */
4729 qdf_mem_copy(mlme_obj->mgmt.generic.bssid,
4730 add_bss->bssId, QDF_MAC_ADDR_SIZE);
4731
4732 wma_save_bss_params(wma, add_bss);
4733
4734 if (!wmi_service_enabled(wma->wmi_handle,
4735 wmi_service_peer_assoc_conf)) {
4736 wma_debug("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
4737 goto send_resp;
4738 }
4739
4740 msg = wma_fill_hold_req(wma, vdev_id, WMA_ADD_BSS_REQ,
4741 WMA_PEER_ASSOC_CNF_START, NULL,
4742 WMA_PEER_ASSOC_TIMEOUT);
4743 if (!msg) {
4744 wma_err("Failed to allocate request for vdev_id %d", vdev_id);
4745 wma_remove_req(wma, vdev_id, WMA_PEER_ASSOC_CNF_START);
4746 status = QDF_STATUS_E_FAILURE;
4747 goto send_resp;
4748 }
4749
4750 return QDF_STATUS_SUCCESS;
4751
4752 send_resp:
4753 wma_send_add_bss_resp(wma, vdev_id, status);
4754
4755 return QDF_STATUS_SUCCESS;
4756 }
4757
4758 #ifdef WLAN_FEATURE_11BE_MLO
4759 /**
4760 * wma_get_mld_info_ap() - get mld mac addr and assoc peer flag for ap
4761 * @add_sta: tpAddStaParams
4762 * @peer_mld_addr: peer mld mac addr
4763 * @is_assoc_peer: is assoc peer or not
4764 *
4765 * Return: void
4766 */
wma_get_mld_info_ap(tpAddStaParams add_sta,uint8_t ** peer_mld_addr,bool * is_assoc_peer)4767 static void wma_get_mld_info_ap(tpAddStaParams add_sta,
4768 uint8_t **peer_mld_addr,
4769 bool *is_assoc_peer)
4770 {
4771 if (add_sta) {
4772 *peer_mld_addr = add_sta->mld_mac_addr;
4773 *is_assoc_peer = add_sta->is_assoc_peer;
4774 } else {
4775 peer_mld_addr = NULL;
4776 *is_assoc_peer = false;
4777 }
4778 }
4779 #else
wma_get_mld_info_ap(tpAddStaParams add_sta,uint8_t ** peer_mld_addr,bool * is_assoc_peer)4780 static void wma_get_mld_info_ap(tpAddStaParams add_sta,
4781 uint8_t **peer_mld_addr,
4782 bool *is_assoc_peer)
4783 {
4784 *peer_mld_addr = NULL;
4785 *is_assoc_peer = false;
4786 }
4787 #endif
4788
4789 /**
4790 * wma_add_sta_req_ap_mode() - process add sta request in ap mode
4791 * @wma: wma handle
4792 * @add_sta: add sta params
4793 *
4794 * Return: none
4795 */
wma_add_sta_req_ap_mode(tp_wma_handle wma,tpAddStaParams add_sta)4796 static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
4797 {
4798 enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN;
4799 uint8_t pdev_id = OL_TXRX_PDEV_ID;
4800 QDF_STATUS status;
4801 int32_t ret;
4802 struct wma_txrx_node *iface = NULL;
4803 struct wma_target_req *msg = NULL;
4804 bool peer_assoc_cnf = false;
4805 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4806 uint32_t i, j;
4807 uint16_t mcs_limit;
4808 uint8_t *rate_pos;
4809 struct mac_context *mac = wma->mac_context;
4810 uint8_t *peer_mld_addr = NULL;
4811 bool is_assoc_peer = false;
4812
4813 /* UMAC sends WMA_ADD_STA_REQ msg twice to WMA when the station
4814 * associates. First WMA_ADD_STA_REQ will have staType as
4815 * STA_ENTRY_PEER and second posting will have STA_ENTRY_SELF.
4816 * Peer creation is done in first WMA_ADD_STA_REQ and second
4817 * WMA_ADD_STA_REQ which has STA_ENTRY_SELF is ignored and
4818 * send fake response with success to UMAC. Otherwise UMAC
4819 * will get blocked.
4820 */
4821 if (add_sta->staType != STA_ENTRY_PEER) {
4822 add_sta->status = QDF_STATUS_SUCCESS;
4823 goto send_rsp;
4824 }
4825
4826 iface = &wma->interfaces[add_sta->smesessionId];
4827
4828 if (cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId,
4829 add_sta->staMac)) {
4830 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4831 false);
4832 wma_err("Peer already exists, Deleted peer with peer_addr "QDF_MAC_ADDR_FMT,
4833 QDF_MAC_ADDR_REF(add_sta->staMac));
4834 }
4835 /* The code above only checks the peer existence on its own vdev.
4836 * Need to check whether the peer exists on other vDevs because firmware
4837 * can't create the peer if the peer with same MAC address already
4838 * exists on the pDev. As this peer belongs to other vDevs, just return
4839 * here.
4840 */
4841 if (cdp_find_peer_exist(soc, pdev_id, add_sta->staMac)) {
4842 wma_err("My vdev id %d, but Peer exists on other vdev with peer_addr "QDF_MAC_ADDR_FMT,
4843 add_sta->smesessionId,
4844 QDF_MAC_ADDR_REF(add_sta->staMac));
4845 add_sta->status = QDF_STATUS_E_FAILURE;
4846 goto send_rsp;
4847 }
4848
4849 wma_delete_invalid_peer_entries(add_sta->smesessionId, add_sta->staMac);
4850
4851 wma_get_mld_info_ap(add_sta, &peer_mld_addr, &is_assoc_peer);
4852 status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_DEFAULT,
4853 add_sta->smesessionId, peer_mld_addr,
4854 is_assoc_peer);
4855 if (status != QDF_STATUS_SUCCESS) {
4856 wma_err("Failed to create peer for "QDF_MAC_ADDR_FMT,
4857 QDF_MAC_ADDR_REF(add_sta->staMac));
4858 add_sta->status = status;
4859 goto send_rsp;
4860 }
4861
4862 if (!cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId,
4863 add_sta->staMac)) {
4864 wma_err("Failed to find peer handle using peer mac "QDF_MAC_ADDR_FMT,
4865 QDF_MAC_ADDR_REF(add_sta->staMac));
4866 add_sta->status = QDF_STATUS_E_FAILURE;
4867 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4868 false);
4869 goto send_rsp;
4870 }
4871
4872 wmi_unified_send_txbf(wma, add_sta);
4873
4874 /*
4875 * Get MCS limit from ini configure, and map it to rate parameters
4876 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
4877 * check whether ini config is enabled and CFG_DATA_MASK to get the
4878 * MCS value.
4879 */
4880 #define CFG_CTRL_MASK 0xFF00
4881 #define CFG_DATA_MASK 0x00FF
4882
4883 mcs_limit = mac->mlme_cfg->rates.sap_max_mcs_txdata;
4884
4885 if (mcs_limit & CFG_CTRL_MASK) {
4886 wma_debug("set mcs_limit %x", mcs_limit);
4887
4888 mcs_limit &= CFG_DATA_MASK;
4889 rate_pos = (u_int8_t *)add_sta->supportedRates.supportedMCSSet;
4890 for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
4891 if (j < mcs_limit / 8) {
4892 rate_pos[j] = 0xff;
4893 j++;
4894 i += 8;
4895 } else if (j < mcs_limit / 8 + 1) {
4896 if (i <= mcs_limit)
4897 rate_pos[i / 8] |= 1 << (i % 8);
4898 else
4899 rate_pos[i / 8] &= ~(1 << (i % 8));
4900 i++;
4901
4902 if (i >= (j + 1) * 8)
4903 j++;
4904 } else {
4905 rate_pos[j++] = 0;
4906 i += 8;
4907 }
4908 }
4909 }
4910
4911 if (wmi_service_enabled(wma->wmi_handle,
4912 wmi_service_peer_assoc_conf)) {
4913 peer_assoc_cnf = true;
4914 msg = wma_fill_hold_req(wma, add_sta->smesessionId,
4915 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
4916 add_sta, WMA_PEER_ASSOC_TIMEOUT);
4917 if (!msg) {
4918 wma_err("Failed to alloc request for vdev_id %d",
4919 add_sta->smesessionId);
4920 add_sta->status = QDF_STATUS_E_FAILURE;
4921 wma_remove_req(wma, add_sta->smesessionId,
4922 WMA_PEER_ASSOC_CNF_START);
4923 wma_remove_peer(wma, add_sta->staMac,
4924 add_sta->smesessionId, false);
4925 peer_assoc_cnf = false;
4926 goto send_rsp;
4927 }
4928 } else {
4929 wma_err("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
4930 }
4931
4932 ret = wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
4933 if (ret) {
4934 add_sta->status = QDF_STATUS_E_FAILURE;
4935 if (msg) {
4936 wma_remove_req(wma, add_sta->smesessionId,
4937 WMA_PEER_ASSOC_CNF_START);
4938 peer_assoc_cnf = false;
4939 }
4940 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4941 false);
4942 goto send_rsp;
4943 }
4944
4945 if (add_sta->rmfEnabled)
4946 wma_set_peer_pmf_status(wma, add_sta->staMac, true);
4947
4948 if (add_sta->uAPSD) {
4949 status = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId,
4950 add_sta->staMac,
4951 add_sta->uAPSD, add_sta->maxSPLen);
4952 if (QDF_IS_STATUS_ERROR(status)) {
4953 wma_err("Failed to set peer uapsd param for "QDF_MAC_ADDR_FMT,
4954 QDF_MAC_ADDR_REF(add_sta->staMac));
4955 add_sta->status = QDF_STATUS_E_FAILURE;
4956 wma_remove_peer(wma, add_sta->staMac,
4957 add_sta->smesessionId, false);
4958 goto send_rsp;
4959 }
4960 }
4961
4962 wma_debug("Moving peer "QDF_MAC_ADDR_FMT" to state %d",
4963 QDF_MAC_ADDR_REF(add_sta->staMac), state);
4964 cdp_peer_state_update(soc, add_sta->staMac, state);
4965
4966 add_sta->nss = wma_objmgr_get_peer_mlme_nss(wma, add_sta->staMac);
4967 add_sta->status = QDF_STATUS_SUCCESS;
4968 send_rsp:
4969 /* Do not send add stat resp when peer assoc cnf is enabled */
4970 if (peer_assoc_cnf) {
4971 wma_debug("WMI_SERVICE_PEER_ASSOC_CONF is enabled");
4972 return;
4973 }
4974
4975 wma_debug("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d",
4976 add_sta->staType, add_sta->smesessionId,
4977 add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId),
4978 add_sta->status);
4979 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
4980 }
4981
4982 #ifdef FEATURE_WLAN_TDLS
4983
4984 /**
4985 * wma_add_tdls_sta() - process add sta request in TDLS mode
4986 * @wma: wma handle
4987 * @add_sta: add sta params
4988 *
4989 * Return: none
4990 */
wma_add_tdls_sta(tp_wma_handle wma,tpAddStaParams add_sta)4991 static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta)
4992 {
4993 QDF_STATUS status;
4994 int32_t ret;
4995 struct tdls_peer_update_state *peer_state;
4996 struct wma_target_req *msg;
4997 bool peer_assoc_cnf = false;
4998 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4999 uint8_t pdev_id = OL_TXRX_PDEV_ID;
5000 struct wma_txrx_node *iface = &wma->interfaces[add_sta->smesessionId];
5001
5002 wma_debug("staType: %d, updateSta: %d, bssId: "QDF_MAC_ADDR_FMT", staMac: "QDF_MAC_ADDR_FMT,
5003 add_sta->staType,
5004 add_sta->updateSta, QDF_MAC_ADDR_REF(add_sta->bssId),
5005 QDF_MAC_ADDR_REF(add_sta->staMac));
5006
5007 if (iface->vdev && wlan_cm_is_vdev_roaming(iface->vdev)) {
5008 wma_err("Vdev %d roaming in progress, reject add sta!",
5009 add_sta->smesessionId);
5010 add_sta->status = QDF_STATUS_E_PERM;
5011 goto send_rsp;
5012 }
5013
5014 if (0 == add_sta->updateSta) {
5015 /* its a add sta request * */
5016
5017 cdp_peer_copy_mac_addr_raw(soc, add_sta->smesessionId,
5018 add_sta->bssId);
5019
5020 wma_debug("addSta, calling wma_create_peer for "QDF_MAC_ADDR_FMT", vdev_id %hu",
5021 QDF_MAC_ADDR_REF(add_sta->staMac),
5022 add_sta->smesessionId);
5023
5024 status = wma_create_peer(wma, add_sta->staMac,
5025 WMI_PEER_TYPE_TDLS,
5026 add_sta->smesessionId, NULL, false);
5027 if (status != QDF_STATUS_SUCCESS) {
5028 wma_err("Failed to create peer for "QDF_MAC_ADDR_FMT,
5029 QDF_MAC_ADDR_REF(add_sta->staMac));
5030 add_sta->status = status;
5031 goto send_rsp;
5032 }
5033
5034 wma_debug("addSta, after calling cdp_local_peer_id, staMac: "QDF_MAC_ADDR_FMT,
5035 QDF_MAC_ADDR_REF(add_sta->staMac));
5036
5037 peer_state = qdf_mem_malloc(sizeof(*peer_state));
5038 if (!peer_state) {
5039 add_sta->status = QDF_STATUS_E_NOMEM;
5040 goto send_rsp;
5041 }
5042
5043 peer_state->peer_state = WMI_TDLS_PEER_STATE_PEERING;
5044 peer_state->vdev_id = add_sta->smesessionId;
5045 qdf_mem_copy(&peer_state->peer_macaddr,
5046 &add_sta->staMac, sizeof(tSirMacAddr));
5047 wma_update_tdls_peer_state(wma, peer_state);
5048 } else {
5049 if (wmi_service_enabled(wma->wmi_handle,
5050 wmi_service_peer_assoc_conf)) {
5051 wma_err("WMI_SERVICE_PEER_ASSOC_CONF is enabled");
5052 peer_assoc_cnf = true;
5053 msg = wma_fill_hold_req(wma, add_sta->smesessionId,
5054 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
5055 add_sta, WMA_PEER_ASSOC_TIMEOUT);
5056 if (!msg) {
5057 wma_err("Failed to alloc request for vdev_id %d",
5058 add_sta->smesessionId);
5059 add_sta->status = QDF_STATUS_E_FAILURE;
5060 wma_remove_req(wma, add_sta->smesessionId,
5061 WMA_PEER_ASSOC_CNF_START);
5062 wma_remove_peer(wma, add_sta->staMac,
5063 add_sta->smesessionId, false);
5064 peer_assoc_cnf = false;
5065 goto send_rsp;
5066 }
5067 } else {
5068 wma_err("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
5069 }
5070
5071 wma_debug("changeSta, calling wma_send_peer_assoc");
5072 if (add_sta->rmfEnabled)
5073 wma_set_peer_pmf_status(wma, add_sta->staMac, true);
5074
5075 ret =
5076 wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
5077 if (ret) {
5078 add_sta->status = QDF_STATUS_E_FAILURE;
5079 wma_remove_peer(wma, add_sta->staMac,
5080 add_sta->smesessionId, false);
5081 cdp_peer_add_last_real_peer(soc, pdev_id,
5082 add_sta->smesessionId);
5083 wma_remove_req(wma, add_sta->smesessionId,
5084 WMA_PEER_ASSOC_CNF_START);
5085 peer_assoc_cnf = false;
5086
5087 goto send_rsp;
5088 }
5089 }
5090
5091 send_rsp:
5092 /* Do not send add stat resp when peer assoc cnf is enabled */
5093 if (peer_assoc_cnf)
5094 return;
5095
5096 wma_debug("statype %d vdev_id %d aid %d bssid "QDF_MAC_ADDR_FMT" status %d",
5097 add_sta->staType, add_sta->smesessionId,
5098 add_sta->assocId, QDF_MAC_ADDR_REF(add_sta->bssId),
5099 add_sta->status);
5100 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
5101 }
5102 #endif
5103
5104 /**
5105 * wma_send_bss_color_change_enable() - send bss color change enable cmd.
5106 * @wma: wma handle
5107 * @params: add sta params
5108 *
5109 * Send bss color change command to firmware, to enable firmware to update
5110 * internally if any change in bss color in advertised by associated AP.
5111 *
5112 * Return: none
5113 */
5114 #ifdef WLAN_FEATURE_11AX
wma_send_bss_color_change_enable(tp_wma_handle wma,tpAddStaParams params)5115 static void wma_send_bss_color_change_enable(tp_wma_handle wma,
5116 tpAddStaParams params)
5117 {
5118 QDF_STATUS status;
5119 uint32_t vdev_id = params->smesessionId;
5120
5121 if (!params->he_capable) {
5122 wma_debug("he_capable is not set for vdev_id:%d", vdev_id);
5123 return;
5124 }
5125
5126 status = wmi_unified_send_bss_color_change_enable_cmd(wma->wmi_handle,
5127 vdev_id,
5128 true);
5129 if (QDF_IS_STATUS_ERROR(status)) {
5130 wma_err("Failed to enable bss color change offload, vdev:%d",
5131 vdev_id);
5132 }
5133
5134 return;
5135 }
5136 #else
wma_send_bss_color_change_enable(tp_wma_handle wma,tpAddStaParams params)5137 static void wma_send_bss_color_change_enable(tp_wma_handle wma,
5138 tpAddStaParams params)
5139 {
5140 }
5141 #endif
5142
5143 #define MAX_VDEV_STA_REQ_PARAMS 5
5144 /* params being sent:
5145 * 1.wmi_vdev_param_max_li_of_moddtim
5146 * 2.wmi_vdev_param_max_li_of_moddtim_ms
5147 * 3.wmi_vdev_param_dyndtim_cnt
5148 * 4.wmi_vdev_param_moddtim_cnt
5149 * 5.wmi_vdev_param_moddtim_cnt
5150 */
5151
5152 /**
5153 * wma_add_sta_req_sta_mode() - process add sta request in sta mode
5154 * @wma: wma handle
5155 * @params: add sta params
5156 *
5157 * Return: none
5158 */
wma_add_sta_req_sta_mode(tp_wma_handle wma,tpAddStaParams params)5159 static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
5160 {
5161 QDF_STATUS status = QDF_STATUS_SUCCESS;
5162 struct wma_txrx_node *iface;
5163 int8_t maxTxPower = 0;
5164 int ret = 0;
5165 struct wma_target_req *msg;
5166 bool peer_assoc_cnf = false;
5167 int smps_param;
5168 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
5169 struct dev_set_param setparam[MAX_VDEV_STA_REQ_PARAMS];
5170 uint8_t index = 0;
5171
5172 #ifdef FEATURE_WLAN_TDLS
5173 if (STA_ENTRY_TDLS_PEER == params->staType) {
5174 wma_add_tdls_sta(wma, params);
5175 return;
5176 }
5177 #endif
5178
5179 iface = &wma->interfaces[params->smesessionId];
5180 if (params->staType != STA_ENTRY_SELF) {
5181 wma_err("unsupported station type %d", params->staType);
5182 goto out;
5183 }
5184 if (params->nonRoamReassoc) {
5185 cdp_peer_state_update(soc, params->bssId,
5186 OL_TXRX_PEER_STATE_AUTH);
5187 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
5188 iface->aid = params->assocId;
5189 goto out;
5190 }
5191
5192 if (wma_is_vdev_up(params->smesessionId)) {
5193 wma_debug("vdev id %d is already UP for "QDF_MAC_ADDR_FMT,
5194 params->smesessionId,
5195 QDF_MAC_ADDR_REF(params->bssId));
5196 status = QDF_STATUS_E_FAILURE;
5197 goto out;
5198 }
5199
5200 if (cdp_peer_state_get(soc, params->smesessionId,
5201 params->bssId, true) == OL_TXRX_PEER_STATE_DISC) {
5202 /*
5203 * This is the case for reassociation.
5204 * peer state update and peer_assoc is required since it
5205 * was not done by WMA_ADD_BSS_REQ.
5206 */
5207
5208 /* Update peer state */
5209 if (params->encryptType == eSIR_ED_NONE) {
5210 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into auth",
5211 QDF_MAC_ADDR_REF(params->bssId));
5212 cdp_peer_state_update(soc, params->bssId,
5213 OL_TXRX_PEER_STATE_AUTH);
5214 } else {
5215 wma_debug("Update peer("QDF_MAC_ADDR_FMT") state into conn",
5216 QDF_MAC_ADDR_REF(params->bssId));
5217 cdp_peer_state_update(soc, params->bssId,
5218 OL_TXRX_PEER_STATE_CONN);
5219 }
5220
5221 if (wlan_cm_is_roam_sync_in_progress(wma->psoc,
5222 params->smesessionId) ||
5223 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc,
5224 params->smesessionId)) {
5225 /* iface->nss = params->nss; */
5226 /*In LFR2.0, the following operations are performed as
5227 * part of wma_send_peer_assoc. As we are
5228 * skipping this operation, we are just executing the
5229 * following which are useful for LFR3.0
5230 */
5231 cdp_peer_state_update(soc, params->bssId,
5232 OL_TXRX_PEER_STATE_AUTH);
5233 qdf_atomic_set(&iface->bss_status,
5234 WMA_BSS_STATUS_STARTED);
5235 iface->aid = params->assocId;
5236 wma_debug("LFR3:statype %d vdev %d aid %d bssid "QDF_MAC_ADDR_FMT,
5237 params->staType, params->smesessionId,
5238 params->assocId,
5239 QDF_MAC_ADDR_REF(params->bssId));
5240 return;
5241 }
5242 wmi_unified_send_txbf(wma, params);
5243
5244 if (wmi_service_enabled(wma->wmi_handle,
5245 wmi_service_peer_assoc_conf)) {
5246 peer_assoc_cnf = true;
5247 msg = wma_fill_hold_req(wma, params->smesessionId,
5248 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
5249 params, WMA_PEER_ASSOC_TIMEOUT);
5250 if (!msg) {
5251 wma_debug("Failed to alloc request for vdev_id %d",
5252 params->smesessionId);
5253 params->status = QDF_STATUS_E_FAILURE;
5254 wma_remove_req(wma, params->smesessionId,
5255 WMA_PEER_ASSOC_CNF_START);
5256 wma_remove_peer(wma, params->bssId,
5257 params->smesessionId, false);
5258 peer_assoc_cnf = false;
5259 goto out;
5260 }
5261 } else {
5262 wma_debug("WMI_SERVICE_PEER_ASSOC_CONF not enabled");
5263 }
5264
5265 ((tAddStaParams *)iface->addBssStaContext)->no_ptk_4_way =
5266 params->no_ptk_4_way;
5267
5268 qdf_mem_copy(((tAddStaParams *)iface->addBssStaContext)->
5269 supportedRates.supportedMCSSet,
5270 params->supportedRates.supportedMCSSet,
5271 SIR_MAC_MAX_SUPPORTED_MCS_SET);
5272
5273
5274 ret = wma_send_peer_assoc(wma,
5275 iface->nwType,
5276 (tAddStaParams *) iface->addBssStaContext);
5277 if (ret) {
5278 status = QDF_STATUS_E_FAILURE;
5279 wma_remove_peer(wma, params->bssId,
5280 params->smesessionId, false);
5281 goto out;
5282 }
5283
5284 if (params->rmfEnabled) {
5285 wma_set_mgmt_frame_protection(wma);
5286 wma_set_peer_pmf_status(wma, params->bssId, true);
5287 }
5288 }
5289
5290 if (!wlan_reg_is_ext_tpc_supported(wma->psoc))
5291 maxTxPower = params->maxTxPower;
5292
5293 if (wma_vdev_set_bss_params(wma, params->smesessionId,
5294 iface->beaconInterval, iface->dtimPeriod,
5295 iface->shortSlotTimeSupported,
5296 iface->llbCoexist, maxTxPower,
5297 iface->bss_max_idle_period)) {
5298 wma_err("Failed to bss params");
5299 }
5300
5301 params->csaOffloadEnable = 0;
5302 if (wmi_service_enabled(wma->wmi_handle,
5303 wmi_service_csa_offload)) {
5304 params->csaOffloadEnable = 1;
5305 if (wma_unified_csa_offload_enable(wma, params->smesessionId) <
5306 0) {
5307 wma_err("Unable to enable CSA offload for vdev_id:%d",
5308 params->smesessionId);
5309 }
5310 }
5311
5312 if (wmi_service_enabled(wma->wmi_handle,
5313 wmi_service_filter_ipsec_natkeepalive)) {
5314 if (wmi_unified_nat_keepalive_en_cmd(wma->wmi_handle,
5315 params->smesessionId)) {
5316 wma_err("Unable to enable NAT keepalive for vdev_id:%d",
5317 params->smesessionId);
5318 }
5319 }
5320 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
5321 /* Sta is now associated, configure various params */
5322
5323 /* Send SMPS force command to FW to send the required
5324 * action frame only when SM power save is enabled in
5325 * from INI. In case dynamic antenna selection, the
5326 * action frames are sent by the chain mask manager
5327 * In addition to the action frames, The SM power save is
5328 * published in the assoc request HT SMPS IE for both cases.
5329 */
5330 if ((params->enableHtSmps) && (params->send_smps_action)) {
5331 smps_param = wma_smps_mode_to_force_mode_param(
5332 params->htSmpsconfig);
5333 if (smps_param >= 0) {
5334 wma_debug("Send SMPS force mode: %d",
5335 params->htSmpsconfig);
5336 wma_set_mimops(wma, params->smesessionId,
5337 smps_param);
5338 }
5339 }
5340
5341 wma_send_bss_color_change_enable(wma, params);
5342
5343 /* Partial AID match power save, enable when SU bformee */
5344 if (params->enableVhtpAid && params->vhtTxBFCapable)
5345 wma_set_ppsconfig(params->smesessionId,
5346 WMA_VHT_PPS_PAID_MATCH, 1);
5347
5348 /* Enable AMPDU power save, if htCapable/vhtCapable */
5349 if (params->enableAmpduPs && (params->htCapable || params->vhtCapable))
5350 wma_set_ppsconfig(params->smesessionId,
5351 WMA_VHT_PPS_DELIM_CRC_FAIL, 1);
5352 if (wmi_service_enabled(wma->wmi_handle,
5353 wmi_service_listen_interval_offload_support)) {
5354 struct wlan_objmgr_vdev *vdev = NULL;
5355 uint32_t moddtim;
5356 bool is_connection_roaming_cfg_set = 0;
5357
5358 wma_debug("listen interval offload enabled, setting params");
5359 status = mlme_check_index_setparam(
5360 setparam,
5361 wmi_vdev_param_max_li_of_moddtim,
5362 wma->staMaxLIModDtim, index++,
5363 MAX_VDEV_STA_REQ_PARAMS);
5364 if (QDF_IS_STATUS_ERROR(status)) {
5365 wma_debug("failed to send wmi_vdev_param_max_li_of_moddtim");
5366 goto out;
5367 }
5368
5369 ucfg_mlme_get_connection_roaming_ini_present(
5370 wma->psoc,
5371 &is_connection_roaming_cfg_set);
5372 if (is_connection_roaming_cfg_set) {
5373 status = mlme_check_index_setparam(
5374 setparam,
5375 wmi_vdev_param_max_li_of_moddtim_ms,
5376 wma->sta_max_li_mod_dtim_ms, index++,
5377 MAX_VDEV_STA_REQ_PARAMS);
5378 if (QDF_IS_STATUS_ERROR(status)) {
5379 wma_debug("failed to send wmi_vdev_param_max_li_of_moddtim_ms");
5380 goto out;
5381 }
5382 }
5383 status = mlme_check_index_setparam(
5384 setparam,
5385 wmi_vdev_param_dyndtim_cnt,
5386 wma->staDynamicDtim, index++,
5387 MAX_VDEV_STA_REQ_PARAMS);
5388 if (QDF_IS_STATUS_ERROR(status)) {
5389 wma_debug("failed to send wmi_vdev_param_dyndtim_cnt");
5390 goto out;
5391 }
5392
5393 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
5394 params->smesessionId,
5395 WLAN_LEGACY_WMA_ID);
5396 if (!vdev) {
5397 wma_debug("Invalid vdev");
5398 goto out;
5399 }
5400
5401 if (!ucfg_pmo_get_moddtim_user_enable(vdev)) {
5402 moddtim = wma->staModDtim;
5403 status = mlme_check_index_setparam(
5404 setparam,
5405 wmi_vdev_param_moddtim_cnt,
5406 moddtim, index++,
5407 MAX_VDEV_STA_REQ_PARAMS);
5408 if (QDF_IS_STATUS_ERROR(status)) {
5409 wma_debug("failed to send wmi_vdev_param_moddtim_cnt");
5410 goto rel_ref;
5411 }
5412 } else if (ucfg_pmo_get_moddtim_user_enable(vdev) &&
5413 !ucfg_pmo_get_moddtim_user_active(vdev)) {
5414 moddtim = ucfg_pmo_get_moddtim_user(vdev);
5415 status = mlme_check_index_setparam(
5416 setparam,
5417 wmi_vdev_param_moddtim_cnt,
5418 moddtim, index++,
5419 MAX_VDEV_STA_REQ_PARAMS);
5420 if (QDF_IS_STATUS_ERROR(status)) {
5421 wma_debug("failed to send wmi_vdev_param_moddtim_cnt");
5422 goto rel_ref;
5423 }
5424 }
5425 status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
5426 params->smesessionId,
5427 setparam, index);
5428 if (QDF_IS_STATUS_ERROR(status)) {
5429 wma_err("failed to send DTIM vdev setparams");
5430 }
5431 rel_ref:
5432 if (vdev)
5433 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
5434
5435 } else {
5436 wma_debug("listen interval offload is not set");
5437 }
5438 params->nss = iface->nss;
5439 out:
5440 iface->aid = params->assocId;
5441
5442 /* Do not send add stat resp when peer assoc cnf is enabled */
5443 if (peer_assoc_cnf)
5444 return;
5445
5446 params->status = status;
5447 wma_debug("vdev_id %d aid %d sta mac " QDF_MAC_ADDR_FMT " status %d",
5448 params->smesessionId, iface->aid,
5449 QDF_MAC_ADDR_REF(params->bssId), params->status);
5450
5451 /* Don't send a response during roam sync operation */
5452 if (!wlan_cm_is_roam_sync_in_progress(wma->psoc,
5453 params->smesessionId) &&
5454 !MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc,
5455 params->smesessionId))
5456 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
5457 (void *)params, 0);
5458 }
5459
5460 /**
5461 * wma_delete_sta_req_ap_mode() - process delete sta request from UMAC in AP mode
5462 * @wma: wma handle
5463 * @del_sta: delete sta params
5464 *
5465 * Return: none
5466 */
wma_delete_sta_req_ap_mode(tp_wma_handle wma,tpDeleteStaParams del_sta)5467 static void wma_delete_sta_req_ap_mode(tp_wma_handle wma,
5468 tpDeleteStaParams del_sta)
5469 {
5470 struct wma_target_req *msg;
5471 QDF_STATUS qdf_status;
5472
5473 qdf_status = wma_remove_peer(wma, del_sta->staMac,
5474 del_sta->smesessionId, false);
5475 if (QDF_IS_STATUS_ERROR(qdf_status)) {
5476 wma_err("wma_remove_peer failed");
5477 del_sta->status = QDF_STATUS_E_FAILURE;
5478 goto send_del_rsp;
5479 }
5480 del_sta->status = QDF_STATUS_SUCCESS;
5481
5482 if (wmi_service_enabled(wma->wmi_handle,
5483 wmi_service_sync_delete_cmds)) {
5484 msg = wma_fill_hold_req(wma, del_sta->smesessionId,
5485 WMA_DELETE_STA_REQ,
5486 WMA_DELETE_STA_RSP_START, del_sta,
5487 WMA_DELETE_STA_TIMEOUT);
5488 if (!msg) {
5489 wma_err("Failed to allocate request. vdev_id %d",
5490 del_sta->smesessionId);
5491 wma_remove_req(wma, del_sta->smesessionId,
5492 WMA_DELETE_STA_RSP_START);
5493 del_sta->status = QDF_STATUS_E_NOMEM;
5494 goto send_del_rsp;
5495 }
5496
5497 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
5498 WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
5499
5500 return;
5501 }
5502
5503 send_del_rsp:
5504 if (del_sta->respReqd) {
5505 wma_debug("Sending del rsp to umac (status: %d)",
5506 del_sta->status);
5507 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5508 (void *)del_sta, 0);
5509 }
5510 }
5511
5512 #ifdef FEATURE_WLAN_TDLS
5513 /**
5514 * wma_del_tdls_sta() - process delete sta request from UMAC in TDLS
5515 * @wma: wma handle
5516 * @del_sta: delete sta params
5517 *
5518 * Return: none
5519 */
wma_del_tdls_sta(tp_wma_handle wma,tpDeleteStaParams del_sta)5520 static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
5521 {
5522 struct tdls_peer_update_state *peer_state;
5523 struct wma_target_req *msg;
5524 int status;
5525
5526 peer_state = qdf_mem_malloc(sizeof(*peer_state));
5527 if (!peer_state) {
5528 del_sta->status = QDF_STATUS_E_NOMEM;
5529 goto send_del_rsp;
5530 }
5531
5532 peer_state->peer_state = TDLS_PEER_STATE_TEARDOWN;
5533 peer_state->vdev_id = del_sta->smesessionId;
5534 peer_state->resp_reqd = del_sta->respReqd;
5535 qdf_mem_copy(&peer_state->peer_macaddr,
5536 &del_sta->staMac, sizeof(tSirMacAddr));
5537
5538 wma_debug("sending tdls_peer_state for peer mac: "QDF_MAC_ADDR_FMT", peerState: %d",
5539 QDF_MAC_ADDR_REF(peer_state->peer_macaddr),
5540 peer_state->peer_state);
5541
5542 status = wma_update_tdls_peer_state(wma, peer_state);
5543
5544 if (status < 0) {
5545 wma_err("wma_update_tdls_peer_state returned failure");
5546 del_sta->status = QDF_STATUS_E_FAILURE;
5547 goto send_del_rsp;
5548 }
5549
5550 if (del_sta->respReqd &&
5551 wmi_service_enabled(wma->wmi_handle,
5552 wmi_service_sync_delete_cmds)) {
5553 del_sta->status = QDF_STATUS_SUCCESS;
5554 msg = wma_fill_hold_req(wma,
5555 del_sta->smesessionId,
5556 WMA_DELETE_STA_REQ,
5557 WMA_DELETE_STA_RSP_START, del_sta,
5558 WMA_DELETE_STA_TIMEOUT);
5559 if (!msg) {
5560 wma_err("Failed to allocate vdev_id %d",
5561 del_sta->smesessionId);
5562 wma_remove_req(wma,
5563 del_sta->smesessionId,
5564 WMA_DELETE_STA_RSP_START);
5565 del_sta->status = QDF_STATUS_E_NOMEM;
5566 goto send_del_rsp;
5567 }
5568
5569 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
5570 WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
5571 }
5572
5573 return;
5574
5575 send_del_rsp:
5576 if (del_sta->respReqd) {
5577 wma_debug("Sending del rsp to umac (status: %d)",
5578 del_sta->status);
5579 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5580 (void *)del_sta, 0);
5581 }
5582 }
5583 #endif
5584
5585 /**
5586 * wma_delete_sta_req_sta_mode() - process delete sta request from UMAC
5587 * @wma: wma handle
5588 * @params: delete sta params
5589 *
5590 * Return: none
5591 */
wma_delete_sta_req_sta_mode(tp_wma_handle wma,tpDeleteStaParams params)5592 static void wma_delete_sta_req_sta_mode(tp_wma_handle wma,
5593 tpDeleteStaParams params)
5594 {
5595 QDF_STATUS status = QDF_STATUS_SUCCESS;
5596 struct wma_txrx_node *iface;
5597
5598 if (wmi_service_enabled(wma->wmi_handle,
5599 wmi_service_listen_interval_offload_support)) {
5600 struct wlan_objmgr_vdev *vdev;
5601
5602 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
5603 params->smesessionId,
5604 WLAN_LEGACY_WMA_ID);
5605 if (vdev) {
5606 if (ucfg_pmo_get_moddtim_user_enable(vdev))
5607 ucfg_pmo_set_moddtim_user_enable(vdev, false);
5608 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
5609 }
5610 }
5611
5612 iface = &wma->interfaces[params->smesessionId];
5613 iface->uapsd_cached_val = 0;
5614 #ifdef FEATURE_WLAN_TDLS
5615 if (STA_ENTRY_TDLS_PEER == params->staType) {
5616 wma_del_tdls_sta(wma, params);
5617 return;
5618 }
5619 #endif
5620 params->status = status;
5621 if (params->respReqd) {
5622 wma_debug("vdev_id %d status %d",
5623 params->smesessionId, status);
5624 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5625 (void *)params, 0);
5626 }
5627 }
5628
wma_sap_prevent_runtime_pm(tp_wma_handle wma)5629 static void wma_sap_prevent_runtime_pm(tp_wma_handle wma)
5630 {
5631 qdf_runtime_pm_prevent_suspend(&wma->sap_prevent_runtime_pm_lock);
5632 }
5633
wma_sap_allow_runtime_pm(tp_wma_handle wma)5634 static void wma_sap_allow_runtime_pm(tp_wma_handle wma)
5635 {
5636 qdf_runtime_pm_allow_suspend(&wma->sap_prevent_runtime_pm_lock);
5637 }
5638
wma_ndp_prevent_runtime_pm(tp_wma_handle wma)5639 static void wma_ndp_prevent_runtime_pm(tp_wma_handle wma)
5640 {
5641 qdf_runtime_pm_prevent_suspend(&wma->ndp_prevent_runtime_pm_lock);
5642 }
5643
wma_ndp_allow_runtime_pm(tp_wma_handle wma)5644 static void wma_ndp_allow_runtime_pm(tp_wma_handle wma)
5645 {
5646 qdf_runtime_pm_allow_suspend(&wma->ndp_prevent_runtime_pm_lock);
5647 }
5648 #ifdef FEATURE_STA_MODE_VOTE_LINK
wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode)5649 static bool wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode)
5650 {
5651 if (oper_mode == BSS_OPERATIONAL_MODE_STA && ucfg_ipa_is_enabled())
5652 return true;
5653
5654 return false;
5655 }
5656 #else /* !FEATURE_STA_MODE_VOTE_LINK */
wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode)5657 static bool wma_add_sta_allow_sta_mode_vote_link(uint8_t oper_mode)
5658 {
5659 return false;
5660 }
5661 #endif /* FEATURE_STA_MODE_VOTE_LINK */
5662
wma_is_vdev_in_sap_mode(tp_wma_handle wma,uint8_t vdev_id)5663 static bool wma_is_vdev_in_sap_mode(tp_wma_handle wma, uint8_t vdev_id)
5664 {
5665 struct wma_txrx_node *intf = wma->interfaces;
5666
5667 if (vdev_id >= wma->max_bssid) {
5668 wma_err("Invalid vdev_id %hu", vdev_id);
5669 QDF_ASSERT(0);
5670 return false;
5671 }
5672
5673 if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
5674 (intf[vdev_id].sub_type == 0))
5675 return true;
5676
5677 return false;
5678 }
5679
wma_is_vdev_in_go_mode(tp_wma_handle wma,uint8_t vdev_id)5680 static bool wma_is_vdev_in_go_mode(tp_wma_handle wma, uint8_t vdev_id)
5681 {
5682 struct wma_txrx_node *intf = wma->interfaces;
5683
5684 if (vdev_id >= wma->max_bssid) {
5685 wma_err("Invalid vdev_id %hu", vdev_id);
5686 QDF_ASSERT(0);
5687 return false;
5688 }
5689
5690 if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
5691 (intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO))
5692 return true;
5693
5694 return false;
5695 }
5696
wma_sap_d3_wow_client_connect(tp_wma_handle wma)5697 static void wma_sap_d3_wow_client_connect(tp_wma_handle wma)
5698 {
5699 uint32_t num_clients;
5700
5701 num_clients = qdf_atomic_inc_return(&wma->sap_num_clients_connected);
5702 wmi_debug("sap d3 wow %d client connected", num_clients);
5703 if (num_clients == SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK) {
5704 wmi_info("max clients connected acquire sap d3 wow wake lock");
5705 qdf_wake_lock_acquire(&wma->sap_d3_wow_wake_lock,
5706 WIFI_POWER_EVENT_WAKELOCK_SAP_D3_WOW);
5707 }
5708 }
5709
wma_sap_d3_wow_client_disconnect(tp_wma_handle wma)5710 static void wma_sap_d3_wow_client_disconnect(tp_wma_handle wma)
5711 {
5712 uint32_t num_clients;
5713
5714 num_clients = qdf_atomic_dec_return(&wma->sap_num_clients_connected);
5715 wmi_debug("sap d3 wow %d client connected", num_clients);
5716 if (num_clients == SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK) {
5717 wmi_info("max clients disconnected release sap d3 wow wake lock");
5718 qdf_wake_lock_release(&wma->sap_d3_wow_wake_lock,
5719 WIFI_POWER_EVENT_WAKELOCK_SAP_D3_WOW);
5720 }
5721 }
5722
wma_go_d3_wow_client_connect(tp_wma_handle wma)5723 static void wma_go_d3_wow_client_connect(tp_wma_handle wma)
5724 {
5725 uint32_t num_clients;
5726
5727 num_clients = qdf_atomic_inc_return(&wma->go_num_clients_connected);
5728 wmi_debug("go d3 wow %d client connected", num_clients);
5729 if (num_clients == SAP_D3_WOW_MAX_CLIENT_HOLD_WAKE_LOCK) {
5730 wmi_info("max clients connected acquire go d3 wow wake lock");
5731 qdf_wake_lock_acquire(&wma->go_d3_wow_wake_lock,
5732 WIFI_POWER_EVENT_WAKELOCK_GO_D3_WOW);
5733 }
5734 }
5735
wma_go_d3_wow_client_disconnect(tp_wma_handle wma)5736 static void wma_go_d3_wow_client_disconnect(tp_wma_handle wma)
5737 {
5738 uint32_t num_clients;
5739
5740 num_clients = qdf_atomic_dec_return(&wma->go_num_clients_connected);
5741 wmi_debug("go d3 wow %d client connected", num_clients);
5742 if (num_clients == SAP_D3_WOW_MAX_CLIENT_RELEASE_WAKE_LOCK) {
5743 wmi_info("max clients disconnected release go d3 wow wake lock");
5744 qdf_wake_lock_release(&wma->go_d3_wow_wake_lock,
5745 WIFI_POWER_EVENT_WAKELOCK_GO_D3_WOW);
5746 }
5747 }
5748
wma_add_sta(tp_wma_handle wma,tpAddStaParams add_sta)5749 void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta)
5750 {
5751 uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
5752 void *htc_handle;
5753 QDF_STATUS status = QDF_STATUS_SUCCESS;
5754 uint8_t vdev_id = add_sta->smesessionId;
5755
5756 htc_handle = lmac_get_htc_hdl(wma->psoc);
5757 if (!htc_handle) {
5758 wma_err("HTC handle is NULL");
5759 return;
5760 }
5761
5762 wma_debug("Vdev %d BSSID "QDF_MAC_ADDR_FMT, vdev_id,
5763 QDF_MAC_ADDR_REF(add_sta->bssId));
5764
5765 if (wma_is_vdev_in_ap_mode(wma, vdev_id))
5766 oper_mode = BSS_OPERATIONAL_MODE_AP;
5767
5768 if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id))
5769 oper_mode = BSS_OPERATIONAL_MODE_NDI;
5770 switch (oper_mode) {
5771 case BSS_OPERATIONAL_MODE_STA:
5772 wma_add_sta_req_sta_mode(wma, add_sta);
5773 break;
5774
5775 case BSS_OPERATIONAL_MODE_AP:
5776 wma_add_sta_req_ap_mode(wma, add_sta);
5777 break;
5778 case BSS_OPERATIONAL_MODE_NDI:
5779 status = wma_add_sta_ndi_mode(wma, add_sta);
5780 break;
5781 }
5782
5783 /*
5784 * not use add_sta after this to avoid use after free
5785 * as it maybe freed.
5786 */
5787
5788 /* handle wow for sap with 1 or more peer in same way */
5789 if (wma_is_vdev_in_sap_mode(wma, vdev_id)) {
5790 bool is_bus_suspend_allowed_in_sap_mode =
5791 (wlan_pmo_get_sap_mode_bus_suspend(wma->psoc) &&
5792 wmi_service_enabled(wma->wmi_handle,
5793 wmi_service_sap_connected_d3_wow));
5794 if (!is_bus_suspend_allowed_in_sap_mode) {
5795 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_SAP_USER_ID);
5796 wmi_info("sap d0 wow");
5797 } else {
5798 wmi_debug("sap d3 wow");
5799 wma_sap_d3_wow_client_connect(wma);
5800 }
5801 wma_sap_prevent_runtime_pm(wma);
5802
5803 return;
5804 }
5805
5806 /* handle wow for p2pgo with 1 or more peer in same way */
5807 if (wma_is_vdev_in_go_mode(wma, vdev_id)) {
5808 bool is_bus_suspend_allowed_in_go_mode =
5809 (wlan_pmo_get_go_mode_bus_suspend(wma->psoc) &&
5810 wmi_service_enabled(wma->wmi_handle,
5811 wmi_service_go_connected_d3_wow));
5812 if (!is_bus_suspend_allowed_in_go_mode) {
5813 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_GO_USER_ID);
5814 wmi_info("p2p go d0 wow");
5815 } else {
5816 wmi_info("p2p go d3 wow");
5817 wma_go_d3_wow_client_connect(wma);
5818 }
5819 wma_sap_prevent_runtime_pm(wma);
5820
5821 return;
5822 }
5823
5824 /* handle wow for nan with 1 or more peer in same way */
5825 if (BSS_OPERATIONAL_MODE_NDI == oper_mode &&
5826 QDF_IS_STATUS_SUCCESS(status)) {
5827 wma_debug("disable runtime pm and vote for link up");
5828 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_NDP_USER_ID);
5829 wma_ndp_prevent_runtime_pm(wma);
5830 } else if (wma_add_sta_allow_sta_mode_vote_link(oper_mode)) {
5831 wma_debug("vote for link up");
5832 htc_vote_link_up(htc_handle, HTC_LINK_VOTE_STA_USER_ID);
5833 }
5834 }
5835
wma_delete_sta(tp_wma_handle wma,tpDeleteStaParams del_sta)5836 void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
5837 {
5838 uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
5839 uint8_t vdev_id = del_sta->smesessionId;
5840 bool rsp_requested = del_sta->respReqd;
5841 void *htc_handle;
5842 QDF_STATUS status = QDF_STATUS_SUCCESS;
5843
5844 htc_handle = lmac_get_htc_hdl(wma->psoc);
5845 if (!htc_handle) {
5846 wma_err("HTC handle is NULL");
5847 return;
5848 }
5849
5850 if (wma_is_vdev_in_ap_mode(wma, vdev_id))
5851 oper_mode = BSS_OPERATIONAL_MODE_AP;
5852 if (del_sta->staType == STA_ENTRY_NDI_PEER)
5853 oper_mode = BSS_OPERATIONAL_MODE_NDI;
5854
5855 wma_debug("vdev %d oper_mode %d", vdev_id, oper_mode);
5856
5857 switch (oper_mode) {
5858 case BSS_OPERATIONAL_MODE_STA:
5859 if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) ||
5860 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) ||
5861 mlo_is_roaming_in_progress(wma->psoc, vdev_id)) {
5862 wma_debug("LFR3: Del STA on vdev_id %d", vdev_id);
5863 qdf_mem_free(del_sta);
5864 return;
5865 }
5866 wma_delete_sta_req_sta_mode(wma, del_sta);
5867 if (!rsp_requested)
5868 qdf_mem_free(del_sta);
5869
5870 break;
5871
5872 case BSS_OPERATIONAL_MODE_AP:
5873 wma_delete_sta_req_ap_mode(wma, del_sta);
5874 /* free the memory here only if sync feature is not enabled */
5875 if (!rsp_requested &&
5876 !wmi_service_enabled(wma->wmi_handle,
5877 wmi_service_sync_delete_cmds))
5878 qdf_mem_free(del_sta);
5879 else if (!rsp_requested &&
5880 (del_sta->status != QDF_STATUS_SUCCESS))
5881 qdf_mem_free(del_sta);
5882 break;
5883 case BSS_OPERATIONAL_MODE_NDI:
5884 status = wma_delete_sta_req_ndi_mode(wma, del_sta);
5885 break;
5886 default:
5887 wma_err("Incorrect oper mode %d", oper_mode);
5888 qdf_mem_free(del_sta);
5889 }
5890
5891 if (wma_is_vdev_in_sap_mode(wma, vdev_id)) {
5892 bool is_bus_suspend_allowed_in_sap_mode =
5893 (wlan_pmo_get_sap_mode_bus_suspend(wma->psoc) &&
5894 wmi_service_enabled(wma->wmi_handle,
5895 wmi_service_sap_connected_d3_wow));
5896 if (!is_bus_suspend_allowed_in_sap_mode) {
5897 htc_vote_link_down(htc_handle,
5898 HTC_LINK_VOTE_SAP_USER_ID);
5899 wmi_info("sap d0 wow");
5900 } else {
5901 wmi_debug("sap d3 wow");
5902 wma_sap_d3_wow_client_disconnect(wma);
5903 }
5904 wma_sap_allow_runtime_pm(wma);
5905
5906 return;
5907 }
5908
5909 if (wma_is_vdev_in_go_mode(wma, vdev_id)) {
5910 bool is_bus_suspend_allowed_in_go_mode =
5911 (wlan_pmo_get_go_mode_bus_suspend(wma->psoc) &&
5912 wmi_service_enabled(wma->wmi_handle,
5913 wmi_service_go_connected_d3_wow));
5914 if (!is_bus_suspend_allowed_in_go_mode) {
5915 htc_vote_link_down(htc_handle,
5916 HTC_LINK_VOTE_GO_USER_ID);
5917 wmi_info("p2p go d0 wow");
5918 } else {
5919 wmi_info("p2p go d3 wow");
5920 wma_go_d3_wow_client_disconnect(wma);
5921 }
5922 wma_sap_allow_runtime_pm(wma);
5923
5924 return;
5925 }
5926
5927 if (BSS_OPERATIONAL_MODE_NDI == oper_mode &&
5928 QDF_IS_STATUS_SUCCESS(status)) {
5929 wma_debug("allow runtime pm and vote for link down");
5930 htc_vote_link_down(htc_handle, HTC_LINK_VOTE_NDP_USER_ID);
5931 wma_ndp_allow_runtime_pm(wma);
5932 } else if (wma_add_sta_allow_sta_mode_vote_link(oper_mode)) {
5933 wma_debug("vote for link down");
5934 htc_vote_link_down(htc_handle, HTC_LINK_VOTE_STA_USER_ID);
5935 }
5936 }
5937
wma_delete_bss_ho_fail(tp_wma_handle wma,uint8_t vdev_id)5938 void wma_delete_bss_ho_fail(tp_wma_handle wma, uint8_t vdev_id)
5939 {
5940 QDF_STATUS status = QDF_STATUS_SUCCESS;
5941 struct wma_txrx_node *iface;
5942 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
5943 struct vdev_stop_response resp_event;
5944 struct del_bss_resp *vdev_stop_resp;
5945 uint8_t *bssid;
5946
5947 iface = &wma->interfaces[vdev_id];
5948 if (!iface) {
5949 wma_err("iface for vdev_id %d is already deleted", vdev_id);
5950 goto fail_del_bss_ho_fail;
5951 }
5952 bssid = wma_get_vdev_bssid(iface->vdev);
5953 if (!bssid) {
5954 wma_err("Invalid bssid");
5955 status = QDF_STATUS_E_FAILURE;
5956 goto fail_del_bss_ho_fail;
5957 }
5958 qdf_mem_zero(bssid, QDF_MAC_ADDR_SIZE);
5959
5960 if (iface->psnr_req) {
5961 qdf_mem_free(iface->psnr_req);
5962 iface->psnr_req = NULL;
5963 }
5964
5965 if (iface->rcpi_req) {
5966 struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
5967
5968 iface->rcpi_req = NULL;
5969 qdf_mem_free(rcpi_req);
5970 }
5971
5972 if (iface->roam_scan_stats_req) {
5973 struct sir_roam_scan_stats *roam_scan_stats_req =
5974 iface->roam_scan_stats_req;
5975
5976 iface->roam_scan_stats_req = NULL;
5977 qdf_mem_free(roam_scan_stats_req);
5978 }
5979
5980 wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
5981 vdev_id);
5982 cdp_fc_vdev_pause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
5983 wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
5984 cdp_fc_vdev_flush(soc, vdev_id);
5985 wma_debug("vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
5986 vdev_id);
5987 cdp_fc_vdev_unpause(soc, vdev_id, OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
5988 wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST);
5989 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
5990 wma_debug("(type %d subtype %d) BSS is stopped",
5991 iface->type, iface->sub_type);
5992
5993 status = mlme_set_vdev_stop_type(iface->vdev,
5994 WMA_DELETE_BSS_HO_FAIL_REQ);
5995 if (QDF_IS_STATUS_ERROR(status)) {
5996 wma_err("Failed to set wma req msg_type for vdev_id: %d",
5997 vdev_id);
5998 goto fail_del_bss_ho_fail;
5999 }
6000
6001 /* Try to use the vdev stop response path */
6002 resp_event.vdev_id = vdev_id;
6003 status = wma_handle_vdev_stop_rsp(wma, &resp_event);
6004 if (QDF_IS_STATUS_ERROR(status)) {
6005 wma_err("Failed to handle vdev stop rsp for vdev_id %d",
6006 vdev_id);
6007 goto fail_del_bss_ho_fail;
6008 }
6009
6010 return;
6011
6012 fail_del_bss_ho_fail:
6013 vdev_stop_resp = qdf_mem_malloc(sizeof(*vdev_stop_resp));
6014 if (!vdev_stop_resp)
6015 return;
6016
6017 vdev_stop_resp->vdev_id = vdev_id;
6018 vdev_stop_resp->status = status;
6019 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_HO_FAIL_RSP,
6020 (void *)vdev_stop_resp, 0);
6021 }
6022
6023 /**
6024 * wma_wait_tx_complete() - Wait till tx packets are drained
6025 * @wma: wma handle
6026 * @session_id: vdev id
6027 *
6028 * Return: none
6029 */
wma_wait_tx_complete(tp_wma_handle wma,uint32_t session_id)6030 static void wma_wait_tx_complete(tp_wma_handle wma,
6031 uint32_t session_id)
6032 {
6033 uint8_t max_wait_iterations = 0, delay = 0;
6034 cdp_config_param_type val;
6035 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
6036 QDF_STATUS status;
6037
6038 if (!wma_is_vdev_valid(session_id)) {
6039 wma_err("Vdev is not valid: %d", session_id);
6040 return;
6041 }
6042
6043 status = ucfg_mlme_get_delay_before_vdev_stop(wma->psoc, &delay);
6044 if (QDF_IS_STATUS_ERROR(status))
6045 wma_err("Failed to get delay before vdev stop");
6046
6047 max_wait_iterations = delay / WMA_TX_Q_RECHECK_TIMER_WAIT;
6048 if (cdp_txrx_get_pdev_param(soc,
6049 wlan_objmgr_pdev_get_pdev_id(wma->pdev),
6050 CDP_TX_PENDING, &val))
6051 return;
6052 while (val.cdp_pdev_param_tx_pending && max_wait_iterations) {
6053 wma_warn("Waiting for outstanding packet to drain");
6054 qdf_wait_for_event_completion(&wma->tx_queue_empty_event,
6055 WMA_TX_Q_RECHECK_TIMER_WAIT);
6056 if (cdp_txrx_get_pdev_param(
6057 soc,
6058 wlan_objmgr_pdev_get_pdev_id(wma->pdev),
6059 CDP_TX_PENDING, &val))
6060 return;
6061 max_wait_iterations--;
6062 }
6063 }
6064
wma_delete_bss(tp_wma_handle wma,uint8_t vdev_id)6065 void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id)
6066 {
6067 bool peer_exist = false;
6068 QDF_STATUS status = QDF_STATUS_SUCCESS;
6069 uint32_t tx_pending = 0;
6070 cdp_config_param_type val;
6071 bool roam_synch_in_progress = false;
6072 struct wma_txrx_node *iface;
6073 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
6074 struct qdf_mac_addr bssid;
6075 struct del_bss_resp *params;
6076 uint8_t *addr, *bssid_addr;
6077
6078 iface = &wma->interfaces[vdev_id];
6079 if (!iface || !iface->vdev) {
6080 wma_err("vdev id %d is already deleted", vdev_id);
6081 goto out;
6082 }
6083
6084 status = wlan_vdev_get_bss_peer_mac(iface->vdev, &bssid);
6085 if (QDF_IS_STATUS_ERROR(status)) {
6086 wma_err("vdev id %d : failed to get bssid", vdev_id);
6087 goto out;
6088 }
6089
6090 addr = wlan_vdev_mlme_get_macaddr(iface->vdev);
6091 if (!addr) {
6092 wma_err("vdev id %d : failed to get macaddr", vdev_id);
6093 goto out;
6094 }
6095
6096 if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
6097 vdev_id))
6098 /* In ndi case, self mac is used to create the self peer */
6099 peer_exist = wma_cdp_find_peer_by_addr(addr);
6100 else
6101 peer_exist = wma_cdp_find_peer_by_addr(bssid.bytes);
6102 if (!peer_exist) {
6103 wma_err("Failed to find peer "QDF_MAC_ADDR_FMT,
6104 QDF_MAC_ADDR_REF(bssid.bytes));
6105 status = QDF_STATUS_E_FAILURE;
6106 goto out;
6107 }
6108 bssid_addr = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev);
6109 if (!bssid_addr) {
6110 wma_err("Failed to bssid for vdev_%d", vdev_id);
6111 status = QDF_STATUS_E_FAILURE;
6112 goto out;
6113 }
6114 qdf_mem_zero(bssid_addr,
6115 QDF_MAC_ADDR_SIZE);
6116
6117 wma_delete_invalid_peer_entries(vdev_id, NULL);
6118
6119 if (iface->psnr_req) {
6120 qdf_mem_free(iface->psnr_req);
6121 iface->psnr_req = NULL;
6122 }
6123
6124 if (iface->rcpi_req) {
6125 struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
6126
6127 iface->rcpi_req = NULL;
6128 qdf_mem_free(rcpi_req);
6129 }
6130
6131 if (iface->roam_scan_stats_req) {
6132 struct sir_roam_scan_stats *roam_scan_stats_req =
6133 iface->roam_scan_stats_req;
6134
6135 iface->roam_scan_stats_req = NULL;
6136 qdf_mem_free(roam_scan_stats_req);
6137 }
6138
6139 if (wlan_cm_is_roam_sync_in_progress(wma->psoc, vdev_id) ||
6140 MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id) ||
6141 mlo_is_roaming_in_progress(wma->psoc, vdev_id)) {
6142 roam_synch_in_progress = true;
6143 wma_debug("LFR3: Setting vdev_up to FALSE for vdev:%d",
6144 vdev_id);
6145
6146 goto detach_peer;
6147 }
6148
6149 status = mlme_set_vdev_stop_type(iface->vdev,
6150 WMA_DELETE_BSS_REQ);
6151 if (QDF_IS_STATUS_ERROR(status)) {
6152 wma_err("Failed to set wma req msg_type for vdev_id: %d",
6153 vdev_id);
6154 goto out;
6155 }
6156
6157 cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev),
6158 CDP_TX_PENDING, &val);
6159 tx_pending = val.cdp_pdev_param_tx_pending;
6160 wma_debug("Outstanding msdu packets: %u", tx_pending);
6161 wma_wait_tx_complete(wma, vdev_id);
6162
6163 cdp_txrx_get_pdev_param(soc, wlan_objmgr_pdev_get_pdev_id(wma->pdev),
6164 CDP_TX_PENDING, &val);
6165 if (tx_pending) {
6166 wma_debug("Outstanding msdu packets before VDEV_STOP : %u",
6167 tx_pending);
6168 }
6169
6170 wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
6171 vdev_id);
6172 wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
6173 cdp_fc_vdev_pause(soc, vdev_id,
6174 OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
6175
6176 if (wma_send_vdev_stop_to_fw(wma, vdev_id)) {
6177 struct vdev_stop_response vdev_stop_rsp = {0};
6178
6179 wma_err("Failed to send vdev stop to FW, explicitly invoke vdev stop rsp");
6180 vdev_stop_rsp.vdev_id = vdev_id;
6181 wma_handle_vdev_stop_rsp(wma, &vdev_stop_rsp);
6182 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
6183 }
6184 wma_debug("bssid "QDF_MAC_ADDR_FMT" vdev_id %d",
6185 QDF_MAC_ADDR_REF(bssid.bytes), vdev_id);
6186
6187 return;
6188
6189 detach_peer:
6190 wma_remove_peer(wma, bssid.bytes, vdev_id, roam_synch_in_progress);
6191 if (roam_synch_in_progress)
6192 return;
6193
6194 out:
6195 /* skip when legacy to mlo roam sync ongoing */
6196 if (MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(wma->psoc, vdev_id))
6197 return;
6198
6199 params = qdf_mem_malloc(sizeof(*params));
6200 if (!params)
6201 return;
6202
6203 params->vdev_id = vdev_id;
6204 params->status = status;
6205 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, params, 0);
6206 }
6207
6208 /**
6209 * wma_find_vdev_by_type() - This function finds vdev_id based on input type
6210 * @wma: wma handle
6211 * @type: vdev type
6212 *
6213 * Return: vdev id
6214 */
wma_find_vdev_by_type(tp_wma_handle wma,int32_t type)6215 int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type)
6216 {
6217 int32_t vdev_id = 0;
6218 struct wma_txrx_node *intf = wma->interfaces;
6219
6220 for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
6221 if (intf) {
6222 if (intf[vdev_id].type == type)
6223 return vdev_id;
6224 }
6225 }
6226
6227 return -EFAULT;
6228 }
6229
wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle,tpDisableIntraBssFwd pdis_intra_fwd)6230 void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle,
6231 tpDisableIntraBssFwd pdis_intra_fwd)
6232 {
6233 struct wlan_objmgr_vdev *vdev;
6234
6235 wma_debug("intra_fwd:vdev(%d) intrabss_dis=%s",
6236 pdis_intra_fwd->sessionId,
6237 (pdis_intra_fwd->disableintrabssfwd ? "true" : "false"));
6238
6239 vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].vdev;
6240 cdp_cfg_vdev_rx_set_intrabss_fwd(cds_get_context(QDF_MODULE_ID_SOC),
6241 pdis_intra_fwd->sessionId,
6242 pdis_intra_fwd->disableintrabssfwd);
6243 }
6244
6245 /**
6246 * wma_get_pdev_from_scn_handle() - API to get pdev from scn handle
6247 * @scn_handle: opaque wma handle
6248 *
6249 * API to get pdev from scn handle
6250 *
6251 * Return: None
6252 */
wma_get_pdev_from_scn_handle(void * scn_handle)6253 static struct wlan_objmgr_pdev *wma_get_pdev_from_scn_handle(void *scn_handle)
6254 {
6255 tp_wma_handle wma_handle;
6256
6257 if (!scn_handle) {
6258 wma_err("invalid scn handle");
6259 return NULL;
6260 }
6261 wma_handle = (tp_wma_handle)scn_handle;
6262
6263 return wma_handle->pdev;
6264 }
6265
wma_store_pdev(void * wma_ctx,struct wlan_objmgr_pdev * pdev)6266 void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev)
6267 {
6268 tp_wma_handle wma = (tp_wma_handle)wma_ctx;
6269 QDF_STATUS status;
6270
6271 status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_WMA_ID);
6272 if (QDF_STATUS_SUCCESS != status) {
6273 wma->pdev = NULL;
6274 return;
6275 }
6276
6277 wma->pdev = pdev;
6278
6279 target_if_store_pdev_target_if_ctx(wma_get_pdev_from_scn_handle);
6280 target_pdev_set_wmi_handle(wma->pdev->tgt_if_handle,
6281 wma->wmi_handle);
6282 }
6283
6284 /**
6285 * wma_vdev_reset_beacon_interval_timer() - reset beacon interval back
6286 * to its original value after the channel switch.
6287 *
6288 * @data: data
6289 *
6290 * Return: void
6291 */
wma_vdev_reset_beacon_interval_timer(void * data)6292 static void wma_vdev_reset_beacon_interval_timer(void *data)
6293 {
6294 tp_wma_handle wma;
6295 struct wma_beacon_interval_reset_req *req =
6296 (struct wma_beacon_interval_reset_req *)data;
6297 uint16_t beacon_interval = req->interval;
6298 uint8_t vdev_id = req->vdev_id;
6299
6300 wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
6301 if (!wma)
6302 goto end;
6303
6304 /* Change the beacon interval back to its original value */
6305 wma_debug("Change beacon interval back to %d", beacon_interval);
6306 wma_update_beacon_interval(wma, vdev_id, beacon_interval);
6307
6308 end:
6309 qdf_timer_stop(&req->event_timeout);
6310 qdf_timer_free(&req->event_timeout);
6311 qdf_mem_free(req);
6312 }
6313
wma_fill_beacon_interval_reset_req(tp_wma_handle wma,uint8_t vdev_id,uint16_t beacon_interval,uint32_t timeout)6314 int wma_fill_beacon_interval_reset_req(tp_wma_handle wma, uint8_t vdev_id,
6315 uint16_t beacon_interval, uint32_t timeout)
6316 {
6317 struct wma_beacon_interval_reset_req *req;
6318
6319 req = qdf_mem_malloc(sizeof(*req));
6320 if (!req)
6321 return -ENOMEM;
6322
6323 wma_debug("vdev_id %d ", vdev_id);
6324 req->vdev_id = vdev_id;
6325 req->interval = beacon_interval;
6326 qdf_timer_init(NULL, &req->event_timeout,
6327 wma_vdev_reset_beacon_interval_timer, req, QDF_TIMER_TYPE_SW);
6328 qdf_timer_start(&req->event_timeout, timeout);
6329
6330 return 0;
6331 }
6332
wma_set_wlm_latency_level(void * wma_ptr,struct wlm_latency_level_param * latency_params)6333 QDF_STATUS wma_set_wlm_latency_level(void *wma_ptr,
6334 struct wlm_latency_level_param *latency_params)
6335 {
6336 QDF_STATUS ret;
6337 tp_wma_handle wma = (tp_wma_handle)wma_ptr;
6338
6339 wma_debug("set latency level %d, fw wlm_latency_flags 0x%x",
6340 latency_params->wlm_latency_level,
6341 latency_params->wlm_latency_flags);
6342
6343 ret = wmi_unified_wlm_latency_level_cmd(wma->wmi_handle,
6344 latency_params);
6345 if (QDF_IS_STATUS_ERROR(ret))
6346 wma_warn("Failed to set latency level");
6347
6348 return ret;
6349 }
6350
wma_add_bss_peer_sta(uint8_t vdev_id,uint8_t * bssid,bool is_resp_required,uint8_t * mld_mac,bool is_assoc_peer)6351 QDF_STATUS wma_add_bss_peer_sta(uint8_t vdev_id, uint8_t *bssid,
6352 bool is_resp_required,
6353 uint8_t *mld_mac, bool is_assoc_peer)
6354 {
6355 tp_wma_handle wma;
6356 QDF_STATUS status = QDF_STATUS_E_FAILURE;
6357
6358 wma = cds_get_context(QDF_MODULE_ID_WMA);
6359 if (!wma)
6360 goto err;
6361
6362 if (is_resp_required)
6363 status = wma_create_sta_mode_bss_peer(wma, bssid,
6364 WMI_PEER_TYPE_DEFAULT,
6365 vdev_id, mld_mac,
6366 is_assoc_peer);
6367 else
6368 status = wma_create_peer(wma, bssid, WMI_PEER_TYPE_DEFAULT,
6369 vdev_id, mld_mac, is_assoc_peer);
6370 err:
6371 return status;
6372 }
6373
wma_send_vdev_stop(uint8_t vdev_id)6374 QDF_STATUS wma_send_vdev_stop(uint8_t vdev_id)
6375 {
6376 tp_wma_handle wma;
6377 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
6378 QDF_STATUS status;
6379
6380 wma = cds_get_context(QDF_MODULE_ID_WMA);
6381 if (!wma)
6382 return QDF_STATUS_E_FAILURE;
6383
6384 wma_debug("vdev_id: %d, pausing tx_ll_queue for VDEV_STOP", vdev_id);
6385 cdp_fc_vdev_pause(soc, vdev_id,
6386 OL_TXQ_PAUSE_REASON_VDEV_STOP, 0);
6387
6388 status = mlme_set_vdev_stop_type(
6389 wma->interfaces[vdev_id].vdev,
6390 WMA_SET_LINK_STATE);
6391 if (QDF_IS_STATUS_ERROR(status)) {
6392 wma_alert("Failed to set wma req msg_type for vdev_id %d",
6393 vdev_id);
6394 return QDF_STATUS_E_FAILURE;
6395 }
6396
6397 wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST);
6398
6399 status = wma_send_vdev_stop_to_fw(wma, vdev_id);
6400 if (QDF_IS_STATUS_ERROR(status)) {
6401 struct vdev_stop_response resp_event;
6402
6403 wma_info("vdev %d Failed to send vdev stop", vdev_id);
6404 resp_event.vdev_id = vdev_id;
6405 mlme_set_connection_fail(wma->interfaces[vdev_id].vdev, false);
6406 wma_handle_vdev_stop_rsp(wma, &resp_event);
6407 }
6408
6409 /*
6410 * Remove peer, Vdev down and sending set link
6411 * response will be handled in vdev stop response
6412 * handler
6413 */
6414
6415 return QDF_STATUS_SUCCESS;
6416 }
6417
6418 #define TX_MGMT_RATE_2G_ENABLE_OFFSET 30
6419 #define TX_MGMT_RATE_5G_ENABLE_OFFSET 31
6420 #define TX_MGMT_RATE_2G_OFFSET 0
6421 #define TX_MGMT_RATE_5G_OFFSET 12
6422
6423 /**
6424 * wma_verify_rate_code() - verify if rate code is valid.
6425 * @rate_code: rate code
6426 * @band: band information
6427 *
6428 * Return: verify result
6429 */
wma_verify_rate_code(uint32_t rate_code,enum cds_band_type band)6430 static bool wma_verify_rate_code(uint32_t rate_code, enum cds_band_type band)
6431 {
6432 uint8_t preamble, nss, rate;
6433 bool valid = true;
6434
6435 preamble = (rate_code & 0xc0) >> 6;
6436 nss = (rate_code & 0x30) >> 4;
6437 rate = rate_code & 0xf;
6438
6439 switch (preamble) {
6440 case WMI_RATE_PREAMBLE_CCK:
6441 if (nss != 0 || rate > 3 || band == CDS_BAND_5GHZ)
6442 valid = false;
6443 break;
6444 case WMI_RATE_PREAMBLE_OFDM:
6445 if (nss != 0 || rate > 7)
6446 valid = false;
6447 break;
6448 case WMI_RATE_PREAMBLE_HT:
6449 if (nss != 0 || rate > 7)
6450 valid = false;
6451 break;
6452 case WMI_RATE_PREAMBLE_VHT:
6453 if (nss != 0 || rate > 9)
6454 valid = false;
6455 break;
6456 default:
6457 break;
6458 }
6459 return valid;
6460 }
6461
6462 /**
6463 * wma_vdev_mgmt_tx_rate() - set vdev mgmt rate.
6464 * @info: pointer to vdev set param.
6465 *
6466 * Return: return status
6467 */
wma_vdev_mgmt_tx_rate(struct dev_set_param * info)6468 static QDF_STATUS wma_vdev_mgmt_tx_rate(struct dev_set_param *info)
6469 {
6470 uint32_t cfg_val;
6471 enum cds_band_type band = 0;
6472 QDF_STATUS status;
6473 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6474
6475 if (!mac) {
6476 wma_err("Failed to get mac");
6477 return QDF_STATUS_E_FAILURE;
6478 }
6479
6480 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
6481 band = CDS_BAND_ALL;
6482 if (cfg_val == MLME_CFG_TX_MGMT_RATE_DEF ||
6483 !wma_verify_rate_code(cfg_val, band)) {
6484 wma_nofl_debug("default WNI_CFG_RATE_FOR_TX_MGMT, ignore");
6485 status = QDF_STATUS_E_FAILURE;
6486 } else {
6487 info->param_id = wmi_vdev_param_mgmt_tx_rate;
6488 info->param_value = cfg_val;
6489 status = QDF_STATUS_SUCCESS;
6490 }
6491 return status;
6492 }
6493
6494 /**
6495 * wma_vdev_mgmt_perband_tx_rate() - set vdev mgmt perband tx rate.
6496 * @info: pointer to vdev set param
6497 *
6498 * Return: returns status
6499 */
wma_vdev_mgmt_perband_tx_rate(struct dev_set_param * info)6500 static QDF_STATUS wma_vdev_mgmt_perband_tx_rate(struct dev_set_param *info)
6501 {
6502 uint32_t cfg_val;
6503 uint32_t per_band_mgmt_tx_rate = 0;
6504 enum cds_band_type band = 0;
6505 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6506
6507 if (!mac) {
6508 wma_err("failed to get mac");
6509 return QDF_STATUS_E_FAILURE;
6510 }
6511
6512 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt_2g;
6513 band = CDS_BAND_2GHZ;
6514 if (cfg_val == MLME_CFG_TX_MGMT_2G_RATE_DEF ||
6515 !wma_verify_rate_code(cfg_val, band)) {
6516 wma_nofl_debug("use default 2G MGMT rate.");
6517 per_band_mgmt_tx_rate &=
6518 ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
6519 } else {
6520 per_band_mgmt_tx_rate |=
6521 (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
6522 per_band_mgmt_tx_rate |=
6523 ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET);
6524 }
6525
6526 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
6527 band = CDS_BAND_5GHZ;
6528 if (cfg_val == MLME_CFG_TX_MGMT_5G_RATE_DEF ||
6529 !wma_verify_rate_code(cfg_val, band)) {
6530 wma_nofl_debug("use default 5G MGMT rate.");
6531 per_band_mgmt_tx_rate &=
6532 ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
6533 } else {
6534 per_band_mgmt_tx_rate |=
6535 (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
6536 per_band_mgmt_tx_rate |=
6537 ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET);
6538 }
6539
6540 info->param_id = wmi_vdev_param_per_band_mgmt_tx_rate;
6541 info->param_value = per_band_mgmt_tx_rate;
6542 return QDF_STATUS_SUCCESS;
6543 }
6544
6545 #define MAX_VDEV_CREATE_PARAMS 22
6546 /* params being sent:
6547 * 1.wmi_vdev_param_wmm_txop_enable
6548 * 2.wmi_vdev_param_disconnect_th
6549 * 3.wmi_vdev_param_mcc_rtscts_protection_enable
6550 * 4.wmi_vdev_param_mcc_broadcast_probe_enable
6551 * 5.wmi_vdev_param_rts_threshold
6552 * 6.wmi_vdev_param_fragmentation_threshold
6553 * 7.wmi_vdev_param_tx_stbc
6554 * 8.wmi_vdev_param_mgmt_tx_rate
6555 * 9.wmi_vdev_param_per_band_mgmt_tx_rate
6556 * 10.wmi_vdev_param_set_eht_mu_mode
6557 * 11.wmi_vdev_param_set_hemu_mode
6558 * 12.wmi_vdev_param_txbf
6559 * 13.wmi_vdev_param_enable_bcast_probe_response
6560 * 14.wmi_vdev_param_fils_max_channel_guard_time
6561 * 15.wmi_vdev_param_probe_delay
6562 * 16.wmi_vdev_param_repeat_probe_time
6563 * 17.wmi_vdev_param_enable_disable_oce_features
6564 * 18.wmi_vdev_param_bmiss_first_bcnt
6565 * 19.wmi_vdev_param_bmiss_final_bcnt
6566 * 20.wmi_vdev_param_set_sap_ps_with_twt
6567 * 21.wmi_vdev_param_disable_2g_twt
6568 * 22.wmi_vdev_param_disable_twt_info_frame
6569 */
6570
wma_vdev_create_set_param(struct wlan_objmgr_vdev * vdev)6571 QDF_STATUS wma_vdev_create_set_param(struct wlan_objmgr_vdev *vdev)
6572 {
6573 QDF_STATUS status;
6574 struct mlme_ht_capabilities_info *ht_cap_info;
6575 uint32_t cfg_val;
6576 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6577 struct dev_set_param ext_val;
6578 wmi_vdev_txbf_en txbf_en = {0};
6579 struct vdev_mlme_obj *vdev_mlme;
6580 uint8_t vdev_id;
6581 uint32_t hemu_mode;
6582 struct dev_set_param setparam[MAX_VDEV_CREATE_PARAMS];
6583 uint8_t index = 0;
6584 bool is_24ghz_twt_enabled;
6585 bool disable_twt_info_frame;
6586 enum QDF_OPMODE opmode;
6587
6588 if (!mac)
6589 return QDF_STATUS_E_FAILURE;
6590
6591 vdev_id = wlan_vdev_get_id(vdev);
6592
6593 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
6594 if (!vdev_mlme) {
6595 wma_err("Failed to get vdev mlme obj!");
6596 return QDF_STATUS_E_FAILURE;
6597 }
6598
6599 status = mlme_check_index_setparam(
6600 setparam, wmi_vdev_param_wmm_txop_enable,
6601 mac->mlme_cfg->edca_params.enable_wmm_txop,
6602 index++, MAX_VDEV_CREATE_PARAMS);
6603 if (QDF_IS_STATUS_ERROR(status)) {
6604 wma_debug("failed to set wmi_vdev_param_wmm_txop_enable");
6605 goto error;
6606 }
6607 wma_debug("Setting wmi_vdev_param_disconnect_th: %d",
6608 mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh);
6609 status = mlme_check_index_setparam(
6610 setparam, wmi_vdev_param_disconnect_th,
6611 mac->mlme_cfg->gen.dropped_pkt_disconnect_thresh,
6612 index++, MAX_VDEV_CREATE_PARAMS);
6613 if (QDF_IS_STATUS_ERROR(status)) {
6614 wma_debug("failed to set wmi_vdev_param_disconnect_th");
6615 goto error;
6616 }
6617 status = mlme_check_index_setparam(
6618 setparam,
6619 wmi_vdev_param_mcc_rtscts_protection_enable,
6620 mac->roam.configParam.mcc_rts_cts_prot_enable,
6621 index++, MAX_VDEV_CREATE_PARAMS);
6622 if (QDF_IS_STATUS_ERROR(status)) {
6623 wma_debug("failed to set wmi_vdev_param_mcc_rtscts_protection_enable");
6624 goto error;
6625 }
6626 status = mlme_check_index_setparam(
6627 setparam,
6628 wmi_vdev_param_mcc_broadcast_probe_enable,
6629 mac->roam.configParam.mcc_bcast_prob_resp_enable,
6630 index++, MAX_VDEV_CREATE_PARAMS);
6631 if (QDF_IS_STATUS_ERROR(status)) {
6632 wma_debug("failed to set wmi_vdev_param_mcc_broadcast_probe_enable");
6633 goto error;
6634 }
6635 if (wlan_mlme_get_rts_threshold(mac->psoc, &cfg_val) ==
6636 QDF_STATUS_SUCCESS) {
6637 status = mlme_check_index_setparam(
6638 setparam,
6639 wmi_vdev_param_rts_threshold,
6640 cfg_val, index++,
6641 MAX_VDEV_CREATE_PARAMS);
6642 if (QDF_IS_STATUS_ERROR(status)) {
6643 wma_debug("failed to set wmi_vdev_param_rts_threshold");
6644 goto error;
6645 }
6646 } else {
6647 wma_err("Fail to get val for rts threshold, leave unchanged");
6648 }
6649 if (wlan_mlme_get_frag_threshold(mac->psoc, &cfg_val) ==
6650 QDF_STATUS_SUCCESS) {
6651 status = mlme_check_index_setparam(
6652 setparam,
6653 wmi_vdev_param_fragmentation_threshold,
6654 cfg_val, index++,
6655 MAX_VDEV_CREATE_PARAMS);
6656 if (QDF_IS_STATUS_ERROR(status)) {
6657 wma_debug("failed to set wmi_vdev_param_fragmentation_threshold");
6658 goto error;
6659 }
6660 } else {
6661 wma_err("Fail to get val for frag threshold, leave unchanged");
6662 }
6663
6664 ht_cap_info = &mac->mlme_cfg->ht_caps.ht_cap_info;
6665 status = mlme_check_index_setparam(setparam,
6666 wmi_vdev_param_tx_stbc,
6667 ht_cap_info->tx_stbc, index++,
6668 MAX_VDEV_CREATE_PARAMS);
6669 if (QDF_IS_STATUS_ERROR(status)) {
6670 wma_debug("failed to set wmi_vdev_param_tx_stbc");
6671 goto error;
6672 }
6673 if (!wma_vdev_mgmt_tx_rate(&ext_val)) {
6674 status = mlme_check_index_setparam(setparam, ext_val.param_id,
6675 ext_val.param_value, index++,
6676 MAX_VDEV_CREATE_PARAMS);
6677 if (QDF_IS_STATUS_ERROR(status)) {
6678 wma_debug("failed to set param for MGMT RATE");
6679 goto error;
6680 }
6681 }
6682 if (!wma_vdev_mgmt_perband_tx_rate(&ext_val)) {
6683 status = mlme_check_index_setparam(setparam, ext_val.param_id,
6684 ext_val.param_value, index++,
6685 MAX_VDEV_CREATE_PARAMS);
6686 if (QDF_IS_STATUS_ERROR(status)) {
6687 wma_debug("failed to set PERBAND_MGMT RATE");
6688 goto error;
6689 }
6690 }
6691 if (IS_FEATURE_11BE_SUPPORTED_BY_FW) {
6692 uint32_t mode;
6693
6694 status = wma_set_eht_txbf_vdev_params(mac, &mode);
6695 if (status == QDF_STATUS_SUCCESS) {
6696 wma_debug("set EHTMU_MODE (ehtmu_mode = 0x%x)", mode);
6697 status = mlme_check_index_setparam(
6698 setparam,
6699 wmi_vdev_param_set_eht_mu_mode,
6700 mode, index++,
6701 MAX_VDEV_CREATE_PARAMS);
6702 if (QDF_IS_STATUS_ERROR(status)) {
6703 wma_debug("failed to set wmi_vdev_param_set_eht_mu_mode");
6704 goto error;
6705 }
6706 }
6707 }
6708 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) {
6709 if (!wma_get_hemu_mode(&hemu_mode, mac)) {
6710 wma_debug("set HEMU_MODE (hemu_mode = 0x%x)",
6711 hemu_mode);
6712 status = mlme_check_index_setparam(
6713 setparam,
6714 wmi_vdev_param_set_hemu_mode,
6715 hemu_mode, index++,
6716 MAX_VDEV_CREATE_PARAMS);
6717 if (QDF_IS_STATUS_ERROR(status)) {
6718 wma_debug("failed to set wmi_vdev_param_set_hemu_mode");
6719 goto error;
6720 }
6721 }
6722 }
6723 if (wlan_nan_is_beamforming_supported(mac->psoc)) {
6724 txbf_en.sutxbfee =
6725 mac->mlme_cfg->vht_caps.vht_cap_info.su_bformee;
6726 txbf_en.mutxbfee =
6727 mac->mlme_cfg->vht_caps.vht_cap_info.enable_mu_bformee;
6728 txbf_en.sutxbfer =
6729 mac->mlme_cfg->vht_caps.vht_cap_info.su_bformer;
6730 status = mlme_check_index_setparam(setparam,
6731 wmi_vdev_param_txbf,
6732 *((A_UINT8 *)&txbf_en), index++,
6733 MAX_VDEV_CREATE_PARAMS);
6734 if (QDF_IS_STATUS_ERROR(status)) {
6735 wma_debug("failed to set wmi_vdev_param_txbf");
6736 goto error;
6737 }
6738 }
6739 /* Initialize roaming offload state */
6740 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_STA &&
6741 vdev_mlme->mgmt.generic.subtype == 0) {
6742 /* Pass down enable/disable bcast probe rsp to FW */
6743 status = mlme_check_index_setparam(
6744 setparam,
6745 wmi_vdev_param_enable_bcast_probe_response,
6746 mac->mlme_cfg->oce.enable_bcast_probe_rsp,
6747 index++, MAX_VDEV_CREATE_PARAMS);
6748 if (QDF_IS_STATUS_ERROR(status)) {
6749 wma_debug("failed to set wmi_vdev_param_enable_bcast_probe_response");
6750 goto error;
6751 }
6752 /* Pass down the FILS max channel guard time to FW */
6753 status = mlme_check_index_setparam(
6754 setparam,
6755 wmi_vdev_param_fils_max_channel_guard_time,
6756 mac->mlme_cfg->sta.fils_max_chan_guard_time,
6757 index++, MAX_VDEV_CREATE_PARAMS);
6758 if (QDF_IS_STATUS_ERROR(status)) {
6759 wma_debug("failed to set wmi_vdev_param_fils_max_channel_guard_time");
6760 goto error;
6761 }
6762 /* Pass down the Probe Request tx delay(in ms) to FW */
6763 status = mlme_check_index_setparam(setparam,
6764 wmi_vdev_param_probe_delay,
6765 PROBE_REQ_TX_DELAY, index++,
6766 MAX_VDEV_CREATE_PARAMS);
6767 if (QDF_IS_STATUS_ERROR(status)) {
6768 wma_debug("failed to set wmi_vdev_param_probe_delay");
6769 goto error;
6770 }
6771 /* Pass down the probe request tx time gap_ms to FW */
6772 status = mlme_check_index_setparam(
6773 setparam,
6774 wmi_vdev_param_repeat_probe_time,
6775 PROBE_REQ_TX_TIME_GAP, index++,
6776 MAX_VDEV_CREATE_PARAMS);
6777 if (QDF_IS_STATUS_ERROR(status)) {
6778 wma_debug("failed to set wmi_vdev_param_repeat_probe_time");
6779 goto error;
6780 }
6781 status = mlme_check_index_setparam(
6782 setparam,
6783 wmi_vdev_param_enable_disable_oce_features,
6784 mac->mlme_cfg->oce.feature_bitmap, index++,
6785 MAX_VDEV_CREATE_PARAMS);
6786 if (QDF_IS_STATUS_ERROR(status)) {
6787 wma_debug("failed to set wmi_vdev_param_enable_disable_oce_features");
6788 goto error;
6789 }
6790 /* Initialize BMISS parameters */
6791 wma_debug("first_bcnt: %d, final_bcnt: %d",
6792 mac->mlme_cfg->lfr.roam_bmiss_first_bcnt,
6793 mac->mlme_cfg->lfr.roam_bmiss_final_bcnt);
6794 status = mlme_check_index_setparam(
6795 setparam,
6796 wmi_vdev_param_bmiss_first_bcnt,
6797 mac->mlme_cfg->lfr.roam_bmiss_first_bcnt,
6798 index++, MAX_VDEV_CREATE_PARAMS);
6799 if (QDF_IS_STATUS_ERROR(status)) {
6800 wma_debug("failed to set wmi_vdev_param_bmiss_first_bcnt");
6801 goto error;
6802 }
6803 status = mlme_check_index_setparam(setparam,
6804 wmi_vdev_param_bmiss_final_bcnt,
6805 mac->mlme_cfg->lfr.roam_bmiss_final_bcnt,
6806 index++, MAX_VDEV_CREATE_PARAMS);
6807 if (QDF_IS_STATUS_ERROR(status)) {
6808 wma_debug("failed to set wmi_vdev_param_bmiss_final_bcnt");
6809 goto error;
6810 }
6811 }
6812 if (vdev_mlme->mgmt.generic.type == WMI_VDEV_TYPE_AP &&
6813 vdev_mlme->mgmt.generic.subtype == 0) {
6814 status = mlme_check_index_setparam(setparam,
6815 wmi_vdev_param_enable_disable_oce_features,
6816 mac->mlme_cfg->oce.feature_bitmap, index++,
6817 MAX_VDEV_CREATE_PARAMS);
6818 if (QDF_IS_STATUS_ERROR(status)) {
6819 wma_debug("failed to set wmi_vdev_param_enable_disable_oce_features");
6820 goto error;
6821 }
6822 }
6823
6824 opmode = wlan_vdev_mlme_get_opmode(vdev);
6825 if (opmode == QDF_SAP_MODE) {
6826 status = mlme_check_index_setparam(
6827 setparam,
6828 wmi_vdev_param_set_sap_ps_with_twt,
6829 wlan_mlme_get_sap_ps_with_twt(mac->psoc),
6830 index++, MAX_VDEV_CREATE_PARAMS);
6831 if (QDF_IS_STATUS_ERROR(status)) {
6832 wma_debug("failed to set wmi_vdev_param_set_sap_ps_with_twt");
6833 goto error;
6834 }
6835 }
6836
6837 is_24ghz_twt_enabled = mlme_is_24ghz_twt_enabled(mac->psoc);
6838 status = mlme_check_index_setparam(setparam,
6839 wmi_vdev_param_disable_2g_twt,
6840 !is_24ghz_twt_enabled,
6841 index++, MAX_VDEV_CREATE_PARAMS);
6842 if (QDF_IS_STATUS_ERROR(status)) {
6843 wma_debug("failed to set wmi_vdev_param_disable_2g_twt");
6844 goto error;
6845 }
6846
6847 disable_twt_info_frame = mlme_is_twt_disable_info_frame(mac->psoc);
6848 status = mlme_check_index_setparam(
6849 setparam,
6850 wmi_vdev_param_disable_twt_info_frame,
6851 disable_twt_info_frame,
6852 index++, MAX_VDEV_CREATE_PARAMS);
6853 if (QDF_IS_STATUS_ERROR(status)) {
6854 wma_debug("failed to set wmi_vdev_param_disable_twt_info_frame");
6855 goto error;
6856 }
6857
6858 status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
6859 vdev_id, setparam, index);
6860 if (QDF_IS_STATUS_ERROR(status)) {
6861 wma_err("failed to update vdev set all params");
6862 status = QDF_STATUS_E_FAILURE;
6863 goto error;
6864 }
6865 error:
6866 return status;
6867 }
6868
wma_tx_is_chainmask_valid(int value,struct target_psoc_info * tgt_hdl)6869 static inline bool wma_tx_is_chainmask_valid(int value,
6870 struct target_psoc_info *tgt_hdl)
6871 {
6872 struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
6873 uint8_t total_mac_phy_cnt, i;
6874
6875 mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
6876 if (!mac_phy_cap) {
6877 wma_err("Invalid MAC PHY capabilities handle");
6878 return false;
6879 }
6880 total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
6881 for (i = 0; i < total_mac_phy_cnt; i++) {
6882 if (((mac_phy_cap[i].tx_chain_mask_5G) & (value)))
6883 return true;
6884 }
6885 return false;
6886 }
6887
6888 QDF_STATUS
wma_validate_txrx_chain_mask(uint32_t id,uint32_t value)6889 wma_validate_txrx_chain_mask(uint32_t id, uint32_t value)
6890 {
6891 tp_wma_handle wma_handle =
6892 cds_get_context(QDF_MODULE_ID_WMA);
6893 struct target_psoc_info *tgt_hdl;
6894
6895 if (!wma_handle)
6896 return QDF_STATUS_E_FAILURE;
6897
6898 tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
6899 if (!tgt_hdl)
6900 return QDF_STATUS_E_FAILURE;
6901
6902 wma_debug("pdev pid %d pval %d", id, value);
6903 if (id == wmi_pdev_param_tx_chain_mask) {
6904 if (wma_check_txrx_chainmask(target_if_get_num_rf_chains(
6905 tgt_hdl), value) || !wma_tx_is_chainmask_valid(value,
6906 tgt_hdl)) {
6907 wma_err("failed in validating tx chainmask");
6908 return QDF_STATUS_E_FAILURE;
6909 }
6910 }
6911 if (id == wmi_pdev_param_rx_chain_mask) {
6912 if (wma_check_txrx_chainmask(target_if_get_num_rf_chains(
6913 tgt_hdl), value)) {
6914 wma_err("failed in validating rtx chainmask");
6915 return QDF_STATUS_SUCCESS;
6916 }
6917 }
6918 return QDF_STATUS_SUCCESS;
6919 }
6920
wma_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type,uint8_t dev_id,struct dev_set_param * param,uint8_t n_params)6921 QDF_STATUS wma_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type,
6922 uint8_t dev_id,
6923 struct dev_set_param *param,
6924 uint8_t n_params)
6925 {
6926 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
6927 struct set_multiple_pdev_vdev_param params = {};
6928 QDF_STATUS status;
6929 wmi_unified_t wmi_handle;
6930
6931 if (!mac)
6932 return QDF_STATUS_E_FAILURE;
6933
6934 wmi_handle = get_wmi_unified_hdl_from_psoc(mac->psoc);
6935 if (!wmi_handle)
6936 return QDF_STATUS_E_FAILURE;
6937
6938 params.param_type = param_type;
6939 params.dev_id = dev_id;
6940 params.is_host_pdev_id = false;
6941 params.params = param;
6942 params.n_params = n_params;
6943
6944 if (param_type == MLME_VDEV_SETPARAM) {
6945 status = wmi_unified_multiple_vdev_param_send(wmi_handle,
6946 ¶ms);
6947 if (QDF_IS_STATUS_ERROR(status))
6948 wma_err("failed to send multi vdev set params");
6949 } else if (param_type == MLME_PDEV_SETPARAM) {
6950 status = wmi_unified_multiple_pdev_param_send(wmi_handle,
6951 ¶ms);
6952 if (QDF_IS_STATUS_ERROR(status))
6953 wma_err("failed to send multi pdev set params");
6954 } else {
6955 status = QDF_STATUS_E_FAILURE;
6956 wma_err("Invalid param type");
6957 }
6958 return status;
6959 }
6960