xref: /wlan-driver/qcacld-3.0/core/wma/src/wma_mgmt.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  *  DOC:  wma_mgmt.c
22*5113495bSYour Name  *
23*5113495bSYour Name  *  This file contains STA/SAP and protocol related functions.
24*5113495bSYour Name  */
25*5113495bSYour Name 
26*5113495bSYour Name /* Header files */
27*5113495bSYour Name 
28*5113495bSYour Name #include "wma.h"
29*5113495bSYour Name #include "wma_api.h"
30*5113495bSYour Name #include "cds_api.h"
31*5113495bSYour Name #include "wmi_unified_api.h"
32*5113495bSYour Name #include "wlan_qct_sys.h"
33*5113495bSYour Name #include "wni_api.h"
34*5113495bSYour Name #include "ani_global.h"
35*5113495bSYour Name #include "wmi_unified.h"
36*5113495bSYour Name #include "wni_cfg.h"
37*5113495bSYour Name 
38*5113495bSYour Name #include "qdf_nbuf.h"
39*5113495bSYour Name #include "qdf_types.h"
40*5113495bSYour Name #include "qdf_mem.h"
41*5113495bSYour Name 
42*5113495bSYour Name #include "wma_types.h"
43*5113495bSYour Name #include "lim_api.h"
44*5113495bSYour Name #include "lim_session_utils.h"
45*5113495bSYour Name 
46*5113495bSYour Name #include "cds_utils.h"
47*5113495bSYour Name #include "wlan_dlm_api.h"
48*5113495bSYour Name #if defined(CONNECTIVITY_PKTLOG) || !defined(REMOVE_PKT_LOG)
49*5113495bSYour Name #include "pktlog_ac.h"
50*5113495bSYour Name #else
51*5113495bSYour Name #include "pktlog_ac_fmt.h"
52*5113495bSYour Name #endif /* REMOVE_PKT_LOG */
53*5113495bSYour Name 
54*5113495bSYour Name #include "dbglog_host.h"
55*5113495bSYour Name #include "csr_api.h"
56*5113495bSYour Name #include "ol_fw.h"
57*5113495bSYour Name #include "wma_internal.h"
58*5113495bSYour Name #include "wlan_policy_mgr_api.h"
59*5113495bSYour Name #include "cdp_txrx_flow_ctrl_legacy.h"
60*5113495bSYour Name #include <cdp_txrx_peer_ops.h>
61*5113495bSYour Name #include <cdp_txrx_pmf.h>
62*5113495bSYour Name #include <cdp_txrx_cfg.h>
63*5113495bSYour Name #include <cdp_txrx_cmn.h>
64*5113495bSYour Name #include <cdp_txrx_misc.h>
65*5113495bSYour Name #include <cdp_txrx_misc.h>
66*5113495bSYour Name #include "wlan_mgmt_txrx_tgt_api.h"
67*5113495bSYour Name #include "wlan_objmgr_psoc_obj.h"
68*5113495bSYour Name #include "wlan_objmgr_pdev_obj.h"
69*5113495bSYour Name #include "wlan_objmgr_vdev_obj.h"
70*5113495bSYour Name #include "wlan_lmac_if_api.h"
71*5113495bSYour Name #include <cdp_txrx_handle.h>
72*5113495bSYour Name #include "wma_he.h"
73*5113495bSYour Name #include "wma_eht.h"
74*5113495bSYour Name #include <qdf_crypto.h>
75*5113495bSYour Name #include "wma_twt.h"
76*5113495bSYour Name #include "wlan_p2p_cfg_api.h"
77*5113495bSYour Name #include "cfg_ucfg_api.h"
78*5113495bSYour Name #include "cfg_mlme_sta.h"
79*5113495bSYour Name #include "wlan_mlme_api.h"
80*5113495bSYour Name #include "wmi_unified_bcn_api.h"
81*5113495bSYour Name #include <wlan_crypto_global_api.h>
82*5113495bSYour Name #include <wlan_mlme_main.h>
83*5113495bSYour Name #include <../../core/src/vdev_mgr_ops.h>
84*5113495bSYour Name #include "wlan_pkt_capture_ucfg_api.h"
85*5113495bSYour Name 
86*5113495bSYour Name #if defined(CONNECTIVITY_PKTLOG) || !defined(REMOVE_PKT_LOG)
87*5113495bSYour Name #include <wlan_logging_sock_svc.h>
88*5113495bSYour Name #endif
89*5113495bSYour Name #include "wlan_cm_roam_api.h"
90*5113495bSYour Name #include "wlan_cm_api.h"
91*5113495bSYour Name #include "wlan_mlo_link_force.h"
92*5113495bSYour Name #include <target_if_spatial_reuse.h>
93*5113495bSYour Name #include "wlan_nan_api_i.h"
94*5113495bSYour Name 
95*5113495bSYour Name /* Max debug string size for WMM in bytes */
96*5113495bSYour Name #define WMA_WMM_DEBUG_STRING_SIZE    512
97*5113495bSYour Name 
98*5113495bSYour Name /**
99*5113495bSYour Name  * wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL
100*5113495bSYour Name  * @wma: wma handle
101*5113495bSYour Name  * @vdev_id: vdev id
102*5113495bSYour Name  * @param_buf: SWBA parameters
103*5113495bSYour Name  *
104*5113495bSYour Name  * Return: none
105*5113495bSYour Name  */
106*5113495bSYour Name #ifdef WLAN_WMI_BCN
wma_send_bcn_buf_ll(tp_wma_handle wma,uint8_t vdev_id,WMI_HOST_SWBA_EVENTID_param_tlvs * param_buf)107*5113495bSYour Name static void wma_send_bcn_buf_ll(tp_wma_handle wma,
108*5113495bSYour Name 				uint8_t vdev_id,
109*5113495bSYour Name 				WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf)
110*5113495bSYour Name {
111*5113495bSYour Name 	struct ieee80211_frame *wh;
112*5113495bSYour Name 	struct beacon_info *bcn;
113*5113495bSYour Name 	wmi_tim_info *tim_info = param_buf->tim_info;
114*5113495bSYour Name 	uint8_t *bcn_payload;
115*5113495bSYour Name 	QDF_STATUS ret;
116*5113495bSYour Name 	struct beacon_tim_ie *tim_ie;
117*5113495bSYour Name 	wmi_p2p_noa_info *p2p_noa_info = param_buf->p2p_noa_info;
118*5113495bSYour Name 	struct p2p_sub_element_noa noa_ie;
119*5113495bSYour Name 	struct wmi_bcn_send_from_host params;
120*5113495bSYour Name 	uint8_t i;
121*5113495bSYour Name 
122*5113495bSYour Name 	bcn = wma->interfaces[vdev_id].beacon;
123*5113495bSYour Name 	if (!bcn || !bcn->buf) {
124*5113495bSYour Name 		wma_err("Invalid beacon buffer");
125*5113495bSYour Name 		return;
126*5113495bSYour Name 	}
127*5113495bSYour Name 
128*5113495bSYour Name 	if (!param_buf->tim_info || !param_buf->p2p_noa_info) {
129*5113495bSYour Name 		wma_err("Invalid tim info or p2p noa info");
130*5113495bSYour Name 		return;
131*5113495bSYour Name 	}
132*5113495bSYour Name 
133*5113495bSYour Name 	if (WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info) >
134*5113495bSYour Name 			WMI_P2P_MAX_NOA_DESCRIPTORS) {
135*5113495bSYour Name 		wma_err("Too many descriptors %d",
136*5113495bSYour Name 			WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info));
137*5113495bSYour Name 		return;
138*5113495bSYour Name 	}
139*5113495bSYour Name 
140*5113495bSYour Name 	qdf_spin_lock_bh(&bcn->lock);
141*5113495bSYour Name 
142*5113495bSYour Name 	bcn_payload = qdf_nbuf_data(bcn->buf);
143*5113495bSYour Name 
144*5113495bSYour Name 	tim_ie = (struct beacon_tim_ie *)(&bcn_payload[bcn->tim_ie_offset]);
145*5113495bSYour Name 
146*5113495bSYour Name 	if (tim_info->tim_changed) {
147*5113495bSYour Name 		if (tim_info->tim_num_ps_pending)
148*5113495bSYour Name 			qdf_mem_copy(&tim_ie->tim_bitmap, tim_info->tim_bitmap,
149*5113495bSYour Name 				     WMA_TIM_SUPPORTED_PVB_LENGTH);
150*5113495bSYour Name 		else
151*5113495bSYour Name 			qdf_mem_zero(&tim_ie->tim_bitmap,
152*5113495bSYour Name 				     WMA_TIM_SUPPORTED_PVB_LENGTH);
153*5113495bSYour Name 		/*
154*5113495bSYour Name 		 * Currently we support fixed number of
155*5113495bSYour Name 		 * peers as limited by HAL_NUM_STA.
156*5113495bSYour Name 		 * tim offset is always 0
157*5113495bSYour Name 		 */
158*5113495bSYour Name 		tim_ie->tim_bitctl = 0;
159*5113495bSYour Name 	}
160*5113495bSYour Name 
161*5113495bSYour Name 	/* Update DTIM Count */
162*5113495bSYour Name 	if (tim_ie->dtim_count == 0)
163*5113495bSYour Name 		tim_ie->dtim_count = tim_ie->dtim_period - 1;
164*5113495bSYour Name 	else
165*5113495bSYour Name 		tim_ie->dtim_count--;
166*5113495bSYour Name 
167*5113495bSYour Name 	/*
168*5113495bSYour Name 	 * DTIM count needs to be backedup so that
169*5113495bSYour Name 	 * when umac updates the beacon template
170*5113495bSYour Name 	 * current dtim count can be updated properly
171*5113495bSYour Name 	 */
172*5113495bSYour Name 	bcn->dtim_count = tim_ie->dtim_count;
173*5113495bSYour Name 
174*5113495bSYour Name 	/* update state for buffered multicast frames on DTIM */
175*5113495bSYour Name 	if (tim_info->tim_mcast && (tim_ie->dtim_count == 0 ||
176*5113495bSYour Name 				    tim_ie->dtim_period == 1))
177*5113495bSYour Name 		tim_ie->tim_bitctl |= 1;
178*5113495bSYour Name 	else
179*5113495bSYour Name 		tim_ie->tim_bitctl &= ~1;
180*5113495bSYour Name 
181*5113495bSYour Name 	/* To avoid sw generated frame sequence the same as H/W generated frame,
182*5113495bSYour Name 	 * the value lower than min_sw_seq is reserved for HW generated frame
183*5113495bSYour Name 	 */
184*5113495bSYour Name 	if ((bcn->seq_no & IEEE80211_SEQ_MASK) < MIN_SW_SEQ)
185*5113495bSYour Name 		bcn->seq_no = MIN_SW_SEQ;
186*5113495bSYour Name 
187*5113495bSYour Name 	wh = (struct ieee80211_frame *)bcn_payload;
188*5113495bSYour Name 	*(uint16_t *) &wh->i_seq[0] = htole16(bcn->seq_no
189*5113495bSYour Name 					      << IEEE80211_SEQ_SEQ_SHIFT);
190*5113495bSYour Name 	bcn->seq_no++;
191*5113495bSYour Name 
192*5113495bSYour Name 	if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
193*5113495bSYour Name 		qdf_mem_zero(&noa_ie, sizeof(noa_ie));
194*5113495bSYour Name 
195*5113495bSYour Name 		noa_ie.index =
196*5113495bSYour Name 			(uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
197*5113495bSYour Name 		noa_ie.oppPS =
198*5113495bSYour Name 			(uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
199*5113495bSYour Name 		noa_ie.ctwindow =
200*5113495bSYour Name 			(uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
201*5113495bSYour Name 		noa_ie.num_descriptors = (uint8_t)
202*5113495bSYour Name 				WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
203*5113495bSYour Name 		wma_debug("index %u, oppPs %u, ctwindow %u, num_descriptors = %u",
204*5113495bSYour Name 			 noa_ie.index,
205*5113495bSYour Name 			 noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
206*5113495bSYour Name 		for (i = 0; i < noa_ie.num_descriptors; i++) {
207*5113495bSYour Name 			noa_ie.noa_descriptors[i].type_count =
208*5113495bSYour Name 				(uint8_t) p2p_noa_info->noa_descriptors[i].
209*5113495bSYour Name 				type_count;
210*5113495bSYour Name 			noa_ie.noa_descriptors[i].duration =
211*5113495bSYour Name 				p2p_noa_info->noa_descriptors[i].duration;
212*5113495bSYour Name 			noa_ie.noa_descriptors[i].interval =
213*5113495bSYour Name 				p2p_noa_info->noa_descriptors[i].interval;
214*5113495bSYour Name 			noa_ie.noa_descriptors[i].start_time =
215*5113495bSYour Name 				p2p_noa_info->noa_descriptors[i].start_time;
216*5113495bSYour Name 			wma_debug("NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
217*5113495bSYour Name 				 i,
218*5113495bSYour Name 				 noa_ie.noa_descriptors[i].type_count,
219*5113495bSYour Name 				 noa_ie.noa_descriptors[i].duration,
220*5113495bSYour Name 				 noa_ie.noa_descriptors[i].interval,
221*5113495bSYour Name 				 noa_ie.noa_descriptors[i].start_time);
222*5113495bSYour Name 		}
223*5113495bSYour Name 		wma_update_noa(bcn, &noa_ie);
224*5113495bSYour Name 
225*5113495bSYour Name 		/* Send a msg to LIM to update the NoA IE in probe response
226*5113495bSYour Name 		 * frames transmitted by the host
227*5113495bSYour Name 		 */
228*5113495bSYour Name 		wma_update_probe_resp_noa(wma, &noa_ie);
229*5113495bSYour Name 	}
230*5113495bSYour Name 
231*5113495bSYour Name 	if (bcn->dma_mapped) {
232*5113495bSYour Name 		qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
233*5113495bSYour Name 		bcn->dma_mapped = 0;
234*5113495bSYour Name 	}
235*5113495bSYour Name 	ret = qdf_nbuf_map_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
236*5113495bSYour Name 	if (ret != QDF_STATUS_SUCCESS) {
237*5113495bSYour Name 		wma_err("failed map beacon buf to DMA region");
238*5113495bSYour Name 		qdf_spin_unlock_bh(&bcn->lock);
239*5113495bSYour Name 		return;
240*5113495bSYour Name 	}
241*5113495bSYour Name 
242*5113495bSYour Name 	bcn->dma_mapped = 1;
243*5113495bSYour Name 	params.vdev_id = vdev_id;
244*5113495bSYour Name 	params.data_len = bcn->len;
245*5113495bSYour Name 	params.frame_ctrl = *((A_UINT16 *) wh->i_fc);
246*5113495bSYour Name 	params.frag_ptr = qdf_nbuf_get_frag_paddr(bcn->buf, 0);
247*5113495bSYour Name 	params.dtim_flag = 0;
248*5113495bSYour Name 	/* notify Firmware of DTM and mcast/bcast traffic */
249*5113495bSYour Name 	if (tim_ie->dtim_count == 0) {
250*5113495bSYour Name 		params.dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
251*5113495bSYour Name 		/* deliver mcast/bcast traffic in next DTIM beacon */
252*5113495bSYour Name 		if (tim_ie->tim_bitctl & 0x01)
253*5113495bSYour Name 			params.dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
254*5113495bSYour Name 	}
255*5113495bSYour Name 
256*5113495bSYour Name 	wmi_unified_bcn_buf_ll_cmd(wma->wmi_handle,
257*5113495bSYour Name 					&params);
258*5113495bSYour Name 
259*5113495bSYour Name 	qdf_spin_unlock_bh(&bcn->lock);
260*5113495bSYour Name }
261*5113495bSYour Name #else
262*5113495bSYour Name static inline void
wma_send_bcn_buf_ll(tp_wma_handle wma,uint8_t vdev_id,WMI_HOST_SWBA_EVENTID_param_tlvs * param_buf)263*5113495bSYour Name wma_send_bcn_buf_ll(tp_wma_handle wma,
264*5113495bSYour Name 		    uint8_t vdev_id,
265*5113495bSYour Name 		    WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf)
266*5113495bSYour Name {
267*5113495bSYour Name }
268*5113495bSYour Name #endif
269*5113495bSYour Name /**
270*5113495bSYour Name  * wma_beacon_swba_handler() - swba event handler
271*5113495bSYour Name  * @handle: wma handle
272*5113495bSYour Name  * @event: event data
273*5113495bSYour Name  * @len: data length
274*5113495bSYour Name  *
275*5113495bSYour Name  * SWBA event is alert event to Host requesting host to Queue a beacon
276*5113495bSYour Name  * for transmission use only in host beacon mode
277*5113495bSYour Name  *
278*5113495bSYour Name  * Return: 0 for success or error code
279*5113495bSYour Name  */
280*5113495bSYour Name #ifdef WLAN_WMI_BCN
wma_beacon_swba_handler(void * handle,uint8_t * event,uint32_t len)281*5113495bSYour Name int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len)
282*5113495bSYour Name {
283*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
284*5113495bSYour Name 	WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
285*5113495bSYour Name 	wmi_host_swba_event_fixed_param *swba_event;
286*5113495bSYour Name 	uint32_t vdev_map;
287*5113495bSYour Name 	uint8_t vdev_id = 0;
288*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
289*5113495bSYour Name 
290*5113495bSYour Name 	param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) event;
291*5113495bSYour Name 	if (!param_buf) {
292*5113495bSYour Name 		wma_err("Invalid swba event buffer");
293*5113495bSYour Name 		return -EINVAL;
294*5113495bSYour Name 	}
295*5113495bSYour Name 	swba_event = param_buf->fixed_param;
296*5113495bSYour Name 	vdev_map = swba_event->vdev_map;
297*5113495bSYour Name 
298*5113495bSYour Name 	wma_debug("vdev_map = %d", vdev_map);
299*5113495bSYour Name 	for (; vdev_map && vdev_id < wma->max_bssid;
300*5113495bSYour Name 			vdev_id++, vdev_map >>= 1) {
301*5113495bSYour Name 		if (!(vdev_map & 0x1))
302*5113495bSYour Name 			continue;
303*5113495bSYour Name 		if (!cdp_cfg_is_high_latency(soc,
304*5113495bSYour Name 			(struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG)))
305*5113495bSYour Name 			wma_send_bcn_buf_ll(wma, vdev_id, param_buf);
306*5113495bSYour Name 		break;
307*5113495bSYour Name 	}
308*5113495bSYour Name 	return 0;
309*5113495bSYour Name }
310*5113495bSYour Name #else
311*5113495bSYour Name static inline int
wma_beacon_swba_handler(void * handle,uint8_t * event,uint32_t len)312*5113495bSYour Name wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len)
313*5113495bSYour Name {
314*5113495bSYour Name 	return 0;
315*5113495bSYour Name }
316*5113495bSYour Name #endif
317*5113495bSYour Name 
318*5113495bSYour Name #ifdef FEATURE_WLAN_DIAG_SUPPORT
wma_sta_kickout_event(uint32_t kickout_reason,uint8_t vdev_id,uint8_t * macaddr)319*5113495bSYour Name void wma_sta_kickout_event(uint32_t kickout_reason, uint8_t vdev_id,
320*5113495bSYour Name 			   uint8_t *macaddr)
321*5113495bSYour Name {
322*5113495bSYour Name 	WLAN_HOST_DIAG_EVENT_DEF(sta_kickout, struct host_event_wlan_kickout);
323*5113495bSYour Name 	qdf_mem_zero(&sta_kickout, sizeof(sta_kickout));
324*5113495bSYour Name 	sta_kickout.reasoncode = kickout_reason;
325*5113495bSYour Name 	sta_kickout.vdev_id = vdev_id;
326*5113495bSYour Name 	if (macaddr)
327*5113495bSYour Name 		qdf_mem_copy(sta_kickout.peer_mac, macaddr,
328*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
329*5113495bSYour Name 	WLAN_HOST_DIAG_EVENT_REPORT(&sta_kickout, EVENT_WLAN_STA_KICKOUT);
330*5113495bSYour Name }
331*5113495bSYour Name #endif
332*5113495bSYour Name 
wma_peer_sta_kickout_event_handler(void * handle,uint8_t * event,uint32_t len)333*5113495bSYour Name int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event,
334*5113495bSYour Name 				       uint32_t len)
335*5113495bSYour Name {
336*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
337*5113495bSYour Name 	WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
338*5113495bSYour Name 	wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
339*5113495bSYour Name 	uint8_t vdev_id, macaddr[QDF_MAC_ADDR_SIZE];
340*5113495bSYour Name 	tpDeleteStaContext del_sta_ctx;
341*5113495bSYour Name 	uint8_t *addr, *bssid;
342*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
343*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
344*5113495bSYour Name 
345*5113495bSYour Name 	param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) event;
346*5113495bSYour Name 	kickout_event = param_buf->fixed_param;
347*5113495bSYour Name 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, macaddr);
348*5113495bSYour Name 	if (cdp_peer_get_vdevid(soc, macaddr, &vdev_id) !=
349*5113495bSYour Name 			QDF_STATUS_SUCCESS) {
350*5113495bSYour Name 		wma_err("Not able to find BSSID for peer ["QDF_MAC_ADDR_FMT"]",
351*5113495bSYour Name 			 QDF_MAC_ADDR_REF(macaddr));
352*5113495bSYour Name 		return -EINVAL;
353*5113495bSYour Name 	}
354*5113495bSYour Name 
355*5113495bSYour Name 	if (!wma_is_vdev_valid(vdev_id))
356*5113495bSYour Name 		return -EINVAL;
357*5113495bSYour Name 
358*5113495bSYour Name 	vdev = wma->interfaces[vdev_id].vdev;
359*5113495bSYour Name 	if (!vdev) {
360*5113495bSYour Name 		wma_err("Not able to find vdev for VDEV_%d", vdev_id);
361*5113495bSYour Name 		return -EINVAL;
362*5113495bSYour Name 	}
363*5113495bSYour Name 	addr = wlan_vdev_mlme_get_macaddr(vdev);
364*5113495bSYour Name 
365*5113495bSYour Name 	wma_nofl_info("STA kickout for "QDF_MAC_ADDR_FMT", on mac "QDF_MAC_ADDR_FMT", vdev %d, reason:%d",
366*5113495bSYour Name 		      QDF_MAC_ADDR_REF(macaddr), QDF_MAC_ADDR_REF(addr),
367*5113495bSYour Name 		      vdev_id, kickout_event->reason);
368*5113495bSYour Name 
369*5113495bSYour Name 	if (wma_is_roam_in_progress(vdev_id)) {
370*5113495bSYour Name 		wma_err("vdev_id %d: Ignore STA kick out since roaming is in progress",
371*5113495bSYour Name 			vdev_id);
372*5113495bSYour Name 		return -EINVAL;
373*5113495bSYour Name 	}
374*5113495bSYour Name 	bssid = wma_get_vdev_bssid(vdev);
375*5113495bSYour Name 	if (!bssid) {
376*5113495bSYour Name 		wma_err("Failed to get bssid for vdev_%d", vdev_id);
377*5113495bSYour Name 		return -ENOMEM;
378*5113495bSYour Name 	}
379*5113495bSYour Name 
380*5113495bSYour Name 	switch (kickout_event->reason) {
381*5113495bSYour Name 	case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT:
382*5113495bSYour Name 		goto exit_handler;
383*5113495bSYour Name #ifdef FEATURE_WLAN_TDLS
384*5113495bSYour Name 	case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT:
385*5113495bSYour Name 		del_sta_ctx = (tpDeleteStaContext)
386*5113495bSYour Name 			qdf_mem_malloc(sizeof(tDeleteStaContext));
387*5113495bSYour Name 		if (!del_sta_ctx) {
388*5113495bSYour Name 			wma_err("mem alloc failed for struct del_sta_context for TDLS peer: "QDF_MAC_ADDR_FMT,
389*5113495bSYour Name 				QDF_MAC_ADDR_REF(macaddr));
390*5113495bSYour Name 			return -ENOMEM;
391*5113495bSYour Name 		}
392*5113495bSYour Name 
393*5113495bSYour Name 		del_sta_ctx->is_tdls = true;
394*5113495bSYour Name 		del_sta_ctx->vdev_id = vdev_id;
395*5113495bSYour Name 		qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE);
396*5113495bSYour Name 		qdf_mem_copy(del_sta_ctx->bssId, bssid,
397*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
398*5113495bSYour Name 		del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
399*5113495bSYour Name 		wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND,
400*5113495bSYour Name 			     (void *)del_sta_ctx, 0);
401*5113495bSYour Name 		goto exit_handler;
402*5113495bSYour Name #endif /* FEATURE_WLAN_TDLS */
403*5113495bSYour Name 
404*5113495bSYour Name 	case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED:
405*5113495bSYour Name 		/*
406*5113495bSYour Name 		 * Default legacy value used by original firmware implementation
407*5113495bSYour Name 		 */
408*5113495bSYour Name 		if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA &&
409*5113495bSYour Name 		    (wma->interfaces[vdev_id].sub_type == 0 ||
410*5113495bSYour Name 		     wma->interfaces[vdev_id].sub_type ==
411*5113495bSYour Name 		     WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
412*5113495bSYour Name 		    !qdf_mem_cmp(bssid,
413*5113495bSYour Name 				    macaddr, QDF_MAC_ADDR_SIZE)) {
414*5113495bSYour Name 			wma_sta_kickout_event(
415*5113495bSYour Name 			HOST_STA_KICKOUT_REASON_UNSPECIFIED, vdev_id, macaddr);
416*5113495bSYour Name 			/*
417*5113495bSYour Name 			 * KICKOUT event is for current station-AP connection.
418*5113495bSYour Name 			 * Treat it like final beacon miss. Station may not have
419*5113495bSYour Name 			 * missed beacons but not able to transmit frames to AP
420*5113495bSYour Name 			 * for a long time. Must disconnect to get out of
421*5113495bSYour Name 			 * this sticky situation.
422*5113495bSYour Name 			 * In future implementation, roaming module will also
423*5113495bSYour Name 			 * handle this event and perform a scan.
424*5113495bSYour Name 			 */
425*5113495bSYour Name 			wma_warn("WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED event for STA");
426*5113495bSYour Name 			wma_beacon_miss_handler(wma, vdev_id,
427*5113495bSYour Name 						kickout_event->rssi);
428*5113495bSYour Name 			goto exit_handler;
429*5113495bSYour Name 		}
430*5113495bSYour Name 		break;
431*5113495bSYour Name 
432*5113495bSYour Name 	case WMI_PEER_STA_KICKOUT_REASON_XRETRY:
433*5113495bSYour Name 	case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY:
434*5113495bSYour Name 	/*
435*5113495bSYour Name 	 * Handle SA query kickout is same as inactivity kickout.
436*5113495bSYour Name 	 * This could be for STA or SAP role
437*5113495bSYour Name 	 */
438*5113495bSYour Name 	case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT:
439*5113495bSYour Name 	default:
440*5113495bSYour Name 		break;
441*5113495bSYour Name 	}
442*5113495bSYour Name 
443*5113495bSYour Name 	/*
444*5113495bSYour Name 	 * default action is to send delete station context indication to LIM
445*5113495bSYour Name 	 */
446*5113495bSYour Name 	del_sta_ctx =
447*5113495bSYour Name 		(tDeleteStaContext *) qdf_mem_malloc(sizeof(tDeleteStaContext));
448*5113495bSYour Name 	if (!del_sta_ctx) {
449*5113495bSYour Name 		wma_err("QDF MEM Alloc Failed for struct del_sta_context");
450*5113495bSYour Name 		return -ENOMEM;
451*5113495bSYour Name 	}
452*5113495bSYour Name 
453*5113495bSYour Name 	del_sta_ctx->is_tdls = false;
454*5113495bSYour Name 	del_sta_ctx->vdev_id = vdev_id;
455*5113495bSYour Name 	qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE);
456*5113495bSYour Name 	qdf_mem_copy(del_sta_ctx->bssId, addr, QDF_MAC_ADDR_SIZE);
457*5113495bSYour Name 	if (kickout_event->reason ==
458*5113495bSYour Name 		WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT)
459*5113495bSYour Name 		del_sta_ctx->reasonCode =
460*5113495bSYour Name 			HAL_DEL_STA_REASON_CODE_SA_QUERY_TIMEOUT;
461*5113495bSYour Name 	else if (kickout_event->reason == WMI_PEER_STA_KICKOUT_REASON_XRETRY)
462*5113495bSYour Name 		del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_XRETRY;
463*5113495bSYour Name 	else
464*5113495bSYour Name 		del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
465*5113495bSYour Name 
466*5113495bSYour Name 	if (wmi_service_enabled(wma->wmi_handle,
467*5113495bSYour Name 				wmi_service_hw_db2dbm_support))
468*5113495bSYour Name 		del_sta_ctx->rssi = kickout_event->rssi;
469*5113495bSYour Name 	else
470*5113495bSYour Name 		del_sta_ctx->rssi = kickout_event->rssi +
471*5113495bSYour Name 					WMA_TGT_NOISE_FLOOR_DBM;
472*5113495bSYour Name 	wma_sta_kickout_event(del_sta_ctx->reasonCode, vdev_id, macaddr);
473*5113495bSYour Name 	wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx,
474*5113495bSYour Name 		     0);
475*5113495bSYour Name 	wma_lost_link_info_handler(wma, vdev_id, del_sta_ctx->rssi);
476*5113495bSYour Name 
477*5113495bSYour Name exit_handler:
478*5113495bSYour Name 	return 0;
479*5113495bSYour Name }
480*5113495bSYour Name 
wma_unified_bcntx_status_event_handler(void * handle,uint8_t * cmd_param_info,uint32_t len)481*5113495bSYour Name int wma_unified_bcntx_status_event_handler(void *handle,
482*5113495bSYour Name 					   uint8_t *cmd_param_info,
483*5113495bSYour Name 					   uint32_t len)
484*5113495bSYour Name {
485*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
486*5113495bSYour Name 	WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf;
487*5113495bSYour Name 	wmi_offload_bcn_tx_status_event_fixed_param *resp_event;
488*5113495bSYour Name 	tSirFirstBeaconTxCompleteInd *beacon_tx_complete_ind;
489*5113495bSYour Name 
490*5113495bSYour Name 	param_buf =
491*5113495bSYour Name 		(WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *) cmd_param_info;
492*5113495bSYour Name 	if (!param_buf) {
493*5113495bSYour Name 		wma_err("Invalid bcn tx response event buffer");
494*5113495bSYour Name 		return -EINVAL;
495*5113495bSYour Name 	}
496*5113495bSYour Name 
497*5113495bSYour Name 	resp_event = param_buf->fixed_param;
498*5113495bSYour Name 
499*5113495bSYour Name 	if (resp_event->vdev_id >= wma->max_bssid) {
500*5113495bSYour Name 		wma_err("received invalid vdev_id %d", resp_event->vdev_id);
501*5113495bSYour Name 		return -EINVAL;
502*5113495bSYour Name 	}
503*5113495bSYour Name 
504*5113495bSYour Name 	/* Check for valid handle to ensure session is not
505*5113495bSYour Name 	 * deleted in any race
506*5113495bSYour Name 	 */
507*5113495bSYour Name 	if (!wma->interfaces[resp_event->vdev_id].vdev) {
508*5113495bSYour Name 		wma_err("vdev is NULL for vdev_%d", resp_event->vdev_id);
509*5113495bSYour Name 		return -EINVAL;
510*5113495bSYour Name 	}
511*5113495bSYour Name 
512*5113495bSYour Name 	/* Beacon Tx Indication supports only AP mode. Ignore in other modes */
513*5113495bSYour Name 	if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) == false) {
514*5113495bSYour Name 		wma_debug("Beacon Tx Indication does not support type %d and sub_type %d",
515*5113495bSYour Name 			 wma->interfaces[resp_event->vdev_id].type,
516*5113495bSYour Name 			 wma->interfaces[resp_event->vdev_id].sub_type);
517*5113495bSYour Name 		return 0;
518*5113495bSYour Name 	}
519*5113495bSYour Name 
520*5113495bSYour Name 	beacon_tx_complete_ind = (tSirFirstBeaconTxCompleteInd *)
521*5113495bSYour Name 			qdf_mem_malloc(sizeof(tSirFirstBeaconTxCompleteInd));
522*5113495bSYour Name 	if (!beacon_tx_complete_ind) {
523*5113495bSYour Name 		wma_err("Failed to alloc beacon_tx_complete_ind");
524*5113495bSYour Name 		return -ENOMEM;
525*5113495bSYour Name 	}
526*5113495bSYour Name 
527*5113495bSYour Name 	beacon_tx_complete_ind->messageType = WMA_DFS_BEACON_TX_SUCCESS_IND;
528*5113495bSYour Name 	beacon_tx_complete_ind->length = sizeof(tSirFirstBeaconTxCompleteInd);
529*5113495bSYour Name 	beacon_tx_complete_ind->bss_idx = resp_event->vdev_id;
530*5113495bSYour Name 
531*5113495bSYour Name 	wma_send_msg(wma, WMA_DFS_BEACON_TX_SUCCESS_IND,
532*5113495bSYour Name 		     (void *)beacon_tx_complete_ind, 0);
533*5113495bSYour Name 	return 0;
534*5113495bSYour Name }
535*5113495bSYour Name 
536*5113495bSYour Name /**
537*5113495bSYour Name  * wma_get_go_probe_timeout() - get P2P GO probe timeout
538*5113495bSYour Name  * @mac: UMAC handler
539*5113495bSYour Name  * @max_inactive_time: return max inactive time
540*5113495bSYour Name  * @max_unresponsive_time: return max unresponsive time
541*5113495bSYour Name  *
542*5113495bSYour Name  * Return: none
543*5113495bSYour Name  */
544*5113495bSYour Name #ifdef CONVERGED_P2P_ENABLE
545*5113495bSYour Name static inline void
wma_get_go_probe_timeout(struct mac_context * mac,uint32_t * max_inactive_time,uint32_t * max_unresponsive_time)546*5113495bSYour Name wma_get_go_probe_timeout(struct mac_context *mac,
547*5113495bSYour Name 			 uint32_t *max_inactive_time,
548*5113495bSYour Name 			 uint32_t *max_unresponsive_time)
549*5113495bSYour Name {
550*5113495bSYour Name 	uint32_t keep_alive;
551*5113495bSYour Name 	QDF_STATUS status;
552*5113495bSYour Name 
553*5113495bSYour Name 	status = cfg_p2p_get_go_link_monitor_period(mac->psoc,
554*5113495bSYour Name 						    max_inactive_time);
555*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
556*5113495bSYour Name 		wma_err("Failed to go monitor period");
557*5113495bSYour Name 		*max_inactive_time = WMA_LINK_MONITOR_DEFAULT_TIME_SECS;
558*5113495bSYour Name 	}
559*5113495bSYour Name 	status = cfg_p2p_get_go_keepalive_period(mac->psoc,
560*5113495bSYour Name 						 &keep_alive);
561*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
562*5113495bSYour Name 		wma_err("Failed to read go keep alive");
563*5113495bSYour Name 		keep_alive = WMA_KEEP_ALIVE_DEFAULT_TIME_SECS;
564*5113495bSYour Name 	}
565*5113495bSYour Name 
566*5113495bSYour Name 	*max_unresponsive_time = *max_inactive_time + keep_alive;
567*5113495bSYour Name }
568*5113495bSYour Name #else
569*5113495bSYour Name static inline void
wma_get_go_probe_timeout(struct mac_context * mac,uint32_t * max_inactive_time,uint32_t * max_unresponsive_time)570*5113495bSYour Name wma_get_go_probe_timeout(struct mac_context *mac,
571*5113495bSYour Name 			 uint32_t *max_inactive_time,
572*5113495bSYour Name 			 uint32_t *max_unresponsive_time)
573*5113495bSYour Name {
574*5113495bSYour Name }
575*5113495bSYour Name #endif
576*5113495bSYour Name 
577*5113495bSYour Name /**
578*5113495bSYour Name  * wma_get_link_probe_timeout() - get link timeout based on sub type
579*5113495bSYour Name  * @mac: UMAC handler
580*5113495bSYour Name  * @sub_type: vdev syb type
581*5113495bSYour Name  * @max_inactive_time: return max inactive time
582*5113495bSYour Name  * @max_unresponsive_time: return max unresponsive time
583*5113495bSYour Name  *
584*5113495bSYour Name  * Return: none
585*5113495bSYour Name  */
586*5113495bSYour Name static inline void
wma_get_link_probe_timeout(struct mac_context * mac,uint32_t sub_type,uint32_t * max_inactive_time,uint32_t * max_unresponsive_time)587*5113495bSYour Name wma_get_link_probe_timeout(struct mac_context *mac,
588*5113495bSYour Name 			   uint32_t sub_type,
589*5113495bSYour Name 			   uint32_t *max_inactive_time,
590*5113495bSYour Name 			   uint32_t *max_unresponsive_time)
591*5113495bSYour Name {
592*5113495bSYour Name 	if (sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) {
593*5113495bSYour Name 		wma_get_go_probe_timeout(mac, max_inactive_time,
594*5113495bSYour Name 					 max_unresponsive_time);
595*5113495bSYour Name 	} else {
596*5113495bSYour Name 		*max_inactive_time =
597*5113495bSYour Name 			mac->mlme_cfg->timeouts.ap_link_monitor_timeout;
598*5113495bSYour Name 		*max_unresponsive_time = *max_inactive_time +
599*5113495bSYour Name 			mac->mlme_cfg->timeouts.ap_keep_alive_timeout;
600*5113495bSYour Name 	}
601*5113495bSYour Name }
602*5113495bSYour Name 
603*5113495bSYour Name /**
604*5113495bSYour Name  * wma_verify_rate_code() - verify if rate code is valid.
605*5113495bSYour Name  * @rate_code:     rate code
606*5113495bSYour Name  * @band:     band information
607*5113495bSYour Name  *
608*5113495bSYour Name  * Return: verify result
609*5113495bSYour Name  */
wma_verify_rate_code(u_int32_t rate_code,enum cds_band_type band)610*5113495bSYour Name static bool wma_verify_rate_code(u_int32_t rate_code, enum cds_band_type band)
611*5113495bSYour Name {
612*5113495bSYour Name 	uint8_t preamble, nss, rate;
613*5113495bSYour Name 	bool valid = true;
614*5113495bSYour Name 
615*5113495bSYour Name 	preamble = (rate_code & 0xc0) >> 6;
616*5113495bSYour Name 	nss = (rate_code & 0x30) >> 4;
617*5113495bSYour Name 	rate = rate_code & 0xf;
618*5113495bSYour Name 
619*5113495bSYour Name 	switch (preamble) {
620*5113495bSYour Name 	case WMI_RATE_PREAMBLE_CCK:
621*5113495bSYour Name 		if (nss != 0 || rate > 3 || band == CDS_BAND_5GHZ)
622*5113495bSYour Name 			valid = false;
623*5113495bSYour Name 		break;
624*5113495bSYour Name 	case WMI_RATE_PREAMBLE_OFDM:
625*5113495bSYour Name 		if (nss != 0 || rate > 7)
626*5113495bSYour Name 			valid = false;
627*5113495bSYour Name 		break;
628*5113495bSYour Name 	case WMI_RATE_PREAMBLE_HT:
629*5113495bSYour Name 		if (nss != 0 || rate > 7)
630*5113495bSYour Name 			valid = false;
631*5113495bSYour Name 		break;
632*5113495bSYour Name 	case WMI_RATE_PREAMBLE_VHT:
633*5113495bSYour Name 		if (nss != 0 || rate > 9)
634*5113495bSYour Name 			valid = false;
635*5113495bSYour Name 		break;
636*5113495bSYour Name 	default:
637*5113495bSYour Name 		break;
638*5113495bSYour Name 	}
639*5113495bSYour Name 	return valid;
640*5113495bSYour Name }
641*5113495bSYour Name 
642*5113495bSYour Name #define TX_MGMT_RATE_2G_ENABLE_OFFSET 30
643*5113495bSYour Name #define TX_MGMT_RATE_5G_ENABLE_OFFSET 31
644*5113495bSYour Name #define TX_MGMT_RATE_2G_OFFSET 0
645*5113495bSYour Name #define TX_MGMT_RATE_5G_OFFSET 12
646*5113495bSYour Name 
647*5113495bSYour Name #define MAX_VDEV_MGMT_RATE_PARAMS 2
648*5113495bSYour Name /* params being sent:
649*5113495bSYour Name  * wmi_vdev_param_mgmt_tx_rate
650*5113495bSYour Name  * wmi_vdev_param_per_band_mgmt_tx_rate
651*5113495bSYour Name  */
652*5113495bSYour Name 
653*5113495bSYour Name /**
654*5113495bSYour Name  * wma_set_mgmt_rate() - set vdev mgmt rate.
655*5113495bSYour Name  * @wma:     wma handle
656*5113495bSYour Name  * @vdev_id: vdev id
657*5113495bSYour Name  *
658*5113495bSYour Name  * Return: None
659*5113495bSYour Name  */
wma_set_vdev_mgmt_rate(tp_wma_handle wma,uint8_t vdev_id)660*5113495bSYour Name void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id)
661*5113495bSYour Name {
662*5113495bSYour Name 	uint32_t cfg_val;
663*5113495bSYour Name 	uint32_t per_band_mgmt_tx_rate = 0;
664*5113495bSYour Name 	enum cds_band_type band = 0;
665*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
666*5113495bSYour Name 	struct dev_set_param setparam[MAX_VDEV_MGMT_RATE_PARAMS] = {};
667*5113495bSYour Name 	uint8_t index = 0;
668*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
669*5113495bSYour Name 
670*5113495bSYour Name 	if (!mac) {
671*5113495bSYour Name 		wma_err("Failed to get mac");
672*5113495bSYour Name 		return;
673*5113495bSYour Name 	}
674*5113495bSYour Name 
675*5113495bSYour Name 	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
676*5113495bSYour Name 	band = CDS_BAND_ALL;
677*5113495bSYour Name 	if ((cfg_val == MLME_CFG_TX_MGMT_RATE_DEF) ||
678*5113495bSYour Name 	    !wma_verify_rate_code(cfg_val, band)) {
679*5113495bSYour Name 		wma_nofl_debug("default WNI_CFG_RATE_FOR_TX_MGMT, ignore");
680*5113495bSYour Name 	} else {
681*5113495bSYour Name 		status = mlme_check_index_setparam(setparam,
682*5113495bSYour Name 						   wmi_vdev_param_mgmt_tx_rate,
683*5113495bSYour Name 						   cfg_val, index++,
684*5113495bSYour Name 						   MAX_VDEV_MGMT_RATE_PARAMS);
685*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
686*5113495bSYour Name 			wma_err("failed at wmi_vdev_param_mgmt_tx_rate");
687*5113495bSYour Name 			goto error;
688*5113495bSYour Name 		}
689*5113495bSYour Name 	}
690*5113495bSYour Name 
691*5113495bSYour Name 	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt_2g;
692*5113495bSYour Name 	band = CDS_BAND_2GHZ;
693*5113495bSYour Name 	if ((cfg_val == MLME_CFG_TX_MGMT_2G_RATE_DEF) ||
694*5113495bSYour Name 	    !wma_verify_rate_code(cfg_val, band)) {
695*5113495bSYour Name 		wma_nofl_debug("use default 2G MGMT rate.");
696*5113495bSYour Name 		per_band_mgmt_tx_rate &=
697*5113495bSYour Name 		    ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
698*5113495bSYour Name 	} else {
699*5113495bSYour Name 		per_band_mgmt_tx_rate |=
700*5113495bSYour Name 		    (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
701*5113495bSYour Name 		per_band_mgmt_tx_rate |=
702*5113495bSYour Name 		    ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET);
703*5113495bSYour Name 	}
704*5113495bSYour Name 
705*5113495bSYour Name 	cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
706*5113495bSYour Name 	band = CDS_BAND_5GHZ;
707*5113495bSYour Name 	if ((cfg_val == MLME_CFG_TX_MGMT_5G_RATE_DEF) ||
708*5113495bSYour Name 	    !wma_verify_rate_code(cfg_val, band)) {
709*5113495bSYour Name 		wma_nofl_debug("use default 5G MGMT rate.");
710*5113495bSYour Name 		per_band_mgmt_tx_rate &=
711*5113495bSYour Name 		    ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
712*5113495bSYour Name 	} else {
713*5113495bSYour Name 		per_band_mgmt_tx_rate |=
714*5113495bSYour Name 		    (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
715*5113495bSYour Name 		per_band_mgmt_tx_rate |=
716*5113495bSYour Name 		    ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET);
717*5113495bSYour Name 	}
718*5113495bSYour Name 
719*5113495bSYour Name 	status = mlme_check_index_setparam(setparam,
720*5113495bSYour Name 					   wmi_vdev_param_per_band_mgmt_tx_rate,
721*5113495bSYour Name 					   per_band_mgmt_tx_rate, index++,
722*5113495bSYour Name 					   MAX_VDEV_MGMT_RATE_PARAMS);
723*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
724*5113495bSYour Name 		wma_err("failed at wmi_vdev_param_per_band_mgmt_tx_rate");
725*5113495bSYour Name 		goto error;
726*5113495bSYour Name 	}
727*5113495bSYour Name 
728*5113495bSYour Name 	status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
729*5113495bSYour Name 						     vdev_id, setparam, index);
730*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
731*5113495bSYour Name 		wma_debug("failed to send MGMT_TX_RATE vdev set params stat:%d",
732*5113495bSYour Name 			  status);
733*5113495bSYour Name error:
734*5113495bSYour Name 	return;
735*5113495bSYour Name }
736*5113495bSYour Name 
737*5113495bSYour Name #define MAX_VDEV_SAP_KEEPALIVE_PARAMS 3
738*5113495bSYour Name /* params being sent:
739*5113495bSYour Name  * wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs
740*5113495bSYour Name  * wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs
741*5113495bSYour Name  * wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs
742*5113495bSYour Name  */
743*5113495bSYour Name 
744*5113495bSYour Name /**
745*5113495bSYour Name  * wma_set_sap_keepalive() - set SAP keep alive parameters to fw
746*5113495bSYour Name  * @wma: wma handle
747*5113495bSYour Name  * @vdev_id: vdev id
748*5113495bSYour Name  *
749*5113495bSYour Name  * Return: none
750*5113495bSYour Name  */
wma_set_sap_keepalive(tp_wma_handle wma,uint8_t vdev_id)751*5113495bSYour Name void wma_set_sap_keepalive(tp_wma_handle wma, uint8_t vdev_id)
752*5113495bSYour Name {
753*5113495bSYour Name 	uint32_t min_inactive_time, max_inactive_time, max_unresponsive_time;
754*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
755*5113495bSYour Name 	QDF_STATUS status;
756*5113495bSYour Name 	struct dev_set_param setparam[MAX_VDEV_SAP_KEEPALIVE_PARAMS] = {};
757*5113495bSYour Name 	uint8_t index = 0;
758*5113495bSYour Name 
759*5113495bSYour Name 	if (!mac) {
760*5113495bSYour Name 		wma_err("Failed to get mac");
761*5113495bSYour Name 		return;
762*5113495bSYour Name 	}
763*5113495bSYour Name 
764*5113495bSYour Name 	wma_get_link_probe_timeout(mac, wma->interfaces[vdev_id].sub_type,
765*5113495bSYour Name 				   &max_inactive_time, &max_unresponsive_time);
766*5113495bSYour Name 
767*5113495bSYour Name 	min_inactive_time = max_inactive_time / 2;
768*5113495bSYour Name 	status = mlme_check_index_setparam(
769*5113495bSYour Name 			setparam,
770*5113495bSYour Name 			wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs,
771*5113495bSYour Name 			min_inactive_time, index++,
772*5113495bSYour Name 			MAX_VDEV_SAP_KEEPALIVE_PARAMS);
773*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
774*5113495bSYour Name 		wma_err("failed to set wmi_vdev_param_ap_keepalive_min_idle_inactive_time_secs");
775*5113495bSYour Name 		goto error;
776*5113495bSYour Name 	}
777*5113495bSYour Name 	status = mlme_check_index_setparam(
778*5113495bSYour Name 			setparam,
779*5113495bSYour Name 			wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs,
780*5113495bSYour Name 			max_inactive_time, index++,
781*5113495bSYour Name 			MAX_VDEV_SAP_KEEPALIVE_PARAMS);
782*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
783*5113495bSYour Name 		wma_err("failed to set wmi_vdev_param_ap_keepalive_max_idle_inactive_time_secs");
784*5113495bSYour Name 		goto error;
785*5113495bSYour Name 	}
786*5113495bSYour Name 	status = mlme_check_index_setparam(
787*5113495bSYour Name 			setparam,
788*5113495bSYour Name 			wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs,
789*5113495bSYour Name 			max_unresponsive_time, index++,
790*5113495bSYour Name 			MAX_VDEV_SAP_KEEPALIVE_PARAMS);
791*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
792*5113495bSYour Name 		wma_err("failed to set wmi_vdev_param_ap_keepalive_max_unresponsive_time_secs");
793*5113495bSYour Name 		goto error;
794*5113495bSYour Name 	}
795*5113495bSYour Name 
796*5113495bSYour Name 	status = wma_send_multi_pdev_vdev_set_params(MLME_VDEV_SETPARAM,
797*5113495bSYour Name 						     vdev_id, setparam, index);
798*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
799*5113495bSYour Name 		wma_err("Failed to Set AP MIN/MAX IDLE INACTIVE TIME, MAX UNRESPONSIVE TIME:%d", status);
800*5113495bSYour Name 	else
801*5113495bSYour Name 		wma_debug("vdev_id:%d min_inactive_time: %u max_inactive_time: %u max_unresponsive_time: %u",
802*5113495bSYour Name 			  vdev_id, min_inactive_time, max_inactive_time,
803*5113495bSYour Name 			  max_unresponsive_time);
804*5113495bSYour Name error:
805*5113495bSYour Name 	return;
806*5113495bSYour Name }
807*5113495bSYour Name 
808*5113495bSYour Name /**
809*5113495bSYour Name  * wma_set_sta_sa_query_param() - set sta sa query parameters
810*5113495bSYour Name  * @wma: wma handle
811*5113495bSYour Name  * @vdev_id: vdev id
812*5113495bSYour Name 
813*5113495bSYour Name  * This function sets sta query related parameters in fw.
814*5113495bSYour Name  *
815*5113495bSYour Name  * Return: none
816*5113495bSYour Name  */
817*5113495bSYour Name 
wma_set_sta_sa_query_param(tp_wma_handle wma,uint8_t vdev_id)818*5113495bSYour Name void wma_set_sta_sa_query_param(tp_wma_handle wma,
819*5113495bSYour Name 				  uint8_t vdev_id)
820*5113495bSYour Name {
821*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
822*5113495bSYour Name 	uint8_t max_retries;
823*5113495bSYour Name 	uint16_t retry_interval;
824*5113495bSYour Name 
825*5113495bSYour Name 	if (!mac) {
826*5113495bSYour Name 		wma_err("mac context is NULL");
827*5113495bSYour Name 		return;
828*5113495bSYour Name 	}
829*5113495bSYour Name 
830*5113495bSYour Name 	max_retries = mac->mlme_cfg->gen.pmf_sa_query_max_retries;
831*5113495bSYour Name 	retry_interval = mac->mlme_cfg->gen.pmf_sa_query_retry_interval;
832*5113495bSYour Name 
833*5113495bSYour Name 	wmi_unified_set_sta_sa_query_param_cmd(wma->wmi_handle,
834*5113495bSYour Name 						vdev_id,
835*5113495bSYour Name 						max_retries,
836*5113495bSYour Name 						retry_interval);
837*5113495bSYour Name }
838*5113495bSYour Name 
839*5113495bSYour Name /**
840*5113495bSYour Name  * wma_set_sta_keep_alive() - set sta keep alive parameters
841*5113495bSYour Name  * @wma: wma handle
842*5113495bSYour Name  * @vdev_id: vdev id
843*5113495bSYour Name  * @method: method for keep alive
844*5113495bSYour Name  * @timeperiod: time period
845*5113495bSYour Name  * @hostv4addr: host ipv4 address
846*5113495bSYour Name  * @destv4addr: dst ipv4 address
847*5113495bSYour Name  * @destmac: destination mac
848*5113495bSYour Name  *
849*5113495bSYour Name  * This function sets keep alive related parameters in fw.
850*5113495bSYour Name  *
851*5113495bSYour Name  * Return: none
852*5113495bSYour Name  */
wma_set_sta_keep_alive(tp_wma_handle wma,uint8_t vdev_id,uint32_t method,uint32_t timeperiod,uint8_t * hostv4addr,uint8_t * destv4addr,uint8_t * destmac)853*5113495bSYour Name void wma_set_sta_keep_alive(tp_wma_handle wma, uint8_t vdev_id,
854*5113495bSYour Name 			    uint32_t method, uint32_t timeperiod,
855*5113495bSYour Name 			    uint8_t *hostv4addr, uint8_t *destv4addr,
856*5113495bSYour Name 			    uint8_t *destmac)
857*5113495bSYour Name {
858*5113495bSYour Name 	struct sta_keep_alive_params params = { 0 };
859*5113495bSYour Name 	struct wma_txrx_node *intr;
860*5113495bSYour Name 
861*5113495bSYour Name 	if (wma_validate_handle(wma))
862*5113495bSYour Name 		return;
863*5113495bSYour Name 
864*5113495bSYour Name 	intr = &wma->interfaces[vdev_id];
865*5113495bSYour Name 	if (timeperiod > cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD)) {
866*5113495bSYour Name 		wmi_err("Invalid period %d Max limit %d", timeperiod,
867*5113495bSYour Name 			 cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD));
868*5113495bSYour Name 		return;
869*5113495bSYour Name 	}
870*5113495bSYour Name 
871*5113495bSYour Name 	params.vdev_id = vdev_id;
872*5113495bSYour Name 	params.method = method;
873*5113495bSYour Name 	params.timeperiod = timeperiod;
874*5113495bSYour Name 	if (intr) {
875*5113495bSYour Name 		if (intr->bss_max_idle_period) {
876*5113495bSYour Name 			if (intr->bss_max_idle_period < timeperiod)
877*5113495bSYour Name 				params.timeperiod = intr->bss_max_idle_period;
878*5113495bSYour Name 
879*5113495bSYour Name 			if (method == WMI_KEEP_ALIVE_NULL_PKT)
880*5113495bSYour Name 				params.method = WMI_KEEP_ALIVE_MGMT_FRAME;
881*5113495bSYour Name 		}
882*5113495bSYour Name 
883*5113495bSYour Name 		wlan_mlme_set_keepalive_period(intr->vdev, params.timeperiod);
884*5113495bSYour Name 	}
885*5113495bSYour Name 
886*5113495bSYour Name 	if (hostv4addr)
887*5113495bSYour Name 		qdf_mem_copy(params.hostv4addr, hostv4addr, QDF_IPV4_ADDR_SIZE);
888*5113495bSYour Name 	if (destv4addr)
889*5113495bSYour Name 		qdf_mem_copy(params.destv4addr, destv4addr, QDF_IPV4_ADDR_SIZE);
890*5113495bSYour Name 	if (destmac)
891*5113495bSYour Name 		qdf_mem_copy(params.destmac, destmac, QDF_MAC_ADDR_SIZE);
892*5113495bSYour Name 
893*5113495bSYour Name 	wmi_unified_set_sta_keep_alive_cmd(wma->wmi_handle, &params);
894*5113495bSYour Name }
895*5113495bSYour Name 
896*5113495bSYour Name /*
897*5113495bSYour Name  * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
898*5113495bSYour Name  *   0 for no restriction
899*5113495bSYour Name  *   1 for 1/4 us - Our lower layer calculations limit our precision to 1 msec
900*5113495bSYour Name  *   2 for 1/2 us - Our lower layer calculations limit our precision to 1 msec
901*5113495bSYour Name  *   3 for 1 us
902*5113495bSYour Name  *   4 for 2 us
903*5113495bSYour Name  *   5 for 4 us
904*5113495bSYour Name  *   6 for 8 us
905*5113495bSYour Name  *   7 for 16 us
906*5113495bSYour Name  */
907*5113495bSYour Name static const uint8_t wma_mpdu_spacing[] = { 0, 1, 1, 1, 2, 4, 8, 16 };
908*5113495bSYour Name 
909*5113495bSYour Name /**
910*5113495bSYour Name  * wma_parse_mpdudensity() - give mpdu spacing from mpdu density
911*5113495bSYour Name  * @mpdudensity: mpdu density
912*5113495bSYour Name  *
913*5113495bSYour Name  * Return: mpdu spacing or 0 for error
914*5113495bSYour Name  */
wma_parse_mpdudensity(uint8_t mpdudensity)915*5113495bSYour Name static inline uint8_t wma_parse_mpdudensity(uint8_t mpdudensity)
916*5113495bSYour Name {
917*5113495bSYour Name 	if (mpdudensity < sizeof(wma_mpdu_spacing))
918*5113495bSYour Name 		return wma_mpdu_spacing[mpdudensity];
919*5113495bSYour Name 	else
920*5113495bSYour Name 		return 0;
921*5113495bSYour Name }
922*5113495bSYour Name 
923*5113495bSYour Name #define CFG_CTRL_MASK              0xFF00
924*5113495bSYour Name #define CFG_DATA_MASK              0x00FF
925*5113495bSYour Name 
926*5113495bSYour Name /**
927*5113495bSYour Name  * wma_mask_tx_ht_rate() - mask tx ht rate based on config
928*5113495bSYour Name  * @wma:     wma handle
929*5113495bSYour Name  * @mcs_set  mcs set buffer
930*5113495bSYour Name  *
931*5113495bSYour Name  * Return: None
932*5113495bSYour Name  */
wma_mask_tx_ht_rate(tp_wma_handle wma,uint8_t * mcs_set)933*5113495bSYour Name static void wma_mask_tx_ht_rate(tp_wma_handle wma, uint8_t *mcs_set)
934*5113495bSYour Name {
935*5113495bSYour Name 	uint32_t i, j;
936*5113495bSYour Name 	uint16_t mcs_limit;
937*5113495bSYour Name 	uint8_t *rate_pos = mcs_set;
938*5113495bSYour Name 	struct mac_context *mac = wma->mac_context;
939*5113495bSYour Name 
940*5113495bSYour Name 	/*
941*5113495bSYour Name 	 * Get MCS limit from ini configure, and map it to rate parameters
942*5113495bSYour Name 	 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
943*5113495bSYour Name 	 * check whether ini config is enabled and CFG_DATA_MASK to get the
944*5113495bSYour Name 	 * MCS value.
945*5113495bSYour Name 	 */
946*5113495bSYour Name 	mcs_limit = mac->mlme_cfg->rates.max_htmcs_txdata;
947*5113495bSYour Name 
948*5113495bSYour Name 	if (mcs_limit & CFG_CTRL_MASK) {
949*5113495bSYour Name 		wma_debug("set mcs_limit %x", mcs_limit);
950*5113495bSYour Name 
951*5113495bSYour Name 		mcs_limit &= CFG_DATA_MASK;
952*5113495bSYour Name 		for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
953*5113495bSYour Name 			if (j < mcs_limit / 8) {
954*5113495bSYour Name 				rate_pos[j] = 0xff;
955*5113495bSYour Name 				j++;
956*5113495bSYour Name 				i += 8;
957*5113495bSYour Name 			} else if (j < mcs_limit / 8 + 1) {
958*5113495bSYour Name 				if (i <= mcs_limit)
959*5113495bSYour Name 					rate_pos[i / 8] |= 1 << (i % 8);
960*5113495bSYour Name 				else
961*5113495bSYour Name 					rate_pos[i / 8] &= ~(1 << (i % 8));
962*5113495bSYour Name 				i++;
963*5113495bSYour Name 
964*5113495bSYour Name 				if (i >= (j + 1) * 8)
965*5113495bSYour Name 					j++;
966*5113495bSYour Name 			} else {
967*5113495bSYour Name 				rate_pos[j++] = 0;
968*5113495bSYour Name 				i += 8;
969*5113495bSYour Name 			}
970*5113495bSYour Name 		}
971*5113495bSYour Name 	}
972*5113495bSYour Name }
973*5113495bSYour Name 
974*5113495bSYour Name #if SUPPORT_11AX
975*5113495bSYour Name /**
976*5113495bSYour Name  * wma_fw_to_host_phymode_11ax() - convert fw to host phymode for 11ax phymodes
977*5113495bSYour Name  * @phymode: phymode to convert
978*5113495bSYour Name  *
979*5113495bSYour Name  * Return: one of the 11ax values defined in enum wlan_phymode;
980*5113495bSYour Name  *         or WLAN_PHYMODE_AUTO if the input is not an 11ax phymode
981*5113495bSYour Name  */
982*5113495bSYour Name static enum wlan_phymode
wma_fw_to_host_phymode_11ax(WMI_HOST_WLAN_PHY_MODE phymode)983*5113495bSYour Name wma_fw_to_host_phymode_11ax(WMI_HOST_WLAN_PHY_MODE phymode)
984*5113495bSYour Name {
985*5113495bSYour Name 	switch (phymode) {
986*5113495bSYour Name 	default:
987*5113495bSYour Name 		return WLAN_PHYMODE_AUTO;
988*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE20:
989*5113495bSYour Name 		return WLAN_PHYMODE_11AXA_HE20;
990*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE40:
991*5113495bSYour Name 		return WLAN_PHYMODE_11AXA_HE40;
992*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE80:
993*5113495bSYour Name 		return WLAN_PHYMODE_11AXA_HE80;
994*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE80_80:
995*5113495bSYour Name 		return WLAN_PHYMODE_11AXA_HE80_80;
996*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE160:
997*5113495bSYour Name 		return WLAN_PHYMODE_11AXA_HE160;
998*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE20_2G:
999*5113495bSYour Name 		return WLAN_PHYMODE_11AXG_HE20;
1000*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE40_2G:
1001*5113495bSYour Name 		return WLAN_PHYMODE_11AXG_HE40;
1002*5113495bSYour Name 	case WMI_HOST_MODE_11AX_HE80_2G:
1003*5113495bSYour Name 		return WLAN_PHYMODE_11AXG_HE80;
1004*5113495bSYour Name 	}
1005*5113495bSYour Name 	return WLAN_PHYMODE_AUTO;
1006*5113495bSYour Name }
1007*5113495bSYour Name #else
1008*5113495bSYour Name static enum wlan_phymode
wma_fw_to_host_phymode_11ax(WMI_HOST_WLAN_PHY_MODE phymode)1009*5113495bSYour Name wma_fw_to_host_phymode_11ax(WMI_HOST_WLAN_PHY_MODE phymode)
1010*5113495bSYour Name {
1011*5113495bSYour Name 	return WLAN_PHYMODE_AUTO;
1012*5113495bSYour Name }
1013*5113495bSYour Name #endif
1014*5113495bSYour Name 
1015*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
1016*5113495bSYour Name /**
1017*5113495bSYour Name  * wma_fw_to_host_phymode_11be() - convert fw to host phymode for 11be phymodes
1018*5113495bSYour Name  * @phymode: phymode to convert
1019*5113495bSYour Name  *
1020*5113495bSYour Name  * Return: one of the 11be values defined in enum wlan_phymode;
1021*5113495bSYour Name  *         or WLAN_PHYMODE_AUTO if the input is not an 11be phymode
1022*5113495bSYour Name  */
1023*5113495bSYour Name static enum wlan_phymode
wma_fw_to_host_phymode_11be(WMI_HOST_WLAN_PHY_MODE phymode)1024*5113495bSYour Name wma_fw_to_host_phymode_11be(WMI_HOST_WLAN_PHY_MODE phymode)
1025*5113495bSYour Name {
1026*5113495bSYour Name 	switch (phymode) {
1027*5113495bSYour Name 	default:
1028*5113495bSYour Name 		return WLAN_PHYMODE_AUTO;
1029*5113495bSYour Name 	case WMI_HOST_MODE_11BE_EHT20:
1030*5113495bSYour Name 		return WLAN_PHYMODE_11BEA_EHT20;
1031*5113495bSYour Name 	case WMI_HOST_MODE_11BE_EHT40:
1032*5113495bSYour Name 		return WLAN_PHYMODE_11BEA_EHT40;
1033*5113495bSYour Name 	case WMI_HOST_MODE_11BE_EHT80:
1034*5113495bSYour Name 		return WLAN_PHYMODE_11BEA_EHT80;
1035*5113495bSYour Name 	case WMI_HOST_MODE_11BE_EHT160:
1036*5113495bSYour Name 		return WLAN_PHYMODE_11BEA_EHT160;
1037*5113495bSYour Name 	case WMI_HOST_MODE_11BE_EHT320:
1038*5113495bSYour Name 		return WLAN_PHYMODE_11BEA_EHT320;
1039*5113495bSYour Name 	case WMI_HOST_MODE_11BE_EHT20_2G:
1040*5113495bSYour Name 		return WLAN_PHYMODE_11BEG_EHT20;
1041*5113495bSYour Name 	case WMI_HOST_MODE_11BE_EHT40_2G:
1042*5113495bSYour Name 		return WLAN_PHYMODE_11BEG_EHT40;
1043*5113495bSYour Name 	}
1044*5113495bSYour Name 	return WLAN_PHYMODE_AUTO;
1045*5113495bSYour Name }
1046*5113495bSYour Name 
wma_is_phymode_eht(enum wlan_phymode phymode)1047*5113495bSYour Name static inline bool wma_is_phymode_eht(enum wlan_phymode phymode)
1048*5113495bSYour Name {
1049*5113495bSYour Name 	return IS_WLAN_PHYMODE_EHT(phymode);
1050*5113495bSYour Name }
1051*5113495bSYour Name #else
1052*5113495bSYour Name static enum wlan_phymode
wma_fw_to_host_phymode_11be(WMI_HOST_WLAN_PHY_MODE phymode)1053*5113495bSYour Name wma_fw_to_host_phymode_11be(WMI_HOST_WLAN_PHY_MODE phymode)
1054*5113495bSYour Name {
1055*5113495bSYour Name 	return WLAN_PHYMODE_AUTO;
1056*5113495bSYour Name }
1057*5113495bSYour Name 
wma_is_phymode_eht(enum wlan_phymode phymode)1058*5113495bSYour Name static inline bool wma_is_phymode_eht(enum wlan_phymode phymode)
1059*5113495bSYour Name {
1060*5113495bSYour Name 	return false;
1061*5113495bSYour Name }
1062*5113495bSYour Name #endif
1063*5113495bSYour Name 
1064*5113495bSYour Name #ifdef CONFIG_160MHZ_SUPPORT
1065*5113495bSYour Name /**
1066*5113495bSYour Name  * wma_fw_to_host_phymode_160() - convert fw to host phymode for 160 mhz
1067*5113495bSYour Name  * phymodes
1068*5113495bSYour Name  * @phymode: phymode to convert
1069*5113495bSYour Name  *
1070*5113495bSYour Name  * Return: one of the 160 mhz values defined in enum wlan_phymode;
1071*5113495bSYour Name  *         or WLAN_PHYMODE_AUTO if the input is not a 160 mhz phymode
1072*5113495bSYour Name  */
1073*5113495bSYour Name static enum wlan_phymode
wma_fw_to_host_phymode_160(WMI_HOST_WLAN_PHY_MODE phymode)1074*5113495bSYour Name wma_fw_to_host_phymode_160(WMI_HOST_WLAN_PHY_MODE phymode)
1075*5113495bSYour Name {
1076*5113495bSYour Name 	switch (phymode) {
1077*5113495bSYour Name 	default:
1078*5113495bSYour Name 		return WLAN_PHYMODE_AUTO;
1079*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT80_80:
1080*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT80_80;
1081*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT160:
1082*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT160;
1083*5113495bSYour Name 	}
1084*5113495bSYour Name }
1085*5113495bSYour Name #else
1086*5113495bSYour Name static enum wlan_phymode
wma_fw_to_host_phymode_160(WMI_HOST_WLAN_PHY_MODE phymode)1087*5113495bSYour Name wma_fw_to_host_phymode_160(WMI_HOST_WLAN_PHY_MODE phymode)
1088*5113495bSYour Name {
1089*5113495bSYour Name 	return WLAN_PHYMODE_AUTO;
1090*5113495bSYour Name }
1091*5113495bSYour Name #endif
1092*5113495bSYour Name 
wma_fw_to_host_phymode(WMI_HOST_WLAN_PHY_MODE phymode)1093*5113495bSYour Name enum wlan_phymode wma_fw_to_host_phymode(WMI_HOST_WLAN_PHY_MODE phymode)
1094*5113495bSYour Name {
1095*5113495bSYour Name 	enum wlan_phymode host_phymode;
1096*5113495bSYour Name 	switch (phymode) {
1097*5113495bSYour Name 	default:
1098*5113495bSYour Name 		host_phymode = wma_fw_to_host_phymode_160(phymode);
1099*5113495bSYour Name 		if (host_phymode != WLAN_PHYMODE_AUTO)
1100*5113495bSYour Name 			return host_phymode;
1101*5113495bSYour Name 		host_phymode = wma_fw_to_host_phymode_11ax(phymode);
1102*5113495bSYour Name 		if (host_phymode != WLAN_PHYMODE_AUTO)
1103*5113495bSYour Name 			return host_phymode;
1104*5113495bSYour Name 		return wma_fw_to_host_phymode_11be(phymode);
1105*5113495bSYour Name 	case WMI_HOST_MODE_11A:
1106*5113495bSYour Name 		return WLAN_PHYMODE_11A;
1107*5113495bSYour Name 	case WMI_HOST_MODE_11G:
1108*5113495bSYour Name 		return WLAN_PHYMODE_11G;
1109*5113495bSYour Name 	case WMI_HOST_MODE_11B:
1110*5113495bSYour Name 		return WLAN_PHYMODE_11B;
1111*5113495bSYour Name 	case WMI_HOST_MODE_11GONLY:
1112*5113495bSYour Name 		return WLAN_PHYMODE_11G_ONLY;
1113*5113495bSYour Name 	case WMI_HOST_MODE_11NA_HT20:
1114*5113495bSYour Name 		return WLAN_PHYMODE_11NA_HT20;
1115*5113495bSYour Name 	case WMI_HOST_MODE_11NG_HT20:
1116*5113495bSYour Name 		return WLAN_PHYMODE_11NG_HT20;
1117*5113495bSYour Name 	case WMI_HOST_MODE_11NA_HT40:
1118*5113495bSYour Name 		return WLAN_PHYMODE_11NA_HT40;
1119*5113495bSYour Name 	case WMI_HOST_MODE_11NG_HT40:
1120*5113495bSYour Name 		return WLAN_PHYMODE_11NG_HT40;
1121*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT20:
1122*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT20;
1123*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT40:
1124*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT40;
1125*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT80:
1126*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT80;
1127*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT20_2G:
1128*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT20_2G;
1129*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT40_2G:
1130*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT40_2G;
1131*5113495bSYour Name 	case WMI_HOST_MODE_11AC_VHT80_2G:
1132*5113495bSYour Name 		return WLAN_PHYMODE_11AC_VHT80_2G;
1133*5113495bSYour Name 	}
1134*5113495bSYour Name }
1135*5113495bSYour Name 
1136*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
wma_populate_peer_puncture(struct peer_assoc_params * peer,struct wlan_channel * des_chan)1137*5113495bSYour Name static void wma_populate_peer_puncture(struct peer_assoc_params *peer,
1138*5113495bSYour Name 				       struct wlan_channel *des_chan)
1139*5113495bSYour Name {
1140*5113495bSYour Name 	peer->puncture_bitmap = des_chan->puncture_bitmap;
1141*5113495bSYour Name 	wma_debug("Peer EHT puncture bitmap %d", peer->puncture_bitmap);
1142*5113495bSYour Name }
1143*5113495bSYour Name 
wma_populate_peer_mlo_cap(struct peer_assoc_params * peer,tpAddStaParams params)1144*5113495bSYour Name static void wma_populate_peer_mlo_cap(struct peer_assoc_params *peer,
1145*5113495bSYour Name 				      tpAddStaParams params)
1146*5113495bSYour Name {
1147*5113495bSYour Name 	struct peer_assoc_ml_partner_links *ml_links;
1148*5113495bSYour Name 	struct peer_assoc_mlo_params *mlo_params;
1149*5113495bSYour Name 	struct peer_ml_info *ml_info;
1150*5113495bSYour Name 	uint8_t i;
1151*5113495bSYour Name 
1152*5113495bSYour Name 	ml_info = &params->ml_info;
1153*5113495bSYour Name 	mlo_params = &peer->mlo_params;
1154*5113495bSYour Name 	ml_links = &peer->ml_links;
1155*5113495bSYour Name 
1156*5113495bSYour Name 	/* Assoc link info */
1157*5113495bSYour Name 	mlo_params->vdev_id = ml_info->vdev_id;
1158*5113495bSYour Name 	mlo_params->ieee_link_id = ml_info->link_id;
1159*5113495bSYour Name 	qdf_mem_copy(&mlo_params->chan, &ml_info->channel_info,
1160*5113495bSYour Name 		     sizeof(struct wlan_channel));
1161*5113495bSYour Name 	qdf_mem_copy(&mlo_params->bssid, &ml_info->link_addr,
1162*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
1163*5113495bSYour Name 	qdf_mem_copy(&mlo_params->mac_addr, &ml_info->self_mac_addr,
1164*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
1165*5113495bSYour Name 
1166*5113495bSYour Name 	mlo_params->rec_max_simultaneous_links =
1167*5113495bSYour Name 		ml_info->rec_max_simultaneous_links;
1168*5113495bSYour Name 
1169*5113495bSYour Name 	/* Fill partner link info */
1170*5113495bSYour Name 	ml_links->num_links = ml_info->num_links;
1171*5113495bSYour Name 	for (i = 0; i < ml_links->num_links; i++) {
1172*5113495bSYour Name 		ml_links->partner_info[i].vdev_id =
1173*5113495bSYour Name 					ml_info->partner_info[i].vdev_id;
1174*5113495bSYour Name 		ml_links->partner_info[i].link_id =
1175*5113495bSYour Name 					ml_info->partner_info[i].link_id;
1176*5113495bSYour Name 		qdf_mem_copy(&ml_links->partner_info[i].chan,
1177*5113495bSYour Name 			     &ml_info->partner_info[i].channel_info,
1178*5113495bSYour Name 			     sizeof(struct wlan_channel));
1179*5113495bSYour Name 		qdf_mem_copy(&ml_links->partner_info[i].bssid,
1180*5113495bSYour Name 			     &ml_info->partner_info[i].link_addr,
1181*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
1182*5113495bSYour Name 		qdf_mem_copy(&ml_links->partner_info[i].mac_addr,
1183*5113495bSYour Name 			     &ml_info->partner_info[i].self_mac_addr,
1184*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
1185*5113495bSYour Name 	}
1186*5113495bSYour Name }
1187*5113495bSYour Name #else
wma_populate_peer_puncture(struct peer_assoc_params * peer,struct wlan_channel * des_chan)1188*5113495bSYour Name static void wma_populate_peer_puncture(struct peer_assoc_params *peer,
1189*5113495bSYour Name 				       struct wlan_channel *des_chan)
1190*5113495bSYour Name {
1191*5113495bSYour Name }
1192*5113495bSYour Name 
wma_populate_peer_mlo_cap(struct peer_assoc_params * peer,tpAddStaParams params)1193*5113495bSYour Name static void wma_populate_peer_mlo_cap(struct peer_assoc_params *peer,
1194*5113495bSYour Name 				      tpAddStaParams params)
1195*5113495bSYour Name {
1196*5113495bSYour Name }
1197*5113495bSYour Name #endif
1198*5113495bSYour Name 
wma_objmgr_set_peer_mlme_nss(tp_wma_handle wma,uint8_t * mac_addr,uint8_t nss)1199*5113495bSYour Name void wma_objmgr_set_peer_mlme_nss(tp_wma_handle wma, uint8_t *mac_addr,
1200*5113495bSYour Name 				  uint8_t nss)
1201*5113495bSYour Name {
1202*5113495bSYour Name 	uint8_t pdev_id;
1203*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1204*5113495bSYour Name 	struct peer_mlme_priv_obj *peer_priv;
1205*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = wma->psoc;
1206*5113495bSYour Name 
1207*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1208*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1209*5113495bSYour Name 				    WLAN_LEGACY_WMA_ID);
1210*5113495bSYour Name 	if (!peer)
1211*5113495bSYour Name 		return;
1212*5113495bSYour Name 
1213*5113495bSYour Name 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
1214*5113495bSYour Name 							  WLAN_UMAC_COMP_MLME);
1215*5113495bSYour Name 	if (!peer_priv) {
1216*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1217*5113495bSYour Name 		return;
1218*5113495bSYour Name 	}
1219*5113495bSYour Name 
1220*5113495bSYour Name 	peer_priv->nss = nss;
1221*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1222*5113495bSYour Name }
1223*5113495bSYour Name 
wma_objmgr_get_peer_mlme_nss(tp_wma_handle wma,uint8_t * mac_addr)1224*5113495bSYour Name uint8_t wma_objmgr_get_peer_mlme_nss(tp_wma_handle wma, uint8_t *mac_addr)
1225*5113495bSYour Name {
1226*5113495bSYour Name 	uint8_t pdev_id;
1227*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1228*5113495bSYour Name 	struct peer_mlme_priv_obj *peer_priv;
1229*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = wma->psoc;
1230*5113495bSYour Name 	uint8_t nss;
1231*5113495bSYour Name 
1232*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1233*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1234*5113495bSYour Name 				    WLAN_LEGACY_WMA_ID);
1235*5113495bSYour Name 	if (!peer)
1236*5113495bSYour Name 		return 0;
1237*5113495bSYour Name 
1238*5113495bSYour Name 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
1239*5113495bSYour Name 							  WLAN_UMAC_COMP_MLME);
1240*5113495bSYour Name 	if (!peer_priv) {
1241*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1242*5113495bSYour Name 		return 0;
1243*5113495bSYour Name 	}
1244*5113495bSYour Name 
1245*5113495bSYour Name 	nss = peer_priv->nss;
1246*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1247*5113495bSYour Name 	return nss;
1248*5113495bSYour Name }
1249*5113495bSYour Name 
wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma,uint8_t * mac_addr,enum wlan_phymode phymode)1250*5113495bSYour Name void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma, uint8_t *mac_addr,
1251*5113495bSYour Name 				      enum wlan_phymode phymode)
1252*5113495bSYour Name {
1253*5113495bSYour Name 	uint8_t pdev_id;
1254*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1255*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = wma->psoc;
1256*5113495bSYour Name 
1257*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1258*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1259*5113495bSYour Name 				    WLAN_LEGACY_WMA_ID);
1260*5113495bSYour Name 	if (!peer)
1261*5113495bSYour Name 		return;
1262*5113495bSYour Name 
1263*5113495bSYour Name 	wlan_peer_obj_lock(peer);
1264*5113495bSYour Name 	wlan_peer_set_phymode(peer, phymode);
1265*5113495bSYour Name 	wlan_peer_obj_unlock(peer);
1266*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1267*5113495bSYour Name }
1268*5113495bSYour Name 
1269*5113495bSYour Name /**
1270*5113495bSYour Name  * wma_objmgr_set_peer_mlme_type() - set peer type to peer object
1271*5113495bSYour Name  * @wma:      wma handle
1272*5113495bSYour Name  * @mac_addr: mac addr of peer
1273*5113495bSYour Name  * @peer_type:  peer type value to set
1274*5113495bSYour Name  *
1275*5113495bSYour Name  * Return: None
1276*5113495bSYour Name  */
wma_objmgr_set_peer_mlme_type(tp_wma_handle wma,uint8_t * mac_addr,enum wlan_peer_type peer_type)1277*5113495bSYour Name static void wma_objmgr_set_peer_mlme_type(tp_wma_handle wma,
1278*5113495bSYour Name 					  uint8_t *mac_addr,
1279*5113495bSYour Name 					  enum wlan_peer_type peer_type)
1280*5113495bSYour Name {
1281*5113495bSYour Name 	uint8_t pdev_id;
1282*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1283*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = wma->psoc;
1284*5113495bSYour Name 
1285*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1286*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1287*5113495bSYour Name 				    WLAN_LEGACY_WMA_ID);
1288*5113495bSYour Name 	if (!peer)
1289*5113495bSYour Name 		return;
1290*5113495bSYour Name 
1291*5113495bSYour Name 	wlan_peer_obj_lock(peer);
1292*5113495bSYour Name 	wlan_peer_set_peer_type(peer, peer_type);
1293*5113495bSYour Name 	wlan_peer_obj_unlock(peer);
1294*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1295*5113495bSYour Name }
1296*5113495bSYour Name 
1297*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
1298*5113495bSYour Name 
1299*5113495bSYour Name #define MIN_TIMEOUT_VAL 0
1300*5113495bSYour Name #define MAX_TIMEOUT_VAL 11
1301*5113495bSYour Name 
1302*5113495bSYour Name #define TIMEOUT_TO_US 6
1303*5113495bSYour Name 
1304*5113495bSYour Name /*
1305*5113495bSYour Name  * wma_convert_trans_timeout_us() - API to convert
1306*5113495bSYour Name  * emlsr transition timeout to microseconds. Refer Table 9-401h
1307*5113495bSYour Name  * of IEEE802.11be specification
1308*5113495bSYour Name  * @timeout: EMLSR transition timeout
1309*5113495bSYour Name  *
1310*5113495bSYour Name  * Return: Timeout value in microseconds
1311*5113495bSYour Name  */
1312*5113495bSYour Name static inline uint32_t
wma_convert_trans_timeout_us(uint16_t timeout)1313*5113495bSYour Name wma_convert_trans_timeout_us(uint16_t timeout)
1314*5113495bSYour Name {
1315*5113495bSYour Name 	uint32_t us = 0;
1316*5113495bSYour Name 
1317*5113495bSYour Name 	if (timeout > MIN_TIMEOUT_VAL && timeout < MAX_TIMEOUT_VAL) {
1318*5113495bSYour Name 		/* timeout = 1 is for 128us*/
1319*5113495bSYour Name 		us = (1 << (timeout + TIMEOUT_TO_US));
1320*5113495bSYour Name 	}
1321*5113495bSYour Name 
1322*5113495bSYour Name 	return us;
1323*5113495bSYour Name }
1324*5113495bSYour Name 
1325*5113495bSYour Name /**
1326*5113495bSYour Name  * wma_set_mlo_capability() - set MLO caps to the peer assoc request
1327*5113495bSYour Name  * @wma: wma handle
1328*5113495bSYour Name  * @vdev: vdev object
1329*5113495bSYour Name  * @params: Add sta params
1330*5113495bSYour Name  * @req: peer assoc request parameters
1331*5113495bSYour Name  *
1332*5113495bSYour Name  * Return: None
1333*5113495bSYour Name  */
wma_set_mlo_capability(tp_wma_handle wma,struct wlan_objmgr_vdev * vdev,tpAddStaParams params,struct peer_assoc_params * req)1334*5113495bSYour Name static void wma_set_mlo_capability(tp_wma_handle wma,
1335*5113495bSYour Name 				   struct wlan_objmgr_vdev *vdev,
1336*5113495bSYour Name 				   tpAddStaParams params,
1337*5113495bSYour Name 				   struct peer_assoc_params *req)
1338*5113495bSYour Name {
1339*5113495bSYour Name 	uint8_t pdev_id;
1340*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1341*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = wma->psoc;
1342*5113495bSYour Name 	uint16_t link_id_bitmap;
1343*5113495bSYour Name 
1344*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1345*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id, req->peer_mac,
1346*5113495bSYour Name 				    WLAN_LEGACY_WMA_ID);
1347*5113495bSYour Name 
1348*5113495bSYour Name 	if (!peer) {
1349*5113495bSYour Name 		wma_err("peer not valid");
1350*5113495bSYour Name 		return;
1351*5113495bSYour Name 	}
1352*5113495bSYour Name 
1353*5113495bSYour Name 	if (!qdf_is_macaddr_zero((struct qdf_mac_addr *)peer->mldaddr)) {
1354*5113495bSYour Name 		req->mlo_params.mlo_enabled = true;
1355*5113495bSYour Name 		req->mlo_params.mlo_assoc_link =
1356*5113495bSYour Name 					wlan_peer_mlme_is_assoc_peer(peer);
1357*5113495bSYour Name 		WLAN_ADDR_COPY(req->mlo_params.mld_mac, peer->mldaddr);
1358*5113495bSYour Name 		if (policy_mgr_ml_link_vdev_need_to_be_disabled(psoc, vdev,
1359*5113495bSYour Name 								true) ||
1360*5113495bSYour Name 		    policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
1361*5113495bSYour Name 			req->mlo_params.mlo_force_link_inactive = 1;
1362*5113495bSYour Name 			link_id_bitmap = 1 << params->link_id;
1363*5113495bSYour Name 			ml_nlink_set_curr_force_inactive_state(
1364*5113495bSYour Name 					psoc, vdev, link_id_bitmap, LINK_ADD);
1365*5113495bSYour Name 			ml_nlink_init_concurrency_link_request(psoc, vdev);
1366*5113495bSYour Name 		}
1367*5113495bSYour Name 		wma_debug("assoc_link %d" QDF_MAC_ADDR_FMT ", force inactive %d link id %d",
1368*5113495bSYour Name 			  req->mlo_params.mlo_assoc_link,
1369*5113495bSYour Name 			  QDF_MAC_ADDR_REF(peer->mldaddr),
1370*5113495bSYour Name 			  req->mlo_params.mlo_force_link_inactive,
1371*5113495bSYour Name 			  params->link_id);
1372*5113495bSYour Name 
1373*5113495bSYour Name 		req->mlo_params.emlsr_support = params->emlsr_support;
1374*5113495bSYour Name 		req->mlo_params.ieee_link_id = params->link_id;
1375*5113495bSYour Name 		if (req->mlo_params.emlsr_support) {
1376*5113495bSYour Name 			req->mlo_params.trans_timeout_us =
1377*5113495bSYour Name 			wma_convert_trans_timeout_us(params->emlsr_trans_timeout);
1378*5113495bSYour Name 		}
1379*5113495bSYour Name 		req->mlo_params.msd_cap_support = params->msd_caps_present;
1380*5113495bSYour Name 		req->mlo_params.medium_sync_duration =
1381*5113495bSYour Name 				params->msd_caps.med_sync_duration;
1382*5113495bSYour Name 		req->mlo_params.medium_sync_ofdm_ed_thresh =
1383*5113495bSYour Name 				params->msd_caps.med_sync_ofdm_ed_thresh;
1384*5113495bSYour Name 		req->mlo_params.medium_sync_max_txop_num =
1385*5113495bSYour Name 				params->msd_caps.med_sync_max_txop_num;
1386*5113495bSYour Name 		req->mlo_params.link_switch_in_progress =
1387*5113495bSYour Name 			wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev);
1388*5113495bSYour Name 		/*
1389*5113495bSYour Name 		 * Set max simultaneous links = 1 for MLSR, 2 for MLMR. The +1
1390*5113495bSYour Name 		 * is added as per the agreement with FW for backward
1391*5113495bSYour Name 		 * compatibility purposes. Our internal structures still
1392*5113495bSYour Name 		 * conform to the values as per spec i.e. 0 = MLSR, 1 = MLMR.
1393*5113495bSYour Name 		 */
1394*5113495bSYour Name 		req->mlo_params.max_num_simultaneous_links =
1395*5113495bSYour Name 			wlan_mlme_get_sta_mlo_simultaneous_links(psoc) + 1;
1396*5113495bSYour Name 	} else {
1397*5113495bSYour Name 		wma_debug("Peer MLO context is NULL");
1398*5113495bSYour Name 		req->mlo_params.mlo_enabled = false;
1399*5113495bSYour Name 		req->mlo_params.emlsr_support = false;
1400*5113495bSYour Name 	}
1401*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1402*5113495bSYour Name }
1403*5113495bSYour Name 
wma_set_mlo_assoc_vdev(struct wlan_objmgr_vdev * vdev,struct peer_assoc_params * req)1404*5113495bSYour Name static void wma_set_mlo_assoc_vdev(struct wlan_objmgr_vdev *vdev,
1405*5113495bSYour Name 				   struct peer_assoc_params *req)
1406*5113495bSYour Name {
1407*5113495bSYour Name 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
1408*5113495bSYour Name 	    !wlan_vdev_mlme_is_mlo_link_vdev(vdev))
1409*5113495bSYour Name 		req->is_assoc_vdev = true;
1410*5113495bSYour Name }
1411*5113495bSYour Name #else
wma_set_mlo_capability(tp_wma_handle wma,struct wlan_objmgr_vdev * vdev,tpAddStaParams params,struct peer_assoc_params * req)1412*5113495bSYour Name static inline void wma_set_mlo_capability(tp_wma_handle wma,
1413*5113495bSYour Name 					  struct wlan_objmgr_vdev *vdev,
1414*5113495bSYour Name 					  tpAddStaParams params,
1415*5113495bSYour Name 					  struct peer_assoc_params *req)
1416*5113495bSYour Name {
1417*5113495bSYour Name }
1418*5113495bSYour Name 
wma_set_mlo_assoc_vdev(struct wlan_objmgr_vdev * vdev,struct peer_assoc_params * req)1419*5113495bSYour Name static inline void wma_set_mlo_assoc_vdev(struct wlan_objmgr_vdev *vdev,
1420*5113495bSYour Name 					  struct peer_assoc_params *req)
1421*5113495bSYour Name {
1422*5113495bSYour Name }
1423*5113495bSYour Name #endif
1424*5113495bSYour Name 
1425*5113495bSYour Name /**
1426*5113495bSYour Name  * wmi_unified_send_peer_assoc() - send peer assoc command to fw
1427*5113495bSYour Name  * @wma: wma handle
1428*5113495bSYour Name  * @nw_type: nw type
1429*5113495bSYour Name  * @params: add sta params
1430*5113495bSYour Name  *
1431*5113495bSYour Name  * This function send peer assoc command to firmware with
1432*5113495bSYour Name  * different parameters.
1433*5113495bSYour Name  *
1434*5113495bSYour Name  * Return: QDF_STATUS
1435*5113495bSYour Name  */
wma_send_peer_assoc(tp_wma_handle wma,tSirNwType nw_type,tpAddStaParams params)1436*5113495bSYour Name QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
1437*5113495bSYour Name 				    tSirNwType nw_type,
1438*5113495bSYour Name 				    tpAddStaParams params)
1439*5113495bSYour Name {
1440*5113495bSYour Name 	struct peer_assoc_params *cmd;
1441*5113495bSYour Name 	int32_t ret, max_rates, i;
1442*5113495bSYour Name 	uint8_t *rate_pos;
1443*5113495bSYour Name 	wmi_rate_set peer_legacy_rates, peer_ht_rates;
1444*5113495bSYour Name 	uint32_t num_peer_11b_rates = 0;
1445*5113495bSYour Name 	uint32_t num_peer_11a_rates = 0;
1446*5113495bSYour Name 	enum wlan_phymode phymode, vdev_phymode;
1447*5113495bSYour Name 	uint32_t peer_nss = 1;
1448*5113495bSYour Name 	struct wma_txrx_node *intr = NULL;
1449*5113495bSYour Name 	bool is_he;
1450*5113495bSYour Name 	bool is_eht;
1451*5113495bSYour Name 	QDF_STATUS status;
1452*5113495bSYour Name 	struct mac_context *mac = wma->mac_context;
1453*5113495bSYour Name 	struct wlan_channel *des_chan;
1454*5113495bSYour Name 	int32_t keymgmt, uccipher, authmode;
1455*5113495bSYour Name 
1456*5113495bSYour Name 	cmd = qdf_mem_malloc(sizeof(struct peer_assoc_params));
1457*5113495bSYour Name 	if (!cmd) {
1458*5113495bSYour Name 		wma_err("Failed to allocate peer_assoc_params param");
1459*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1460*5113495bSYour Name 	}
1461*5113495bSYour Name 
1462*5113495bSYour Name 	intr = &wma->interfaces[params->smesessionId];
1463*5113495bSYour Name 
1464*5113495bSYour Name 	wma_mask_tx_ht_rate(wma, params->supportedRates.supportedMCSSet);
1465*5113495bSYour Name 
1466*5113495bSYour Name 	qdf_mem_zero(&peer_legacy_rates, sizeof(wmi_rate_set));
1467*5113495bSYour Name 	qdf_mem_zero(&peer_ht_rates, sizeof(wmi_rate_set));
1468*5113495bSYour Name 	qdf_mem_zero(cmd, sizeof(struct peer_assoc_params));
1469*5113495bSYour Name 
1470*5113495bSYour Name 	is_he = wma_is_peer_he_capable(params);
1471*5113495bSYour Name 	is_eht = wma_is_peer_eht_capable(params);
1472*5113495bSYour Name 	if ((params->ch_width > CH_WIDTH_40MHZ) &&
1473*5113495bSYour Name 	    ((nw_type == eSIR_11G_NW_TYPE) ||
1474*5113495bSYour Name 	     (nw_type == eSIR_11B_NW_TYPE))) {
1475*5113495bSYour Name 		wma_err("ch_width %d sent in 11G, configure to 40MHz",
1476*5113495bSYour Name 			params->ch_width);
1477*5113495bSYour Name 		params->ch_width = CH_WIDTH_40MHZ;
1478*5113495bSYour Name 	}
1479*5113495bSYour Name 	phymode = wma_peer_phymode(nw_type, params->staType,
1480*5113495bSYour Name 				   params->htCapable, params->ch_width,
1481*5113495bSYour Name 				   params->vhtCapable, is_he, is_eht);
1482*5113495bSYour Name 
1483*5113495bSYour Name 	des_chan = wlan_vdev_mlme_get_des_chan(intr->vdev);
1484*5113495bSYour Name 	vdev_phymode = des_chan->ch_phymode;
1485*5113495bSYour Name 	if ((intr->type == WMI_VDEV_TYPE_AP) && (phymode > vdev_phymode)) {
1486*5113495bSYour Name 		wma_nofl_debug("Peer phymode %d is not allowed. Set it equal to sap/go phymode %d",
1487*5113495bSYour Name 			       phymode, vdev_phymode);
1488*5113495bSYour Name 		phymode = vdev_phymode;
1489*5113495bSYour Name 	}
1490*5113495bSYour Name 
1491*5113495bSYour Name 	if (!mac->mlme_cfg->rates.disable_abg_rate_txdata &&
1492*5113495bSYour Name 	    !WLAN_REG_IS_6GHZ_CHAN_FREQ(des_chan->ch_freq)) {
1493*5113495bSYour Name 		/* Legacy Rateset */
1494*5113495bSYour Name 		rate_pos = (uint8_t *) peer_legacy_rates.rates;
1495*5113495bSYour Name 		for (i = 0; i < SIR_NUM_11B_RATES; i++) {
1496*5113495bSYour Name 			if (!params->supportedRates.llbRates[i])
1497*5113495bSYour Name 				continue;
1498*5113495bSYour Name 			rate_pos[peer_legacy_rates.num_rates++] =
1499*5113495bSYour Name 				params->supportedRates.llbRates[i];
1500*5113495bSYour Name 			num_peer_11b_rates++;
1501*5113495bSYour Name 		}
1502*5113495bSYour Name 		for (i = 0; i < SIR_NUM_11A_RATES; i++) {
1503*5113495bSYour Name 			if (!params->supportedRates.llaRates[i])
1504*5113495bSYour Name 				continue;
1505*5113495bSYour Name 			rate_pos[peer_legacy_rates.num_rates++] =
1506*5113495bSYour Name 				params->supportedRates.llaRates[i];
1507*5113495bSYour Name 			num_peer_11a_rates++;
1508*5113495bSYour Name 		}
1509*5113495bSYour Name 	}
1510*5113495bSYour Name 
1511*5113495bSYour Name 	if ((phymode == WLAN_PHYMODE_11A && num_peer_11a_rates == 0) ||
1512*5113495bSYour Name 	    (phymode == WLAN_PHYMODE_11B && num_peer_11b_rates == 0)) {
1513*5113495bSYour Name 		wma_warn("Invalid phy rates. phymode 0x%x, 11b_rates %d, 11a_rates %d",
1514*5113495bSYour Name 			phymode, num_peer_11b_rates,
1515*5113495bSYour Name 			num_peer_11a_rates);
1516*5113495bSYour Name 		qdf_mem_free(cmd);
1517*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1518*5113495bSYour Name 	}
1519*5113495bSYour Name 
1520*5113495bSYour Name 	/* HT Rateset */
1521*5113495bSYour Name 	max_rates = sizeof(peer_ht_rates.rates) /
1522*5113495bSYour Name 		    sizeof(peer_ht_rates.rates[0]);
1523*5113495bSYour Name 	rate_pos = (uint8_t *) peer_ht_rates.rates;
1524*5113495bSYour Name 	for (i = 0; i < MAX_SUPPORTED_RATES; i++) {
1525*5113495bSYour Name 		if (params->supportedRates.supportedMCSSet[i / 8] &
1526*5113495bSYour Name 		    (1 << (i % 8))) {
1527*5113495bSYour Name 			rate_pos[peer_ht_rates.num_rates++] = i;
1528*5113495bSYour Name 			if (i >= 8) {
1529*5113495bSYour Name 				/* MCS8 or higher rate is present, must be 2x2 */
1530*5113495bSYour Name 				peer_nss = 2;
1531*5113495bSYour Name 			}
1532*5113495bSYour Name 		}
1533*5113495bSYour Name 		if (peer_ht_rates.num_rates == max_rates)
1534*5113495bSYour Name 			break;
1535*5113495bSYour Name 	}
1536*5113495bSYour Name 
1537*5113495bSYour Name 	if (params->htCapable && !peer_ht_rates.num_rates) {
1538*5113495bSYour Name 		uint8_t temp_ni_rates[8] = { 0x0, 0x1, 0x2, 0x3,
1539*5113495bSYour Name 					     0x4, 0x5, 0x6, 0x7};
1540*5113495bSYour Name 		/*
1541*5113495bSYour Name 		 * Workaround for EV 116382: The peer is marked HT but with
1542*5113495bSYour Name 		 * supported rx mcs set is set to 0. 11n spec mandates MCS0-7
1543*5113495bSYour Name 		 * for a HT STA. So forcing the supported rx mcs rate to
1544*5113495bSYour Name 		 * MCS 0-7. This workaround will be removed once we get
1545*5113495bSYour Name 		 * clarification from WFA regarding this STA behavior.
1546*5113495bSYour Name 		 */
1547*5113495bSYour Name 
1548*5113495bSYour Name 		/* TODO: Do we really need this? */
1549*5113495bSYour Name 		wma_warn("Peer is marked as HT capable but supported mcs rate is 0");
1550*5113495bSYour Name 		peer_ht_rates.num_rates = sizeof(temp_ni_rates);
1551*5113495bSYour Name 		qdf_mem_copy((uint8_t *) peer_ht_rates.rates, temp_ni_rates,
1552*5113495bSYour Name 			     peer_ht_rates.num_rates);
1553*5113495bSYour Name 	}
1554*5113495bSYour Name 
1555*5113495bSYour Name 	/* in ap mode and for tdls peer, use mac address of the peer in
1556*5113495bSYour Name 	 * the other end as the new peer address; in sta mode, use bss id to
1557*5113495bSYour Name 	 * be the new peer address
1558*5113495bSYour Name 	 */
1559*5113495bSYour Name 	if ((wma_is_vdev_in_ap_mode(wma, params->smesessionId))
1560*5113495bSYour Name #ifdef FEATURE_WLAN_TDLS
1561*5113495bSYour Name 	    || (STA_ENTRY_TDLS_PEER == params->staType)
1562*5113495bSYour Name #endif /* FEATURE_WLAN_TDLS */
1563*5113495bSYour Name 	    ) {
1564*5113495bSYour Name 		qdf_mem_copy(cmd->peer_mac, params->staMac,
1565*5113495bSYour Name 						sizeof(cmd->peer_mac));
1566*5113495bSYour Name 	} else {
1567*5113495bSYour Name 		qdf_mem_copy(cmd->peer_mac, params->bssId,
1568*5113495bSYour Name 						sizeof(cmd->peer_mac));
1569*5113495bSYour Name 	}
1570*5113495bSYour Name 	wma_objmgr_set_peer_mlme_phymode(wma, cmd->peer_mac, phymode);
1571*5113495bSYour Name 
1572*5113495bSYour Name 	cmd->vdev_id = params->smesessionId;
1573*5113495bSYour Name 	cmd->peer_new_assoc = 1;
1574*5113495bSYour Name 	cmd->peer_associd = params->assocId;
1575*5113495bSYour Name 
1576*5113495bSYour Name 	cmd->is_wme_set = 1;
1577*5113495bSYour Name 
1578*5113495bSYour Name 	if (params->wmmEnabled)
1579*5113495bSYour Name 		cmd->qos_flag = 1;
1580*5113495bSYour Name 
1581*5113495bSYour Name 	if (params->uAPSD) {
1582*5113495bSYour Name 		cmd->apsd_flag = 1;
1583*5113495bSYour Name 		wma_nofl_debug("Set WMI_PEER_APSD: uapsd Mask %d",
1584*5113495bSYour Name 			       params->uAPSD);
1585*5113495bSYour Name 	}
1586*5113495bSYour Name 
1587*5113495bSYour Name 	if (params->htCapable) {
1588*5113495bSYour Name 		cmd->ht_flag = 1;
1589*5113495bSYour Name 		cmd->qos_flag = 1;
1590*5113495bSYour Name 		cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
1591*5113495bSYour Name 	}
1592*5113495bSYour Name 
1593*5113495bSYour Name 	if (params->vhtCapable) {
1594*5113495bSYour Name 		cmd->ht_flag = 1;
1595*5113495bSYour Name 		cmd->qos_flag = 1;
1596*5113495bSYour Name 		cmd->vht_flag = 1;
1597*5113495bSYour Name 		cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
1598*5113495bSYour Name 	}
1599*5113495bSYour Name 
1600*5113495bSYour Name 	if (params->ch_width) {
1601*5113495bSYour Name 		cmd->peer_rate_caps |= WMI_RC_CW40_FLAG;
1602*5113495bSYour Name 		if (params->fShortGI40Mhz)
1603*5113495bSYour Name 			cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
1604*5113495bSYour Name 	} else if (params->fShortGI20Mhz) {
1605*5113495bSYour Name 		cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
1606*5113495bSYour Name 	}
1607*5113495bSYour Name 
1608*5113495bSYour Name 	switch (params->ch_width) {
1609*5113495bSYour Name 	case CH_WIDTH_320MHZ:
1610*5113495bSYour Name 		wma_set_peer_assoc_params_bw_320(cmd, params->ch_width);
1611*5113495bSYour Name 		fallthrough;
1612*5113495bSYour Name 	case CH_WIDTH_80P80MHZ:
1613*5113495bSYour Name 	case CH_WIDTH_160MHZ:
1614*5113495bSYour Name 		cmd->bw_160 = 1;
1615*5113495bSYour Name 		fallthrough;
1616*5113495bSYour Name 	case CH_WIDTH_80MHZ:
1617*5113495bSYour Name 		cmd->bw_80 = 1;
1618*5113495bSYour Name 		fallthrough;
1619*5113495bSYour Name 	case CH_WIDTH_40MHZ:
1620*5113495bSYour Name 		cmd->bw_40 = 1;
1621*5113495bSYour Name 		fallthrough;
1622*5113495bSYour Name 	default:
1623*5113495bSYour Name 		break;
1624*5113495bSYour Name 	}
1625*5113495bSYour Name 
1626*5113495bSYour Name 	cmd->peer_vht_caps = params->vht_caps;
1627*5113495bSYour Name 	if (params->p2pCapableSta) {
1628*5113495bSYour Name 		cmd->p2p_capable_sta = 1;
1629*5113495bSYour Name 		wma_objmgr_set_peer_mlme_type(wma, params->staMac,
1630*5113495bSYour Name 					      WLAN_PEER_P2P_CLI);
1631*5113495bSYour Name 	}
1632*5113495bSYour Name 
1633*5113495bSYour Name 	if (params->rmfEnabled)
1634*5113495bSYour Name 		cmd->is_pmf_enabled = 1;
1635*5113495bSYour Name 
1636*5113495bSYour Name 	if (params->stbc_capable)
1637*5113495bSYour Name 		cmd->stbc_flag = 1;
1638*5113495bSYour Name 
1639*5113495bSYour Name 	if (params->htLdpcCapable || params->vhtLdpcCapable)
1640*5113495bSYour Name 		cmd->ldpc_flag = 1;
1641*5113495bSYour Name 
1642*5113495bSYour Name 	switch (params->mimoPS) {
1643*5113495bSYour Name 	case eSIR_HT_MIMO_PS_STATIC:
1644*5113495bSYour Name 		cmd->static_mimops_flag = 1;
1645*5113495bSYour Name 		break;
1646*5113495bSYour Name 	case eSIR_HT_MIMO_PS_DYNAMIC:
1647*5113495bSYour Name 		cmd->dynamic_mimops_flag = 1;
1648*5113495bSYour Name 		break;
1649*5113495bSYour Name 	case eSIR_HT_MIMO_PS_NO_LIMIT:
1650*5113495bSYour Name 		cmd->spatial_mux_flag = 1;
1651*5113495bSYour Name 		break;
1652*5113495bSYour Name 	default:
1653*5113495bSYour Name 		break;
1654*5113495bSYour Name 	}
1655*5113495bSYour Name 
1656*5113495bSYour Name 	wma_set_twt_peer_caps(params, cmd);
1657*5113495bSYour Name #ifdef FEATURE_WLAN_TDLS
1658*5113495bSYour Name 	if (STA_ENTRY_TDLS_PEER == params->staType)
1659*5113495bSYour Name 		cmd->auth_flag = 1;
1660*5113495bSYour Name #endif /* FEATURE_WLAN_TDLS */
1661*5113495bSYour Name 
1662*5113495bSYour Name 	if (params->wpa_rsn
1663*5113495bSYour Name #ifdef FEATURE_WLAN_WAPI
1664*5113495bSYour Name 	    || params->encryptType == eSIR_ED_WPI
1665*5113495bSYour Name #endif /* FEATURE_WLAN_WAPI */
1666*5113495bSYour Name 	    ) {
1667*5113495bSYour Name 		if (!params->no_ptk_4_way) {
1668*5113495bSYour Name 			cmd->need_ptk_4_way = 1;
1669*5113495bSYour Name 			wlan_acquire_peer_key_wakelock(wma->pdev,
1670*5113495bSYour Name 						       cmd->peer_mac);
1671*5113495bSYour Name 		}
1672*5113495bSYour Name 	}
1673*5113495bSYour Name 
1674*5113495bSYour Name 	if (params->wpa_rsn >> 1)
1675*5113495bSYour Name 		cmd->need_gtk_2_way = 1;
1676*5113495bSYour Name 
1677*5113495bSYour Name #ifdef FEATURE_WLAN_WAPI
1678*5113495bSYour Name 	if (params->encryptType == eSIR_ED_WPI) {
1679*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle, params->smesessionId,
1680*5113495bSYour Name 				      wmi_vdev_param_drop_unencry, false);
1681*5113495bSYour Name 		if (ret) {
1682*5113495bSYour Name 			wma_err("Set wmi_vdev_param_drop_unencry Param status:%d",
1683*5113495bSYour Name 				ret);
1684*5113495bSYour Name 			qdf_mem_free(cmd);
1685*5113495bSYour Name 			return ret;
1686*5113495bSYour Name 		}
1687*5113495bSYour Name 	}
1688*5113495bSYour Name #endif /* FEATURE_WLAN_WAPI */
1689*5113495bSYour Name 
1690*5113495bSYour Name 	cmd->peer_caps = params->capab_info;
1691*5113495bSYour Name 	cmd->peer_listen_intval = params->listenInterval;
1692*5113495bSYour Name 	cmd->peer_ht_caps = params->ht_caps;
1693*5113495bSYour Name 	cmd->peer_max_mpdu = (1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
1694*5113495bSYour Name 				    params->maxAmpduSize)) - 1;
1695*5113495bSYour Name 	cmd->peer_mpdu_density = wma_parse_mpdudensity(params->maxAmpduDensity);
1696*5113495bSYour Name 
1697*5113495bSYour Name 	if (params->supportedRates.supportedMCSSet[1] &&
1698*5113495bSYour Name 	    params->supportedRates.supportedMCSSet[2])
1699*5113495bSYour Name 		cmd->peer_rate_caps |= WMI_RC_TS_FLAG;
1700*5113495bSYour Name 	else if (params->supportedRates.supportedMCSSet[1])
1701*5113495bSYour Name 		cmd->peer_rate_caps |= WMI_RC_DS_FLAG;
1702*5113495bSYour Name 
1703*5113495bSYour Name 	/* Update peer legacy rate information */
1704*5113495bSYour Name 	cmd->peer_legacy_rates.num_rates = peer_legacy_rates.num_rates;
1705*5113495bSYour Name 	qdf_mem_copy(cmd->peer_legacy_rates.rates, peer_legacy_rates.rates,
1706*5113495bSYour Name 		     peer_legacy_rates.num_rates);
1707*5113495bSYour Name 
1708*5113495bSYour Name 	/* Update peer HT rate information */
1709*5113495bSYour Name 	cmd->peer_ht_rates.num_rates = peer_ht_rates.num_rates;
1710*5113495bSYour Name 	qdf_mem_copy(cmd->peer_ht_rates.rates, peer_ht_rates.rates,
1711*5113495bSYour Name 				 peer_ht_rates.num_rates);
1712*5113495bSYour Name 
1713*5113495bSYour Name 	/* VHT Rates */
1714*5113495bSYour Name 
1715*5113495bSYour Name 	cmd->peer_nss = peer_nss;
1716*5113495bSYour Name 	/*
1717*5113495bSYour Name 	 * Because of DBS a vdev may come up in any of the two MACs with
1718*5113495bSYour Name 	 * different capabilities. STBC capab should be fetched for given
1719*5113495bSYour Name 	 * hard_mode->MAC_id combo. It is planned that firmware should provide
1720*5113495bSYour Name 	 * these dev capabilities. But for now number of tx streams can be used
1721*5113495bSYour Name 	 * to identify if Tx STBC needs to be disabled.
1722*5113495bSYour Name 	 */
1723*5113495bSYour Name 	if (intr->tx_streams < 2) {
1724*5113495bSYour Name 		cmd->peer_vht_caps &= ~(1 << SIR_MAC_VHT_CAP_TXSTBC);
1725*5113495bSYour Name 		wma_nofl_debug("Num tx_streams: %d, Disabled txSTBC",
1726*5113495bSYour Name 			       intr->tx_streams);
1727*5113495bSYour Name 	}
1728*5113495bSYour Name 
1729*5113495bSYour Name 	cmd->vht_capable = params->vhtCapable;
1730*5113495bSYour Name 	if (params->vhtCapable) {
1731*5113495bSYour Name #define VHT2x2MCSMASK 0xc
1732*5113495bSYour Name 		cmd->rx_max_rate = params->supportedRates.vhtRxHighestDataRate;
1733*5113495bSYour Name 		cmd->rx_mcs_set = params->supportedRates.vhtRxMCSMap;
1734*5113495bSYour Name 		cmd->tx_max_rate = params->supportedRates.vhtTxHighestDataRate;
1735*5113495bSYour Name 		cmd->tx_mcs_set = params->supportedRates.vhtTxMCSMap;
1736*5113495bSYour Name 		/*
1737*5113495bSYour Name 		 *  tx_mcs_set is intersection of self tx NSS and peer rx mcs map
1738*5113495bSYour Name 		 */
1739*5113495bSYour Name 		if (params->vhtSupportedRxNss)
1740*5113495bSYour Name 			cmd->peer_nss = params->vhtSupportedRxNss;
1741*5113495bSYour Name 		else
1742*5113495bSYour Name 			cmd->peer_nss = ((cmd->tx_mcs_set & VHT2x2MCSMASK)
1743*5113495bSYour Name 					== VHT2x2MCSMASK) ? 1 : 2;
1744*5113495bSYour Name 
1745*5113495bSYour Name 		if (params->vht_mcs_10_11_supp) {
1746*5113495bSYour Name 			WMI_SET_BITS(cmd->tx_mcs_set, 16, cmd->peer_nss,
1747*5113495bSYour Name 				     ((1 << cmd->peer_nss) - 1));
1748*5113495bSYour Name 			WMI_VHT_MCS_NOTIFY_EXT_SS_SET(cmd->tx_mcs_set, 1);
1749*5113495bSYour Name 		}
1750*5113495bSYour Name 		if (params->vht_extended_nss_bw_cap &&
1751*5113495bSYour Name 		    (params->vht_160mhz_nss || params->vht_80p80mhz_nss)) {
1752*5113495bSYour Name 			/*
1753*5113495bSYour Name 			 * bit[2:0] : Represents value of Rx NSS for 160 MHz
1754*5113495bSYour Name 			 * bit[5:3] : Represents value of Rx NSS for 80_80 MHz
1755*5113495bSYour Name 			 *             Extended NSS support
1756*5113495bSYour Name 			 * bit[30:6]: Reserved
1757*5113495bSYour Name 			 * bit[31]  : MSB(0/1): 1 in case of valid data
1758*5113495bSYour Name 			 */
1759*5113495bSYour Name 			cmd->peer_bw_rxnss_override |= (1 << 31);
1760*5113495bSYour Name 			if (params->vht_160mhz_nss)
1761*5113495bSYour Name 				cmd->peer_bw_rxnss_override |=
1762*5113495bSYour Name 					(params->vht_160mhz_nss - 1);
1763*5113495bSYour Name 			if (params->vht_80p80mhz_nss)
1764*5113495bSYour Name 				cmd->peer_bw_rxnss_override |=
1765*5113495bSYour Name 					((params->vht_80p80mhz_nss - 1) << 3);
1766*5113495bSYour Name 			wma_debug("peer_bw_rxnss_override %0X",
1767*5113495bSYour Name 				  cmd->peer_bw_rxnss_override);
1768*5113495bSYour Name 		}
1769*5113495bSYour Name 	}
1770*5113495bSYour Name 
1771*5113495bSYour Name 	wma_set_mlo_capability(wma, intr->vdev, params, cmd);
1772*5113495bSYour Name 
1773*5113495bSYour Name 	wma_set_mlo_assoc_vdev(intr->vdev, cmd);
1774*5113495bSYour Name 
1775*5113495bSYour Name 	wma_debug("rx_max_rate %d, rx_mcs %x, tx_max_rate %d, tx_mcs: %x num rates %d need 4 way %d",
1776*5113495bSYour Name 		  cmd->rx_max_rate, cmd->rx_mcs_set, cmd->tx_max_rate,
1777*5113495bSYour Name 		  cmd->tx_mcs_set, peer_ht_rates.num_rates,
1778*5113495bSYour Name 		  cmd->need_ptk_4_way);
1779*5113495bSYour Name 
1780*5113495bSYour Name 	/*
1781*5113495bSYour Name 	 * Limit nss to max number of rf chain supported by target
1782*5113495bSYour Name 	 * Otherwise Fw will crash
1783*5113495bSYour Name 	 */
1784*5113495bSYour Name 	if (cmd->peer_nss > WMA_MAX_NSS) {
1785*5113495bSYour Name 		wma_err("peer Nss %d is more than supported", cmd->peer_nss);
1786*5113495bSYour Name 		cmd->peer_nss = WMA_MAX_NSS;
1787*5113495bSYour Name 	}
1788*5113495bSYour Name 
1789*5113495bSYour Name 	wma_populate_peer_he_cap(cmd, params);
1790*5113495bSYour Name 	wma_populate_peer_eht_cap(cmd, params);
1791*5113495bSYour Name 	wma_populate_peer_puncture(cmd, des_chan);
1792*5113495bSYour Name 	wma_populate_peer_mlo_cap(cmd, params);
1793*5113495bSYour Name 	if (!wma_is_vdev_in_ap_mode(wma, params->smesessionId))
1794*5113495bSYour Name 		intr->nss = cmd->peer_nss;
1795*5113495bSYour Name 	wma_objmgr_set_peer_mlme_nss(wma, cmd->peer_mac, cmd->peer_nss);
1796*5113495bSYour Name 
1797*5113495bSYour Name 	/* Till conversion is not done in WMI we need to fill fw phy mode */
1798*5113495bSYour Name 	cmd->peer_phymode = wmi_host_to_fw_phymode(phymode);
1799*5113495bSYour Name 
1800*5113495bSYour Name 	keymgmt = wlan_crypto_get_param(intr->vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
1801*5113495bSYour Name 	authmode = wlan_crypto_get_param(intr->vdev,
1802*5113495bSYour Name 					 WLAN_CRYPTO_PARAM_AUTH_MODE);
1803*5113495bSYour Name 	uccipher = wlan_crypto_get_param(intr->vdev,
1804*5113495bSYour Name 					 WLAN_CRYPTO_PARAM_UCAST_CIPHER);
1805*5113495bSYour Name 
1806*5113495bSYour Name 	cmd->akm = cm_crypto_authmode_to_wmi_authmode(authmode,
1807*5113495bSYour Name 						      keymgmt,
1808*5113495bSYour Name 						      uccipher);
1809*5113495bSYour Name 
1810*5113495bSYour Name 	status = wmi_unified_peer_assoc_send(wma->wmi_handle,
1811*5113495bSYour Name 					 cmd);
1812*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
1813*5113495bSYour Name 		wma_alert("Failed to send peer assoc command status = %d",
1814*5113495bSYour Name 			 status);
1815*5113495bSYour Name 	qdf_mem_free(cmd);
1816*5113495bSYour Name 
1817*5113495bSYour Name 	return status;
1818*5113495bSYour Name }
1819*5113495bSYour Name 
1820*5113495bSYour Name /**
1821*5113495bSYour Name  * wmi_unified_vdev_set_gtx_cfg_send() - set GTX params
1822*5113495bSYour Name  * @wmi_handle: wmi handle
1823*5113495bSYour Name  * @if_id: vdev id
1824*5113495bSYour Name  * @gtx_info: GTX config params
1825*5113495bSYour Name  *
1826*5113495bSYour Name  * This function set GTX related params in firmware.
1827*5113495bSYour Name  *
1828*5113495bSYour Name  * Return: 0 for success or error code
1829*5113495bSYour Name  */
wmi_unified_vdev_set_gtx_cfg_send(wmi_unified_t wmi_handle,uint32_t if_id,gtx_config_t * gtx_info)1830*5113495bSYour Name QDF_STATUS wmi_unified_vdev_set_gtx_cfg_send(wmi_unified_t wmi_handle,
1831*5113495bSYour Name 				  uint32_t if_id,
1832*5113495bSYour Name 				  gtx_config_t *gtx_info)
1833*5113495bSYour Name {
1834*5113495bSYour Name 	struct wmi_gtx_config params;
1835*5113495bSYour Name 
1836*5113495bSYour Name 	params.gtx_rt_mask[0] = gtx_info->gtxRTMask[0];
1837*5113495bSYour Name 	params.gtx_rt_mask[1] = gtx_info->gtxRTMask[1];
1838*5113495bSYour Name 	params.gtx_usrcfg = gtx_info->gtxUsrcfg;
1839*5113495bSYour Name 	params.gtx_threshold = gtx_info->gtxPERThreshold;
1840*5113495bSYour Name 	params.gtx_margin = gtx_info->gtxPERMargin;
1841*5113495bSYour Name 	params.gtx_tpcstep = gtx_info->gtxTPCstep;
1842*5113495bSYour Name 	params.gtx_tpcmin = gtx_info->gtxTPCMin;
1843*5113495bSYour Name 	params.gtx_bwmask = gtx_info->gtxBWMask;
1844*5113495bSYour Name 
1845*5113495bSYour Name 	return wmi_unified_vdev_set_gtx_cfg_cmd(wmi_handle,
1846*5113495bSYour Name 						if_id, &params);
1847*5113495bSYour Name 
1848*5113495bSYour Name }
1849*5113495bSYour Name 
1850*5113495bSYour Name /**
1851*5113495bSYour Name  * wma_update_protection_mode() - update protection mode
1852*5113495bSYour Name  * @wma: wma handle
1853*5113495bSYour Name  * @vdev_id: vdev id
1854*5113495bSYour Name  * @llbcoexist: protection mode info
1855*5113495bSYour Name  *
1856*5113495bSYour Name  * This function set protection mode(RTS/CTS) to fw for passed vdev id.
1857*5113495bSYour Name  *
1858*5113495bSYour Name  * Return: none
1859*5113495bSYour Name  */
wma_update_protection_mode(tp_wma_handle wma,uint8_t vdev_id,uint8_t llbcoexist)1860*5113495bSYour Name void wma_update_protection_mode(tp_wma_handle wma, uint8_t vdev_id,
1861*5113495bSYour Name 			   uint8_t llbcoexist)
1862*5113495bSYour Name {
1863*5113495bSYour Name 	QDF_STATUS ret;
1864*5113495bSYour Name 	enum ieee80211_protmode prot_mode;
1865*5113495bSYour Name 
1866*5113495bSYour Name 	prot_mode = llbcoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE;
1867*5113495bSYour Name 
1868*5113495bSYour Name 	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1869*5113495bSYour Name 					      wmi_vdev_param_protection_mode,
1870*5113495bSYour Name 					      prot_mode);
1871*5113495bSYour Name 
1872*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1873*5113495bSYour Name 		wma_err("Failed to send wmi protection mode cmd");
1874*5113495bSYour Name 	else
1875*5113495bSYour Name 		wma_nofl_debug("Updated protection mode %d to target",
1876*5113495bSYour Name 			       prot_mode);
1877*5113495bSYour Name }
1878*5113495bSYour Name 
1879*5113495bSYour Name void
wma_update_beacon_interval(tp_wma_handle wma,uint8_t vdev_id,uint16_t beaconInterval)1880*5113495bSYour Name wma_update_beacon_interval(tp_wma_handle wma, uint8_t vdev_id,
1881*5113495bSYour Name 			   uint16_t beaconInterval)
1882*5113495bSYour Name {
1883*5113495bSYour Name 	QDF_STATUS ret;
1884*5113495bSYour Name 
1885*5113495bSYour Name 	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1886*5113495bSYour Name 					      wmi_vdev_param_beacon_interval,
1887*5113495bSYour Name 					      beaconInterval);
1888*5113495bSYour Name 
1889*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1890*5113495bSYour Name 		wma_err("Failed to update beacon interval");
1891*5113495bSYour Name 	else
1892*5113495bSYour Name 		wma_info("Updated beacon interval %d for vdev %d",
1893*5113495bSYour Name 			 beaconInterval, vdev_id);
1894*5113495bSYour Name }
1895*5113495bSYour Name 
1896*5113495bSYour Name #ifdef WLAN_FEATURE_11AX_BSS_COLOR
1897*5113495bSYour Name /**
1898*5113495bSYour Name  * wma_update_bss_color() - update beacon bss color in fw
1899*5113495bSYour Name  * @wma: wma handle
1900*5113495bSYour Name  * @vdev_id: vdev id
1901*5113495bSYour Name  * @he_ops: HE operation, only the bss_color and bss_color_disabled fields
1902*5113495bSYour Name  * are updated.
1903*5113495bSYour Name  *
1904*5113495bSYour Name  * Return: none
1905*5113495bSYour Name  */
1906*5113495bSYour Name static void
wma_update_bss_color(tp_wma_handle wma,uint8_t vdev_id,tUpdateBeaconParams * bcn_params)1907*5113495bSYour Name wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
1908*5113495bSYour Name 		     tUpdateBeaconParams *bcn_params)
1909*5113495bSYour Name {
1910*5113495bSYour Name 	QDF_STATUS ret;
1911*5113495bSYour Name 	uint32_t dword_he_ops = 0;
1912*5113495bSYour Name 
1913*5113495bSYour Name 	WMI_HEOPS_COLOR_SET(dword_he_ops, bcn_params->bss_color);
1914*5113495bSYour Name 	WMI_HEOPS_BSSCOLORDISABLE_SET(dword_he_ops,
1915*5113495bSYour Name 				bcn_params->bss_color_disabled);
1916*5113495bSYour Name 	wma_nofl_debug("vdev: %d, update bss color, HE_OPS: 0x%x",
1917*5113495bSYour Name 		       vdev_id, dword_he_ops);
1918*5113495bSYour Name 	ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1919*5113495bSYour Name 			      wmi_vdev_param_he_bss_color, dword_he_ops);
1920*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1921*5113495bSYour Name 		wma_err("Failed to update HE operations");
1922*5113495bSYour Name }
1923*5113495bSYour Name #else
wma_update_bss_color(tp_wma_handle wma,uint8_t vdev_id,tUpdateBeaconParams * bcn_params)1924*5113495bSYour Name static void wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
1925*5113495bSYour Name 			   tUpdateBeaconParams *bcn_params)
1926*5113495bSYour Name {
1927*5113495bSYour Name }
1928*5113495bSYour Name #endif
1929*5113495bSYour Name 
1930*5113495bSYour Name /**
1931*5113495bSYour Name  * wma_process_update_beacon_params() - update beacon parameters to target
1932*5113495bSYour Name  * @wma: wma handle
1933*5113495bSYour Name  * @bcn_params: beacon parameters
1934*5113495bSYour Name  *
1935*5113495bSYour Name  * Return: none
1936*5113495bSYour Name  */
1937*5113495bSYour Name void
wma_process_update_beacon_params(tp_wma_handle wma,tUpdateBeaconParams * bcn_params)1938*5113495bSYour Name wma_process_update_beacon_params(tp_wma_handle wma,
1939*5113495bSYour Name 				 tUpdateBeaconParams *bcn_params)
1940*5113495bSYour Name {
1941*5113495bSYour Name 	if (!bcn_params) {
1942*5113495bSYour Name 		wma_err("bcn_params NULL");
1943*5113495bSYour Name 		return;
1944*5113495bSYour Name 	}
1945*5113495bSYour Name 
1946*5113495bSYour Name 	if (bcn_params->vdev_id >= wma->max_bssid) {
1947*5113495bSYour Name 		wma_err("Invalid vdev id %d", bcn_params->vdev_id);
1948*5113495bSYour Name 		return;
1949*5113495bSYour Name 	}
1950*5113495bSYour Name 
1951*5113495bSYour Name 	if (bcn_params->paramChangeBitmap & PARAM_BCN_INTERVAL_CHANGED) {
1952*5113495bSYour Name 		wma_update_beacon_interval(wma, bcn_params->vdev_id,
1953*5113495bSYour Name 					   bcn_params->beaconInterval);
1954*5113495bSYour Name 	}
1955*5113495bSYour Name 
1956*5113495bSYour Name 	if (bcn_params->paramChangeBitmap & PARAM_llBCOEXIST_CHANGED)
1957*5113495bSYour Name 		wma_update_protection_mode(wma, bcn_params->vdev_id,
1958*5113495bSYour Name 					   bcn_params->llbCoexist);
1959*5113495bSYour Name 
1960*5113495bSYour Name 	if (bcn_params->paramChangeBitmap & PARAM_BSS_COLOR_CHANGED)
1961*5113495bSYour Name 		wma_update_bss_color(wma, bcn_params->vdev_id,
1962*5113495bSYour Name 				     bcn_params);
1963*5113495bSYour Name }
1964*5113495bSYour Name 
wma_update_rts_params(tp_wma_handle wma,uint32_t value)1965*5113495bSYour Name void wma_update_rts_params(tp_wma_handle wma, uint32_t value)
1966*5113495bSYour Name {
1967*5113495bSYour Name 	uint8_t vdev_id;
1968*5113495bSYour Name 	QDF_STATUS ret;
1969*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1970*5113495bSYour Name 
1971*5113495bSYour Name 	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
1972*5113495bSYour Name 		vdev = wma->interfaces[vdev_id].vdev;
1973*5113495bSYour Name 		if (!vdev)
1974*5113495bSYour Name 			continue;
1975*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle,
1976*5113495bSYour Name 					 vdev_id,
1977*5113495bSYour Name 					 wmi_vdev_param_rts_threshold,
1978*5113495bSYour Name 					 value);
1979*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret))
1980*5113495bSYour Name 			wma_err("Update cfg param fail for vdevId %d", vdev_id);
1981*5113495bSYour Name 	}
1982*5113495bSYour Name }
1983*5113495bSYour Name 
wma_update_frag_params(tp_wma_handle wma,uint32_t value)1984*5113495bSYour Name void wma_update_frag_params(tp_wma_handle wma, uint32_t value)
1985*5113495bSYour Name {
1986*5113495bSYour Name 	uint8_t vdev_id;
1987*5113495bSYour Name 	QDF_STATUS ret;
1988*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1989*5113495bSYour Name 
1990*5113495bSYour Name 	for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
1991*5113495bSYour Name 		vdev = wma->interfaces[vdev_id].vdev;
1992*5113495bSYour Name 		if (!vdev)
1993*5113495bSYour Name 			continue;
1994*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1995*5113495bSYour Name 					 wmi_vdev_param_fragmentation_threshold,
1996*5113495bSYour Name 					 value);
1997*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret))
1998*5113495bSYour Name 			wma_err("Update cfg params failed for vdevId %d",
1999*5113495bSYour Name 				 vdev_id);
2000*5113495bSYour Name 	}
2001*5113495bSYour Name }
2002*5113495bSYour Name 
2003*5113495bSYour Name /**
2004*5113495bSYour Name  * wma_process_update_edca_param_req() - update EDCA params
2005*5113495bSYour Name  * @handle: wma handle
2006*5113495bSYour Name  * @edca_params: edca parameters
2007*5113495bSYour Name  *
2008*5113495bSYour Name  * This function updates EDCA parameters to the target
2009*5113495bSYour Name  *
2010*5113495bSYour Name  * Return: QDF Status
2011*5113495bSYour Name  */
wma_process_update_edca_param_req(WMA_HANDLE handle,tEdcaParams * edca_params)2012*5113495bSYour Name QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle,
2013*5113495bSYour Name 					     tEdcaParams *edca_params)
2014*5113495bSYour Name {
2015*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
2016*5113495bSYour Name 	struct wmi_host_wme_vparams wmm_param[QCA_WLAN_AC_ALL];
2017*5113495bSYour Name 	tSirMacEdcaParamRecord *edca_record;
2018*5113495bSYour Name 	int ac;
2019*5113495bSYour Name 	struct ol_tx_wmm_param_t ol_tx_wmm_param;
2020*5113495bSYour Name 	uint8_t vdev_id;
2021*5113495bSYour Name 	QDF_STATUS status;
2022*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2023*5113495bSYour Name 	uint8_t *debug_str;
2024*5113495bSYour Name 	uint32_t len = 0;
2025*5113495bSYour Name 
2026*5113495bSYour Name 	vdev_id = edca_params->vdev_id;
2027*5113495bSYour Name 	if (!wma_is_vdev_valid(vdev_id)) {
2028*5113495bSYour Name 		wma_err("vdev id:%d is not active ", vdev_id);
2029*5113495bSYour Name 		goto fail;
2030*5113495bSYour Name 	}
2031*5113495bSYour Name 
2032*5113495bSYour Name 	debug_str = qdf_mem_malloc(WMA_WMM_DEBUG_STRING_SIZE);
2033*5113495bSYour Name 	if (!debug_str)
2034*5113495bSYour Name 		goto fail;
2035*5113495bSYour Name 
2036*5113495bSYour Name 	for (ac = 0; ac < QCA_WLAN_AC_ALL; ac++) {
2037*5113495bSYour Name 		switch (ac) {
2038*5113495bSYour Name 		case QCA_WLAN_AC_BE:
2039*5113495bSYour Name 			edca_record = &edca_params->acbe;
2040*5113495bSYour Name 			break;
2041*5113495bSYour Name 		case QCA_WLAN_AC_BK:
2042*5113495bSYour Name 			edca_record = &edca_params->acbk;
2043*5113495bSYour Name 			break;
2044*5113495bSYour Name 		case QCA_WLAN_AC_VI:
2045*5113495bSYour Name 			edca_record = &edca_params->acvi;
2046*5113495bSYour Name 			break;
2047*5113495bSYour Name 		case QCA_WLAN_AC_VO:
2048*5113495bSYour Name 			edca_record = &edca_params->acvo;
2049*5113495bSYour Name 			break;
2050*5113495bSYour Name 		default:
2051*5113495bSYour Name 			qdf_mem_free(debug_str);
2052*5113495bSYour Name 			goto fail;
2053*5113495bSYour Name 		}
2054*5113495bSYour Name 
2055*5113495bSYour Name 		wma_update_edca_params_for_ac(edca_record, &wmm_param[ac], ac,
2056*5113495bSYour Name 					      edca_params->mu_edca_params,
2057*5113495bSYour Name 					      debug_str,
2058*5113495bSYour Name 					      WMA_WMM_DEBUG_STRING_SIZE, &len);
2059*5113495bSYour Name 
2060*5113495bSYour Name 		ol_tx_wmm_param.ac[ac].aifs = wmm_param[ac].aifs;
2061*5113495bSYour Name 		ol_tx_wmm_param.ac[ac].cwmin = wmm_param[ac].cwmin;
2062*5113495bSYour Name 		ol_tx_wmm_param.ac[ac].cwmax = wmm_param[ac].cwmax;
2063*5113495bSYour Name 	}
2064*5113495bSYour Name 
2065*5113495bSYour Name 	wma_nofl_debug("WMM params: %s", debug_str);
2066*5113495bSYour Name 	qdf_mem_free(debug_str);
2067*5113495bSYour Name 
2068*5113495bSYour Name 	status = wmi_unified_process_update_edca_param(wma_handle->wmi_handle,
2069*5113495bSYour Name 						vdev_id,
2070*5113495bSYour Name 						edca_params->mu_edca_params,
2071*5113495bSYour Name 						wmm_param);
2072*5113495bSYour Name 	if (status == QDF_STATUS_E_NOMEM)
2073*5113495bSYour Name 		return status;
2074*5113495bSYour Name 	else if (status == QDF_STATUS_E_FAILURE)
2075*5113495bSYour Name 		goto fail;
2076*5113495bSYour Name 
2077*5113495bSYour Name 	cdp_set_wmm_param(soc, WMI_PDEV_ID_SOC, ol_tx_wmm_param);
2078*5113495bSYour Name 
2079*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2080*5113495bSYour Name 
2081*5113495bSYour Name fail:
2082*5113495bSYour Name 	wma_err("Failed to set WMM Parameters");
2083*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
2084*5113495bSYour Name }
2085*5113495bSYour Name 
2086*5113495bSYour Name /**
2087*5113495bSYour Name  * wmi_unified_probe_rsp_tmpl_send() - send probe response template to fw
2088*5113495bSYour Name  * @wma: wma handle
2089*5113495bSYour Name  * @vdev_id: vdev id
2090*5113495bSYour Name  * @probe_rsp_info: probe response info
2091*5113495bSYour Name  *
2092*5113495bSYour Name  * Return: 0 for success or error code
2093*5113495bSYour Name  */
wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma,uint8_t vdev_id,tpSendProbeRespParams probe_rsp_info)2094*5113495bSYour Name static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma,
2095*5113495bSYour Name 				   uint8_t vdev_id,
2096*5113495bSYour Name 				   tpSendProbeRespParams probe_rsp_info)
2097*5113495bSYour Name {
2098*5113495bSYour Name 	uint64_t adjusted_tsf_le;
2099*5113495bSYour Name 	struct ieee80211_frame *wh;
2100*5113495bSYour Name 	struct wmi_probe_resp_params params;
2101*5113495bSYour Name 
2102*5113495bSYour Name 	/*
2103*5113495bSYour Name 	 * Make the TSF offset negative so probe response in the same
2104*5113495bSYour Name 	 * staggered batch have the same TSF.
2105*5113495bSYour Name 	 */
2106*5113495bSYour Name 	adjusted_tsf_le = cpu_to_le64(0ULL -
2107*5113495bSYour Name 				      wma->interfaces[vdev_id].tsfadjust);
2108*5113495bSYour Name 	/* Update the timstamp in the probe response buffer with adjusted TSF */
2109*5113495bSYour Name 	wh = (struct ieee80211_frame *)probe_rsp_info->probeRespTemplate;
2110*5113495bSYour Name 	A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
2111*5113495bSYour Name 
2112*5113495bSYour Name 	params.prb_rsp_template_len = probe_rsp_info->probeRespTemplateLen;
2113*5113495bSYour Name 	params.prb_rsp_template_frm = probe_rsp_info->probeRespTemplate;
2114*5113495bSYour Name 	params.go_ignore_non_p2p_probe_req =
2115*5113495bSYour Name 		probe_rsp_info->go_ignore_non_p2p_probe_req;
2116*5113495bSYour Name 
2117*5113495bSYour Name 	return wmi_unified_probe_rsp_tmpl_send_cmd(wma->wmi_handle, vdev_id,
2118*5113495bSYour Name 						   &params);
2119*5113495bSYour Name }
2120*5113495bSYour Name 
2121*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
2122*5113495bSYour Name /**
2123*5113495bSYour Name  * wma_upt_mlo_partner_info() - update mlo info in beacon template
2124*5113495bSYour Name  * @params: beacon template params
2125*5113495bSYour Name  * @bcn_param: beacon params
2126*5113495bSYour Name  * @bytes_to_strip: bytes to strip
2127*5113495bSYour Name  *
2128*5113495bSYour Name  * Return: Void
2129*5113495bSYour Name  */
wma_upt_mlo_partner_info(struct beacon_tmpl_params * params,const tpSendbeaconParams bcn_param,uint8_t bytes_to_strip)2130*5113495bSYour Name static void wma_upt_mlo_partner_info(struct beacon_tmpl_params *params,
2131*5113495bSYour Name 				     const tpSendbeaconParams bcn_param,
2132*5113495bSYour Name 				     uint8_t bytes_to_strip)
2133*5113495bSYour Name {
2134*5113495bSYour Name 	struct ml_bcn_partner_info *bcn_info;
2135*5113495bSYour Name 	struct ml_bcn_partner_info *info;
2136*5113495bSYour Name 	int link;
2137*5113495bSYour Name 
2138*5113495bSYour Name 	params->mlo_partner.num_links = bcn_param->mlo_partner.num_links;
2139*5113495bSYour Name 	for (link = 0; link < params->mlo_partner.num_links; link++) {
2140*5113495bSYour Name 		bcn_info = &bcn_param->mlo_partner.partner_info[link];
2141*5113495bSYour Name 		info = &params->mlo_partner.partner_info[link];
2142*5113495bSYour Name 		info->vdev_id = bcn_info->vdev_id;
2143*5113495bSYour Name 		info->beacon_interval = bcn_info->beacon_interval;
2144*5113495bSYour Name 		if (bcn_info->csa_switch_count_offset &&
2145*5113495bSYour Name 		    bcn_info->csa_switch_count_offset > bytes_to_strip)
2146*5113495bSYour Name 			info->csa_switch_count_offset =
2147*5113495bSYour Name 				bcn_info->csa_switch_count_offset -
2148*5113495bSYour Name 					bytes_to_strip;
2149*5113495bSYour Name 		if (bcn_info->ext_csa_switch_count_offset &&
2150*5113495bSYour Name 		    bcn_info->ext_csa_switch_count_offset > bytes_to_strip)
2151*5113495bSYour Name 			info->ext_csa_switch_count_offset =
2152*5113495bSYour Name 				bcn_info->ext_csa_switch_count_offset -
2153*5113495bSYour Name 					bytes_to_strip;
2154*5113495bSYour Name 	}
2155*5113495bSYour Name }
2156*5113495bSYour Name #else
wma_upt_mlo_partner_info(struct beacon_tmpl_params * params,const tpSendbeaconParams bcn_param,uint8_t bytes_to_strip)2157*5113495bSYour Name static void wma_upt_mlo_partner_info(struct beacon_tmpl_params *params,
2158*5113495bSYour Name 				     const tpSendbeaconParams bcn_param,
2159*5113495bSYour Name 				     uint8_t bytes_to_strip)
2160*5113495bSYour Name {
2161*5113495bSYour Name }
2162*5113495bSYour Name #endif
2163*5113495bSYour Name 
2164*5113495bSYour Name /**
2165*5113495bSYour Name  * wma_unified_bcn_tmpl_send() - send beacon template to fw
2166*5113495bSYour Name  * @wma:wma handle
2167*5113495bSYour Name  * @vdev_id: vdev id
2168*5113495bSYour Name  * @bcn_info: beacon info
2169*5113495bSYour Name  * @bytes_to_strip: bytes to strip
2170*5113495bSYour Name  *
2171*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for success or error code
2172*5113495bSYour Name  */
wma_unified_bcn_tmpl_send(tp_wma_handle wma,uint8_t vdev_id,const tpSendbeaconParams bcn_info,uint8_t bytes_to_strip)2173*5113495bSYour Name static QDF_STATUS wma_unified_bcn_tmpl_send(tp_wma_handle wma,
2174*5113495bSYour Name 				     uint8_t vdev_id,
2175*5113495bSYour Name 				     const tpSendbeaconParams bcn_info,
2176*5113495bSYour Name 				     uint8_t bytes_to_strip)
2177*5113495bSYour Name {
2178*5113495bSYour Name 	struct beacon_tmpl_params params = {0};
2179*5113495bSYour Name 	uint32_t tmpl_len, tmpl_len_aligned;
2180*5113495bSYour Name 	uint8_t *frm;
2181*5113495bSYour Name 	QDF_STATUS ret;
2182*5113495bSYour Name 	uint8_t *p2p_ie;
2183*5113495bSYour Name 	uint16_t p2p_ie_len = 0;
2184*5113495bSYour Name 	uint64_t adjusted_tsf_le;
2185*5113495bSYour Name 	struct ieee80211_frame *wh;
2186*5113495bSYour Name 
2187*5113495bSYour Name 	if (!wma_is_vdev_valid(vdev_id)) {
2188*5113495bSYour Name 		wma_err("vdev id:%d is not active ", vdev_id);
2189*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2190*5113495bSYour Name 	}
2191*5113495bSYour Name 
2192*5113495bSYour Name 	wma_nofl_debug("vdev %d: bcn update reason %d", vdev_id,
2193*5113495bSYour Name 		       bcn_info->reason);
2194*5113495bSYour Name 
2195*5113495bSYour Name 	if (bcn_info->p2pIeOffset) {
2196*5113495bSYour Name 		p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
2197*5113495bSYour Name 		p2p_ie_len = (uint16_t) p2p_ie[1] + 2;
2198*5113495bSYour Name 	}
2199*5113495bSYour Name 
2200*5113495bSYour Name 	/*
2201*5113495bSYour Name 	 * XXX: The first byte of beacon buffer contains beacon length
2202*5113495bSYour Name 	 * only when UMAC in sending the beacon template. In othercases
2203*5113495bSYour Name 	 * (ex: from tbtt update) beacon length is read from beacon
2204*5113495bSYour Name 	 * information.
2205*5113495bSYour Name 	 */
2206*5113495bSYour Name 	if (bytes_to_strip)
2207*5113495bSYour Name 		tmpl_len = *(uint32_t *) &bcn_info->beacon[0];
2208*5113495bSYour Name 	else
2209*5113495bSYour Name 		tmpl_len = bcn_info->beaconLength;
2210*5113495bSYour Name 
2211*5113495bSYour Name 	if (tmpl_len > WMI_BEACON_TX_BUFFER_SIZE) {
2212*5113495bSYour Name 		wma_err("tmpl_len: %d > %d. Invalid tmpl len", tmpl_len,
2213*5113495bSYour Name 			WMI_BEACON_TX_BUFFER_SIZE);
2214*5113495bSYour Name 		return -EINVAL;
2215*5113495bSYour Name 	}
2216*5113495bSYour Name 
2217*5113495bSYour Name 	if (p2p_ie_len) {
2218*5113495bSYour Name 		if (tmpl_len <= p2p_ie_len) {
2219*5113495bSYour Name 			wma_err("tmpl_len %d <= p2p_ie_len %d, Invalid",
2220*5113495bSYour Name 				tmpl_len, p2p_ie_len);
2221*5113495bSYour Name 			return -EINVAL;
2222*5113495bSYour Name 		}
2223*5113495bSYour Name 		tmpl_len -= (uint32_t) p2p_ie_len;
2224*5113495bSYour Name 	}
2225*5113495bSYour Name 
2226*5113495bSYour Name 	frm = bcn_info->beacon + bytes_to_strip;
2227*5113495bSYour Name 	tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32));
2228*5113495bSYour Name 	/*
2229*5113495bSYour Name 	 * Make the TSF offset negative so beacons in the same
2230*5113495bSYour Name 	 * staggered batch have the same TSF.
2231*5113495bSYour Name 	 */
2232*5113495bSYour Name 	adjusted_tsf_le = cpu_to_le64(0ULL -
2233*5113495bSYour Name 				      wma->interfaces[vdev_id].tsfadjust);
2234*5113495bSYour Name 	/* Update the timstamp in the beacon buffer with adjusted TSF */
2235*5113495bSYour Name 	wh = (struct ieee80211_frame *)frm;
2236*5113495bSYour Name 	A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
2237*5113495bSYour Name 
2238*5113495bSYour Name 
2239*5113495bSYour Name 
2240*5113495bSYour Name 	params.vdev_id = vdev_id;
2241*5113495bSYour Name 	params.tim_ie_offset = bcn_info->timIeOffset - bytes_to_strip;
2242*5113495bSYour Name 	params.tmpl_len = tmpl_len;
2243*5113495bSYour Name 	params.frm = frm;
2244*5113495bSYour Name 	params.tmpl_len_aligned = tmpl_len_aligned;
2245*5113495bSYour Name 	params.enable_bigtk =
2246*5113495bSYour Name 		mlme_get_bigtk_support(wma->interfaces[vdev_id].vdev);
2247*5113495bSYour Name 	if (bcn_info->csa_count_offset &&
2248*5113495bSYour Name 	    (bcn_info->csa_count_offset > bytes_to_strip))
2249*5113495bSYour Name 		params.csa_switch_count_offset =
2250*5113495bSYour Name 			bcn_info->csa_count_offset - bytes_to_strip;
2251*5113495bSYour Name 	if (bcn_info->ecsa_count_offset &&
2252*5113495bSYour Name 	    (bcn_info->ecsa_count_offset > bytes_to_strip))
2253*5113495bSYour Name 		params.ext_csa_switch_count_offset =
2254*5113495bSYour Name 			bcn_info->ecsa_count_offset - bytes_to_strip;
2255*5113495bSYour Name 
2256*5113495bSYour Name 	wma_upt_mlo_partner_info(&params, bcn_info, bytes_to_strip);
2257*5113495bSYour Name 
2258*5113495bSYour Name 	ret = wmi_unified_beacon_tmpl_send_cmd(wma->wmi_handle,
2259*5113495bSYour Name 				 &params);
2260*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
2261*5113495bSYour Name 		wma_err("Failed to send bcn tmpl: %d", ret);
2262*5113495bSYour Name 
2263*5113495bSYour Name 	return ret;
2264*5113495bSYour Name }
2265*5113495bSYour Name 
2266*5113495bSYour Name /**
2267*5113495bSYour Name  * wma_store_bcn_tmpl() - store beacon template
2268*5113495bSYour Name  * @wma: wma handle
2269*5113495bSYour Name  * @vdev_id: vdev id
2270*5113495bSYour Name  * @bcn_info: beacon params
2271*5113495bSYour Name  *
2272*5113495bSYour Name  * This function stores beacon template locally.
2273*5113495bSYour Name  * This will send to target on the reception of
2274*5113495bSYour Name  * SWBA event.
2275*5113495bSYour Name  *
2276*5113495bSYour Name  * Return: QDF status
2277*5113495bSYour Name  */
wma_store_bcn_tmpl(tp_wma_handle wma,uint8_t vdev_id,tpSendbeaconParams bcn_info)2278*5113495bSYour Name static QDF_STATUS wma_store_bcn_tmpl(tp_wma_handle wma, uint8_t vdev_id,
2279*5113495bSYour Name 				     tpSendbeaconParams bcn_info)
2280*5113495bSYour Name {
2281*5113495bSYour Name 	struct beacon_info *bcn;
2282*5113495bSYour Name 	uint32_t len;
2283*5113495bSYour Name 	uint8_t *bcn_payload;
2284*5113495bSYour Name 	struct beacon_tim_ie *tim_ie;
2285*5113495bSYour Name 
2286*5113495bSYour Name 	bcn = wma->interfaces[vdev_id].beacon;
2287*5113495bSYour Name 	if (!bcn || !bcn->buf) {
2288*5113495bSYour Name 		wma_err("Memory is not allocated to hold bcn template");
2289*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2290*5113495bSYour Name 	}
2291*5113495bSYour Name 
2292*5113495bSYour Name 	len = *(uint32_t *) &bcn_info->beacon[0];
2293*5113495bSYour Name 	if (len > SIR_MAX_BEACON_SIZE - sizeof(uint32_t)) {
2294*5113495bSYour Name 		wma_err("Received beacon len %u exceeding max limit %lu",
2295*5113495bSYour Name 			len, (unsigned long)(
2296*5113495bSYour Name 			 SIR_MAX_BEACON_SIZE - sizeof(uint32_t)));
2297*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2298*5113495bSYour Name 	}
2299*5113495bSYour Name 	qdf_spin_lock_bh(&bcn->lock);
2300*5113495bSYour Name 
2301*5113495bSYour Name 	/*
2302*5113495bSYour Name 	 * Copy received beacon template content in local buffer.
2303*5113495bSYour Name 	 * this will be send to target on the reception of SWBA
2304*5113495bSYour Name 	 * event from target.
2305*5113495bSYour Name 	 */
2306*5113495bSYour Name 	qdf_nbuf_trim_tail(bcn->buf, qdf_nbuf_len(bcn->buf));
2307*5113495bSYour Name 	memcpy(qdf_nbuf_data(bcn->buf),
2308*5113495bSYour Name 	       bcn_info->beacon + 4 /* Exclude beacon length field */,
2309*5113495bSYour Name 	       len);
2310*5113495bSYour Name 	if (bcn_info->timIeOffset > 3)
2311*5113495bSYour Name 		bcn->tim_ie_offset = bcn_info->timIeOffset - 4;
2312*5113495bSYour Name 	else
2313*5113495bSYour Name 		bcn->tim_ie_offset = bcn_info->timIeOffset;
2314*5113495bSYour Name 
2315*5113495bSYour Name 	if (bcn_info->p2pIeOffset > 3)
2316*5113495bSYour Name 		bcn->p2p_ie_offset = bcn_info->p2pIeOffset - 4;
2317*5113495bSYour Name 	else
2318*5113495bSYour Name 		bcn->p2p_ie_offset = bcn_info->p2pIeOffset;
2319*5113495bSYour Name 
2320*5113495bSYour Name 	if (bcn_info->csa_count_offset > 3)
2321*5113495bSYour Name 		bcn->csa_count_offset = bcn_info->csa_count_offset - 4;
2322*5113495bSYour Name 	else
2323*5113495bSYour Name 		bcn->csa_count_offset = bcn_info->csa_count_offset;
2324*5113495bSYour Name 
2325*5113495bSYour Name 	if (bcn_info->ecsa_count_offset > 3)
2326*5113495bSYour Name 		bcn->ecsa_count_offset = bcn_info->ecsa_count_offset - 4;
2327*5113495bSYour Name 	else
2328*5113495bSYour Name 		bcn->ecsa_count_offset = bcn_info->ecsa_count_offset;
2329*5113495bSYour Name 
2330*5113495bSYour Name 	bcn_payload = qdf_nbuf_data(bcn->buf);
2331*5113495bSYour Name 	if (bcn->tim_ie_offset) {
2332*5113495bSYour Name 		tim_ie = (struct beacon_tim_ie *)
2333*5113495bSYour Name 				(&bcn_payload[bcn->tim_ie_offset]);
2334*5113495bSYour Name 		/*
2335*5113495bSYour Name 		 * Initial Value of bcn->dtim_count will be 0.
2336*5113495bSYour Name 		 * But if the beacon gets updated then current dtim
2337*5113495bSYour Name 		 * count will be restored
2338*5113495bSYour Name 		 */
2339*5113495bSYour Name 		tim_ie->dtim_count = bcn->dtim_count;
2340*5113495bSYour Name 		tim_ie->tim_bitctl = 0;
2341*5113495bSYour Name 	}
2342*5113495bSYour Name 
2343*5113495bSYour Name 	qdf_nbuf_put_tail(bcn->buf, len);
2344*5113495bSYour Name 	bcn->len = len;
2345*5113495bSYour Name 
2346*5113495bSYour Name 	qdf_spin_unlock_bh(&bcn->lock);
2347*5113495bSYour Name 
2348*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2349*5113495bSYour Name }
2350*5113495bSYour Name 
wma_tbttoffset_update_event_handler(void * handle,uint8_t * event,uint32_t len)2351*5113495bSYour Name int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event,
2352*5113495bSYour Name 					       uint32_t len)
2353*5113495bSYour Name {
2354*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle) handle;
2355*5113495bSYour Name 	WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
2356*5113495bSYour Name 	wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
2357*5113495bSYour Name 	struct wma_txrx_node *intf;
2358*5113495bSYour Name 	struct beacon_info *bcn;
2359*5113495bSYour Name 	tSendbeaconParams bcn_info;
2360*5113495bSYour Name 	uint32_t *adjusted_tsf = NULL;
2361*5113495bSYour Name 	uint32_t if_id = 0, vdev_map;
2362*5113495bSYour Name 
2363*5113495bSYour Name 	if (wma_validate_handle(wma))
2364*5113495bSYour Name 		return -EINVAL;
2365*5113495bSYour Name 
2366*5113495bSYour Name 	param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) event;
2367*5113495bSYour Name 	if (!param_buf) {
2368*5113495bSYour Name 		wma_err("Invalid tbtt update event buffer");
2369*5113495bSYour Name 		return -EINVAL;
2370*5113495bSYour Name 	}
2371*5113495bSYour Name 
2372*5113495bSYour Name 	tbtt_offset_event = param_buf->fixed_param;
2373*5113495bSYour Name 	intf = wma->interfaces;
2374*5113495bSYour Name 	vdev_map = tbtt_offset_event->vdev_map;
2375*5113495bSYour Name 	adjusted_tsf = param_buf->tbttoffset_list;
2376*5113495bSYour Name 	if (!adjusted_tsf) {
2377*5113495bSYour Name 		wma_err("Invalid adjusted_tsf");
2378*5113495bSYour Name 		return -EINVAL;
2379*5113495bSYour Name 	}
2380*5113495bSYour Name 
2381*5113495bSYour Name 	for (; (if_id < wma->max_bssid && vdev_map); vdev_map >>= 1, if_id++) {
2382*5113495bSYour Name 		if (!intf[if_id].vdev)
2383*5113495bSYour Name 			continue;
2384*5113495bSYour Name 
2385*5113495bSYour Name 		if (!(vdev_map & 0x1))
2386*5113495bSYour Name 			continue;
2387*5113495bSYour Name 
2388*5113495bSYour Name 		bcn = intf[if_id].beacon;
2389*5113495bSYour Name 		if (!bcn) {
2390*5113495bSYour Name 			wma_err("Invalid beacon");
2391*5113495bSYour Name 			return -EINVAL;
2392*5113495bSYour Name 		}
2393*5113495bSYour Name 		if (!bcn->buf) {
2394*5113495bSYour Name 			wma_err("Invalid beacon buffer");
2395*5113495bSYour Name 			return -EINVAL;
2396*5113495bSYour Name 		}
2397*5113495bSYour Name 		/* Save the adjusted TSF */
2398*5113495bSYour Name 		intf[if_id].tsfadjust = adjusted_tsf[if_id];
2399*5113495bSYour Name 
2400*5113495bSYour Name 		qdf_spin_lock_bh(&bcn->lock);
2401*5113495bSYour Name 		qdf_mem_zero(&bcn_info, sizeof(bcn_info));
2402*5113495bSYour Name 		qdf_mem_copy(bcn_info.beacon,
2403*5113495bSYour Name 			     qdf_nbuf_data(bcn->buf), bcn->len);
2404*5113495bSYour Name 		bcn_info.p2pIeOffset = bcn->p2p_ie_offset;
2405*5113495bSYour Name 		bcn_info.beaconLength = bcn->len;
2406*5113495bSYour Name 		bcn_info.timIeOffset = bcn->tim_ie_offset;
2407*5113495bSYour Name 		bcn_info.csa_count_offset = bcn->csa_count_offset;
2408*5113495bSYour Name 		bcn_info.ecsa_count_offset = bcn->ecsa_count_offset;
2409*5113495bSYour Name 		qdf_spin_unlock_bh(&bcn->lock);
2410*5113495bSYour Name 
2411*5113495bSYour Name 		wma_err_rl("Update beacon template for vdev %d due to TBTT offset update",
2412*5113495bSYour Name 			   if_id);
2413*5113495bSYour Name 		/* Update beacon template in firmware */
2414*5113495bSYour Name 		wma_unified_bcn_tmpl_send(wma, if_id, &bcn_info, 0);
2415*5113495bSYour Name 	}
2416*5113495bSYour Name 	return 0;
2417*5113495bSYour Name }
2418*5113495bSYour Name 
2419*5113495bSYour Name /**
2420*5113495bSYour Name  * wma_p2p_go_set_beacon_ie() - set beacon IE for p2p go
2421*5113495bSYour Name  * @wma_handle: wma handle
2422*5113495bSYour Name  * @vdev_id: vdev id
2423*5113495bSYour Name  * @p2pIe: p2p IE
2424*5113495bSYour Name  *
2425*5113495bSYour Name  * Return: 0 for success or error code
2426*5113495bSYour Name  */
wma_p2p_go_set_beacon_ie(t_wma_handle * wma_handle,A_UINT32 vdev_id,uint8_t * p2pIe)2427*5113495bSYour Name static int wma_p2p_go_set_beacon_ie(t_wma_handle *wma_handle,
2428*5113495bSYour Name 				    A_UINT32 vdev_id, uint8_t *p2pIe)
2429*5113495bSYour Name {
2430*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
2431*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2432*5113495bSYour Name 
2433*5113495bSYour Name 	return wmi_unified_p2p_go_set_beacon_ie_cmd(wma_handle->wmi_handle,
2434*5113495bSYour Name 							vdev_id, p2pIe);
2435*5113495bSYour Name }
2436*5113495bSYour Name 
2437*5113495bSYour Name /**
2438*5113495bSYour Name  * wma_send_probe_rsp_tmpl() - send probe resp template
2439*5113495bSYour Name  * @wma: wma handle
2440*5113495bSYour Name  * @probe_rsp_info: probe response info
2441*5113495bSYour Name  *
2442*5113495bSYour Name  * This function sends probe response template to fw which
2443*5113495bSYour Name  * firmware will use in case of probe response offload.
2444*5113495bSYour Name  *
2445*5113495bSYour Name  * Return: none
2446*5113495bSYour Name  */
wma_send_probe_rsp_tmpl(tp_wma_handle wma,tpSendProbeRespParams probe_rsp_info)2447*5113495bSYour Name void wma_send_probe_rsp_tmpl(tp_wma_handle wma,
2448*5113495bSYour Name 				    tpSendProbeRespParams probe_rsp_info)
2449*5113495bSYour Name {
2450*5113495bSYour Name 	uint8_t vdev_id;
2451*5113495bSYour Name 	struct sAniProbeRspStruct *probe_rsp;
2452*5113495bSYour Name 
2453*5113495bSYour Name 	if (!probe_rsp_info) {
2454*5113495bSYour Name 		wma_err("probe_rsp_info is NULL");
2455*5113495bSYour Name 		return;
2456*5113495bSYour Name 	}
2457*5113495bSYour Name 
2458*5113495bSYour Name 	probe_rsp = (struct sAniProbeRspStruct *)
2459*5113495bSYour Name 			(probe_rsp_info->probeRespTemplate);
2460*5113495bSYour Name 	if (!probe_rsp) {
2461*5113495bSYour Name 		wma_err("probe_rsp is NULL");
2462*5113495bSYour Name 		return;
2463*5113495bSYour Name 	}
2464*5113495bSYour Name 
2465*5113495bSYour Name 	if (wma_find_vdev_id_by_addr(wma, probe_rsp->macHdr.sa, &vdev_id)) {
2466*5113495bSYour Name 		wma_err("failed to get vdev id");
2467*5113495bSYour Name 		return;
2468*5113495bSYour Name 	}
2469*5113495bSYour Name 
2470*5113495bSYour Name 	if (wmi_service_enabled(wma->wmi_handle,
2471*5113495bSYour Name 				   wmi_service_beacon_offload)) {
2472*5113495bSYour Name 		if (wmi_unified_probe_rsp_tmpl_send(wma, vdev_id,
2473*5113495bSYour Name 						    probe_rsp_info) < 0) {
2474*5113495bSYour Name 			wma_err("wmi_unified_probe_rsp_tmpl_send Failed");
2475*5113495bSYour Name 			return;
2476*5113495bSYour Name 		}
2477*5113495bSYour Name 	}
2478*5113495bSYour Name }
2479*5113495bSYour Name 
wma_set_ap_vdev_up(tp_wma_handle wma,uint8_t vdev_id)2480*5113495bSYour Name QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id)
2481*5113495bSYour Name {
2482*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2483*5113495bSYour Name 	struct vdev_mlme_obj *mlme_obj;
2484*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2485*5113495bSYour Name 	struct wma_txrx_node *iface;
2486*5113495bSYour Name 
2487*5113495bSYour Name 	iface = &wma->interfaces[vdev_id];
2488*5113495bSYour Name 	vdev = iface->vdev;
2489*5113495bSYour Name 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
2490*5113495bSYour Name 	if (!mlme_obj) {
2491*5113495bSYour Name 		wma_err("failed to get mlme_obj");
2492*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2493*5113495bSYour Name 	}
2494*5113495bSYour Name 	mlme_obj->proto.sta.assoc_id = 0;
2495*5113495bSYour Name 
2496*5113495bSYour Name 	status = vdev_mgr_up_send(mlme_obj);
2497*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
2498*5113495bSYour Name 		wma_err("failed to send vdev up");
2499*5113495bSYour Name 		return status;
2500*5113495bSYour Name 	}
2501*5113495bSYour Name 	wma_set_sap_keepalive(wma, vdev_id);
2502*5113495bSYour Name 	wma_set_vdev_mgmt_rate(wma, vdev_id);
2503*5113495bSYour Name 	wma_vdev_set_he_bss_params(wma, vdev_id, &mlme_obj->proto.he_ops_info);
2504*5113495bSYour Name 	mlme_sr_update(vdev, true);
2505*5113495bSYour Name 
2506*5113495bSYour Name 	return status;
2507*5113495bSYour Name }
2508*5113495bSYour Name 
2509*5113495bSYour Name /**
2510*5113495bSYour Name  * wma_send_beacon() - send beacon template
2511*5113495bSYour Name  * @wma: wma handle
2512*5113495bSYour Name  * @bcn_info: beacon info
2513*5113495bSYour Name  *
2514*5113495bSYour Name  * This function store beacon template locally and
2515*5113495bSYour Name  * update keep alive parameters
2516*5113495bSYour Name  *
2517*5113495bSYour Name  * Return: none
2518*5113495bSYour Name  */
wma_send_beacon(tp_wma_handle wma,tpSendbeaconParams bcn_info)2519*5113495bSYour Name void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
2520*5113495bSYour Name {
2521*5113495bSYour Name 	uint8_t vdev_id;
2522*5113495bSYour Name 	QDF_STATUS status;
2523*5113495bSYour Name 	uint8_t *p2p_ie;
2524*5113495bSYour Name 	struct sAniBeaconStruct *beacon;
2525*5113495bSYour Name 
2526*5113495bSYour Name 	beacon = (struct sAniBeaconStruct *) (bcn_info->beacon);
2527*5113495bSYour Name 	if (wma_find_vdev_id_by_addr(wma, beacon->macHdr.sa, &vdev_id)) {
2528*5113495bSYour Name 		wma_err("failed to get vdev id");
2529*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
2530*5113495bSYour Name 		goto send_rsp;
2531*5113495bSYour Name 	}
2532*5113495bSYour Name 
2533*5113495bSYour Name 	if (wmi_service_enabled(wma->wmi_handle,
2534*5113495bSYour Name 				   wmi_service_beacon_offload)) {
2535*5113495bSYour Name 		status = wma_unified_bcn_tmpl_send(wma, vdev_id, bcn_info, 4);
2536*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
2537*5113495bSYour Name 			wma_err("wmi_unified_bcn_tmpl_send Failed");
2538*5113495bSYour Name 			goto send_rsp;
2539*5113495bSYour Name 		}
2540*5113495bSYour Name 
2541*5113495bSYour Name 		if (bcn_info->p2pIeOffset) {
2542*5113495bSYour Name 			p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
2543*5113495bSYour Name 			wma_debug("p2pIe is present - vdev_id %hu, p2p_ie = %pK, p2p ie len = %hu",
2544*5113495bSYour Name 				  vdev_id, p2p_ie, p2p_ie[1]);
2545*5113495bSYour Name 			if (wma_p2p_go_set_beacon_ie(wma, vdev_id,
2546*5113495bSYour Name 							 p2p_ie) < 0) {
2547*5113495bSYour Name 				wma_err("wmi_unified_bcn_tmpl_send Failed");
2548*5113495bSYour Name 				status = QDF_STATUS_E_INVAL;
2549*5113495bSYour Name 				goto send_rsp;
2550*5113495bSYour Name 			}
2551*5113495bSYour Name 		}
2552*5113495bSYour Name 	}
2553*5113495bSYour Name 	status = wma_store_bcn_tmpl(wma, vdev_id, bcn_info);
2554*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
2555*5113495bSYour Name 		wma_err("wma_store_bcn_tmpl Failed");
2556*5113495bSYour Name 		goto send_rsp;
2557*5113495bSYour Name 	}
2558*5113495bSYour Name 
2559*5113495bSYour Name send_rsp:
2560*5113495bSYour Name 	bcn_info->status = status;
2561*5113495bSYour Name 	wma_send_msg(wma, WMA_SEND_BCN_RSP, (void *)bcn_info, 0);
2562*5113495bSYour Name }
2563*5113495bSYour Name 
2564*5113495bSYour Name /**
2565*5113495bSYour Name  * wma_set_keepalive_req() - send keep alive request to fw
2566*5113495bSYour Name  * @wma: wma handle
2567*5113495bSYour Name  * @keepalive: keep alive parameters
2568*5113495bSYour Name  *
2569*5113495bSYour Name  * Return: none
2570*5113495bSYour Name  */
wma_set_keepalive_req(tp_wma_handle wma,struct keep_alive_req * keepalive)2571*5113495bSYour Name void wma_set_keepalive_req(tp_wma_handle wma,
2572*5113495bSYour Name 			   struct keep_alive_req *keepalive)
2573*5113495bSYour Name {
2574*5113495bSYour Name 	wma_nofl_debug("KEEPALIVE:PacketType:%d", keepalive->packetType);
2575*5113495bSYour Name 	wma_set_sta_keep_alive(wma, keepalive->sessionId,
2576*5113495bSYour Name 			       keepalive->packetType,
2577*5113495bSYour Name 			       keepalive->timePeriod,
2578*5113495bSYour Name 			       keepalive->hostIpv4Addr,
2579*5113495bSYour Name 			       keepalive->destIpv4Addr,
2580*5113495bSYour Name 			       keepalive->dest_macaddr.bytes);
2581*5113495bSYour Name 
2582*5113495bSYour Name 	qdf_mem_free(keepalive);
2583*5113495bSYour Name }
2584*5113495bSYour Name 
2585*5113495bSYour Name /**
2586*5113495bSYour Name  * wma_beacon_miss_handler() - beacon miss event handler
2587*5113495bSYour Name  * @wma: wma handle
2588*5113495bSYour Name  * @vdev_id: vdev id
2589*5113495bSYour Name  * @rssi: rssi value
2590*5113495bSYour Name  *
2591*5113495bSYour Name  * This function send beacon miss indication to upper layers.
2592*5113495bSYour Name  *
2593*5113495bSYour Name  * Return: none
2594*5113495bSYour Name  */
wma_beacon_miss_handler(tp_wma_handle wma,uint32_t vdev_id,int32_t rssi)2595*5113495bSYour Name void wma_beacon_miss_handler(tp_wma_handle wma, uint32_t vdev_id, int32_t rssi)
2596*5113495bSYour Name {
2597*5113495bSYour Name 	struct missed_beacon_ind *beacon_miss_ind;
2598*5113495bSYour Name 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
2599*5113495bSYour Name 
2600*5113495bSYour Name 	beacon_miss_ind = qdf_mem_malloc(sizeof(*beacon_miss_ind));
2601*5113495bSYour Name 	if (!beacon_miss_ind)
2602*5113495bSYour Name 		return;
2603*5113495bSYour Name 
2604*5113495bSYour Name 	if (mac && mac->sme.tx_queue_cb)
2605*5113495bSYour Name 		mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id,
2606*5113495bSYour Name 				     WLAN_STOP_ALL_NETIF_QUEUE,
2607*5113495bSYour Name 				     WLAN_CONTROL_PATH);
2608*5113495bSYour Name 	beacon_miss_ind->messageType = WMA_MISSED_BEACON_IND;
2609*5113495bSYour Name 	beacon_miss_ind->length = sizeof(*beacon_miss_ind);
2610*5113495bSYour Name 	beacon_miss_ind->bss_idx = vdev_id;
2611*5113495bSYour Name 	beacon_miss_ind->rssi = rssi;
2612*5113495bSYour Name 
2613*5113495bSYour Name 	wma_send_msg(wma, WMA_MISSED_BEACON_IND, beacon_miss_ind, 0);
2614*5113495bSYour Name 	if (!wmi_service_enabled(wma->wmi_handle,
2615*5113495bSYour Name 				 wmi_service_hw_db2dbm_support))
2616*5113495bSYour Name 		rssi += WMA_TGT_NOISE_FLOOR_DBM;
2617*5113495bSYour Name 	wma_lost_link_info_handler(wma, vdev_id, rssi);
2618*5113495bSYour Name }
2619*5113495bSYour Name 
wlan_cm_send_beacon_miss(uint8_t vdev_id,int32_t rssi)2620*5113495bSYour Name void wlan_cm_send_beacon_miss(uint8_t vdev_id, int32_t rssi)
2621*5113495bSYour Name {
2622*5113495bSYour Name 	tp_wma_handle wma;
2623*5113495bSYour Name 
2624*5113495bSYour Name 	wma = cds_get_context(QDF_MODULE_ID_WMA);
2625*5113495bSYour Name 	if (!wma)
2626*5113495bSYour Name 		return;
2627*5113495bSYour Name 
2628*5113495bSYour Name 	wma_beacon_miss_handler(wma, vdev_id, rssi);
2629*5113495bSYour Name }
2630*5113495bSYour Name 
2631*5113495bSYour Name /**
2632*5113495bSYour Name  * wma_get_status_str() - get string of tx status from firmware
2633*5113495bSYour Name  * @status: tx status
2634*5113495bSYour Name  *
2635*5113495bSYour Name  * Return: converted string of tx status
2636*5113495bSYour Name  */
wma_get_status_str(uint32_t status)2637*5113495bSYour Name static const char *wma_get_status_str(uint32_t status)
2638*5113495bSYour Name {
2639*5113495bSYour Name 	switch (status) {
2640*5113495bSYour Name 	default:
2641*5113495bSYour Name 		return "unknown";
2642*5113495bSYour Name 	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK);
2643*5113495bSYour Name 	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_DISCARD);
2644*5113495bSYour Name 	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_INSPECT);
2645*5113495bSYour Name 	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK);
2646*5113495bSYour Name 	CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_MAX);
2647*5113495bSYour Name 	}
2648*5113495bSYour Name }
2649*5113495bSYour Name 
2650*5113495bSYour Name #ifdef CONFIG_HL_SUPPORT
wma_mgmt_unmap_buf(tp_wma_handle wma_handle,qdf_nbuf_t buf)2651*5113495bSYour Name static inline void wma_mgmt_unmap_buf(tp_wma_handle wma_handle, qdf_nbuf_t buf)
2652*5113495bSYour Name {
2653*5113495bSYour Name }
2654*5113495bSYour Name #else
wma_mgmt_unmap_buf(tp_wma_handle wma_handle,qdf_nbuf_t buf)2655*5113495bSYour Name static inline void wma_mgmt_unmap_buf(tp_wma_handle wma_handle, qdf_nbuf_t buf)
2656*5113495bSYour Name {
2657*5113495bSYour Name 	qdf_nbuf_unmap_single(wma_handle->qdf_dev, buf, QDF_DMA_TO_DEVICE);
2658*5113495bSYour Name }
2659*5113495bSYour Name #endif
2660*5113495bSYour Name 
2661*5113495bSYour Name #if defined(CONNECTIVITY_PKTLOG) || !defined(REMOVE_PKT_LOG)
2662*5113495bSYour Name /**
2663*5113495bSYour Name  * wma_mgmt_qdf_status_map() - map MGMT Tx completion status with
2664*5113495bSYour Name  * packet dump Tx status
2665*5113495bSYour Name  * @status: MGMT Tx completion status
2666*5113495bSYour Name  *
2667*5113495bSYour Name  * Return: packet dump tx_status enum
2668*5113495bSYour Name  */
2669*5113495bSYour Name static inline enum qdf_dp_tx_rx_status
wma_mgmt_qdf_status_map(WMI_MGMT_TX_COMP_STATUS_TYPE status)2670*5113495bSYour Name wma_mgmt_qdf_status_map(WMI_MGMT_TX_COMP_STATUS_TYPE status)
2671*5113495bSYour Name {
2672*5113495bSYour Name 	enum qdf_dp_tx_rx_status pktdump_status;
2673*5113495bSYour Name 
2674*5113495bSYour Name 	switch (status) {
2675*5113495bSYour Name 	case WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK:
2676*5113495bSYour Name 		pktdump_status = QDF_TX_RX_STATUS_OK;
2677*5113495bSYour Name 		break;
2678*5113495bSYour Name 	case WMI_MGMT_TX_COMP_TYPE_DISCARD:
2679*5113495bSYour Name 		pktdump_status = QDF_TX_RX_STATUS_DROP;
2680*5113495bSYour Name 		break;
2681*5113495bSYour Name 	case WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK:
2682*5113495bSYour Name 		pktdump_status = QDF_TX_RX_STATUS_NO_ACK;
2683*5113495bSYour Name 		break;
2684*5113495bSYour Name 	default:
2685*5113495bSYour Name 		pktdump_status = QDF_TX_RX_STATUS_DROP;
2686*5113495bSYour Name 		break;
2687*5113495bSYour Name 	}
2688*5113495bSYour Name 	return pktdump_status;
2689*5113495bSYour Name }
2690*5113495bSYour Name 
2691*5113495bSYour Name /**
2692*5113495bSYour Name  * wma_mgmt_pktdump_tx_handler() - calls tx cb if CONNECTIVITY_PKTLOG
2693*5113495bSYour Name  * feature is enabled
2694*5113495bSYour Name  * @wma_handle: wma handle
2695*5113495bSYour Name  * @buf: nbuf
2696*5113495bSYour Name  * @vdev_id : vdev id
2697*5113495bSYour Name  * @status : status
2698*5113495bSYour Name  *
2699*5113495bSYour Name  * Return: none
2700*5113495bSYour Name  */
wma_mgmt_pktdump_tx_handler(tp_wma_handle wma_handle,qdf_nbuf_t buf,uint8_t vdev_id,uint32_t status)2701*5113495bSYour Name static inline void wma_mgmt_pktdump_tx_handler(tp_wma_handle wma_handle,
2702*5113495bSYour Name 					       qdf_nbuf_t buf, uint8_t vdev_id,
2703*5113495bSYour Name 					       uint32_t status)
2704*5113495bSYour Name {
2705*5113495bSYour Name 	ol_txrx_pktdump_cb packetdump_cb;
2706*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2707*5113495bSYour Name 	enum qdf_dp_tx_rx_status pktdump_status;
2708*5113495bSYour Name 
2709*5113495bSYour Name 	packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb;
2710*5113495bSYour Name 	pktdump_status = wma_mgmt_qdf_status_map(status);
2711*5113495bSYour Name 	if (packetdump_cb)
2712*5113495bSYour Name 		packetdump_cb(soc, WMI_PDEV_ID_SOC, vdev_id,
2713*5113495bSYour Name 			      buf, pktdump_status, QDF_TX_MGMT_PKT);
2714*5113495bSYour Name }
2715*5113495bSYour Name 
2716*5113495bSYour Name /**
2717*5113495bSYour Name  * wma_mgmt_pktdump_rx_handler() - calls rx cb if CONNECTIVITY_PKTLOG
2718*5113495bSYour Name  * feature is enabled
2719*5113495bSYour Name  * @mgmt_rx_params: mgmt rx params
2720*5113495bSYour Name  * @rx_pkt: cds packet
2721*5113495bSYour Name  * @wma_handle: wma handle
2722*5113495bSYour Name  * mgt_type: management type
2723*5113495bSYour Name  * mgt_subtype: management subtype
2724*5113495bSYour Name  *
2725*5113495bSYour Name  * Return: none
2726*5113495bSYour Name  */
wma_mgmt_pktdump_rx_handler(struct mgmt_rx_event_params * mgmt_rx_params,cds_pkt_t * rx_pkt,tp_wma_handle wma_handle,uint8_t mgt_type,uint8_t mgt_subtype)2727*5113495bSYour Name static inline void wma_mgmt_pktdump_rx_handler(
2728*5113495bSYour Name 			struct mgmt_rx_event_params *mgmt_rx_params,
2729*5113495bSYour Name 			cds_pkt_t *rx_pkt, tp_wma_handle wma_handle,
2730*5113495bSYour Name 			uint8_t mgt_type, uint8_t mgt_subtype)
2731*5113495bSYour Name {
2732*5113495bSYour Name 	ol_txrx_pktdump_cb packetdump_cb;
2733*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2734*5113495bSYour Name 
2735*5113495bSYour Name 	packetdump_cb = wma_handle->wma_mgmt_rx_packetdump_cb;
2736*5113495bSYour Name 	if ((mgt_type == IEEE80211_FC0_TYPE_MGT &&
2737*5113495bSYour Name 	     mgt_subtype != MGMT_SUBTYPE_BEACON) &&
2738*5113495bSYour Name 	     packetdump_cb)
2739*5113495bSYour Name 		packetdump_cb(soc, mgmt_rx_params->pdev_id,
2740*5113495bSYour Name 			      rx_pkt->pkt_meta.session_id, rx_pkt->pkt_buf,
2741*5113495bSYour Name 			      QDF_TX_RX_STATUS_OK, QDF_RX_MGMT_PKT);
2742*5113495bSYour Name }
2743*5113495bSYour Name 
2744*5113495bSYour Name #else
wma_mgmt_pktdump_tx_handler(tp_wma_handle wma_handle,qdf_nbuf_t buf,uint8_t vdev_id,uint32_t status)2745*5113495bSYour Name static inline void wma_mgmt_pktdump_tx_handler(tp_wma_handle wma_handle,
2746*5113495bSYour Name 					       qdf_nbuf_t buf, uint8_t vdev_id,
2747*5113495bSYour Name 					       uint32_t status)
2748*5113495bSYour Name {
2749*5113495bSYour Name }
2750*5113495bSYour Name 
wma_mgmt_pktdump_rx_handler(struct mgmt_rx_event_params * mgmt_rx_params,cds_pkt_t * rx_pkt,tp_wma_handle wma_handle,uint8_t mgt_type,uint8_t mgt_subtype)2751*5113495bSYour Name static inline void wma_mgmt_pktdump_rx_handler(
2752*5113495bSYour Name 			struct mgmt_rx_event_params *mgmt_rx_params,
2753*5113495bSYour Name 			cds_pkt_t *rx_pkt, tp_wma_handle wma_handle,
2754*5113495bSYour Name 			uint8_t mgt_type, uint8_t mgt_subtype)
2755*5113495bSYour Name {
2756*5113495bSYour Name }
2757*5113495bSYour Name #endif
2758*5113495bSYour Name 
2759*5113495bSYour Name /**
2760*5113495bSYour Name  * wma_process_mgmt_tx_completion() - process mgmt completion
2761*5113495bSYour Name  * @wma_handle: wma handle
2762*5113495bSYour Name  * @desc_id: descriptor id
2763*5113495bSYour Name  * @status: status
2764*5113495bSYour Name  *
2765*5113495bSYour Name  * Return: 0 for success or error code
2766*5113495bSYour Name  */
wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,uint32_t desc_id,uint32_t status)2767*5113495bSYour Name static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
2768*5113495bSYour Name 					  uint32_t desc_id, uint32_t status)
2769*5113495bSYour Name {
2770*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
2771*5113495bSYour Name 	qdf_nbuf_t buf = NULL;
2772*5113495bSYour Name 	QDF_STATUS ret;
2773*5113495bSYour Name 	uint8_t vdev_id = 0;
2774*5113495bSYour Name 	struct wmi_mgmt_params mgmt_params = {};
2775*5113495bSYour Name 
2776*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
2777*5113495bSYour Name 		return -EINVAL;
2778*5113495bSYour Name 
2779*5113495bSYour Name 	wma_debug("status: %s wmi_desc_id: %d",
2780*5113495bSYour Name 		  wma_get_status_str(status), desc_id);
2781*5113495bSYour Name 
2782*5113495bSYour Name 	pdev = wma_handle->pdev;
2783*5113495bSYour Name 	if (!pdev) {
2784*5113495bSYour Name 		wma_err("psoc ptr is NULL");
2785*5113495bSYour Name 		return -EINVAL;
2786*5113495bSYour Name 	}
2787*5113495bSYour Name 
2788*5113495bSYour Name 	buf = mgmt_txrx_get_nbuf(pdev, desc_id);
2789*5113495bSYour Name 
2790*5113495bSYour Name 
2791*5113495bSYour Name 	if (buf)
2792*5113495bSYour Name 		wma_mgmt_unmap_buf(wma_handle, buf);
2793*5113495bSYour Name 
2794*5113495bSYour Name 	vdev_id = mgmt_txrx_get_vdev_id(pdev, desc_id);
2795*5113495bSYour Name 	mgmt_params.vdev_id = vdev_id;
2796*5113495bSYour Name 
2797*5113495bSYour Name 	wma_mgmt_pktdump_tx_handler(wma_handle, buf, vdev_id, status);
2798*5113495bSYour Name 	ret = mgmt_txrx_tx_completion_handler(pdev, desc_id, status,
2799*5113495bSYour Name 					      &mgmt_params);
2800*5113495bSYour Name 
2801*5113495bSYour Name 	if (ret != QDF_STATUS_SUCCESS) {
2802*5113495bSYour Name 		wma_err("Failed to process mgmt tx completion");
2803*5113495bSYour Name 		return -EINVAL;
2804*5113495bSYour Name 	}
2805*5113495bSYour Name 
2806*5113495bSYour Name 	return 0;
2807*5113495bSYour Name }
2808*5113495bSYour Name 
2809*5113495bSYour Name /**
2810*5113495bSYour Name  * wma_extract_mgmt_offload_event_params() - Extract mgmt event params
2811*5113495bSYour Name  * @params: Management offload event params
2812*5113495bSYour Name  * @hdr: Management header to extract
2813*5113495bSYour Name  *
2814*5113495bSYour Name  * Return: None
2815*5113495bSYour Name  */
wma_extract_mgmt_offload_event_params(struct mgmt_offload_event_params * params,wmi_mgmt_hdr * hdr)2816*5113495bSYour Name static void wma_extract_mgmt_offload_event_params(
2817*5113495bSYour Name 				struct mgmt_offload_event_params *params,
2818*5113495bSYour Name 				wmi_mgmt_hdr *hdr)
2819*5113495bSYour Name {
2820*5113495bSYour Name 	params->tsf_l32 = hdr->tsf_l32;
2821*5113495bSYour Name 	params->chan_freq = hdr->chan_freq;
2822*5113495bSYour Name 	params->rate_kbps = hdr->rate_kbps;
2823*5113495bSYour Name 	params->rssi = hdr->rssi;
2824*5113495bSYour Name 	params->buf_len = hdr->buf_len;
2825*5113495bSYour Name 	params->tx_status = hdr->tx_status;
2826*5113495bSYour Name 	params->tx_retry_cnt = hdr->tx_retry_cnt;
2827*5113495bSYour Name }
2828*5113495bSYour Name 
2829*5113495bSYour Name /**
2830*5113495bSYour Name  * wma_mgmt_tx_completion_handler() - wma mgmt Tx completion event handler
2831*5113495bSYour Name  * @handle: wma handle
2832*5113495bSYour Name  * @cmpl_event_params: completion event handler data
2833*5113495bSYour Name  * @len: length of @cmpl_event_params
2834*5113495bSYour Name  *
2835*5113495bSYour Name  * Return: 0 on success; error number otherwise
2836*5113495bSYour Name  */
2837*5113495bSYour Name 
wma_mgmt_tx_completion_handler(void * handle,uint8_t * cmpl_event_params,uint32_t len)2838*5113495bSYour Name int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params,
2839*5113495bSYour Name 				   uint32_t len)
2840*5113495bSYour Name {
2841*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle)handle;
2842*5113495bSYour Name 	WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
2843*5113495bSYour Name 	wmi_mgmt_tx_compl_event_fixed_param *cmpl_params;
2844*5113495bSYour Name 
2845*5113495bSYour Name 	param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
2846*5113495bSYour Name 		cmpl_event_params;
2847*5113495bSYour Name 	if (!param_buf || !wma_handle) {
2848*5113495bSYour Name 		wma_err("Invalid mgmt Tx completion event");
2849*5113495bSYour Name 		return -EINVAL;
2850*5113495bSYour Name 	}
2851*5113495bSYour Name 	cmpl_params = param_buf->fixed_param;
2852*5113495bSYour Name 
2853*5113495bSYour Name 	if ((ucfg_pkt_capture_get_pktcap_mode(wma_handle->psoc) &
2854*5113495bSYour Name 	    PKT_CAPTURE_MODE_MGMT_ONLY) && param_buf->mgmt_hdr) {
2855*5113495bSYour Name 		struct mgmt_offload_event_params params = {0};
2856*5113495bSYour Name 
2857*5113495bSYour Name 		wma_extract_mgmt_offload_event_params(
2858*5113495bSYour Name 					&params,
2859*5113495bSYour Name 					(wmi_mgmt_hdr *)param_buf->mgmt_hdr);
2860*5113495bSYour Name 		ucfg_pkt_capture_mgmt_tx_completion(wma_handle->pdev,
2861*5113495bSYour Name 						    cmpl_params->desc_id,
2862*5113495bSYour Name 						    cmpl_params->status,
2863*5113495bSYour Name 						    &params);
2864*5113495bSYour Name 	}
2865*5113495bSYour Name 
2866*5113495bSYour Name 	wma_process_mgmt_tx_completion(wma_handle, cmpl_params->desc_id,
2867*5113495bSYour Name 				       cmpl_params->status);
2868*5113495bSYour Name 
2869*5113495bSYour Name 	return 0;
2870*5113495bSYour Name }
2871*5113495bSYour Name 
2872*5113495bSYour Name /**
2873*5113495bSYour Name  * wma_mgmt_tx_bundle_completion_handler() - mgmt bundle comp handler
2874*5113495bSYour Name  * @handle: wma handle
2875*5113495bSYour Name  * @buf: buffer
2876*5113495bSYour Name  * @len: length
2877*5113495bSYour Name  *
2878*5113495bSYour Name  * Return: 0 for success or error code
2879*5113495bSYour Name  */
wma_mgmt_tx_bundle_completion_handler(void * handle,uint8_t * buf,uint32_t len)2880*5113495bSYour Name int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf,
2881*5113495bSYour Name 				   uint32_t len)
2882*5113495bSYour Name {
2883*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle)handle;
2884*5113495bSYour Name 	WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *param_buf;
2885*5113495bSYour Name 	wmi_mgmt_tx_compl_bundle_event_fixed_param	*cmpl_params;
2886*5113495bSYour Name 	uint32_t num_reports;
2887*5113495bSYour Name 	uint32_t *desc_ids;
2888*5113495bSYour Name 	uint32_t *status;
2889*5113495bSYour Name 	uint32_t i, buf_len;
2890*5113495bSYour Name 	bool excess_data = false;
2891*5113495bSYour Name 
2892*5113495bSYour Name 	param_buf = (WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *)buf;
2893*5113495bSYour Name 	if (!param_buf || !wma_handle) {
2894*5113495bSYour Name 		wma_err("Invalid mgmt Tx completion event");
2895*5113495bSYour Name 		return -EINVAL;
2896*5113495bSYour Name 	}
2897*5113495bSYour Name 	cmpl_params = param_buf->fixed_param;
2898*5113495bSYour Name 	num_reports = cmpl_params->num_reports;
2899*5113495bSYour Name 	desc_ids = (uint32_t *)(param_buf->desc_ids);
2900*5113495bSYour Name 	status = (uint32_t *)(param_buf->status);
2901*5113495bSYour Name 
2902*5113495bSYour Name 	/* buf contains num_reports * sizeof(uint32) len of desc_ids and
2903*5113495bSYour Name 	 * num_reports * sizeof(uint32) status,
2904*5113495bSYour Name 	 * so (2 x (num_reports * sizeof(uint32)) should not exceed MAX
2905*5113495bSYour Name 	 */
2906*5113495bSYour Name 	if (cmpl_params->num_reports > (WMI_SVC_MSG_MAX_SIZE /
2907*5113495bSYour Name 	    (2 * sizeof(uint32_t))))
2908*5113495bSYour Name 		excess_data = true;
2909*5113495bSYour Name 	else
2910*5113495bSYour Name 		buf_len = cmpl_params->num_reports * (2 * sizeof(uint32_t));
2911*5113495bSYour Name 
2912*5113495bSYour Name 	if (excess_data || (sizeof(*cmpl_params) > (WMI_SVC_MSG_MAX_SIZE -
2913*5113495bSYour Name 	    buf_len))) {
2914*5113495bSYour Name 		wma_err("excess wmi buffer: num_reports %d",
2915*5113495bSYour Name 			cmpl_params->num_reports);
2916*5113495bSYour Name 		return -EINVAL;
2917*5113495bSYour Name 	}
2918*5113495bSYour Name 
2919*5113495bSYour Name 	if ((cmpl_params->num_reports > param_buf->num_desc_ids) ||
2920*5113495bSYour Name 	    (cmpl_params->num_reports > param_buf->num_status)) {
2921*5113495bSYour Name 		wma_err("Invalid num_reports %d, num_desc_ids %d, num_status %d",
2922*5113495bSYour Name 			 cmpl_params->num_reports, param_buf->num_desc_ids,
2923*5113495bSYour Name 			 param_buf->num_status);
2924*5113495bSYour Name 		return -EINVAL;
2925*5113495bSYour Name 	}
2926*5113495bSYour Name 
2927*5113495bSYour Name 	for (i = 0; i < num_reports; i++) {
2928*5113495bSYour Name 		if ((ucfg_pkt_capture_get_pktcap_mode(wma_handle->psoc) &
2929*5113495bSYour Name 		    PKT_CAPTURE_MODE_MGMT_ONLY) && param_buf->mgmt_hdr) {
2930*5113495bSYour Name 			struct mgmt_offload_event_params params = {0};
2931*5113495bSYour Name 
2932*5113495bSYour Name 			wma_extract_mgmt_offload_event_params(
2933*5113495bSYour Name 				&params,
2934*5113495bSYour Name 				&((wmi_mgmt_hdr *)param_buf->mgmt_hdr)[i]);
2935*5113495bSYour Name 			ucfg_pkt_capture_mgmt_tx_completion(
2936*5113495bSYour Name 				wma_handle->pdev, desc_ids[i],
2937*5113495bSYour Name 				status[i], &params);
2938*5113495bSYour Name 		}
2939*5113495bSYour Name 
2940*5113495bSYour Name 		wma_process_mgmt_tx_completion(wma_handle,
2941*5113495bSYour Name 					       desc_ids[i], status[i]);
2942*5113495bSYour Name 	}
2943*5113495bSYour Name 	return 0;
2944*5113495bSYour Name }
2945*5113495bSYour Name 
2946*5113495bSYour Name /**
2947*5113495bSYour Name  * wma_process_update_opmode() - process update VHT opmode cmd from UMAC
2948*5113495bSYour Name  * @wma_handle: wma handle
2949*5113495bSYour Name  * @update_vht_opmode: vht opmode
2950*5113495bSYour Name  *
2951*5113495bSYour Name  * Return: none
2952*5113495bSYour Name  */
wma_process_update_opmode(tp_wma_handle wma_handle,tUpdateVHTOpMode * update_vht_opmode)2953*5113495bSYour Name void wma_process_update_opmode(tp_wma_handle wma_handle,
2954*5113495bSYour Name 			       tUpdateVHTOpMode *update_vht_opmode)
2955*5113495bSYour Name {
2956*5113495bSYour Name 	wmi_host_channel_width ch_width;
2957*5113495bSYour Name 	uint8_t pdev_id;
2958*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
2959*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc = wma_handle->psoc;
2960*5113495bSYour Name 	enum wlan_phymode peer_phymode;
2961*5113495bSYour Name 	uint32_t fw_phymode;
2962*5113495bSYour Name 	enum wlan_peer_type peer_type;
2963*5113495bSYour Name 
2964*5113495bSYour Name 	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev);
2965*5113495bSYour Name 	peer = wlan_objmgr_get_peer(psoc, pdev_id,
2966*5113495bSYour Name 				    update_vht_opmode->peer_mac,
2967*5113495bSYour Name 				    WLAN_LEGACY_WMA_ID);
2968*5113495bSYour Name 	if (!peer) {
2969*5113495bSYour Name 		wma_err("peer object invalid");
2970*5113495bSYour Name 		return;
2971*5113495bSYour Name 	}
2972*5113495bSYour Name 
2973*5113495bSYour Name 	peer_type = wlan_peer_get_peer_type(peer);
2974*5113495bSYour Name 	if (peer_type == WLAN_PEER_SELF) {
2975*5113495bSYour Name 		wma_err("self peer wrongly used");
2976*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
2977*5113495bSYour Name 		return;
2978*5113495bSYour Name 	}
2979*5113495bSYour Name 
2980*5113495bSYour Name 	wlan_peer_obj_lock(peer);
2981*5113495bSYour Name 	peer_phymode = wlan_peer_get_phymode(peer);
2982*5113495bSYour Name 	wlan_peer_obj_unlock(peer);
2983*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
2984*5113495bSYour Name 
2985*5113495bSYour Name 	fw_phymode = wmi_host_to_fw_phymode(peer_phymode);
2986*5113495bSYour Name 
2987*5113495bSYour Name 	ch_width = wmi_get_ch_width_from_phy_mode(wma_handle->wmi_handle,
2988*5113495bSYour Name 						  fw_phymode);
2989*5113495bSYour Name 	wma_debug("ch_width: %d, fw phymode: %d peer_phymode: %d, op_mode: %d",
2990*5113495bSYour Name 		  ch_width, fw_phymode, peer_phymode,
2991*5113495bSYour Name 		  update_vht_opmode->opMode);
2992*5113495bSYour Name 
2993*5113495bSYour Name 	if (ch_width < update_vht_opmode->opMode) {
2994*5113495bSYour Name 		wma_err("Invalid peer bw update %d, self bw %d",
2995*5113495bSYour Name 			update_vht_opmode->opMode, ch_width);
2996*5113495bSYour Name 		return;
2997*5113495bSYour Name 	}
2998*5113495bSYour Name 
2999*5113495bSYour Name 	wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
3000*5113495bSYour Name 			   WMI_HOST_PEER_CHWIDTH, update_vht_opmode->opMode,
3001*5113495bSYour Name 			   update_vht_opmode->smesessionId);
3002*5113495bSYour Name 
3003*5113495bSYour Name 	wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
3004*5113495bSYour Name 			   WMI_HOST_PEER_PHYMODE,
3005*5113495bSYour Name 			   fw_phymode, update_vht_opmode->smesessionId);
3006*5113495bSYour Name }
3007*5113495bSYour Name 
3008*5113495bSYour Name /**
3009*5113495bSYour Name  * wma_process_update_rx_nss() - process update RX NSS cmd from UMAC
3010*5113495bSYour Name  * @wma_handle: wma handle
3011*5113495bSYour Name  * @update_rx_nss: rx nss value
3012*5113495bSYour Name  *
3013*5113495bSYour Name  * Return: none
3014*5113495bSYour Name  */
wma_process_update_rx_nss(tp_wma_handle wma_handle,tUpdateRxNss * update_rx_nss)3015*5113495bSYour Name void wma_process_update_rx_nss(tp_wma_handle wma_handle,
3016*5113495bSYour Name 			       tUpdateRxNss *update_rx_nss)
3017*5113495bSYour Name {
3018*5113495bSYour Name 	struct target_psoc_info *tgt_hdl;
3019*5113495bSYour Name 	struct wma_txrx_node *intr =
3020*5113495bSYour Name 		&wma_handle->interfaces[update_rx_nss->smesessionId];
3021*5113495bSYour Name 	int rx_nss = update_rx_nss->rxNss;
3022*5113495bSYour Name 	int num_rf_chains;
3023*5113495bSYour Name 
3024*5113495bSYour Name 	tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
3025*5113495bSYour Name 	if (!tgt_hdl) {
3026*5113495bSYour Name 		wma_err("target psoc info is NULL");
3027*5113495bSYour Name 		return;
3028*5113495bSYour Name 	}
3029*5113495bSYour Name 
3030*5113495bSYour Name 	num_rf_chains = target_if_get_num_rf_chains(tgt_hdl);
3031*5113495bSYour Name 	if (rx_nss > num_rf_chains || rx_nss > WMA_MAX_NSS)
3032*5113495bSYour Name 		rx_nss = QDF_MIN(num_rf_chains, WMA_MAX_NSS);
3033*5113495bSYour Name 
3034*5113495bSYour Name 	intr->nss = (uint8_t)rx_nss;
3035*5113495bSYour Name 	update_rx_nss->rxNss = (uint32_t)rx_nss;
3036*5113495bSYour Name 
3037*5113495bSYour Name 	wma_debug("Rx Nss = %d", update_rx_nss->rxNss);
3038*5113495bSYour Name 
3039*5113495bSYour Name 	wma_set_peer_param(wma_handle, update_rx_nss->peer_mac,
3040*5113495bSYour Name 			   WMI_HOST_PEER_NSS, update_rx_nss->rxNss,
3041*5113495bSYour Name 			   update_rx_nss->smesessionId);
3042*5113495bSYour Name }
3043*5113495bSYour Name 
3044*5113495bSYour Name /**
3045*5113495bSYour Name  * wma_process_update_membership() - process update group membership cmd
3046*5113495bSYour Name  * @wma_handle: wma handle
3047*5113495bSYour Name  * @membership: group membership info
3048*5113495bSYour Name  *
3049*5113495bSYour Name  * Return: none
3050*5113495bSYour Name  */
wma_process_update_membership(tp_wma_handle wma_handle,tUpdateMembership * membership)3051*5113495bSYour Name void wma_process_update_membership(tp_wma_handle wma_handle,
3052*5113495bSYour Name 				   tUpdateMembership *membership)
3053*5113495bSYour Name {
3054*5113495bSYour Name 	wma_debug("membership = %x ", membership->membership);
3055*5113495bSYour Name 
3056*5113495bSYour Name 	wma_set_peer_param(wma_handle, membership->peer_mac,
3057*5113495bSYour Name 			   WMI_HOST_PEER_MEMBERSHIP, membership->membership,
3058*5113495bSYour Name 			   membership->smesessionId);
3059*5113495bSYour Name }
3060*5113495bSYour Name 
3061*5113495bSYour Name /**
3062*5113495bSYour Name  * wma_process_update_userpos() - process update user pos cmd from UMAC
3063*5113495bSYour Name  * @wma_handle: wma handle
3064*5113495bSYour Name  * @userpos: user pos value
3065*5113495bSYour Name  *
3066*5113495bSYour Name  * Return: none
3067*5113495bSYour Name  */
wma_process_update_userpos(tp_wma_handle wma_handle,tUpdateUserPos * userpos)3068*5113495bSYour Name void wma_process_update_userpos(tp_wma_handle wma_handle,
3069*5113495bSYour Name 				tUpdateUserPos *userpos)
3070*5113495bSYour Name {
3071*5113495bSYour Name 	wma_debug("userPos = %x ", userpos->userPos);
3072*5113495bSYour Name 
3073*5113495bSYour Name 	wma_set_peer_param(wma_handle, userpos->peer_mac,
3074*5113495bSYour Name 			   WMI_HOST_PEER_USERPOS, userpos->userPos,
3075*5113495bSYour Name 			   userpos->smesessionId);
3076*5113495bSYour Name 
3077*5113495bSYour Name 	/* Now that membership/userpos is updated in fw,
3078*5113495bSYour Name 	 * enable GID PPS.
3079*5113495bSYour Name 	 */
3080*5113495bSYour Name 	wma_set_ppsconfig(userpos->smesessionId, WMA_VHT_PPS_GID_MATCH, 1);
3081*5113495bSYour Name 
3082*5113495bSYour Name }
3083*5113495bSYour Name 
wma_set_cts2self_for_p2p_go(void * wma_handle,uint32_t cts2self_for_p2p_go)3084*5113495bSYour Name QDF_STATUS wma_set_cts2self_for_p2p_go(void *wma_handle,
3085*5113495bSYour Name 				    uint32_t cts2self_for_p2p_go)
3086*5113495bSYour Name {
3087*5113495bSYour Name 	int32_t ret;
3088*5113495bSYour Name 	tp_wma_handle wma = (tp_wma_handle)wma_handle;
3089*5113495bSYour Name 	struct pdev_params pdevparam = {};
3090*5113495bSYour Name 
3091*5113495bSYour Name 	pdevparam.param_id = wmi_pdev_param_cts2self_for_p2p_go_config;
3092*5113495bSYour Name 	pdevparam.param_value = cts2self_for_p2p_go;
3093*5113495bSYour Name 
3094*5113495bSYour Name 	ret = wmi_unified_pdev_param_send(wma->wmi_handle,
3095*5113495bSYour Name 			&pdevparam,
3096*5113495bSYour Name 			WMA_WILDCARD_PDEV_ID);
3097*5113495bSYour Name 	if (ret) {
3098*5113495bSYour Name 		wma_err("Fail to Set CTS2SELF for p2p GO %d",
3099*5113495bSYour Name 			cts2self_for_p2p_go);
3100*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3101*5113495bSYour Name 	}
3102*5113495bSYour Name 
3103*5113495bSYour Name 	wma_nofl_debug("Successfully Set CTS2SELF for p2p GO %d",
3104*5113495bSYour Name 		       cts2self_for_p2p_go);
3105*5113495bSYour Name 
3106*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3107*5113495bSYour Name }
3108*5113495bSYour Name 
3109*5113495bSYour Name 
3110*5113495bSYour Name /**
3111*5113495bSYour Name  * wma_set_htconfig() - set ht config parameters to target
3112*5113495bSYour Name  * @vdev_id: vdev id
3113*5113495bSYour Name  * @ht_capab: ht capability
3114*5113495bSYour Name  * @value: value of ht param
3115*5113495bSYour Name  *
3116*5113495bSYour Name  * Return: QDF status
3117*5113495bSYour Name  */
wma_set_htconfig(uint8_t vdev_id,uint16_t ht_capab,int value)3118*5113495bSYour Name QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value)
3119*5113495bSYour Name {
3120*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
3121*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_E_FAILURE;
3122*5113495bSYour Name 
3123*5113495bSYour Name 	if (!wma)
3124*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3125*5113495bSYour Name 
3126*5113495bSYour Name 	switch (ht_capab) {
3127*5113495bSYour Name 	case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
3128*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3129*5113495bSYour Name 						      wmi_vdev_param_ldpc,
3130*5113495bSYour Name 						      value);
3131*5113495bSYour Name 		break;
3132*5113495bSYour Name 	case WNI_CFG_HT_CAP_INFO_TX_STBC:
3133*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3134*5113495bSYour Name 						      wmi_vdev_param_tx_stbc,
3135*5113495bSYour Name 						      value);
3136*5113495bSYour Name 		break;
3137*5113495bSYour Name 	case WNI_CFG_HT_CAP_INFO_RX_STBC:
3138*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3139*5113495bSYour Name 						      wmi_vdev_param_rx_stbc,
3140*5113495bSYour Name 						      value);
3141*5113495bSYour Name 		break;
3142*5113495bSYour Name 	case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
3143*5113495bSYour Name 	case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
3144*5113495bSYour Name 		wma_err("ht_capab = %d, value = %d", ht_capab,
3145*5113495bSYour Name 			 value);
3146*5113495bSYour Name 		ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3147*5113495bSYour Name 						wmi_vdev_param_sgi, value);
3148*5113495bSYour Name 		if (ret == QDF_STATUS_SUCCESS)
3149*5113495bSYour Name 			wma->interfaces[vdev_id].config.shortgi = value;
3150*5113495bSYour Name 		break;
3151*5113495bSYour Name 	default:
3152*5113495bSYour Name 		wma_err("INVALID HT CONFIG");
3153*5113495bSYour Name 	}
3154*5113495bSYour Name 
3155*5113495bSYour Name 	return ret;
3156*5113495bSYour Name }
3157*5113495bSYour Name 
3158*5113495bSYour Name /**
3159*5113495bSYour Name  * wma_extract_ccmp_pn() - extract 6 byte PN from the CCMP header
3160*5113495bSYour Name  * @ccmp_ptr: CCMP header
3161*5113495bSYour Name  *
3162*5113495bSYour Name  * Return: PN extracted from header.
3163*5113495bSYour Name  */
wma_extract_ccmp_pn(uint8_t * ccmp_ptr)3164*5113495bSYour Name static uint64_t wma_extract_ccmp_pn(uint8_t *ccmp_ptr)
3165*5113495bSYour Name {
3166*5113495bSYour Name 	uint8_t rsvd, key, pn[6];
3167*5113495bSYour Name 	uint64_t new_pn;
3168*5113495bSYour Name 
3169*5113495bSYour Name 	/*
3170*5113495bSYour Name 	 *   +-----+-----+------+----------+-----+-----+-----+-----+
3171*5113495bSYour Name 	 *   | PN0 | PN1 | rsvd | rsvd/key | PN2 | PN3 | PN4 | PN5 |
3172*5113495bSYour Name 	 *   +-----+-----+------+----------+-----+-----+-----+-----+
3173*5113495bSYour Name 	 *                   CCMP Header Format
3174*5113495bSYour Name 	 */
3175*5113495bSYour Name 
3176*5113495bSYour Name 	/* Extract individual bytes */
3177*5113495bSYour Name 	pn[0] = (uint8_t) *ccmp_ptr;
3178*5113495bSYour Name 	pn[1] = (uint8_t) *(ccmp_ptr + 1);
3179*5113495bSYour Name 	rsvd = (uint8_t) *(ccmp_ptr + 2);
3180*5113495bSYour Name 	key = (uint8_t) *(ccmp_ptr + 3);
3181*5113495bSYour Name 	pn[2] = (uint8_t) *(ccmp_ptr + 4);
3182*5113495bSYour Name 	pn[3] = (uint8_t) *(ccmp_ptr + 5);
3183*5113495bSYour Name 	pn[4] = (uint8_t) *(ccmp_ptr + 6);
3184*5113495bSYour Name 	pn[5] = (uint8_t) *(ccmp_ptr + 7);
3185*5113495bSYour Name 
3186*5113495bSYour Name 	/* Form 6 byte PN with 6 individual bytes of PN */
3187*5113495bSYour Name 	new_pn = ((uint64_t) pn[5] << 40) |
3188*5113495bSYour Name 		 ((uint64_t) pn[4] << 32) |
3189*5113495bSYour Name 		 ((uint64_t) pn[3] << 24) |
3190*5113495bSYour Name 		 ((uint64_t) pn[2] << 16) |
3191*5113495bSYour Name 		 ((uint64_t) pn[1] << 8) | ((uint64_t) pn[0] << 0);
3192*5113495bSYour Name 
3193*5113495bSYour Name 	return new_pn;
3194*5113495bSYour Name }
3195*5113495bSYour Name 
3196*5113495bSYour Name /**
3197*5113495bSYour Name  * wma_is_ccmp_pn_replay_attack() - detect replay attacking using PN in CCMP
3198*5113495bSYour Name  * @wma: wma context
3199*5113495bSYour Name  * @wh: 802.11 frame header
3200*5113495bSYour Name  * @ccmp_ptr: CCMP frame header
3201*5113495bSYour Name  *
3202*5113495bSYour Name  * Return: true/false
3203*5113495bSYour Name  */
3204*5113495bSYour Name static bool
wma_is_ccmp_pn_replay_attack(tp_wma_handle wma,struct ieee80211_frame * wh,uint8_t * ccmp_ptr)3205*5113495bSYour Name wma_is_ccmp_pn_replay_attack(tp_wma_handle wma, struct ieee80211_frame *wh,
3206*5113495bSYour Name 			     uint8_t *ccmp_ptr)
3207*5113495bSYour Name {
3208*5113495bSYour Name 	uint64_t new_pn;
3209*5113495bSYour Name 	bool ret = false;
3210*5113495bSYour Name 	struct peer_mlme_priv_obj *peer_priv;
3211*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
3212*5113495bSYour Name 
3213*5113495bSYour Name 	new_pn = wma_extract_ccmp_pn(ccmp_ptr);
3214*5113495bSYour Name 
3215*5113495bSYour Name 	peer = wlan_objmgr_get_peer_by_mac(wma->psoc, wh->i_addr2,
3216*5113495bSYour Name 					   WLAN_LEGACY_WMA_ID);
3217*5113495bSYour Name 	if (!peer)
3218*5113495bSYour Name 		return ret;
3219*5113495bSYour Name 
3220*5113495bSYour Name 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
3221*5113495bSYour Name 							  WLAN_UMAC_COMP_MLME);
3222*5113495bSYour Name 	if (!peer_priv) {
3223*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
3224*5113495bSYour Name 		return ret;
3225*5113495bSYour Name 	}
3226*5113495bSYour Name 
3227*5113495bSYour Name 	if (peer_priv->last_pn_valid) {
3228*5113495bSYour Name 		if (new_pn > peer_priv->last_pn) {
3229*5113495bSYour Name 			peer_priv->last_pn = new_pn;
3230*5113495bSYour Name 		} else {
3231*5113495bSYour Name 			wma_err_rl("PN Replay attack detected");
3232*5113495bSYour Name 			/* per 11W amendment, keeping track of replay attacks */
3233*5113495bSYour Name 			peer_priv->rmf_pn_replays += 1;
3234*5113495bSYour Name 			ret = true;
3235*5113495bSYour Name 		}
3236*5113495bSYour Name 	} else {
3237*5113495bSYour Name 		peer_priv->last_pn_valid = 1;
3238*5113495bSYour Name 		peer_priv->last_pn = new_pn;
3239*5113495bSYour Name 	}
3240*5113495bSYour Name 
3241*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
3242*5113495bSYour Name 
3243*5113495bSYour Name 	return ret;
3244*5113495bSYour Name }
3245*5113495bSYour Name 
3246*5113495bSYour Name /**
3247*5113495bSYour Name  * wma_process_bip() - process mmie in rmf frame
3248*5113495bSYour Name  * @wma_handle: wma handle
3249*5113495bSYour Name  * @iface: txrx node
3250*5113495bSYour Name  * @wh: 80211 frame
3251*5113495bSYour Name  * @wbuf: Buffer
3252*5113495bSYour Name  *
3253*5113495bSYour Name  * Return: 0 for success or error code
3254*5113495bSYour Name  */
3255*5113495bSYour Name static
wma_process_bip(tp_wma_handle wma_handle,struct wma_txrx_node * iface,struct ieee80211_frame * wh,qdf_nbuf_t wbuf)3256*5113495bSYour Name int wma_process_bip(tp_wma_handle wma_handle, struct wma_txrx_node *iface,
3257*5113495bSYour Name 		    struct ieee80211_frame *wh, qdf_nbuf_t wbuf)
3258*5113495bSYour Name {
3259*5113495bSYour Name 	uint16_t mmie_size;
3260*5113495bSYour Name 	uint8_t *efrm;
3261*5113495bSYour Name 	int32_t mgmtcipherset;
3262*5113495bSYour Name 	enum wlan_crypto_cipher_type key_cipher;
3263*5113495bSYour Name 
3264*5113495bSYour Name 	efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf);
3265*5113495bSYour Name 
3266*5113495bSYour Name 	mgmtcipherset = wlan_crypto_get_param(iface->vdev,
3267*5113495bSYour Name 					      WLAN_CRYPTO_PARAM_MGMT_CIPHER);
3268*5113495bSYour Name 	if (mgmtcipherset <= 0) {
3269*5113495bSYour Name 		wma_err("Invalid key cipher %d", mgmtcipherset);
3270*5113495bSYour Name 		return -EINVAL;
3271*5113495bSYour Name 	}
3272*5113495bSYour Name 
3273*5113495bSYour Name 	if (mgmtcipherset & (1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) {
3274*5113495bSYour Name 		key_cipher = WLAN_CRYPTO_CIPHER_AES_CMAC;
3275*5113495bSYour Name 		mmie_size = cds_get_mmie_size();
3276*5113495bSYour Name 	} else if (mgmtcipherset & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC)) {
3277*5113495bSYour Name 		key_cipher = WLAN_CRYPTO_CIPHER_AES_GMAC;
3278*5113495bSYour Name 		mmie_size = cds_get_gmac_mmie_size();
3279*5113495bSYour Name 	} else if (mgmtcipherset & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
3280*5113495bSYour Name 		key_cipher = WLAN_CRYPTO_CIPHER_AES_GMAC_256;
3281*5113495bSYour Name 		mmie_size = cds_get_gmac_mmie_size();
3282*5113495bSYour Name 	} else {
3283*5113495bSYour Name 		wma_err("Invalid key cipher %d", mgmtcipherset);
3284*5113495bSYour Name 		return -EINVAL;
3285*5113495bSYour Name 	}
3286*5113495bSYour Name 
3287*5113495bSYour Name 	/* Check if frame is invalid length */
3288*5113495bSYour Name 	if (efrm - (uint8_t *)wh < sizeof(*wh) + mmie_size) {
3289*5113495bSYour Name 		wma_err("Invalid frame length");
3290*5113495bSYour Name 		return -EINVAL;
3291*5113495bSYour Name 	}
3292*5113495bSYour Name 
3293*5113495bSYour Name 	switch (key_cipher) {
3294*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_CMAC:
3295*5113495bSYour Name 		if (!wmi_service_enabled(wma_handle->wmi_handle,
3296*5113495bSYour Name 					 wmi_service_sta_pmf_offload)) {
3297*5113495bSYour Name 			if (!wlan_crypto_is_mmie_valid(iface->vdev,
3298*5113495bSYour Name 						       (uint8_t *)wh, efrm)) {
3299*5113495bSYour Name 				wma_debug("BC/MC MIC error or MMIE not present, dropping the frame");
3300*5113495bSYour Name 				return -EINVAL;
3301*5113495bSYour Name 			}
3302*5113495bSYour Name 		}
3303*5113495bSYour Name 		break;
3304*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_GMAC:
3305*5113495bSYour Name 	case WLAN_CRYPTO_CIPHER_AES_GMAC_256:
3306*5113495bSYour Name 		if (!wmi_service_enabled(wma_handle->wmi_handle,
3307*5113495bSYour Name 					 wmi_service_gmac_offload_support)) {
3308*5113495bSYour Name 			if (!wlan_crypto_is_mmie_valid(iface->vdev,
3309*5113495bSYour Name 						       (uint8_t *)wh, efrm)) {
3310*5113495bSYour Name 				wma_debug("BC/MC GMAC MIC error or MMIE not present, dropping the frame");
3311*5113495bSYour Name 				return -EINVAL;
3312*5113495bSYour Name 			}
3313*5113495bSYour Name 		}
3314*5113495bSYour Name 		break;
3315*5113495bSYour Name 	default:
3316*5113495bSYour Name 		wma_err("Invalid key_type %d", key_cipher);
3317*5113495bSYour Name 		return -EINVAL;
3318*5113495bSYour Name 	}
3319*5113495bSYour Name 
3320*5113495bSYour Name 	qdf_nbuf_trim_tail(wbuf, mmie_size);
3321*5113495bSYour Name 
3322*5113495bSYour Name 	return 0;
3323*5113495bSYour Name }
3324*5113495bSYour Name 
3325*5113495bSYour Name /**
3326*5113495bSYour Name  * wma_process_rmf_frame() - process rmf frame
3327*5113495bSYour Name  * @wma_handle: wma handle
3328*5113495bSYour Name  * @iface: txrx node
3329*5113495bSYour Name  * @wh: 80211 frame
3330*5113495bSYour Name  * @rx_pkt: rx packet
3331*5113495bSYour Name  * @wbuf: Buffer
3332*5113495bSYour Name  *
3333*5113495bSYour Name  * Return: 0 for success or error code
3334*5113495bSYour Name  */
3335*5113495bSYour Name static
wma_process_rmf_frame(tp_wma_handle wma_handle,struct wma_txrx_node * iface,struct ieee80211_frame * wh,cds_pkt_t * rx_pkt,qdf_nbuf_t wbuf)3336*5113495bSYour Name int wma_process_rmf_frame(tp_wma_handle wma_handle,
3337*5113495bSYour Name 	struct wma_txrx_node *iface,
3338*5113495bSYour Name 	struct ieee80211_frame *wh,
3339*5113495bSYour Name 	cds_pkt_t *rx_pkt,
3340*5113495bSYour Name 	qdf_nbuf_t wbuf)
3341*5113495bSYour Name {
3342*5113495bSYour Name 	uint8_t *orig_hdr;
3343*5113495bSYour Name 	uint8_t *ccmp;
3344*5113495bSYour Name 	uint8_t mic_len, hdr_len, pdev_id;
3345*5113495bSYour Name 	QDF_STATUS status;
3346*5113495bSYour Name 
3347*5113495bSYour Name 	if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) {
3348*5113495bSYour Name 		if (QDF_IS_ADDR_BROADCAST(wh->i_addr1) ||
3349*5113495bSYour Name 		    IEEE80211_IS_MULTICAST(wh->i_addr1)) {
3350*5113495bSYour Name 			wma_err("Encrypted BC/MC frame dropping the frame");
3351*5113495bSYour Name 			cds_pkt_return_packet(rx_pkt);
3352*5113495bSYour Name 			return -EINVAL;
3353*5113495bSYour Name 		}
3354*5113495bSYour Name 
3355*5113495bSYour Name 		if (iface->type == WMI_VDEV_TYPE_NDI ||
3356*5113495bSYour Name 		    iface->type == WMI_VDEV_TYPE_NAN) {
3357*5113495bSYour Name 			hdr_len = IEEE80211_CCMP_HEADERLEN;
3358*5113495bSYour Name 			mic_len = IEEE80211_CCMP_MICLEN;
3359*5113495bSYour Name 		} else {
3360*5113495bSYour Name 			pdev_id =
3361*5113495bSYour Name 				wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev);
3362*5113495bSYour Name 			status = mlme_get_peer_mic_len(wma_handle->psoc,
3363*5113495bSYour Name 						       pdev_id, wh->i_addr2,
3364*5113495bSYour Name 						       &mic_len, &hdr_len);
3365*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status)) {
3366*5113495bSYour Name 				wma_err("Failed to get mic hdr and length");
3367*5113495bSYour Name 				cds_pkt_return_packet(rx_pkt);
3368*5113495bSYour Name 				return -EINVAL;
3369*5113495bSYour Name 			}
3370*5113495bSYour Name 		}
3371*5113495bSYour Name 
3372*5113495bSYour Name 		if (qdf_nbuf_len(wbuf) < (sizeof(*wh) + hdr_len + mic_len)) {
3373*5113495bSYour Name 			wma_err("Buffer length less than expected %d",
3374*5113495bSYour Name 				 (int)qdf_nbuf_len(wbuf));
3375*5113495bSYour Name 			cds_pkt_return_packet(rx_pkt);
3376*5113495bSYour Name 			return -EINVAL;
3377*5113495bSYour Name 		}
3378*5113495bSYour Name 
3379*5113495bSYour Name 		orig_hdr = (uint8_t *) qdf_nbuf_data(wbuf);
3380*5113495bSYour Name 		/* Pointer to head of CCMP header */
3381*5113495bSYour Name 		ccmp = orig_hdr + sizeof(*wh);
3382*5113495bSYour Name 		if (wma_is_ccmp_pn_replay_attack(wma_handle, wh, ccmp)) {
3383*5113495bSYour Name 			wma_err_rl("Dropping the frame");
3384*5113495bSYour Name 			cds_pkt_return_packet(rx_pkt);
3385*5113495bSYour Name 			return -EINVAL;
3386*5113495bSYour Name 		}
3387*5113495bSYour Name 
3388*5113495bSYour Name 		/* Strip privacy headers (and trailer)
3389*5113495bSYour Name 		 * for a received frame
3390*5113495bSYour Name 		 */
3391*5113495bSYour Name 		qdf_mem_move(orig_hdr +
3392*5113495bSYour Name 			hdr_len, wh,
3393*5113495bSYour Name 			sizeof(*wh));
3394*5113495bSYour Name 		qdf_nbuf_pull_head(wbuf,
3395*5113495bSYour Name 			hdr_len);
3396*5113495bSYour Name 		qdf_nbuf_trim_tail(wbuf, mic_len);
3397*5113495bSYour Name 		/*
3398*5113495bSYour Name 		 * CCMP header has been pulled off
3399*5113495bSYour Name 		 * reinitialize the start pointer of mac header
3400*5113495bSYour Name 		 * to avoid accessing incorrect address
3401*5113495bSYour Name 		 */
3402*5113495bSYour Name 		wh = (struct ieee80211_frame *) qdf_nbuf_data(wbuf);
3403*5113495bSYour Name 		rx_pkt->pkt_meta.mpdu_hdr_ptr =
3404*5113495bSYour Name 				qdf_nbuf_data(wbuf);
3405*5113495bSYour Name 		rx_pkt->pkt_meta.mpdu_len = qdf_nbuf_len(wbuf);
3406*5113495bSYour Name 		rx_pkt->pkt_buf = wbuf;
3407*5113495bSYour Name 		if (rx_pkt->pkt_meta.mpdu_len >=
3408*5113495bSYour Name 			rx_pkt->pkt_meta.mpdu_hdr_len) {
3409*5113495bSYour Name 			rx_pkt->pkt_meta.mpdu_data_len =
3410*5113495bSYour Name 				rx_pkt->pkt_meta.mpdu_len -
3411*5113495bSYour Name 				rx_pkt->pkt_meta.mpdu_hdr_len;
3412*5113495bSYour Name 		} else {
3413*5113495bSYour Name 			wma_err("mpdu len %d less than hdr %d, dropping frame",
3414*5113495bSYour Name 				rx_pkt->pkt_meta.mpdu_len,
3415*5113495bSYour Name 				rx_pkt->pkt_meta.mpdu_hdr_len);
3416*5113495bSYour Name 			cds_pkt_return_packet(rx_pkt);
3417*5113495bSYour Name 			return -EINVAL;
3418*5113495bSYour Name 		}
3419*5113495bSYour Name 
3420*5113495bSYour Name 		if (rx_pkt->pkt_meta.mpdu_data_len > MAX_MGMT_MPDU_LEN) {
3421*5113495bSYour Name 			wma_err("Data Len %d greater than max, dropping frame",
3422*5113495bSYour Name 				rx_pkt->pkt_meta.mpdu_data_len);
3423*5113495bSYour Name 			cds_pkt_return_packet(rx_pkt);
3424*5113495bSYour Name 			return -EINVAL;
3425*5113495bSYour Name 		}
3426*5113495bSYour Name 		rx_pkt->pkt_meta.mpdu_data_ptr =
3427*5113495bSYour Name 		rx_pkt->pkt_meta.mpdu_hdr_ptr +
3428*5113495bSYour Name 		rx_pkt->pkt_meta.mpdu_hdr_len;
3429*5113495bSYour Name 		wma_debug("BSSID: "QDF_MAC_ADDR_FMT" tsf_delta: %u",
3430*5113495bSYour Name 			  QDF_MAC_ADDR_REF(wh->i_addr3),
3431*5113495bSYour Name 			  rx_pkt->pkt_meta.tsf_delta);
3432*5113495bSYour Name 	} else {
3433*5113495bSYour Name 		if (QDF_IS_ADDR_BROADCAST(wh->i_addr1) ||
3434*5113495bSYour Name 		    IEEE80211_IS_MULTICAST(wh->i_addr1)) {
3435*5113495bSYour Name 			if (0 != wma_process_bip(wma_handle, iface, wh, wbuf)) {
3436*5113495bSYour Name 				cds_pkt_return_packet(rx_pkt);
3437*5113495bSYour Name 				return -EINVAL;
3438*5113495bSYour Name 			}
3439*5113495bSYour Name 		} else {
3440*5113495bSYour Name 			wma_err_rl("Rx unprotected unicast mgmt frame");
3441*5113495bSYour Name 			rx_pkt->pkt_meta.dpuFeedback =
3442*5113495bSYour Name 				DPU_FEEDBACK_UNPROTECTED_ERROR;
3443*5113495bSYour Name 		}
3444*5113495bSYour Name 	}
3445*5113495bSYour Name 	return 0;
3446*5113495bSYour Name }
3447*5113495bSYour Name 
3448*5113495bSYour Name /**
3449*5113495bSYour Name  * wma_get_peer_pmf_status() - Get the PMF capability of peer
3450*5113495bSYour Name  * @wma: wma handle
3451*5113495bSYour Name  * @peer_mac: peer mac addr
3452*5113495bSYour Name  *
3453*5113495bSYour Name  * Return: True if PMF is enabled, false otherwise.
3454*5113495bSYour Name  */
3455*5113495bSYour Name static bool
wma_get_peer_pmf_status(tp_wma_handle wma,uint8_t * peer_mac)3456*5113495bSYour Name wma_get_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac)
3457*5113495bSYour Name {
3458*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
3459*5113495bSYour Name 	bool is_pmf_enabled;
3460*5113495bSYour Name 
3461*5113495bSYour Name 	if (!peer_mac) {
3462*5113495bSYour Name 		wma_err("peer_mac is NULL");
3463*5113495bSYour Name 		return false;
3464*5113495bSYour Name 	}
3465*5113495bSYour Name 
3466*5113495bSYour Name 	peer = wlan_objmgr_get_peer(wma->psoc,
3467*5113495bSYour Name 				    wlan_objmgr_pdev_get_pdev_id(wma->pdev),
3468*5113495bSYour Name 				    peer_mac, WLAN_LEGACY_WMA_ID);
3469*5113495bSYour Name 	if (!peer) {
3470*5113495bSYour Name 		wma_debug("Peer of peer_mac " QDF_MAC_ADDR_FMT " not found",
3471*5113495bSYour Name 			  QDF_MAC_ADDR_REF(peer_mac));
3472*5113495bSYour Name 		return false;
3473*5113495bSYour Name 	}
3474*5113495bSYour Name 	is_pmf_enabled = mlme_get_peer_pmf_status(peer);
3475*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
3476*5113495bSYour Name 	wma_nofl_debug("get is_pmf_enabled %d for "QDF_MAC_ADDR_FMT,
3477*5113495bSYour Name 		       is_pmf_enabled, QDF_MAC_ADDR_REF(peer_mac));
3478*5113495bSYour Name 
3479*5113495bSYour Name 	return is_pmf_enabled;
3480*5113495bSYour Name }
3481*5113495bSYour Name 
3482*5113495bSYour Name /**
3483*5113495bSYour Name  * wma_check_and_process_rmf_frame() - Process the frame if it is of rmf type
3484*5113495bSYour Name  * @wma_handle: wma handle
3485*5113495bSYour Name  * @vdev_id: vdev id
3486*5113495bSYour Name  * @wh: double pointer to 802.11 frame header which will be updated if the
3487*5113495bSYour Name  *	frame is of rmf type.
3488*5113495bSYour Name  * @rx_pkt: rx packet
3489*5113495bSYour Name  * @buf: Buffer
3490*5113495bSYour Name  *
3491*5113495bSYour Name  * Process the frame as rmf frame only if both DUT and peer are of PMF capable
3492*5113495bSYour Name  *
3493*5113495bSYour Name  * Return: 0 for success or error code
3494*5113495bSYour Name  */
3495*5113495bSYour Name static int
wma_check_and_process_rmf_frame(tp_wma_handle wma_handle,uint8_t vdev_id,struct ieee80211_frame ** wh,cds_pkt_t * rx_pkt,qdf_nbuf_t buf)3496*5113495bSYour Name wma_check_and_process_rmf_frame(tp_wma_handle wma_handle,
3497*5113495bSYour Name 				uint8_t vdev_id,
3498*5113495bSYour Name 				struct ieee80211_frame **wh,
3499*5113495bSYour Name 				cds_pkt_t *rx_pkt,
3500*5113495bSYour Name 				qdf_nbuf_t buf)
3501*5113495bSYour Name {
3502*5113495bSYour Name 	int status;
3503*5113495bSYour Name 	struct wma_txrx_node *iface;
3504*5113495bSYour Name 	struct ieee80211_frame *hdr = *wh;
3505*5113495bSYour Name 
3506*5113495bSYour Name 	iface = &(wma_handle->interfaces[vdev_id]);
3507*5113495bSYour Name 	if ((iface->type != WMI_VDEV_TYPE_NDI &&
3508*5113495bSYour Name 	     iface->type != WMI_VDEV_TYPE_NAN) && !iface->rmfEnabled)
3509*5113495bSYour Name 		return 0;
3510*5113495bSYour Name 
3511*5113495bSYour Name 	if (qdf_is_macaddr_group((struct qdf_mac_addr *)(hdr->i_addr1)) ||
3512*5113495bSYour Name 	    qdf_is_macaddr_broadcast((struct qdf_mac_addr *)(hdr->i_addr1)) ||
3513*5113495bSYour Name 	    wma_get_peer_pmf_status(wma_handle, hdr->i_addr2) ||
3514*5113495bSYour Name 	    ((iface->type == WMI_VDEV_TYPE_NDI ||
3515*5113495bSYour Name 	      iface->type == WMI_VDEV_TYPE_NAN) &&
3516*5113495bSYour Name 	     (hdr->i_fc[1] & IEEE80211_FC1_WEP))) {
3517*5113495bSYour Name 		status = wma_process_rmf_frame(wma_handle, iface, hdr,
3518*5113495bSYour Name 					       rx_pkt, buf);
3519*5113495bSYour Name 		if (status)
3520*5113495bSYour Name 			return status;
3521*5113495bSYour Name 		/*
3522*5113495bSYour Name 		 * CCMP header might have been pulled off reinitialize the
3523*5113495bSYour Name 		 * start pointer of mac header
3524*5113495bSYour Name 		 */
3525*5113495bSYour Name 		*wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
3526*5113495bSYour Name 	}
3527*5113495bSYour Name 
3528*5113495bSYour Name 	return 0;
3529*5113495bSYour Name }
3530*5113495bSYour Name 
3531*5113495bSYour Name /**
3532*5113495bSYour Name  * wma_is_pkt_drop_candidate() - check if the mgmt frame should be dropped
3533*5113495bSYour Name  * @wma_handle: wma handle
3534*5113495bSYour Name  * @peer_addr: peer MAC address
3535*5113495bSYour Name  * @bssid: BSSID Address
3536*5113495bSYour Name  * @subtype: Management frame subtype
3537*5113495bSYour Name  *
3538*5113495bSYour Name  * This function is used to decide if a particular management frame should be
3539*5113495bSYour Name  * dropped to prevent DOS attack. Timestamp is used to decide the DOS attack.
3540*5113495bSYour Name  *
3541*5113495bSYour Name  * Return: true if the packet should be dropped and false otherwise
3542*5113495bSYour Name  */
wma_is_pkt_drop_candidate(tp_wma_handle wma_handle,uint8_t * peer_addr,uint8_t * bssid,uint8_t subtype)3543*5113495bSYour Name static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle,
3544*5113495bSYour Name 				      uint8_t *peer_addr, uint8_t *bssid,
3545*5113495bSYour Name 				      uint8_t subtype)
3546*5113495bSYour Name {
3547*5113495bSYour Name 	bool should_drop = false;
3548*5113495bSYour Name 	uint8_t nan_addr[] = {0x50, 0x6F, 0x9A, 0x01, 0x00, 0x00};
3549*5113495bSYour Name 
3550*5113495bSYour Name 	/* Drop the beacons from NAN device */
3551*5113495bSYour Name 	if ((subtype == MGMT_SUBTYPE_BEACON) &&
3552*5113495bSYour Name 		(!qdf_mem_cmp(nan_addr, bssid, NAN_CLUSTER_ID_BYTES))) {
3553*5113495bSYour Name 			should_drop = true;
3554*5113495bSYour Name 			goto end;
3555*5113495bSYour Name 	}
3556*5113495bSYour Name end:
3557*5113495bSYour Name 	return should_drop;
3558*5113495bSYour Name }
3559*5113495bSYour Name 
3560*5113495bSYour Name #define RATE_LIMIT 16
3561*5113495bSYour Name 
wma_form_rx_packet(qdf_nbuf_t buf,struct mgmt_rx_event_params * mgmt_rx_params,cds_pkt_t * rx_pkt)3562*5113495bSYour Name int wma_form_rx_packet(qdf_nbuf_t buf,
3563*5113495bSYour Name 			struct mgmt_rx_event_params *mgmt_rx_params,
3564*5113495bSYour Name 			cds_pkt_t *rx_pkt)
3565*5113495bSYour Name {
3566*5113495bSYour Name 	uint8_t vdev_id = WMA_INVALID_VDEV_ID;
3567*5113495bSYour Name 	struct ieee80211_frame *wh;
3568*5113495bSYour Name 	uint8_t mgt_type, mgt_subtype;
3569*5113495bSYour Name 	int status;
3570*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle)
3571*5113495bSYour Name 				cds_get_context(QDF_MODULE_ID_WMA);
3572*5113495bSYour Name 	static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1;
3573*5113495bSYour Name 	static uint8_t limit_prints_load_unload = RATE_LIMIT - 1;
3574*5113495bSYour Name 	static uint8_t limit_prints_recovery = RATE_LIMIT - 1;
3575*5113495bSYour Name 
3576*5113495bSYour Name 	if (!wma_handle) {
3577*5113495bSYour Name 		qdf_nbuf_free(buf);
3578*5113495bSYour Name 		qdf_mem_free(rx_pkt);
3579*5113495bSYour Name 		return -EINVAL;
3580*5113495bSYour Name 	}
3581*5113495bSYour Name 
3582*5113495bSYour Name 	if (!mgmt_rx_params) {
3583*5113495bSYour Name 		limit_prints_invalid_len++;
3584*5113495bSYour Name 		if (limit_prints_invalid_len == RATE_LIMIT) {
3585*5113495bSYour Name 			wma_debug("mgmt rx params is NULL");
3586*5113495bSYour Name 			limit_prints_invalid_len = 0;
3587*5113495bSYour Name 		}
3588*5113495bSYour Name 		qdf_nbuf_free(buf);
3589*5113495bSYour Name 		qdf_mem_free(rx_pkt);
3590*5113495bSYour Name 		return -EINVAL;
3591*5113495bSYour Name 	}
3592*5113495bSYour Name 
3593*5113495bSYour Name 	if (cds_is_load_or_unload_in_progress()) {
3594*5113495bSYour Name 		limit_prints_load_unload++;
3595*5113495bSYour Name 		if (limit_prints_load_unload == RATE_LIMIT) {
3596*5113495bSYour Name 			wma_debug("Load/Unload in progress");
3597*5113495bSYour Name 			limit_prints_load_unload = 0;
3598*5113495bSYour Name 		}
3599*5113495bSYour Name 		qdf_nbuf_free(buf);
3600*5113495bSYour Name 		qdf_mem_free(rx_pkt);
3601*5113495bSYour Name 		return -EINVAL;
3602*5113495bSYour Name 	}
3603*5113495bSYour Name 
3604*5113495bSYour Name 	if (cds_is_driver_recovering()) {
3605*5113495bSYour Name 		limit_prints_recovery++;
3606*5113495bSYour Name 		if (limit_prints_recovery == RATE_LIMIT) {
3607*5113495bSYour Name 			wma_debug("Recovery in progress");
3608*5113495bSYour Name 			limit_prints_recovery = 0;
3609*5113495bSYour Name 		}
3610*5113495bSYour Name 		qdf_nbuf_free(buf);
3611*5113495bSYour Name 		qdf_mem_free(rx_pkt);
3612*5113495bSYour Name 		return -EINVAL;
3613*5113495bSYour Name 	}
3614*5113495bSYour Name 
3615*5113495bSYour Name 	if (cds_is_driver_in_bad_state()) {
3616*5113495bSYour Name 		limit_prints_recovery++;
3617*5113495bSYour Name 		if (limit_prints_recovery == RATE_LIMIT) {
3618*5113495bSYour Name 			wma_debug("Driver in bad state");
3619*5113495bSYour Name 			limit_prints_recovery = 0;
3620*5113495bSYour Name 		}
3621*5113495bSYour Name 		qdf_nbuf_free(buf);
3622*5113495bSYour Name 		qdf_mem_free(rx_pkt);
3623*5113495bSYour Name 		return -EINVAL;
3624*5113495bSYour Name 	}
3625*5113495bSYour Name 
3626*5113495bSYour Name 	/*
3627*5113495bSYour Name 	 * Fill in meta information needed by pe/lim
3628*5113495bSYour Name 	 * TODO: Try to maintain rx metainfo as part of skb->data.
3629*5113495bSYour Name 	 */
3630*5113495bSYour Name 	rx_pkt->pkt_meta.frequency = mgmt_rx_params->chan_freq;
3631*5113495bSYour Name 	rx_pkt->pkt_meta.scan_src = mgmt_rx_params->flags;
3632*5113495bSYour Name 
3633*5113495bSYour Name 	/*
3634*5113495bSYour Name 	 * Get the rssi value from the current snr value
3635*5113495bSYour Name 	 * using standard noise floor of -96.
3636*5113495bSYour Name 	 */
3637*5113495bSYour Name 	rx_pkt->pkt_meta.rssi = mgmt_rx_params->snr +
3638*5113495bSYour Name 				WMA_NOISE_FLOOR_DBM_DEFAULT;
3639*5113495bSYour Name 	rx_pkt->pkt_meta.snr = mgmt_rx_params->snr;
3640*5113495bSYour Name 
3641*5113495bSYour Name 	/* If absolute rssi is available from firmware, use it */
3642*5113495bSYour Name 	if (mgmt_rx_params->rssi != 0)
3643*5113495bSYour Name 		rx_pkt->pkt_meta.rssi_raw = mgmt_rx_params->rssi;
3644*5113495bSYour Name 	else
3645*5113495bSYour Name 		rx_pkt->pkt_meta.rssi_raw = rx_pkt->pkt_meta.rssi;
3646*5113495bSYour Name 
3647*5113495bSYour Name 
3648*5113495bSYour Name 	/*
3649*5113495bSYour Name 	 * FIXME: Assigning the local timestamp as hw timestamp is not
3650*5113495bSYour Name 	 * available. Need to see if pe/lim really uses this data.
3651*5113495bSYour Name 	 */
3652*5113495bSYour Name 	rx_pkt->pkt_meta.timestamp = (uint32_t) jiffies;
3653*5113495bSYour Name 	rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame);
3654*5113495bSYour Name 	rx_pkt->pkt_meta.mpdu_len = mgmt_rx_params->buf_len;
3655*5113495bSYour Name 
3656*5113495bSYour Name 	/*
3657*5113495bSYour Name 	 * The buf_len should be at least 802.11 header len
3658*5113495bSYour Name 	 */
3659*5113495bSYour Name 	if (mgmt_rx_params->buf_len < rx_pkt->pkt_meta.mpdu_hdr_len) {
3660*5113495bSYour Name 		wma_err("MPDU Len %d lesser than header len %d",
3661*5113495bSYour Name 			 mgmt_rx_params->buf_len,
3662*5113495bSYour Name 			 rx_pkt->pkt_meta.mpdu_hdr_len);
3663*5113495bSYour Name 		qdf_nbuf_free(buf);
3664*5113495bSYour Name 		qdf_mem_free(rx_pkt);
3665*5113495bSYour Name 		return -EINVAL;
3666*5113495bSYour Name 	}
3667*5113495bSYour Name 
3668*5113495bSYour Name 	rx_pkt->pkt_meta.mpdu_data_len = mgmt_rx_params->buf_len -
3669*5113495bSYour Name 					 rx_pkt->pkt_meta.mpdu_hdr_len;
3670*5113495bSYour Name 
3671*5113495bSYour Name 	rx_pkt->pkt_meta.roamCandidateInd = 0;
3672*5113495bSYour Name 
3673*5113495bSYour Name 	wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
3674*5113495bSYour Name 
3675*5113495bSYour Name 	/*
3676*5113495bSYour Name 	 * If the mpdu_data_len is greater than Max (2k), drop the frame
3677*5113495bSYour Name 	 */
3678*5113495bSYour Name 	if (rx_pkt->pkt_meta.mpdu_data_len > MAX_MGMT_MPDU_LEN) {
3679*5113495bSYour Name 		wma_err("Data Len %d greater than max, dropping frame from "QDF_MAC_ADDR_FMT,
3680*5113495bSYour Name 			 rx_pkt->pkt_meta.mpdu_data_len,
3681*5113495bSYour Name 			 QDF_MAC_ADDR_REF(wh->i_addr3));
3682*5113495bSYour Name 		qdf_nbuf_free(buf);
3683*5113495bSYour Name 		qdf_mem_free(rx_pkt);
3684*5113495bSYour Name 		return -EINVAL;
3685*5113495bSYour Name 	}
3686*5113495bSYour Name 
3687*5113495bSYour Name 	rx_pkt->pkt_meta.mpdu_hdr_ptr = qdf_nbuf_data(buf);
3688*5113495bSYour Name 	rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr +
3689*5113495bSYour Name 					 rx_pkt->pkt_meta.mpdu_hdr_len;
3690*5113495bSYour Name 	rx_pkt->pkt_meta.tsf_delta = mgmt_rx_params->tsf_delta;
3691*5113495bSYour Name 	rx_pkt->pkt_buf = buf;
3692*5113495bSYour Name 	rx_pkt->pkt_meta.pkt_qdf_buf = buf;
3693*5113495bSYour Name 
3694*5113495bSYour Name 	/* If it is a beacon/probe response, save it for future use */
3695*5113495bSYour Name 	mgt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
3696*5113495bSYour Name 	mgt_subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
3697*5113495bSYour Name 
3698*5113495bSYour Name 	if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
3699*5113495bSYour Name 	    (mgt_subtype == MGMT_SUBTYPE_DISASSOC ||
3700*5113495bSYour Name 	     mgt_subtype == MGMT_SUBTYPE_DEAUTH ||
3701*5113495bSYour Name 	     mgt_subtype == MGMT_SUBTYPE_ACTION)) {
3702*5113495bSYour Name 		if (wma_find_vdev_id_by_bssid(wma_handle, wh->i_addr3,
3703*5113495bSYour Name 					      &vdev_id) == QDF_STATUS_SUCCESS) {
3704*5113495bSYour Name 			status = wma_check_and_process_rmf_frame(wma_handle,
3705*5113495bSYour Name 								 vdev_id,
3706*5113495bSYour Name 								 &wh,
3707*5113495bSYour Name 								 rx_pkt,
3708*5113495bSYour Name 								 buf);
3709*5113495bSYour Name 			if (status)
3710*5113495bSYour Name 				return status;
3711*5113495bSYour Name 		} else if (wma_find_vdev_id_by_addr(wma_handle, wh->i_addr1,
3712*5113495bSYour Name 					      &vdev_id) == QDF_STATUS_SUCCESS) {
3713*5113495bSYour Name 			status = wma_check_and_process_rmf_frame(wma_handle,
3714*5113495bSYour Name 								 vdev_id,
3715*5113495bSYour Name 								 &wh,
3716*5113495bSYour Name 								 rx_pkt,
3717*5113495bSYour Name 								 buf);
3718*5113495bSYour Name 			if (status)
3719*5113495bSYour Name 				return status;
3720*5113495bSYour Name 		} else if (mgt_subtype == MGMT_SUBTYPE_ACTION) {
3721*5113495bSYour Name 			/* NAN Action frame */
3722*5113495bSYour Name 			vdev_id = wlan_nan_get_vdev_id_from_bssid(
3723*5113495bSYour Name 							wma_handle->pdev,
3724*5113495bSYour Name 							wh->i_addr3,
3725*5113495bSYour Name 							WLAN_ACTION_OUI_ID);
3726*5113495bSYour Name 
3727*5113495bSYour Name 			if (vdev_id != WMA_INVALID_VDEV_ID) {
3728*5113495bSYour Name 				status = wma_check_and_process_rmf_frame(
3729*5113495bSYour Name 								wma_handle,
3730*5113495bSYour Name 								vdev_id, &wh,
3731*5113495bSYour Name 								rx_pkt, buf);
3732*5113495bSYour Name 				if (status)
3733*5113495bSYour Name 					return status;
3734*5113495bSYour Name 			}
3735*5113495bSYour Name 		}
3736*5113495bSYour Name 	}
3737*5113495bSYour Name 
3738*5113495bSYour Name 	rx_pkt->pkt_meta.session_id =
3739*5113495bSYour Name 		(vdev_id == WMA_INVALID_VDEV_ID ? 0 : vdev_id);
3740*5113495bSYour Name 
3741*5113495bSYour Name 	if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
3742*5113495bSYour Name 	    (mgt_subtype == MGMT_SUBTYPE_BEACON ||
3743*5113495bSYour Name 	     mgt_subtype == MGMT_SUBTYPE_PROBE_RESP)) {
3744*5113495bSYour Name 		if (mgmt_rx_params->buf_len <=
3745*5113495bSYour Name 			(sizeof(struct ieee80211_frame) +
3746*5113495bSYour Name 			offsetof(struct wlan_bcn_frame, ie))) {
3747*5113495bSYour Name 			wma_debug("Dropping frame from "QDF_MAC_ADDR_FMT,
3748*5113495bSYour Name 				 QDF_MAC_ADDR_REF(wh->i_addr3));
3749*5113495bSYour Name 			cds_pkt_return_packet(rx_pkt);
3750*5113495bSYour Name 			return -EINVAL;
3751*5113495bSYour Name 		}
3752*5113495bSYour Name 	}
3753*5113495bSYour Name 
3754*5113495bSYour Name 	if (wma_is_pkt_drop_candidate(wma_handle, wh->i_addr2, wh->i_addr3,
3755*5113495bSYour Name 					mgt_subtype)) {
3756*5113495bSYour Name 		cds_pkt_return_packet(rx_pkt);
3757*5113495bSYour Name 		return -EINVAL;
3758*5113495bSYour Name 	}
3759*5113495bSYour Name 	wma_mgmt_pktdump_rx_handler(mgmt_rx_params, rx_pkt,
3760*5113495bSYour Name 				    wma_handle, mgt_type, mgt_subtype);
3761*5113495bSYour Name 
3762*5113495bSYour Name 	return 0;
3763*5113495bSYour Name }
3764*5113495bSYour Name 
3765*5113495bSYour Name /**
3766*5113495bSYour Name  * wma_mem_endianness_based_copy() - does memory copy from src to dst
3767*5113495bSYour Name  * @dst: destination address
3768*5113495bSYour Name  * @src: source address
3769*5113495bSYour Name  * @size: size to be copied
3770*5113495bSYour Name  *
3771*5113495bSYour Name  * This function copies the memory of size passed from source
3772*5113495bSYour Name  * address to destination address.
3773*5113495bSYour Name  *
3774*5113495bSYour Name  * Return: Nothing
3775*5113495bSYour Name  */
3776*5113495bSYour Name #ifdef BIG_ENDIAN_HOST
wma_mem_endianness_based_copy(uint8_t * dst,uint8_t * src,uint32_t size)3777*5113495bSYour Name static void wma_mem_endianness_based_copy(
3778*5113495bSYour Name 			uint8_t *dst, uint8_t *src, uint32_t size)
3779*5113495bSYour Name {
3780*5113495bSYour Name 	/*
3781*5113495bSYour Name 	 * For big endian host, copy engine byte_swap is enabled
3782*5113495bSYour Name 	 * But the rx mgmt frame buffer content is in network byte order
3783*5113495bSYour Name 	 * Need to byte swap the mgmt frame buffer content - so when
3784*5113495bSYour Name 	 * copy engine does byte_swap - host gets buffer content in the
3785*5113495bSYour Name 	 * correct byte order.
3786*5113495bSYour Name 	 */
3787*5113495bSYour Name 
3788*5113495bSYour Name 	uint32_t i;
3789*5113495bSYour Name 	uint32_t *destp, *srcp;
3790*5113495bSYour Name 
3791*5113495bSYour Name 	destp = (uint32_t *) dst;
3792*5113495bSYour Name 	srcp = (uint32_t *) src;
3793*5113495bSYour Name 	for (i = 0; i < (roundup(size, sizeof(uint32_t)) / 4); i++) {
3794*5113495bSYour Name 		*destp = cpu_to_le32(*srcp);
3795*5113495bSYour Name 		destp++;
3796*5113495bSYour Name 		srcp++;
3797*5113495bSYour Name 	}
3798*5113495bSYour Name }
3799*5113495bSYour Name #else
wma_mem_endianness_based_copy(uint8_t * dst,uint8_t * src,uint32_t size)3800*5113495bSYour Name static void wma_mem_endianness_based_copy(
3801*5113495bSYour Name 			uint8_t *dst, uint8_t *src, uint32_t size)
3802*5113495bSYour Name {
3803*5113495bSYour Name 	qdf_mem_copy(dst, src, size);
3804*5113495bSYour Name }
3805*5113495bSYour Name #endif
3806*5113495bSYour Name 
3807*5113495bSYour Name #define RESERVE_BYTES                   100
3808*5113495bSYour Name /**
3809*5113495bSYour Name  * wma_mgmt_rx_process() - process management rx frame.
3810*5113495bSYour Name  * @handle: wma handle
3811*5113495bSYour Name  * @data: rx data
3812*5113495bSYour Name  * @data_len: data length
3813*5113495bSYour Name  *
3814*5113495bSYour Name  * Return: 0 for success or error code
3815*5113495bSYour Name  */
wma_mgmt_rx_process(void * handle,uint8_t * data,uint32_t data_len)3816*5113495bSYour Name static int wma_mgmt_rx_process(void *handle, uint8_t *data,
3817*5113495bSYour Name 				  uint32_t data_len)
3818*5113495bSYour Name {
3819*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
3820*5113495bSYour Name 	struct mgmt_rx_event_params *mgmt_rx_params;
3821*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
3822*5113495bSYour Name 	uint8_t *bufp;
3823*5113495bSYour Name 	qdf_nbuf_t wbuf;
3824*5113495bSYour Name 	QDF_STATUS status;
3825*5113495bSYour Name 
3826*5113495bSYour Name 	if (wma_validate_handle(wma_handle))
3827*5113495bSYour Name 		return -EINVAL;
3828*5113495bSYour Name 
3829*5113495bSYour Name 	mgmt_rx_params = qdf_mem_malloc(sizeof(*mgmt_rx_params));
3830*5113495bSYour Name 	if (!mgmt_rx_params) {
3831*5113495bSYour Name 		return -ENOMEM;
3832*5113495bSYour Name 	}
3833*5113495bSYour Name 
3834*5113495bSYour Name 	if (wmi_extract_mgmt_rx_params(wma_handle->wmi_handle,
3835*5113495bSYour Name 			data, mgmt_rx_params, &bufp) != QDF_STATUS_SUCCESS) {
3836*5113495bSYour Name 		wma_err_rl("Extraction of mgmt rx params failed");
3837*5113495bSYour Name 		qdf_mem_free(mgmt_rx_params);
3838*5113495bSYour Name 		return -EINVAL;
3839*5113495bSYour Name 	}
3840*5113495bSYour Name 
3841*5113495bSYour Name 	if (mgmt_rx_params->buf_len > data_len ||
3842*5113495bSYour Name 	    !mgmt_rx_params->buf_len ||
3843*5113495bSYour Name 	    !bufp) {
3844*5113495bSYour Name 		wma_err_rl("Invalid data_len %u, buf_len %u bufp %pK",
3845*5113495bSYour Name 			   data_len, mgmt_rx_params->buf_len, bufp);
3846*5113495bSYour Name 		qdf_mem_free(mgmt_rx_params);
3847*5113495bSYour Name 		return -EINVAL;
3848*5113495bSYour Name 	}
3849*5113495bSYour Name 
3850*5113495bSYour Name 	if (!mgmt_rx_params->chan_freq) {
3851*5113495bSYour Name 		/*
3852*5113495bSYour Name 		 * It indicates that FW is legacy and is operating on
3853*5113495bSYour Name 		 * channel numbers and it also indicates that BAND_6G support
3854*5113495bSYour Name 		 * is not there as BAND_6G works only on frequencies and channel
3855*5113495bSYour Name 		 * numbers can be treated as unique.
3856*5113495bSYour Name 		 */
3857*5113495bSYour Name 		mgmt_rx_params->chan_freq = wlan_reg_legacy_chan_to_freq(
3858*5113495bSYour Name 					    wma_handle->pdev,
3859*5113495bSYour Name 					    mgmt_rx_params->channel);
3860*5113495bSYour Name 	}
3861*5113495bSYour Name 
3862*5113495bSYour Name 	mgmt_rx_params->pdev_id = 0;
3863*5113495bSYour Name 	mgmt_rx_params->rx_params = NULL;
3864*5113495bSYour Name 
3865*5113495bSYour Name 	/*
3866*5113495bSYour Name 	 * Allocate the memory for this rx packet, add extra 100 bytes for:-
3867*5113495bSYour Name 	 *
3868*5113495bSYour Name 	 * 1.  Filling the missing RSN capabilities by some APs, which fill the
3869*5113495bSYour Name 	 *     RSN IE length as extra 2 bytes but dont fill the IE data with
3870*5113495bSYour Name 	 *     capabilities, resulting in failure in unpack core due to length
3871*5113495bSYour Name 	 *     mismatch. Check sir_validate_and_rectify_ies for more info.
3872*5113495bSYour Name 	 *
3873*5113495bSYour Name 	 * 2.  In the API wma_process_rmf_frame(), the driver trims the CCMP
3874*5113495bSYour Name 	 *     header by overwriting the IEEE header to memory occupied by CCMP
3875*5113495bSYour Name 	 *     header, but an overflow is possible if the memory allocated to
3876*5113495bSYour Name 	 *     frame is less than the sizeof(struct ieee80211_frame) +CCMP
3877*5113495bSYour Name 	 *     HEADER len, so allocating 100 bytes would solve this issue too.
3878*5113495bSYour Name 	 *
3879*5113495bSYour Name 	 * 3.  CCMP header is pointing to orig_hdr +
3880*5113495bSYour Name 	 *     sizeof(struct ieee80211_frame) which could also result in OOB
3881*5113495bSYour Name 	 *     access, if the data len is less than
3882*5113495bSYour Name 	 *     sizeof(struct ieee80211_frame), allocating extra bytes would
3883*5113495bSYour Name 	 *     result in solving this issue too.
3884*5113495bSYour Name 	 */
3885*5113495bSYour Name 	wbuf = qdf_nbuf_alloc(NULL, roundup(mgmt_rx_params->buf_len +
3886*5113495bSYour Name 							RESERVE_BYTES,
3887*5113495bSYour Name 							4), 0, 4, false);
3888*5113495bSYour Name 	if (!wbuf) {
3889*5113495bSYour Name 		qdf_mem_free(mgmt_rx_params);
3890*5113495bSYour Name 		return -ENOMEM;
3891*5113495bSYour Name 	}
3892*5113495bSYour Name 
3893*5113495bSYour Name 	qdf_nbuf_put_tail(wbuf, mgmt_rx_params->buf_len);
3894*5113495bSYour Name 	qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL);
3895*5113495bSYour Name 
3896*5113495bSYour Name 	qdf_mem_zero(((uint8_t *)qdf_nbuf_data(wbuf) + mgmt_rx_params->buf_len),
3897*5113495bSYour Name 		     (roundup(mgmt_rx_params->buf_len + RESERVE_BYTES, 4) -
3898*5113495bSYour Name 		     mgmt_rx_params->buf_len));
3899*5113495bSYour Name 
3900*5113495bSYour Name 	wma_mem_endianness_based_copy(qdf_nbuf_data(wbuf),
3901*5113495bSYour Name 			bufp, mgmt_rx_params->buf_len);
3902*5113495bSYour Name 
3903*5113495bSYour Name 	psoc = (struct wlan_objmgr_psoc *)
3904*5113495bSYour Name 				wma_handle->psoc;
3905*5113495bSYour Name 	if (!psoc) {
3906*5113495bSYour Name 		wma_err("psoc ctx is NULL");
3907*5113495bSYour Name 		qdf_nbuf_free(wbuf);
3908*5113495bSYour Name 		qdf_mem_free(mgmt_rx_params);
3909*5113495bSYour Name 		return -EINVAL;
3910*5113495bSYour Name 	}
3911*5113495bSYour Name 
3912*5113495bSYour Name 	status = mgmt_txrx_rx_handler(psoc, wbuf, mgmt_rx_params);
3913*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
3914*5113495bSYour Name 		qdf_mem_free(mgmt_rx_params);
3915*5113495bSYour Name 		return -EINVAL;
3916*5113495bSYour Name 	}
3917*5113495bSYour Name 
3918*5113495bSYour Name 	qdf_mem_free(mgmt_rx_params);
3919*5113495bSYour Name 	return 0;
3920*5113495bSYour Name }
3921*5113495bSYour Name 
3922*5113495bSYour Name /**
3923*5113495bSYour Name  * wma_de_register_mgmt_frm_client() - deregister management frame
3924*5113495bSYour Name  *
3925*5113495bSYour Name  * This function deregisters the event handler registered for
3926*5113495bSYour Name  * WMI_MGMT_RX_EVENTID.
3927*5113495bSYour Name  *
3928*5113495bSYour Name  * Return: QDF status
3929*5113495bSYour Name  */
wma_de_register_mgmt_frm_client(void)3930*5113495bSYour Name QDF_STATUS wma_de_register_mgmt_frm_client(void)
3931*5113495bSYour Name {
3932*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle)
3933*5113495bSYour Name 				cds_get_context(QDF_MODULE_ID_WMA);
3934*5113495bSYour Name 
3935*5113495bSYour Name 	if (!wma_handle)
3936*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
3937*5113495bSYour Name 
3938*5113495bSYour Name #ifdef QCA_WIFI_FTM
3939*5113495bSYour Name 	if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
3940*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
3941*5113495bSYour Name #endif
3942*5113495bSYour Name 
3943*5113495bSYour Name 	if (wmi_unified_unregister_event_handler(wma_handle->wmi_handle,
3944*5113495bSYour Name 						 wmi_mgmt_rx_event_id) != 0) {
3945*5113495bSYour Name 		wma_err("Failed to Unregister rx mgmt handler with wmi");
3946*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3947*5113495bSYour Name 	}
3948*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3949*5113495bSYour Name }
3950*5113495bSYour Name 
3951*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
3952*5113495bSYour Name /**
3953*5113495bSYour Name  * wma_register_roaming_callbacks() - Register roaming callbacks
3954*5113495bSYour Name  * @csr_roam_auth_event_handle_cb: CSR callback routine pointer
3955*5113495bSYour Name  * @pe_roam_synch_cb: PE roam synch callback routine pointer
3956*5113495bSYour Name  *
3957*5113495bSYour Name  * Register the SME and PE callback routines with WMA for
3958*5113495bSYour Name  * handling roaming
3959*5113495bSYour Name  *
3960*5113495bSYour Name  * Return: Success or Failure Status
3961*5113495bSYour Name  */
wma_register_roaming_callbacks(QDF_STATUS (* csr_roam_auth_event_handle_cb)(struct mac_context * mac,uint8_t vdev_id,struct qdf_mac_addr bssid,uint32_t akm),pe_roam_synch_fn_t pe_roam_synch_cb,QDF_STATUS (* pe_disconnect_cb)(struct mac_context * mac,uint8_t vdev_id,uint8_t * deauth_disassoc_frame,uint16_t deauth_disassoc_frame_len,uint16_t reason_code),set_ies_fn_t pe_roam_set_ie_cb)3962*5113495bSYour Name QDF_STATUS wma_register_roaming_callbacks(
3963*5113495bSYour Name 	QDF_STATUS (*csr_roam_auth_event_handle_cb)(struct mac_context *mac,
3964*5113495bSYour Name 						    uint8_t vdev_id,
3965*5113495bSYour Name 						    struct qdf_mac_addr bssid,
3966*5113495bSYour Name 						    uint32_t akm),
3967*5113495bSYour Name 	pe_roam_synch_fn_t pe_roam_synch_cb,
3968*5113495bSYour Name 	QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
3969*5113495bSYour Name 					uint8_t vdev_id,
3970*5113495bSYour Name 					uint8_t *deauth_disassoc_frame,
3971*5113495bSYour Name 					uint16_t deauth_disassoc_frame_len,
3972*5113495bSYour Name 					uint16_t reason_code),
3973*5113495bSYour Name 	set_ies_fn_t pe_roam_set_ie_cb)
3974*5113495bSYour Name {
3975*5113495bSYour Name 
3976*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
3977*5113495bSYour Name 
3978*5113495bSYour Name 	if (!wma)
3979*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3980*5113495bSYour Name 
3981*5113495bSYour Name 	wma->csr_roam_auth_event_handle_cb = csr_roam_auth_event_handle_cb;
3982*5113495bSYour Name 	wma->pe_roam_synch_cb = pe_roam_synch_cb;
3983*5113495bSYour Name 	wma->pe_disconnect_cb = pe_disconnect_cb;
3984*5113495bSYour Name 	wma->pe_roam_set_ie_cb = pe_roam_set_ie_cb;
3985*5113495bSYour Name 	wma_debug("Registered roam synch callbacks with WMA successfully");
3986*5113495bSYour Name 
3987*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3988*5113495bSYour Name }
3989*5113495bSYour Name #endif
3990*5113495bSYour Name 
3991*5113495bSYour Name /**
3992*5113495bSYour Name  * wma_register_mgmt_frm_client() - register management frame callback
3993*5113495bSYour Name  *
3994*5113495bSYour Name  * This function registers event handler for WMI_MGMT_RX_EVENTID.
3995*5113495bSYour Name  *
3996*5113495bSYour Name  * Return: QDF status
3997*5113495bSYour Name  */
wma_register_mgmt_frm_client(void)3998*5113495bSYour Name QDF_STATUS wma_register_mgmt_frm_client(void)
3999*5113495bSYour Name {
4000*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle)
4001*5113495bSYour Name 				cds_get_context(QDF_MODULE_ID_WMA);
4002*5113495bSYour Name 
4003*5113495bSYour Name 	if (!wma_handle)
4004*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
4005*5113495bSYour Name 
4006*5113495bSYour Name 	if (wmi_unified_register_event_handler(wma_handle->wmi_handle,
4007*5113495bSYour Name 					       wmi_mgmt_rx_event_id,
4008*5113495bSYour Name 					       wma_mgmt_rx_process,
4009*5113495bSYour Name 					       WMA_RX_WORK_CTX) != 0) {
4010*5113495bSYour Name 		wma_err("Failed to register rx mgmt handler with wmi");
4011*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4012*5113495bSYour Name 	}
4013*5113495bSYour Name 
4014*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4015*5113495bSYour Name }
4016*5113495bSYour Name 
4017*5113495bSYour Name /**
4018*5113495bSYour Name  * wma_register_packetdump_callback() - stores tx and rx mgmt packet dump
4019*5113495bSYour Name  *   callback handler
4020*5113495bSYour Name  * @tx_cb: tx mgmt packetdump cb
4021*5113495bSYour Name  * @rx_cb: rx mgmt packetdump cb
4022*5113495bSYour Name  *
4023*5113495bSYour Name  * This function is used to store tx and rx mgmt. packet dump callback
4024*5113495bSYour Name  *
4025*5113495bSYour Name  * Return: None
4026*5113495bSYour Name  *
4027*5113495bSYour Name  */
wma_register_packetdump_callback(ol_txrx_pktdump_cb tx_cb,ol_txrx_pktdump_cb rx_cb)4028*5113495bSYour Name void wma_register_packetdump_callback(
4029*5113495bSYour Name 	ol_txrx_pktdump_cb tx_cb,
4030*5113495bSYour Name 	ol_txrx_pktdump_cb rx_cb)
4031*5113495bSYour Name {
4032*5113495bSYour Name 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4033*5113495bSYour Name 
4034*5113495bSYour Name 	if (!wma_handle)
4035*5113495bSYour Name 		return;
4036*5113495bSYour Name 
4037*5113495bSYour Name 	wma_handle->wma_mgmt_tx_packetdump_cb = tx_cb;
4038*5113495bSYour Name 	wma_handle->wma_mgmt_rx_packetdump_cb = rx_cb;
4039*5113495bSYour Name }
4040*5113495bSYour Name 
4041*5113495bSYour Name /**
4042*5113495bSYour Name  * wma_deregister_packetdump_callback() - removes tx and rx mgmt packet dump
4043*5113495bSYour Name  *   callback handler
4044*5113495bSYour Name  *
4045*5113495bSYour Name  * This function is used to remove tx and rx mgmt. packet dump callback
4046*5113495bSYour Name  *
4047*5113495bSYour Name  * Return: None
4048*5113495bSYour Name  *
4049*5113495bSYour Name  */
wma_deregister_packetdump_callback(void)4050*5113495bSYour Name void wma_deregister_packetdump_callback(void)
4051*5113495bSYour Name {
4052*5113495bSYour Name 	tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4053*5113495bSYour Name 
4054*5113495bSYour Name 	if (!wma_handle)
4055*5113495bSYour Name 		return;
4056*5113495bSYour Name 
4057*5113495bSYour Name 	wma_handle->wma_mgmt_tx_packetdump_cb = NULL;
4058*5113495bSYour Name 	wma_handle->wma_mgmt_rx_packetdump_cb = NULL;
4059*5113495bSYour Name }
4060*5113495bSYour Name 
wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev * vdev,qdf_nbuf_t buf,uint32_t desc_id,void * mgmt_tx_params)4061*5113495bSYour Name QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev,
4062*5113495bSYour Name 				qdf_nbuf_t buf, uint32_t desc_id,
4063*5113495bSYour Name 				void *mgmt_tx_params)
4064*5113495bSYour Name {
4065*5113495bSYour Name 	tp_wma_handle wma_handle;
4066*5113495bSYour Name 	int ret;
4067*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
4068*5113495bSYour Name 	struct wmi_mgmt_params *mgmt_params =
4069*5113495bSYour Name 			(struct wmi_mgmt_params *)mgmt_tx_params;
4070*5113495bSYour Name 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4071*5113495bSYour Name 
4072*5113495bSYour Name 	if (!mgmt_params) {
4073*5113495bSYour Name 		wma_err("mgmt_params ptr passed is NULL");
4074*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4075*5113495bSYour Name 	}
4076*5113495bSYour Name 	mgmt_params->desc_id = desc_id;
4077*5113495bSYour Name 
4078*5113495bSYour Name 	if (!vdev) {
4079*5113495bSYour Name 		wma_err("vdev ptr passed is NULL");
4080*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4081*5113495bSYour Name 	}
4082*5113495bSYour Name 
4083*5113495bSYour Name 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4084*5113495bSYour Name 	if (!wma_handle)
4085*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4086*5113495bSYour Name 
4087*5113495bSYour Name 	if (wmi_service_enabled(wma_handle->wmi_handle,
4088*5113495bSYour Name 				   wmi_service_mgmt_tx_wmi)) {
4089*5113495bSYour Name 		status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle,
4090*5113495bSYour Name 						   mgmt_params);
4091*5113495bSYour Name 	} else {
4092*5113495bSYour Name 		QDF_NBUF_CB_MGMT_TXRX_DESC_ID(buf)
4093*5113495bSYour Name 						= mgmt_params->desc_id;
4094*5113495bSYour Name 
4095*5113495bSYour Name 		ret = cdp_mgmt_send_ext(soc, mgmt_params->vdev_id, buf,
4096*5113495bSYour Name 					mgmt_params->tx_type,
4097*5113495bSYour Name 					mgmt_params->use_6mbps,
4098*5113495bSYour Name 					mgmt_params->chanfreq);
4099*5113495bSYour Name 		status = qdf_status_from_os_return(ret);
4100*5113495bSYour Name 	}
4101*5113495bSYour Name 
4102*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
4103*5113495bSYour Name 		wma_err("mgmt tx failed");
4104*5113495bSYour Name 		return status;
4105*5113495bSYour Name 	}
4106*5113495bSYour Name 
4107*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4108*5113495bSYour Name }
4109*5113495bSYour Name 
4110*5113495bSYour Name #ifndef CONFIG_HL_SUPPORT
wma_mgmt_nbuf_unmap_cb(struct wlan_objmgr_pdev * pdev,qdf_nbuf_t buf)4111*5113495bSYour Name void wma_mgmt_nbuf_unmap_cb(struct wlan_objmgr_pdev *pdev,
4112*5113495bSYour Name 			    qdf_nbuf_t buf)
4113*5113495bSYour Name {
4114*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
4115*5113495bSYour Name 	qdf_device_t dev;
4116*5113495bSYour Name 
4117*5113495bSYour Name 	if (!buf)
4118*5113495bSYour Name 		return;
4119*5113495bSYour Name 
4120*5113495bSYour Name 	psoc = wlan_pdev_get_psoc(pdev);
4121*5113495bSYour Name 	if (!psoc) {
4122*5113495bSYour Name 		wma_err("Psoc handle NULL");
4123*5113495bSYour Name 		return;
4124*5113495bSYour Name 	}
4125*5113495bSYour Name 
4126*5113495bSYour Name 	dev = wlan_psoc_get_qdf_dev(psoc);
4127*5113495bSYour Name 	qdf_nbuf_unmap_single(dev, buf, QDF_DMA_TO_DEVICE);
4128*5113495bSYour Name }
4129*5113495bSYour Name 
wma_mgmt_frame_fill_peer_cb(struct wlan_objmgr_peer * peer,qdf_nbuf_t buf)4130*5113495bSYour Name QDF_STATUS wma_mgmt_frame_fill_peer_cb(struct wlan_objmgr_peer *peer,
4131*5113495bSYour Name 				       qdf_nbuf_t buf)
4132*5113495bSYour Name {
4133*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
4134*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
4135*5113495bSYour Name 
4136*5113495bSYour Name 	psoc = wlan_peer_get_psoc(peer);
4137*5113495bSYour Name 	if (!psoc) {
4138*5113495bSYour Name 		wma_err("Psoc handle NULL");
4139*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4140*5113495bSYour Name 	}
4141*5113495bSYour Name 
4142*5113495bSYour Name 	pdev = wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
4143*5113495bSYour Name 					  wlan_peer_get_pdev_id(peer),
4144*5113495bSYour Name 					  WLAN_LEGACY_WMA_ID);
4145*5113495bSYour Name 	if (!pdev) {
4146*5113495bSYour Name 		wma_err("Pdev handle NULL");
4147*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4148*5113495bSYour Name 	}
4149*5113495bSYour Name 	wma_mgmt_nbuf_unmap_cb(pdev, buf);
4150*5113495bSYour Name 	wlan_objmgr_pdev_release_ref(pdev, WLAN_LEGACY_WMA_ID);
4151*5113495bSYour Name 
4152*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4153*5113495bSYour Name }
4154*5113495bSYour Name 
4155*5113495bSYour Name QDF_STATUS
wma_update_edca_pifs_param(WMA_HANDLE handle,struct edca_pifs_vparam * edca_pifs_param)4156*5113495bSYour Name wma_update_edca_pifs_param(WMA_HANDLE handle,
4157*5113495bSYour Name 			   struct edca_pifs_vparam *edca_pifs_param)
4158*5113495bSYour Name {
4159*5113495bSYour Name 	tp_wma_handle wma_handle = (tp_wma_handle) handle;
4160*5113495bSYour Name 	QDF_STATUS status;
4161*5113495bSYour Name 
4162*5113495bSYour Name 	status = wmi_unified_update_edca_pifs_param(wma_handle->wmi_handle,
4163*5113495bSYour Name 						    edca_pifs_param);
4164*5113495bSYour Name 
4165*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
4166*5113495bSYour Name 		wma_err("Failed to set EDCA/PIFS Parameters");
4167*5113495bSYour Name 
4168*5113495bSYour Name 	return status;
4169*5113495bSYour Name }
4170*5113495bSYour Name #endif
4171*5113495bSYour Name 
4172*5113495bSYour Name QDF_STATUS
wma_update_bss_peer_phy_mode(struct wlan_channel * des_chan,struct wlan_objmgr_vdev * vdev)4173*5113495bSYour Name wma_update_bss_peer_phy_mode(struct wlan_channel *des_chan,
4174*5113495bSYour Name 			     struct wlan_objmgr_vdev *vdev)
4175*5113495bSYour Name {
4176*5113495bSYour Name 	struct wlan_objmgr_peer *bss_peer;
4177*5113495bSYour Name 	enum wlan_phymode old_peer_phymode, new_phymode;
4178*5113495bSYour Name 	tSirNwType nw_type;
4179*5113495bSYour Name 	struct vdev_mlme_obj *mlme_obj;
4180*5113495bSYour Name 
4181*5113495bSYour Name 	bss_peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_LEGACY_WMA_ID);
4182*5113495bSYour Name 	if (!bss_peer) {
4183*5113495bSYour Name 		wma_err("not able to find bss peer for vdev %d",
4184*5113495bSYour Name 			wlan_vdev_get_id(vdev));
4185*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4186*5113495bSYour Name 	}
4187*5113495bSYour Name 
4188*5113495bSYour Name 	old_peer_phymode = wlan_peer_get_phymode(bss_peer);
4189*5113495bSYour Name 
4190*5113495bSYour Name 	if (WLAN_REG_IS_24GHZ_CH_FREQ(des_chan->ch_freq)) {
4191*5113495bSYour Name 		if (des_chan->ch_phymode == WLAN_PHYMODE_11B ||
4192*5113495bSYour Name 		    old_peer_phymode == WLAN_PHYMODE_11B)
4193*5113495bSYour Name 			nw_type = eSIR_11B_NW_TYPE;
4194*5113495bSYour Name 		else
4195*5113495bSYour Name 			nw_type = eSIR_11G_NW_TYPE;
4196*5113495bSYour Name 	} else {
4197*5113495bSYour Name 		nw_type = eSIR_11A_NW_TYPE;
4198*5113495bSYour Name 	}
4199*5113495bSYour Name 
4200*5113495bSYour Name 	new_phymode = wma_peer_phymode(nw_type, STA_ENTRY_PEER,
4201*5113495bSYour Name 				       IS_WLAN_PHYMODE_HT(old_peer_phymode),
4202*5113495bSYour Name 				       des_chan->ch_width,
4203*5113495bSYour Name 				       IS_WLAN_PHYMODE_VHT(old_peer_phymode),
4204*5113495bSYour Name 				       IS_WLAN_PHYMODE_HE(old_peer_phymode),
4205*5113495bSYour Name 				       wma_is_phymode_eht(old_peer_phymode));
4206*5113495bSYour Name 
4207*5113495bSYour Name 	if (new_phymode == old_peer_phymode) {
4208*5113495bSYour Name 		wma_debug("Ignore update, old %d and new %d phymode are same, vdev_id : %d",
4209*5113495bSYour Name 			  old_peer_phymode, new_phymode,
4210*5113495bSYour Name 			  wlan_vdev_get_id(vdev));
4211*5113495bSYour Name 		wlan_objmgr_peer_release_ref(bss_peer, WLAN_LEGACY_WMA_ID);
4212*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
4213*5113495bSYour Name 	}
4214*5113495bSYour Name 
4215*5113495bSYour Name 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
4216*5113495bSYour Name 	if (!mlme_obj) {
4217*5113495bSYour Name 		wma_err("not able to get mlme_obj");
4218*5113495bSYour Name 		wlan_objmgr_peer_release_ref(bss_peer, WLAN_LEGACY_WMA_ID);
4219*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
4220*5113495bSYour Name 	}
4221*5113495bSYour Name 
4222*5113495bSYour Name 	wlan_peer_obj_lock(bss_peer);
4223*5113495bSYour Name 	wlan_peer_set_phymode(bss_peer, new_phymode);
4224*5113495bSYour Name 	wlan_peer_obj_unlock(bss_peer);
4225*5113495bSYour Name 
4226*5113495bSYour Name 	wlan_objmgr_peer_release_ref(bss_peer, WLAN_LEGACY_WMA_ID);
4227*5113495bSYour Name 
4228*5113495bSYour Name 	mlme_obj->mgmt.generic.phy_mode = wmi_host_to_fw_phymode(new_phymode);
4229*5113495bSYour Name 	des_chan->ch_phymode = new_phymode;
4230*5113495bSYour Name 
4231*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4232*5113495bSYour Name }
4233*5113495bSYour Name 
4234*5113495bSYour Name QDF_STATUS
cm_send_ies_for_roam_invoke(struct wlan_objmgr_vdev * vdev,uint16_t dot11_mode)4235*5113495bSYour Name cm_send_ies_for_roam_invoke(struct wlan_objmgr_vdev *vdev, uint16_t dot11_mode)
4236*5113495bSYour Name {
4237*5113495bSYour Name 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
4238*5113495bSYour Name 	enum QDF_OPMODE op_mode;
4239*5113495bSYour Name 	QDF_STATUS status;
4240*5113495bSYour Name 	uint8_t vdev_id;
4241*5113495bSYour Name 
4242*5113495bSYour Name 	if (!wma)
4243*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4244*5113495bSYour Name 
4245*5113495bSYour Name 	vdev_id = wlan_vdev_get_id(vdev);
4246*5113495bSYour Name 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
4247*5113495bSYour Name 
4248*5113495bSYour Name 	status = wma->pe_roam_set_ie_cb(wma->mac_context, vdev_id, dot11_mode,
4249*5113495bSYour Name 					op_mode);
4250*5113495bSYour Name 	return status;
4251*5113495bSYour Name }
4252