blob: 7c81539b20f4be16718feb03f06d6117abb5b20e [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Harprit Chhabada98225f62018-12-11 15:29:55 -08002 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/**
20 * DOC: wma_mgmt.c
21 *
22 * This file contains STA/SAP/IBSS and protocol related functions.
23 */
24
25/* Header files */
26
27#include "wma.h"
28#include "wma_api.h"
29#include "cds_api.h"
30#include "wmi_unified_api.h"
31#include "wlan_qct_sys.h"
32#include "wni_api.h"
33#include "ani_global.h"
34#include "wmi_unified.h"
35#include "wni_cfg.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080036
Nirav Shahcbc6d722016-03-01 16:24:53 +053037#include "qdf_nbuf.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053038#include "qdf_types.h"
Anurag Chouhan600c3a02016-03-01 10:33:54 +053039#include "qdf_mem.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040
41#include "wma_types.h"
42#include "lim_api.h"
43#include "lim_session_utils.h"
44
45#include "cds_utils.h"
46
47#if !defined(REMOVE_PKT_LOG)
48#include "pktlog_ac.h"
Nirav Shahbb8e47c2018-05-17 16:56:41 +053049#else
50#include "pktlog_ac_fmt.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051#endif /* REMOVE_PKT_LOG */
52
53#include "dbglog_host.h"
54#include "csr_api.h"
55#include "ol_fw.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080056#include "wma_internal.h"
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -070057#include "wlan_policy_mgr_api.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080058#include "cdp_txrx_flow_ctrl_legacy.h"
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -070059#include <cdp_txrx_peer_ops.h>
60#include <cdp_txrx_pmf.h>
61#include <cdp_txrx_cfg.h>
62#include <cdp_txrx_cmn.h>
63#include <cdp_txrx_misc.h>
Leo Chang96464902016-10-28 11:10:54 -070064#include <cdp_txrx_misc.h>
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +053065#include "wlan_mgmt_txrx_tgt_api.h"
66#include "wlan_objmgr_psoc_obj.h"
67#include "wlan_objmgr_pdev_obj.h"
68#include "wlan_objmgr_vdev_obj.h"
Himanshu Agarwal795b7f72017-01-17 21:19:43 +053069#include "wlan_lmac_if_api.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080070#include <cdp_txrx_handle.h>
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -080071#include "wma_he.h"
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +053072#include <qdf_crypto.h>
Varun Reddy Yeturu4f849e52018-06-15 18:08:37 -070073#include "wma_twt.h"
Wu Gao3365e782018-07-27 18:19:35 +080074#include "wlan_p2p_cfg_api.h"
Wu Gao93816212018-08-31 16:49:54 +080075#include "cfg_ucfg_api.h"
76#include "cfg_mlme_sta.h"
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +053077#include "wlan_mlme_api.h"
Harprit Chhabada253e36a2018-12-11 15:29:55 -080078#include "wmi_unified_bcn_api.h"
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070079#include <wlan_crypto_global_api.h>
Abhishek Singh7c1c7432019-04-04 12:11:57 +053080#include <wlan_mlme_main.h>
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070081
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080082/**
83 * wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL
84 * @wma: wma handle
85 * @pdev: txrx pdev
86 * @vdev_id: vdev id
87 * @param_buf: SWBA parameters
88 *
89 * Return: none
90 */
Harprit Chhabada98225f62018-12-11 15:29:55 -080091#ifdef CONFIG_WMI_BCN_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092static void wma_send_bcn_buf_ll(tp_wma_handle wma,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080093 struct cdp_pdev *pdev,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080094 uint8_t vdev_id,
95 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf)
96{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097 struct ieee80211_frame *wh;
98 struct beacon_info *bcn;
99 wmi_tim_info *tim_info = param_buf->tim_info;
100 uint8_t *bcn_payload;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530101 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102 struct beacon_tim_ie *tim_ie;
103 wmi_p2p_noa_info *p2p_noa_info = param_buf->p2p_noa_info;
104 struct p2p_sub_element_noa noa_ie;
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530105 struct wmi_bcn_send_from_host params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106 uint8_t i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107
108 bcn = wma->interfaces[vdev_id].beacon;
Bala Venkateshd267bf82018-10-26 13:56:25 +0530109 if (!bcn || !bcn->buf) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800110 WMA_LOGE("%s: Invalid beacon buffer", __func__);
111 return;
112 }
Abhinav Kumare48f34d2018-10-12 14:44:44 +0530113
114 if (!param_buf->tim_info || !param_buf->p2p_noa_info) {
115 WMA_LOGE("%s: Invalid tim info or p2p noa info", __func__);
116 return;
117 }
118
Varun Reddy Yeturu0a2c3102017-09-27 21:17:54 -0700119 if (WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info) >
120 WMI_P2P_MAX_NOA_DESCRIPTORS) {
121 WMA_LOGE("%s: Too many descriptors %d", __func__,
122 WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info));
123 return;
124 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800125
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530126 qdf_spin_lock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800127
Nirav Shahcbc6d722016-03-01 16:24:53 +0530128 bcn_payload = qdf_nbuf_data(bcn->buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800129
130 tim_ie = (struct beacon_tim_ie *)(&bcn_payload[bcn->tim_ie_offset]);
131
132 if (tim_info->tim_changed) {
133 if (tim_info->tim_num_ps_pending)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530134 qdf_mem_copy(&tim_ie->tim_bitmap, tim_info->tim_bitmap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800135 WMA_TIM_SUPPORTED_PVB_LENGTH);
136 else
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530137 qdf_mem_zero(&tim_ie->tim_bitmap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800138 WMA_TIM_SUPPORTED_PVB_LENGTH);
139 /*
140 * Currently we support fixed number of
141 * peers as limited by HAL_NUM_STA.
142 * tim offset is always 0
143 */
144 tim_ie->tim_bitctl = 0;
145 }
146
147 /* Update DTIM Count */
148 if (tim_ie->dtim_count == 0)
149 tim_ie->dtim_count = tim_ie->dtim_period - 1;
150 else
151 tim_ie->dtim_count--;
152
153 /*
154 * DTIM count needs to be backedup so that
155 * when umac updates the beacon template
156 * current dtim count can be updated properly
157 */
158 bcn->dtim_count = tim_ie->dtim_count;
159
160 /* update state for buffered multicast frames on DTIM */
161 if (tim_info->tim_mcast && (tim_ie->dtim_count == 0 ||
162 tim_ie->dtim_period == 1))
163 tim_ie->tim_bitctl |= 1;
164 else
165 tim_ie->tim_bitctl &= ~1;
166
167 /* To avoid sw generated frame sequence the same as H/W generated frame,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700168 * the value lower than min_sw_seq is reserved for HW generated frame
169 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800170 if ((bcn->seq_no & IEEE80211_SEQ_MASK) < MIN_SW_SEQ)
171 bcn->seq_no = MIN_SW_SEQ;
172
173 wh = (struct ieee80211_frame *)bcn_payload;
174 *(uint16_t *) &wh->i_seq[0] = htole16(bcn->seq_no
175 << IEEE80211_SEQ_SEQ_SHIFT);
176 bcn->seq_no++;
177
178 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530179 qdf_mem_zero(&noa_ie, sizeof(noa_ie));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800180
181 noa_ie.index =
182 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
183 noa_ie.oppPS =
184 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
185 noa_ie.ctwindow =
186 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700187 noa_ie.num_descriptors = (uint8_t)
188 WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
189 WMA_LOGI("%s: index %u, oppPs %u, ctwindow %u, num_descriptors = %u",
190 __func__, noa_ie.index,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800191 noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
192 for (i = 0; i < noa_ie.num_descriptors; i++) {
193 noa_ie.noa_descriptors[i].type_count =
194 (uint8_t) p2p_noa_info->noa_descriptors[i].
195 type_count;
196 noa_ie.noa_descriptors[i].duration =
197 p2p_noa_info->noa_descriptors[i].duration;
198 noa_ie.noa_descriptors[i].interval =
199 p2p_noa_info->noa_descriptors[i].interval;
200 noa_ie.noa_descriptors[i].start_time =
201 p2p_noa_info->noa_descriptors[i].start_time;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700202 WMA_LOGI("%s: NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800203 __func__, i,
204 noa_ie.noa_descriptors[i].type_count,
205 noa_ie.noa_descriptors[i].duration,
206 noa_ie.noa_descriptors[i].interval,
207 noa_ie.noa_descriptors[i].start_time);
208 }
209 wma_update_noa(bcn, &noa_ie);
210
211 /* Send a msg to LIM to update the NoA IE in probe response
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700212 * frames transmitted by the host
213 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800214 wma_update_probe_resp_noa(wma, &noa_ie);
215 }
216
217 if (bcn->dma_mapped) {
Leo Chang96464902016-10-28 11:10:54 -0700218 qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219 bcn->dma_mapped = 0;
220 }
Leo Chang96464902016-10-28 11:10:54 -0700221 ret = qdf_nbuf_map_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530222 if (ret != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800223 WMA_LOGE("%s: failed map beacon buf to DMA region", __func__);
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530224 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800225 return;
226 }
227
228 bcn->dma_mapped = 1;
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530229 params.vdev_id = vdev_id;
230 params.data_len = bcn->len;
231 params.frame_ctrl = *((A_UINT16 *) wh->i_fc);
232 params.frag_ptr = qdf_nbuf_get_frag_paddr(bcn->buf, 0);
233 params.dtim_flag = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800234 /* notify Firmware of DTM and mcast/bcast traffic */
235 if (tim_ie->dtim_count == 0) {
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530236 params.dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800237 /* deliver mcast/bcast traffic in next DTIM beacon */
238 if (tim_ie->tim_bitctl & 0x01)
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530239 params.dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800240 }
241
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530242 wmi_unified_bcn_buf_ll_cmd(wma->wmi_handle,
243 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800244
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530245 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246}
Harprit Chhabada98225f62018-12-11 15:29:55 -0800247#else
248static inline void
249wma_send_bcn_buf_ll(tp_wma_handle wma,
250 struct cdp_pdev *pdev,
251 uint8_t vdev_id,
252 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf)
253{
254}
255#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800256/**
257 * wma_beacon_swba_handler() - swba event handler
258 * @handle: wma handle
259 * @event: event data
260 * @len: data length
261 *
262 * SWBA event is alert event to Host requesting host to Queue a beacon
263 * for transmission use only in host beacon mode
264 *
265 * Return: 0 for success or error code
266 */
Harprit Chhabada98225f62018-12-11 15:29:55 -0800267#ifdef CONFIG_WMI_BCN_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800268int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len)
269{
270 tp_wma_handle wma = (tp_wma_handle) handle;
271 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
272 wmi_host_swba_event_fixed_param *swba_event;
273 uint32_t vdev_map;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800274 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800275 uint8_t vdev_id = 0;
Leo Chang96464902016-10-28 11:10:54 -0700276 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800277
278 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) event;
279 if (!param_buf) {
280 WMA_LOGE("Invalid swba event buffer");
281 return -EINVAL;
282 }
283 swba_event = param_buf->fixed_param;
284 vdev_map = swba_event->vdev_map;
285
Anurag Chouhan6d760662016-02-20 16:05:43 +0530286 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800287 if (!pdev) {
288 WMA_LOGE("%s: pdev is NULL", __func__);
289 return -EINVAL;
290 }
291
Varun Reddy Yeturu4353e4f2017-10-03 18:22:42 -0700292 WMA_LOGD("vdev_map = %d", vdev_map);
293 for (; vdev_map && vdev_id < wma->max_bssid;
294 vdev_id++, vdev_map >>= 1) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295 if (!(vdev_map & 0x1))
296 continue;
Leo Chang96464902016-10-28 11:10:54 -0700297 if (!cdp_cfg_is_high_latency(soc,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800298 (struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800299 wma_send_bcn_buf_ll(wma, pdev, vdev_id, param_buf);
300 break;
301 }
302 return 0;
303}
Harprit Chhabada98225f62018-12-11 15:29:55 -0800304#else
305static inline int
306wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len)
307{
308 return 0;
309}
310#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800311
Sen, Devendra154b3c42017-02-13 20:44:15 +0530312#ifdef FEATURE_WLAN_DIAG_SUPPORT
313void wma_sta_kickout_event(uint32_t kickout_reason, uint8_t vdev_id,
314 uint8_t *macaddr)
315{
316 WLAN_HOST_DIAG_EVENT_DEF(sta_kickout, struct host_event_wlan_kickout);
317 qdf_mem_zero(&sta_kickout, sizeof(sta_kickout));
318 sta_kickout.reasoncode = kickout_reason;
319 sta_kickout.vdev_id = vdev_id;
320 if (macaddr)
321 qdf_mem_copy(sta_kickout.peer_mac, macaddr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800322 QDF_MAC_ADDR_SIZE);
Sen, Devendra154b3c42017-02-13 20:44:15 +0530323 WLAN_HOST_DIAG_EVENT_REPORT(&sta_kickout, EVENT_WLAN_STA_KICKOUT);
324}
325#endif
326
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327/**
328 * wma_peer_sta_kickout_event_handler() - kickout event handler
329 * @handle: wma handle
330 * @event: event data
331 * @len: data length
332 *
333 * Kickout event is received from firmware on observing beacon miss
334 * It handles kickout event for different modes and indicate to
335 * upper layers.
336 *
337 * Return: 0 for success or error code
338 */
Krunal Sonibd7e8932018-10-03 11:14:51 -0700339int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event,
340 uint32_t len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341{
342 tp_wma_handle wma = (tp_wma_handle) handle;
343 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
344 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800345 uint8_t vdev_id, peer_id, macaddr[QDF_MAC_ADDR_SIZE];
Leo Chang96464902016-10-28 11:10:54 -0700346 void *peer;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800347 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800348 tpDeleteStaContext del_sta_ctx;
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800349 struct ibss_peer_inactivity_ind *inactivity;
Leo Chang96464902016-10-28 11:10:54 -0700350 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800351
352 WMA_LOGD("%s: Enter", __func__);
353 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) event;
354 kickout_event = param_buf->fixed_param;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530355 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356 if (!pdev) {
357 WMA_LOGE("%s: pdev is NULL", __func__);
358 return -EINVAL;
359 }
360 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, macaddr);
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800361 peer = cdp_peer_find_by_addr(soc, pdev, macaddr, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362 if (!peer) {
363 WMA_LOGE("PEER [%pM] not found", macaddr);
364 return -EINVAL;
365 }
366
Leo Chang96464902016-10-28 11:10:54 -0700367 if (cdp_peer_get_vdevid(soc, peer, &vdev_id) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800368 WMA_LOGE("Not able to find BSSID for peer [%pM]", macaddr);
369 return -EINVAL;
370 }
371
372 WMA_LOGA("%s: PEER:[%pM], ADDR:[%pN], INTERFACE:%d, peer_id:%d, reason:%d",
373 __func__, macaddr, wma->interfaces[vdev_id].addr, vdev_id,
374 peer_id, kickout_event->reason);
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -0800375 if (wma->interfaces[vdev_id].roaming_in_progress) {
376 WMA_LOGE("Ignore STA kick out since roaming is in progress");
377 return -EINVAL;
378 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379
380 switch (kickout_event->reason) {
381 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT:
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800382 inactivity = qdf_mem_malloc(sizeof(*inactivity));
383 if (!inactivity) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530384 WMA_LOGE("QDF MEM Alloc Failed for tSirIbssPeerInactivity");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800385 return -ENOMEM;
386 }
387
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800388 inactivity->staIdx = peer_id;
389 qdf_mem_copy(inactivity->peer_addr.bytes, macaddr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800390 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800391 wma_send_msg(wma, WMA_IBSS_PEER_INACTIVITY_IND,
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800392 inactivity, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800393 goto exit_handler;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800394#ifdef FEATURE_WLAN_TDLS
395 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT:
396 del_sta_ctx = (tpDeleteStaContext)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530397 qdf_mem_malloc(sizeof(tDeleteStaContext));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 if (!del_sta_ctx) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700399 WMA_LOGE("%s: mem alloc failed for struct del_sta_context for TDLS peer: %pM",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400 __func__, macaddr);
401 return -ENOMEM;
402 }
403
Naveen Rawat9801ac02016-06-22 11:02:50 -0700404 del_sta_ctx->is_tdls = true;
405 del_sta_ctx->vdev_id = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 del_sta_ctx->staId = peer_id;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800407 qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530408 qdf_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].bssid,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800409 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410 del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
411 wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND,
412 (void *)del_sta_ctx, 0);
413 goto exit_handler;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414#endif /* FEATURE_WLAN_TDLS */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 case WMI_PEER_STA_KICKOUT_REASON_XRETRY:
416 if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA &&
417 (wma->interfaces[vdev_id].sub_type == 0 ||
418 wma->interfaces[vdev_id].sub_type ==
419 WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530420 !qdf_mem_cmp(wma->interfaces[vdev_id].bssid,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800421 macaddr, QDF_MAC_ADDR_SIZE)) {
Sen, Devendra154b3c42017-02-13 20:44:15 +0530422 wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_XRETRY,
423 vdev_id, macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424 /*
425 * KICKOUT event is for current station-AP connection.
426 * Treat it like final beacon miss. Station may not have
427 * missed beacons but not able to transmit frames to AP
428 * for a long time. Must disconnect to get out of
429 * this sticky situation.
430 * In future implementation, roaming module will also
431 * handle this event and perform a scan.
432 */
433 WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_XRETRY event for STA",
434 __func__);
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +0530435 wma_beacon_miss_handler(wma, vdev_id,
436 kickout_event->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800437 goto exit_handler;
438 }
439 break;
440
441 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED:
442 /*
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700443 * Default legacy value used by original firmware implementation
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444 */
445 if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA &&
446 (wma->interfaces[vdev_id].sub_type == 0 ||
447 wma->interfaces[vdev_id].sub_type ==
448 WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530449 !qdf_mem_cmp(wma->interfaces[vdev_id].bssid,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800450 macaddr, QDF_MAC_ADDR_SIZE)) {
Sen, Devendra154b3c42017-02-13 20:44:15 +0530451 wma_sta_kickout_event(
452 HOST_STA_KICKOUT_REASON_UNSPECIFIED, vdev_id, macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453 /*
454 * KICKOUT event is for current station-AP connection.
455 * Treat it like final beacon miss. Station may not have
456 * missed beacons but not able to transmit frames to AP
457 * for a long time. Must disconnect to get out of
458 * this sticky situation.
459 * In future implementation, roaming module will also
460 * handle this event and perform a scan.
461 */
462 WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED event for STA",
463 __func__);
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +0530464 wma_beacon_miss_handler(wma, vdev_id,
465 kickout_event->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466 goto exit_handler;
467 }
468 break;
469
470 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY:
Naveen Rawat9801ac02016-06-22 11:02:50 -0700471 /*
472 * Handle SA query kickout is same as inactivity kickout.
473 * This could be for STA or SAP role
474 */
mukul sharma72c8b222015-09-04 17:02:01 +0530475 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800476 default:
477 break;
478 }
479
480 /*
481 * default action is to send delete station context indication to LIM
482 */
483 del_sta_ctx =
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700484 (tDeleteStaContext *) qdf_mem_malloc(sizeof(tDeleteStaContext));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800485 if (!del_sta_ctx) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700486 WMA_LOGE("QDF MEM Alloc Failed for struct del_sta_context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487 return -ENOMEM;
488 }
489
Naveen Rawat9801ac02016-06-22 11:02:50 -0700490 del_sta_ctx->is_tdls = false;
491 del_sta_ctx->vdev_id = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800492 del_sta_ctx->staId = peer_id;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800493 qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530494 qdf_mem_copy(del_sta_ctx->bssId, wma->interfaces[vdev_id].addr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800495 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496 del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
Yeshwanth Sriram Guntuka14ab04c2018-09-21 15:06:49 +0530497 if (wmi_service_enabled(wma->wmi_handle,
498 wmi_service_hw_db2dbm_support))
499 del_sta_ctx->rssi = kickout_event->rssi;
500 else
501 del_sta_ctx->rssi = kickout_event->rssi +
502 WMA_TGT_NOISE_FLOOR_DBM;
Sen, Devendra154b3c42017-02-13 20:44:15 +0530503 wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_KEEP_ALIVE,
504 vdev_id, macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800505 wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx,
506 0);
Yeshwanth Sriram Guntuka14ab04c2018-09-21 15:06:49 +0530507 wma_lost_link_info_handler(wma, vdev_id, del_sta_ctx->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508exit_handler:
509 WMA_LOGD("%s: Exit", __func__);
510 return 0;
511}
512
513/**
514 * wma_unified_bcntx_status_event_handler() - beacon tx status event handler
515 * @handle: wma handle
516 * @cmd_param_info: event data
517 * @len: data length
518 *
519 * WMI Handler for WMI_OFFLOAD_BCN_TX_STATUS_EVENTID event from firmware.
520 * This event is generated by FW when the beacon transmission is offloaded
521 * and the host performs beacon template modification using WMI_BCN_TMPL_CMDID
522 * The FW generates this event when the first successful beacon transmission
523 * after template update
524 *
525 * Return: 0 for success or error code
526 */
527int wma_unified_bcntx_status_event_handler(void *handle,
528 uint8_t *cmd_param_info,
529 uint32_t len)
530{
531 tp_wma_handle wma = (tp_wma_handle) handle;
532 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf;
533 wmi_offload_bcn_tx_status_event_fixed_param *resp_event;
534 tSirFirstBeaconTxCompleteInd *beacon_tx_complete_ind;
535
536 param_buf =
537 (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *) cmd_param_info;
538 if (!param_buf) {
539 WMA_LOGE("Invalid bcn tx response event buffer");
540 return -EINVAL;
541 }
542
543 resp_event = param_buf->fixed_param;
544
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +0530545 WMA_LOGD("%s", __func__);
546
Vignesh Viswanathan07db59e2017-10-04 18:24:08 +0530547 if (resp_event->vdev_id >= wma->max_bssid) {
548 WMA_LOGE("%s: received invalid vdev_id %d",
549 __func__, resp_event->vdev_id);
550 return -EINVAL;
551 }
552
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 /* Check for valid handle to ensure session is not
554 * deleted in any race
555 */
556 if (!wma->interfaces[resp_event->vdev_id].handle) {
557 WMA_LOGE("%s: The session does not exist", __func__);
558 return -EINVAL;
559 }
560
561 /* Beacon Tx Indication supports only AP mode. Ignore in other modes */
562 if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) == false) {
563 WMA_LOGI("%s: Beacon Tx Indication does not support type %d and sub_type %d",
564 __func__, wma->interfaces[resp_event->vdev_id].type,
565 wma->interfaces[resp_event->vdev_id].sub_type);
566 return 0;
567 }
568
569 beacon_tx_complete_ind = (tSirFirstBeaconTxCompleteInd *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530570 qdf_mem_malloc(sizeof(tSirFirstBeaconTxCompleteInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 if (!beacon_tx_complete_ind) {
572 WMA_LOGE("%s: Failed to alloc beacon_tx_complete_ind",
573 __func__);
574 return -ENOMEM;
575 }
576
577 beacon_tx_complete_ind->messageType = WMA_DFS_BEACON_TX_SUCCESS_IND;
578 beacon_tx_complete_ind->length = sizeof(tSirFirstBeaconTxCompleteInd);
Pragaspathi Thilagaraje05162d2019-05-23 13:10:46 +0530579 beacon_tx_complete_ind->bss_idx = resp_event->vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800580
581 wma_send_msg(wma, WMA_DFS_BEACON_TX_SUCCESS_IND,
582 (void *)beacon_tx_complete_ind, 0);
583 return 0;
584}
585
586/**
Wu Gao3365e782018-07-27 18:19:35 +0800587 * wma_get_go_probe_timeout() - get P2P GO probe timeout
588 * @mac: UMAC handler
589 * @max_inactive_time: return max inactive time
590 * @max_unresponsive_time: return max unresponsive time
591 *
592 * Return: none
593 */
594#ifdef CONVERGED_P2P_ENABLE
595static inline void
Jeff Johnson009c40f2018-11-05 09:54:37 -0800596wma_get_go_probe_timeout(struct mac_context *mac,
Wu Gao3365e782018-07-27 18:19:35 +0800597 uint32_t *max_inactive_time,
598 uint32_t *max_unresponsive_time)
599{
600 uint32_t keep_alive;
601 QDF_STATUS status;
602
603 status = cfg_p2p_get_go_link_monitor_period(mac->psoc,
604 max_inactive_time);
605 if (QDF_IS_STATUS_ERROR(status)) {
606 WMA_LOGE("Failed to go monitor period");
607 *max_inactive_time = WMA_LINK_MONITOR_DEFAULT_TIME_SECS;
608 }
609 status = cfg_p2p_get_go_keepalive_period(mac->psoc,
610 &keep_alive);
611 if (QDF_IS_STATUS_ERROR(status)) {
612 WMA_LOGE("Failed to read go keep alive");
613 keep_alive = WMA_KEEP_ALIVE_DEFAULT_TIME_SECS;
614 }
615
616 *max_unresponsive_time = *max_inactive_time + keep_alive;
617}
618#else
619static inline void
Jeff Johnson009c40f2018-11-05 09:54:37 -0800620wma_get_go_probe_timeout(struct mac_context *mac,
Wu Gao3365e782018-07-27 18:19:35 +0800621 uint32_t *max_inactive_time,
622 uint32_t *max_unresponsive_time)
623{
624}
625#endif
626
627/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628 * wma_get_link_probe_timeout() - get link timeout based on sub type
629 * @mac: UMAC handler
630 * @sub_type: vdev syb type
631 * @max_inactive_time: return max inactive time
632 * @max_unresponsive_time: return max unresponsive time
633 *
634 * Return: none
635 */
Wu Gao3365e782018-07-27 18:19:35 +0800636static inline void
Jeff Johnson009c40f2018-11-05 09:54:37 -0800637wma_get_link_probe_timeout(struct mac_context *mac,
Wu Gao3365e782018-07-27 18:19:35 +0800638 uint32_t sub_type,
639 uint32_t *max_inactive_time,
640 uint32_t *max_unresponsive_time)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800641{
Arif Hussain43e09712018-09-18 19:31:57 -0700642 if (sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) {
Wu Gao3365e782018-07-27 18:19:35 +0800643 wma_get_go_probe_timeout(mac, max_inactive_time,
644 max_unresponsive_time);
Arif Hussain43e09712018-09-18 19:31:57 -0700645 } else {
646 *max_inactive_time =
647 mac->mlme_cfg->timeouts.ap_link_monitor_timeout;
648 *max_unresponsive_time = *max_inactive_time +
649 mac->mlme_cfg->timeouts.ap_keep_alive_timeout;
650 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651}
652
653/**
Hong Shi2d384fd2017-05-22 18:38:41 +0800654 * wma_verify_rate_code() - verify if rate code is valid.
655 * @rate_code: rate code
gaolezd1a229d2018-03-28 17:26:40 +0800656 * @band: band information
Hong Shi2d384fd2017-05-22 18:38:41 +0800657 *
658 * Return: verify result
659 */
gaolezd1a229d2018-03-28 17:26:40 +0800660static bool wma_verify_rate_code(u_int32_t rate_code, enum cds_band_type band)
Hong Shi2d384fd2017-05-22 18:38:41 +0800661{
662 uint8_t preamble, nss, rate;
663 bool valid = true;
664
665 preamble = (rate_code & 0xc0) >> 6;
666 nss = (rate_code & 0x30) >> 4;
667 rate = rate_code & 0xf;
668
669 switch (preamble) {
670 case WMI_RATE_PREAMBLE_CCK:
gaolezd1a229d2018-03-28 17:26:40 +0800671 if (nss != 0 || rate > 3 || band == CDS_BAND_5GHZ)
Hong Shi2d384fd2017-05-22 18:38:41 +0800672 valid = false;
673 break;
674 case WMI_RATE_PREAMBLE_OFDM:
675 if (nss != 0 || rate > 7)
676 valid = false;
677 break;
678 case WMI_RATE_PREAMBLE_HT:
gaolezd1a229d2018-03-28 17:26:40 +0800679 if (nss != 0 || rate > 7)
Hong Shi2d384fd2017-05-22 18:38:41 +0800680 valid = false;
681 break;
682 case WMI_RATE_PREAMBLE_VHT:
gaolezd1a229d2018-03-28 17:26:40 +0800683 if (nss != 0 || rate > 9)
Hong Shi2d384fd2017-05-22 18:38:41 +0800684 valid = false;
685 break;
686 default:
687 break;
688 }
689 return valid;
690}
691
692#define TX_MGMT_RATE_2G_ENABLE_OFFSET 30
693#define TX_MGMT_RATE_5G_ENABLE_OFFSET 31
694#define TX_MGMT_RATE_2G_OFFSET 0
695#define TX_MGMT_RATE_5G_OFFSET 12
696
697/**
Hong Shib90718f2017-02-20 00:57:22 +0800698 * wma_set_mgmt_rate() - set vdev mgmt rate.
699 * @wma: wma handle
700 * @vdev_id: vdev id
701 *
702 * Return: None
703 */
704void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id)
705{
706 uint32_t cfg_val;
707 int ret;
Hong Shi2d384fd2017-05-22 18:38:41 +0800708 uint32_t per_band_mgmt_tx_rate = 0;
gaolezd1a229d2018-03-28 17:26:40 +0800709 enum cds_band_type band = 0;
Jeff Johnson009c40f2018-11-05 09:54:37 -0800710 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Hong Shib90718f2017-02-20 00:57:22 +0800711
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -0700712 if (!mac) {
Hong Shib90718f2017-02-20 00:57:22 +0800713 WMA_LOGE("%s: Failed to get mac", __func__);
714 return;
715 }
716
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530717 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
718 band = CDS_BAND_ALL;
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530719 if ((cfg_val == MLME_CFG_TX_MGMT_RATE_DEF) ||
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530720 !wma_verify_rate_code(cfg_val, band)) {
721 WMA_LOGD("default WNI_CFG_RATE_FOR_TX_MGMT, ignore");
Hong Shib90718f2017-02-20 00:57:22 +0800722 } else {
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530723 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
724 WMI_VDEV_PARAM_MGMT_TX_RATE,
725 cfg_val);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530726 if (ret)
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530727 WMA_LOGE("Failed to set WMI_VDEV_PARAM_MGMT_TX_RATE");
Hong Shib90718f2017-02-20 00:57:22 +0800728 }
Hong Shi2d384fd2017-05-22 18:38:41 +0800729
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530730 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt_2g;
731 band = CDS_BAND_2GHZ;
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530732 if ((cfg_val == MLME_CFG_TX_MGMT_2G_RATE_DEF) ||
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530733 !wma_verify_rate_code(cfg_val, band)) {
734 WMA_LOGD("use default 2G MGMT rate.");
735 per_band_mgmt_tx_rate &=
736 ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800737 } else {
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530738 per_band_mgmt_tx_rate |=
739 (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
740 per_band_mgmt_tx_rate |=
741 ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800742 }
743
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530744 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
745 band = CDS_BAND_5GHZ;
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530746 if ((cfg_val == MLME_CFG_TX_MGMT_5G_RATE_DEF) ||
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530747 !wma_verify_rate_code(cfg_val, band)) {
748 WMA_LOGD("use default 5G MGMT rate.");
749 per_band_mgmt_tx_rate &=
750 ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800751 } else {
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530752 per_band_mgmt_tx_rate |=
753 (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
754 per_band_mgmt_tx_rate |=
755 ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800756 }
757
758 ret = wma_vdev_set_param(
759 wma->wmi_handle,
760 vdev_id,
761 WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE,
762 per_band_mgmt_tx_rate);
763 if (ret)
764 WMA_LOGE("Failed to set WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE");
765
Hong Shib90718f2017-02-20 00:57:22 +0800766}
767
768/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 * wma_set_sap_keepalive() - set SAP keep alive parameters to fw
770 * @wma: wma handle
771 * @vdev_id: vdev id
772 *
773 * Return: none
774 */
775void wma_set_sap_keepalive(tp_wma_handle wma, uint8_t vdev_id)
776{
777 uint32_t min_inactive_time, max_inactive_time, max_unresponsive_time;
Jeff Johnson009c40f2018-11-05 09:54:37 -0800778 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Govind Singhd76a5b02016-03-08 15:12:14 +0530779 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800780
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -0700781 if (!mac) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800782 WMA_LOGE("%s: Failed to get mac", __func__);
783 return;
784 }
785
786 wma_get_link_probe_timeout(mac, wma->interfaces[vdev_id].sub_type,
787 &max_inactive_time, &max_unresponsive_time);
788
789 min_inactive_time = max_inactive_time / 2;
790
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700791 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
792 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
793 min_inactive_time);
Govind Singhd76a5b02016-03-08 15:12:14 +0530794 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 WMA_LOGE("Failed to Set AP MIN IDLE INACTIVE TIME");
796
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700797 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
798 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
799 max_inactive_time);
Govind Singhd76a5b02016-03-08 15:12:14 +0530800 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 WMA_LOGE("Failed to Set AP MAX IDLE INACTIVE TIME");
802
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700803 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
804 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
805 max_unresponsive_time);
Govind Singhd76a5b02016-03-08 15:12:14 +0530806 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807 WMA_LOGE("Failed to Set MAX UNRESPONSIVE TIME");
808
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700809 WMA_LOGD("%s:vdev_id:%d min_inactive_time: %u max_inactive_time: %u max_unresponsive_time: %u",
810 __func__, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811 min_inactive_time, max_inactive_time, max_unresponsive_time);
812}
813
814/**
mukul sharma72c8b222015-09-04 17:02:01 +0530815 * wma_set_sta_sa_query_param() - set sta sa query parameters
816 * @wma: wma handle
817 * @vdev_id: vdev id
818
819 * This function sets sta query related parameters in fw.
820 *
821 * Return: none
822 */
823
824void wma_set_sta_sa_query_param(tp_wma_handle wma,
825 uint8_t vdev_id)
826{
Jeff Johnson009c40f2018-11-05 09:54:37 -0800827 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Karthik Kantamneni24f71bc2018-09-11 19:08:38 +0530828 uint8_t max_retries;
829 uint16_t retry_interval;
mukul sharma72c8b222015-09-04 17:02:01 +0530830
831 WMA_LOGD(FL("Enter:"));
mukul sharma72c8b222015-09-04 17:02:01 +0530832
Krunal Sonifea06802017-04-13 14:44:48 -0700833 if (!mac) {
834 WMA_LOGE(FL("mac context is NULL"));
835 return;
836 }
Karthik Kantamneni24f71bc2018-09-11 19:08:38 +0530837
838 max_retries = mac->mlme_cfg->gen.pmf_sa_query_max_retries;
839 retry_interval = mac->mlme_cfg->gen.pmf_sa_query_retry_interval;
mukul sharma72c8b222015-09-04 17:02:01 +0530840
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530841 wmi_unified_set_sta_sa_query_param_cmd(wma->wmi_handle,
842 vdev_id,
843 max_retries,
844 retry_interval);
mukul sharma72c8b222015-09-04 17:02:01 +0530845
846 WMA_LOGD(FL("Exit :"));
mukul sharma72c8b222015-09-04 17:02:01 +0530847}
848
849/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800850 * wma_set_sta_keep_alive() - set sta keep alive parameters
851 * @wma: wma handle
852 * @vdev_id: vdev id
853 * @method: method for keep alive
854 * @timeperiod: time period
855 * @hostv4addr: host ipv4 address
856 * @destv4addr: dst ipv4 address
857 * @destmac: destination mac
858 *
859 * This function sets keep alive related parameters in fw.
860 *
861 * Return: none
862 */
863void wma_set_sta_keep_alive(tp_wma_handle wma, uint8_t vdev_id,
864 uint32_t method, uint32_t timeperiod,
865 uint8_t *hostv4addr, uint8_t *destv4addr,
866 uint8_t *destmac)
867{
Jeff Johnson4c2837f2019-02-28 13:42:20 -0800868 struct sta_keep_alive_params params = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869
870 WMA_LOGD("%s: Enter", __func__);
871
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530872 if (!wma) {
873 WMA_LOGE("%s: wma handle is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800874 return;
875 }
876
Wu Gao93816212018-08-31 16:49:54 +0800877 if (timeperiod > cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD)) {
Govind Singhfe9ab252016-06-21 14:35:35 +0530878 WMI_LOGE("Invalid period %d Max limit %d", timeperiod,
Wu Gao93816212018-08-31 16:49:54 +0800879 cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD));
Govind Singhfe9ab252016-06-21 14:35:35 +0530880 return;
881 }
882
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530883 params.vdev_id = vdev_id;
884 params.method = method;
885 params.timeperiod = timeperiod;
Jeff Johnson4c2837f2019-02-28 13:42:20 -0800886 if (hostv4addr)
887 qdf_mem_copy(params.hostv4addr, hostv4addr, QDF_IPV4_ADDR_SIZE);
888 if (destv4addr)
889 qdf_mem_copy(params.destv4addr, destv4addr, QDF_IPV4_ADDR_SIZE);
890 if (destmac)
891 qdf_mem_copy(params.destmac, destmac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892
Jeff Johnsonf32bf012019-02-25 11:37:32 -0800893 wmi_unified_set_sta_keep_alive_cmd(wma->wmi_handle, &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894 WMA_LOGD("%s: Exit", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800895}
896
897/**
898 * wma_vdev_install_key_complete_event_handler() - install key complete handler
899 * @handle: wma handle
900 * @event: event data
901 * @len: data length
902 *
903 * This event is sent by fw once WPA/WPA2 keys are installed in fw.
904 *
905 * Return: 0 for success or error code
906 */
907int wma_vdev_install_key_complete_event_handler(void *handle,
908 uint8_t *event,
909 uint32_t len)
910{
911 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf = NULL;
912 wmi_vdev_install_key_complete_event_fixed_param *key_fp = NULL;
913
914 if (!event) {
915 WMA_LOGE("%s: event param null", __func__);
916 return -EINVAL;
917 }
918
919 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *) event;
920 if (!param_buf) {
921 WMA_LOGE("%s: received null buf from target", __func__);
922 return -EINVAL;
923 }
924
925 key_fp = param_buf->fixed_param;
926 if (!key_fp) {
927 WMA_LOGE("%s: received null event data from target", __func__);
928 return -EINVAL;
929 }
930 /*
931 * Do nothing for now. Completion of set key is already indicated to lim
932 */
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800933 WMA_LOGD("%s: WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800934 return 0;
935}
936/*
937 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
938 * 0 for no restriction
939 * 1 for 1/4 us - Our lower layer calculations limit our precision to 1 msec
940 * 2 for 1/2 us - Our lower layer calculations limit our precision to 1 msec
941 * 3 for 1 us
942 * 4 for 2 us
943 * 5 for 4 us
944 * 6 for 8 us
945 * 7 for 16 us
946 */
947static const uint8_t wma_mpdu_spacing[] = { 0, 1, 1, 1, 2, 4, 8, 16 };
948
949/**
950 * wma_parse_mpdudensity() - give mpdu spacing from mpdu density
951 * @mpdudensity: mpdu density
952 *
953 * Return: mpdu spacing or 0 for error
954 */
955static inline uint8_t wma_parse_mpdudensity(uint8_t mpdudensity)
956{
957 if (mpdudensity < sizeof(wma_mpdu_spacing))
958 return wma_mpdu_spacing[mpdudensity];
959 else
960 return 0;
961}
962
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530963#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
964
965/**
966 * wma_unified_peer_state_update() - update peer state
967 * @pdev: pdev handle
968 * @sta_mac: pointer to sta mac addr
969 * @bss_addr: bss address
970 * @sta_type: sta entry type
971 *
972 *
973 * Return: None
974 */
975static void
976wma_unified_peer_state_update(
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800977 struct cdp_pdev *pdev,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530978 uint8_t *sta_mac,
979 uint8_t *bss_addr,
980 uint8_t sta_type)
981{
Leo Chang96464902016-10-28 11:10:54 -0700982 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
983
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530984 if (STA_ENTRY_TDLS_PEER == sta_type)
Leo Chang96464902016-10-28 11:10:54 -0700985 cdp_peer_state_update(soc, pdev, sta_mac,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530986 OL_TXRX_PEER_STATE_AUTH);
987 else
Leo Chang96464902016-10-28 11:10:54 -0700988 cdp_peer_state_update(soc, pdev, bss_addr,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530989 OL_TXRX_PEER_STATE_AUTH);
990}
991#else
992
993static inline void
994wma_unified_peer_state_update(
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800995 struct cdp_pdev *pdev,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530996 uint8_t *sta_mac,
997 uint8_t *bss_addr,
998 uint8_t sta_type)
999{
Leo Chang96464902016-10-28 11:10:54 -07001000 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1001
1002 cdp_peer_state_update(soc, pdev, bss_addr, OL_TXRX_PEER_STATE_AUTH);
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05301003}
1004#endif
1005
Hong Shi417824f2017-01-12 02:31:14 +08001006#define CFG_CTRL_MASK 0xFF00
1007#define CFG_DATA_MASK 0x00FF
1008
1009/**
1010 * wma_mask_tx_ht_rate() - mask tx ht rate based on config
1011 * @wma: wma handle
1012 * @mcs_set mcs set buffer
1013 *
1014 * Return: None
1015 */
1016static void wma_mask_tx_ht_rate(tp_wma_handle wma, uint8_t *mcs_set)
1017{
Karthik Kantamneni22dd0f62018-08-07 14:53:50 +05301018 uint32_t i, j;
1019 uint16_t mcs_limit;
Hong Shi417824f2017-01-12 02:31:14 +08001020 uint8_t *rate_pos = mcs_set;
Jeff Johnson009c40f2018-11-05 09:54:37 -08001021 struct mac_context *mac = (struct mac_context *)wma->mac_context;
Hong Shi417824f2017-01-12 02:31:14 +08001022
1023 /*
1024 * Get MCS limit from ini configure, and map it to rate parameters
1025 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
1026 * check whether ini config is enabled and CFG_DATA_MASK to get the
1027 * MCS value.
1028 */
Karthik Kantamneni22dd0f62018-08-07 14:53:50 +05301029 mcs_limit = mac->mlme_cfg->rates.max_htmcs_txdata;
Hong Shi417824f2017-01-12 02:31:14 +08001030
1031 if (mcs_limit & CFG_CTRL_MASK) {
1032 WMA_LOGD("%s: set mcs_limit %x", __func__, mcs_limit);
1033
1034 mcs_limit &= CFG_DATA_MASK;
1035 for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
1036 if (j < mcs_limit / 8) {
1037 rate_pos[j] = 0xff;
1038 j++;
1039 i += 8;
1040 } else if (j < mcs_limit / 8 + 1) {
1041 if (i <= mcs_limit)
1042 rate_pos[i / 8] |= 1 << (i % 8);
1043 else
1044 rate_pos[i / 8] &= ~(1 << (i % 8));
1045 i++;
1046
1047 if (i >= (j + 1) * 8)
1048 j++;
1049 } else {
1050 rate_pos[j++] = 0;
1051 i += 8;
1052 }
1053 }
1054 }
1055}
1056
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001057#if SUPPORT_11AX
1058/**
1059 * wma_fw_to_host_phymode_11ac() - convert fw to host phymode for 11ax phymodes
1060 * @wma: wma handle
1061 * @phymode: phymode to convert
1062 *
1063 * Return: None
1064 */
1065static enum wlan_phymode wma_fw_to_host_phymode_11ac(WLAN_PHY_MODE phymode)
1066{
1067 switch (phymode) {
1068 default:
1069 return WLAN_PHYMODE_AUTO;
1070 case MODE_11AX_HE20:
1071 return WLAN_PHYMODE_11AC_VHT20;
1072 case MODE_11AX_HE40:
1073 return WLAN_PHYMODE_11AC_VHT40;
1074 case MODE_11AX_HE80:
1075 return WLAN_PHYMODE_11AC_VHT80;
1076 case MODE_11AX_HE80_80:
1077 return WLAN_PHYMODE_11AC_VHT80_80;
1078 case MODE_11AX_HE160:
1079 return WLAN_PHYMODE_11AC_VHT160;
1080 case MODE_11AX_HE20_2G:
1081 return WLAN_PHYMODE_11AC_VHT20;
1082 case MODE_11AX_HE40_2G:
1083 return WLAN_PHYMODE_11AC_VHT40;
1084 case MODE_11AX_HE80_2G:
1085 return WLAN_PHYMODE_11AC_VHT80;
1086 }
1087 return WLAN_PHYMODE_AUTO;
1088}
1089#else
1090static enum wlan_phymode wma_fw_to_host_phymode_11ac(WLAN_PHY_MODE phymode)
1091{
1092 return WLAN_PHYMODE_AUTO;
1093}
1094#endif
1095
1096#ifdef CONFIG_160MHZ_SUPPORT
1097/**
1098 * wma_fw_to_host_phymode_160() - convert fw to host phymode for 160 mhz
1099 * phymodes
1100 * @wma: wma handle
1101 * @phymode: phymode to convert
1102 *
1103 * Return: None
1104 */
1105static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
1106{
1107 switch (phymode) {
1108 default:
1109 return WLAN_PHYMODE_AUTO;
1110 case MODE_11AC_VHT80_80:
1111 return WLAN_PHYMODE_11AC_VHT80_80;
1112 case MODE_11AC_VHT160:
1113 return WLAN_PHYMODE_11AC_VHT160;
1114 }
1115}
1116#else
1117static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
1118{
1119 return WLAN_PHYMODE_AUTO;
1120}
1121#endif
1122/**
1123 * wma_fw_to_host_phymode() - convert fw to host phymode
1124 * @wma: wma handle
1125 * @phymode: phymode to convert
1126 *
1127 * Return: None
1128 */
1129static enum wlan_phymode wma_fw_to_host_phymode(WLAN_PHY_MODE phymode)
1130{
1131 enum wlan_phymode host_phymode;
1132 switch (phymode) {
1133 default:
1134 host_phymode = wma_fw_to_host_phymode_160(phymode);
1135 if (host_phymode != WLAN_PHYMODE_AUTO)
1136 return host_phymode;
1137 return wma_fw_to_host_phymode_11ac(phymode);
1138 case MODE_11A:
1139 return WLAN_PHYMODE_11A;
1140 case MODE_11G:
1141 return WLAN_PHYMODE_11G;
1142 case MODE_11B:
1143 return WLAN_PHYMODE_11B;
1144 case MODE_11GONLY:
1145 return WLAN_PHYMODE_11G;
1146 case MODE_11NA_HT20:
1147 return WLAN_PHYMODE_11NA_HT20;
1148 case MODE_11NG_HT20:
1149 return WLAN_PHYMODE_11NG_HT20;
1150 case MODE_11NA_HT40:
1151 return WLAN_PHYMODE_11NA_HT40;
1152 case MODE_11NG_HT40:
1153 return WLAN_PHYMODE_11NG_HT40;
1154 case MODE_11AC_VHT20:
1155 return WLAN_PHYMODE_11AC_VHT20;
1156 case MODE_11AC_VHT40:
1157 return WLAN_PHYMODE_11AC_VHT40;
1158 case MODE_11AC_VHT80:
1159 return WLAN_PHYMODE_11AC_VHT80;
1160 case MODE_11AC_VHT20_2G:
1161 return WLAN_PHYMODE_11AC_VHT20;
1162 case MODE_11AC_VHT40_2G:
1163 return WLAN_PHYMODE_11AC_VHT40;
1164 case MODE_11AC_VHT80_2G:
1165 return WLAN_PHYMODE_11AC_VHT80;
1166 }
1167}
1168
1169/**
1170 * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object
1171 * @wma: wma handle
1172 * @mac_addr: mac addr of peer
1173 * @phymode: phymode value to set
1174 *
1175 * Return: None
1176 */
1177static void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma,
1178 uint8_t *mac_addr,
1179 WLAN_PHY_MODE phymode)
1180{
1181 uint8_t pdev_id;
1182 struct wlan_objmgr_peer *peer;
1183 struct wlan_objmgr_psoc *psoc = wma->psoc;
1184
1185 pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1186 peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1187 WLAN_LEGACY_WMA_ID);
1188 if (!peer) {
1189 WMA_LOGE(FL("peer object null"));
1190 return;
1191 }
1192
1193 wlan_peer_obj_lock(peer);
1194 wlan_peer_set_phymode(peer, wma_fw_to_host_phymode(phymode));
1195 wlan_peer_obj_unlock(peer);
1196 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1197}
1198
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001199/**
Jayachandran Sreekumaran2613f322019-03-01 19:05:59 +05301200 * wma_objmgr_set_peer_mlme_type() - set peer type to peer object
1201 * @wma: wma handle
1202 * @mac_addr: mac addr of peer
1203 * @peer_type: peer type value to set
1204 *
1205 * Return: None
1206 */
1207static void wma_objmgr_set_peer_mlme_type(tp_wma_handle wma,
1208 uint8_t *mac_addr,
1209 enum wlan_peer_type peer_type)
1210{
1211 uint8_t pdev_id;
1212 struct wlan_objmgr_peer *peer;
1213 struct wlan_objmgr_psoc *psoc = wma->psoc;
1214
1215 pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1216 peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1217 WLAN_LEGACY_WMA_ID);
1218 if (!peer) {
1219 WMA_LOGE(FL("peer object null"));
1220 return;
1221 }
1222
1223 wlan_peer_obj_lock(peer);
1224 wlan_peer_set_peer_type(peer, peer_type);
1225 wlan_peer_obj_unlock(peer);
1226 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1227}
1228
1229/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 * wmi_unified_send_peer_assoc() - send peer assoc command to fw
1231 * @wma: wma handle
1232 * @nw_type: nw type
1233 * @params: add sta params
1234 *
1235 * This function send peer assoc command to firmware with
1236 * different parameters.
1237 *
Govind Singhb30d4c02016-03-24 11:01:23 +05301238 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001239 */
Govind Singhb30d4c02016-03-24 11:01:23 +05301240QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001241 tSirNwType nw_type,
1242 tpAddStaParams params)
1243{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001244 struct cdp_pdev *pdev;
Govind Singhb30d4c02016-03-24 11:01:23 +05301245 struct peer_assoc_params *cmd;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001246 int32_t ret, max_rates, i;
Govind Singhb30d4c02016-03-24 11:01:23 +05301247 uint8_t *rate_pos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001248 wmi_rate_set peer_legacy_rates, peer_ht_rates;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001249 uint32_t num_peer_11b_rates = 0;
1250 uint32_t num_peer_11a_rates = 0;
1251 uint32_t phymode;
1252 uint32_t peer_nss = 1;
1253 struct wma_txrx_node *intr = NULL;
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001254 bool is_he;
Govind Singhb30d4c02016-03-24 11:01:23 +05301255 QDF_STATUS status;
Jeff Johnson009c40f2018-11-05 09:54:37 -08001256 struct mac_context *mac = (struct mac_context *)wma->mac_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257
Govind Singhb30d4c02016-03-24 11:01:23 +05301258 cmd = qdf_mem_malloc(sizeof(struct peer_assoc_params));
1259 if (!cmd) {
1260 WMA_LOGE("Failed to allocate peer_assoc_params param");
1261 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 }
Govind Singhb30d4c02016-03-24 11:01:23 +05301263
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001264 intr = &wma->interfaces[params->smesessionId];
1265
Anurag Chouhan6d760662016-02-20 16:05:43 +05301266 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07001268 if (!pdev) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 WMA_LOGE("%s: Failed to get pdev", __func__);
Govind Singhb30d4c02016-03-24 11:01:23 +05301270 qdf_mem_free(cmd);
1271 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 }
1273
Hong Shi417824f2017-01-12 02:31:14 +08001274 wma_mask_tx_ht_rate(wma, params->supportedRates.supportedMCSSet);
1275
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301276 qdf_mem_zero(&peer_legacy_rates, sizeof(wmi_rate_set));
1277 qdf_mem_zero(&peer_ht_rates, sizeof(wmi_rate_set));
Govind Singhb30d4c02016-03-24 11:01:23 +05301278 qdf_mem_zero(cmd, sizeof(struct peer_assoc_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001280 is_he = wma_is_peer_he_capable(params);
Abhishek Singh1d8bd622018-11-13 11:43:55 +05301281 if ((params->ch_width > CH_WIDTH_40MHZ) &&
1282 ((nw_type == eSIR_11G_NW_TYPE) ||
1283 (nw_type == eSIR_11B_NW_TYPE))) {
1284 WMA_LOGE("ch_width %d sent in 11G, configure to 40MHz",
1285 params->ch_width);
1286 params->ch_width = CH_WIDTH_40MHZ;
1287 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288 phymode = wma_peer_phymode(nw_type, params->staType,
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001289 params->htCapable, params->ch_width,
1290 params->vhtCapable, is_he);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001291
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001292 wma_objmgr_set_peer_mlme_phymode(wma, params->staMac, phymode);
1293
Karthik Kantamneni22dd0f62018-08-07 14:53:50 +05301294 if (!mac->mlme_cfg->rates.disable_abg_rate_txdata) {
Hong Shia9ef8712017-02-19 21:54:02 +08001295 /* Legacy Rateset */
1296 rate_pos = (uint8_t *) peer_legacy_rates.rates;
1297 for (i = 0; i < SIR_NUM_11B_RATES; i++) {
1298 if (!params->supportedRates.llbRates[i])
1299 continue;
1300 rate_pos[peer_legacy_rates.num_rates++] =
1301 params->supportedRates.llbRates[i];
1302 num_peer_11b_rates++;
1303 }
1304 for (i = 0; i < SIR_NUM_11A_RATES; i++) {
1305 if (!params->supportedRates.llaRates[i])
1306 continue;
1307 rate_pos[peer_legacy_rates.num_rates++] =
1308 params->supportedRates.llaRates[i];
1309 num_peer_11a_rates++;
1310 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311 }
1312
1313 if ((phymode == MODE_11A && num_peer_11a_rates == 0) ||
1314 (phymode == MODE_11B && num_peer_11b_rates == 0)) {
1315 WMA_LOGW("%s: Invalid phy rates. phymode 0x%x, 11b_rates %d, 11a_rates %d",
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001316 __func__, phymode, num_peer_11b_rates,
1317 num_peer_11a_rates);
Govind Singhb30d4c02016-03-24 11:01:23 +05301318 qdf_mem_free(cmd);
1319 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001320 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321
1322 /* HT Rateset */
1323 max_rates = sizeof(peer_ht_rates.rates) /
1324 sizeof(peer_ht_rates.rates[0]);
1325 rate_pos = (uint8_t *) peer_ht_rates.rates;
1326 for (i = 0; i < MAX_SUPPORTED_RATES; i++) {
1327 if (params->supportedRates.supportedMCSSet[i / 8] &
1328 (1 << (i % 8))) {
1329 rate_pos[peer_ht_rates.num_rates++] = i;
1330 if (i >= 8) {
1331 /* MCS8 or higher rate is present, must be 2x2 */
1332 peer_nss = 2;
1333 }
1334 }
1335 if (peer_ht_rates.num_rates == max_rates)
1336 break;
1337 }
1338
1339 if (params->htCapable && !peer_ht_rates.num_rates) {
1340 uint8_t temp_ni_rates[8] = { 0x0, 0x1, 0x2, 0x3,
1341 0x4, 0x5, 0x6, 0x7};
1342 /*
1343 * Workaround for EV 116382: The peer is marked HT but with
1344 * supported rx mcs set is set to 0. 11n spec mandates MCS0-7
1345 * for a HT STA. So forcing the supported rx mcs rate to
1346 * MCS 0-7. This workaround will be removed once we get
1347 * clarification from WFA regarding this STA behavior.
1348 */
1349
1350 /* TODO: Do we really need this? */
1351 WMA_LOGW("Peer is marked as HT capable but supported mcs rate is 0");
1352 peer_ht_rates.num_rates = sizeof(temp_ni_rates);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301353 qdf_mem_copy((uint8_t *) peer_ht_rates.rates, temp_ni_rates,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354 peer_ht_rates.num_rates);
1355 }
1356
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357 /* in ap/ibss mode and for tdls peer, use mac address of the peer in
1358 * the other end as the new peer address; in sta mode, use bss id to
1359 * be the new peer address
1360 */
1361 if ((wma_is_vdev_in_ap_mode(wma, params->smesessionId))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362 || (wma_is_vdev_in_ibss_mode(wma, params->smesessionId))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001363#ifdef FEATURE_WLAN_TDLS
1364 || (STA_ENTRY_TDLS_PEER == params->staType)
1365#endif /* FEATURE_WLAN_TDLS */
1366 )
gaurank kathpaliac3803832019-01-28 19:47:44 +05301367 qdf_mem_copy(cmd->peer_mac, params->staMac,
1368 sizeof(cmd->peer_mac));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001369 else
gaurank kathpaliac3803832019-01-28 19:47:44 +05301370 qdf_mem_copy(cmd->peer_mac, params->bssId,
1371 sizeof(cmd->peer_mac));
1372
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001373 cmd->vdev_id = params->smesessionId;
1374 cmd->peer_new_assoc = 1;
1375 cmd->peer_associd = params->assocId;
1376
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301377 cmd->is_wme_set = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001378
1379 if (params->wmmEnabled)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301380 cmd->qos_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001381
1382 if (params->uAPSD) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301383 cmd->apsd_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001384 WMA_LOGD("Set WMI_PEER_APSD: uapsd Mask %d", params->uAPSD);
1385 }
1386
1387 if (params->htCapable) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301388 cmd->ht_flag = 1;
1389 cmd->qos_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390 cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391
Krishna Kumaar Natarajan59f546c2016-02-16 10:31:55 -08001392 if (params->ch_width) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301393 cmd->bw_40 = 1;
Krishna Kumaar Natarajan59f546c2016-02-16 10:31:55 -08001394 cmd->peer_rate_caps |= WMI_RC_CW40_FLAG;
1395 if (params->fShortGI40Mhz)
1396 cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
1397 } else if (params->fShortGI20Mhz) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398 cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
Krishna Kumaar Natarajan59f546c2016-02-16 10:31:55 -08001399 }
1400 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001401
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001402 if (params->vhtCapable) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301403 cmd->ht_flag = 1;
1404 cmd->qos_flag = 1;
1405 cmd->vht_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001406 cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
1407 }
1408
1409 if (params->ch_width == CH_WIDTH_80MHZ)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301410 cmd->bw_80 = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 else if (params->ch_width == CH_WIDTH_160MHZ)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301412 cmd->bw_160 = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413 else if (params->ch_width == CH_WIDTH_80P80MHZ)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301414 cmd->bw_160 = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415
1416 cmd->peer_vht_caps = params->vht_caps;
Jayachandran Sreekumaran2613f322019-03-01 19:05:59 +05301417 if (params->p2pCapableSta) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301418 cmd->p2p_capable_sta = 1;
Jayachandran Sreekumaran2613f322019-03-01 19:05:59 +05301419 wma_objmgr_set_peer_mlme_type(wma, params->staMac,
1420 WLAN_PEER_P2P_CLI);
1421 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422
1423 if (params->rmfEnabled)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301424 cmd->is_pmf_enabled = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425
Arif Hussain53cf5692018-04-05 16:35:54 -07001426 if (params->stbc_capable)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301427 cmd->stbc_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428
1429 if (params->htLdpcCapable || params->vhtLdpcCapable)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301430 cmd->ldpc_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431
1432 switch (params->mimoPS) {
1433 case eSIR_HT_MIMO_PS_STATIC:
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301434 cmd->static_mimops_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001435 break;
1436 case eSIR_HT_MIMO_PS_DYNAMIC:
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301437 cmd->dynamic_mimops_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001438 break;
1439 case eSIR_HT_MIMO_PS_NO_LIMIT:
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301440 cmd->spatial_mux_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441 break;
1442 default:
1443 break;
1444 }
1445
Varun Reddy Yeturu4f849e52018-06-15 18:08:37 -07001446 wma_set_twt_peer_caps(params, cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447#ifdef FEATURE_WLAN_TDLS
1448 if (STA_ENTRY_TDLS_PEER == params->staType)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301449 cmd->auth_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001450#endif /* FEATURE_WLAN_TDLS */
1451
1452 if (params->wpa_rsn
1453#ifdef FEATURE_WLAN_WAPI
1454 || params->encryptType == eSIR_ED_WPI
1455#endif /* FEATURE_WLAN_WAPI */
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001456 ) {
bings11172832019-05-23 16:41:25 +08001457 if (!params->no_ptk_4_way) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301458 cmd->need_ptk_4_way = 1;
bings11172832019-05-23 16:41:25 +08001459 WMA_LOGD("no ptk 4 way %d", params->no_ptk_4_way);
1460 }
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001461 WMA_LOGD("Acquire set key wake lock for %d ms",
Dustin Brownd0a76562017-10-13 14:48:37 -07001462 WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001463 wma_acquire_wakelock(&intr->vdev_set_key_wakelock,
Dustin Brownd0a76562017-10-13 14:48:37 -07001464 WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001465 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001466 if (params->wpa_rsn >> 1)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301467 cmd->need_gtk_2_way = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001468
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05301469 wma_unified_peer_state_update(pdev, params->staMac,
1470 params->bssId, params->staType);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471
1472#ifdef FEATURE_WLAN_WAPI
1473 if (params->encryptType == eSIR_ED_WPI) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001474 ret = wma_vdev_set_param(wma->wmi_handle, params->smesessionId,
1475 WMI_VDEV_PARAM_DROP_UNENCRY, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 if (ret) {
1477 WMA_LOGE
1478 ("Set WMI_VDEV_PARAM_DROP_UNENCRY Param status:%d\n",
1479 ret);
Govind Singhb30d4c02016-03-24 11:01:23 +05301480 qdf_mem_free(cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001481 return ret;
1482 }
1483 }
1484#endif /* FEATURE_WLAN_WAPI */
1485
1486 cmd->peer_caps = params->capab_info;
1487 cmd->peer_listen_intval = params->listenInterval;
1488 cmd->peer_ht_caps = params->ht_caps;
1489 cmd->peer_max_mpdu = (1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
1490 params->maxAmpduSize)) - 1;
1491 cmd->peer_mpdu_density = wma_parse_mpdudensity(params->maxAmpduDensity);
1492
1493 if (params->supportedRates.supportedMCSSet[1] &&
1494 params->supportedRates.supportedMCSSet[2])
1495 cmd->peer_rate_caps |= WMI_RC_TS_FLAG;
1496 else if (params->supportedRates.supportedMCSSet[1])
1497 cmd->peer_rate_caps |= WMI_RC_DS_FLAG;
1498
1499 /* Update peer legacy rate information */
Govind Singhb30d4c02016-03-24 11:01:23 +05301500 cmd->peer_legacy_rates.num_rates = peer_legacy_rates.num_rates;
1501 qdf_mem_copy(cmd->peer_legacy_rates.rates, peer_legacy_rates.rates,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001502 peer_legacy_rates.num_rates);
1503
1504 /* Update peer HT rate information */
Govind Singhb30d4c02016-03-24 11:01:23 +05301505 cmd->peer_ht_rates.num_rates = peer_ht_rates.num_rates;
1506 qdf_mem_copy(cmd->peer_ht_rates.rates, peer_ht_rates.rates,
1507 peer_ht_rates.num_rates);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001508
1509 /* VHT Rates */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510
1511 cmd->peer_nss = peer_nss;
Naveen Rawatb14cab32015-11-02 17:01:51 -08001512 /*
1513 * Because of DBS a vdev may come up in any of the two MACs with
1514 * different capabilities. STBC capab should be fetched for given
1515 * hard_mode->MAC_id combo. It is planned that firmware should provide
1516 * these dev capabilities. But for now number of tx streams can be used
1517 * to identify if Tx STBC needs to be disabled.
1518 */
1519 if (intr->tx_streams < 2) {
1520 cmd->peer_vht_caps &= ~(1 << SIR_MAC_VHT_CAP_TXSTBC);
1521 WMA_LOGD("Num tx_streams: %d, Disabled txSTBC",
1522 intr->tx_streams);
1523 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524 WMA_LOGD("peer_nss %d peer_ht_rates.num_rates %d ", cmd->peer_nss,
1525 peer_ht_rates.num_rates);
1526
Govind Singhb30d4c02016-03-24 11:01:23 +05301527 cmd->vht_capable = params->vhtCapable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 if (params->vhtCapable) {
1529#define VHT2x2MCSMASK 0xc
Govind Singhb30d4c02016-03-24 11:01:23 +05301530 cmd->rx_max_rate = params->supportedRates.vhtRxHighestDataRate;
1531 cmd->rx_mcs_set = params->supportedRates.vhtRxMCSMap;
1532 cmd->tx_max_rate = params->supportedRates.vhtTxHighestDataRate;
1533 cmd->tx_mcs_set = params->supportedRates.vhtTxMCSMap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534
1535 if (params->vhtSupportedRxNss) {
1536 cmd->peer_nss = params->vhtSupportedRxNss;
1537 } else {
Govind Singhb30d4c02016-03-24 11:01:23 +05301538 cmd->peer_nss = ((cmd->rx_mcs_set & VHT2x2MCSMASK)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539 == VHT2x2MCSMASK) ? 1 : 2;
1540 }
1541 }
1542
Krishna Kumaar Natarajand1cd56e2016-09-30 08:43:03 -07001543 WMA_LOGD(FL("rx_max_rate: %d, rx_mcs: %x, tx_max_rate: %d, tx_mcs: %x"),
1544 cmd->rx_max_rate, cmd->rx_mcs_set, cmd->tx_max_rate,
1545 cmd->tx_mcs_set);
1546
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 /*
1548 * Limit nss to max number of rf chain supported by target
1549 * Otherwise Fw will crash
1550 */
Abhishek Singh9100cc82017-04-17 11:03:55 +05301551 if (cmd->peer_nss > WMA_MAX_NSS)
1552 cmd->peer_nss = WMA_MAX_NSS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001553
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001554 wma_populate_peer_he_cap(cmd, params);
1555
Pragaspathi Thilagarajb3472f02019-06-04 14:10:44 +05301556 if (!wma_is_vdev_in_ap_mode(wma, params->smesessionId))
1557 intr->nss = cmd->peer_nss;
1558
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 cmd->peer_phymode = phymode;
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301560 WMA_LOGD("%s: vdev_id %d associd %d rate_caps %x peer_caps %x",
1561 __func__, cmd->vdev_id, cmd->peer_associd,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001562 cmd->peer_rate_caps, cmd->peer_caps);
1563 WMA_LOGD("%s:listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d",
1564 __func__, cmd->peer_listen_intval, cmd->peer_ht_caps,
1565 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode);
1566 WMA_LOGD("%s: peer_mpdu_density %d encr_type %d cmd->peer_vht_caps %x",
1567 __func__, cmd->peer_mpdu_density, params->encryptType,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001568 cmd->peer_vht_caps);
1569
Govind Singhb30d4c02016-03-24 11:01:23 +05301570 status = wmi_unified_peer_assoc_send(wma->wmi_handle,
1571 cmd);
1572 if (QDF_IS_STATUS_ERROR(status))
Arif Hussain49a5ffc2016-07-19 10:11:58 -07001573 WMA_LOGP(FL("Failed to send peer assoc command status = %d"),
1574 status);
Govind Singhb30d4c02016-03-24 11:01:23 +05301575 qdf_mem_free(cmd);
1576
1577 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001578}
1579
1580/**
1581 * wmi_unified_vdev_set_gtx_cfg_send() - set GTX params
1582 * @wmi_handle: wmi handle
1583 * @if_id: vdev id
1584 * @gtx_info: GTX config params
1585 *
1586 * This function set GTX related params in firmware.
1587 *
1588 * Return: 0 for success or error code
1589 */
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301590QDF_STATUS wmi_unified_vdev_set_gtx_cfg_send(wmi_unified_t wmi_handle,
1591 uint32_t if_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 gtx_config_t *gtx_info)
1593{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301594 struct wmi_gtx_config params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301596 params.gtx_rt_mask[0] = gtx_info->gtxRTMask[0];
1597 params.gtx_rt_mask[1] = gtx_info->gtxRTMask[1];
1598 params.gtx_usrcfg = gtx_info->gtxUsrcfg;
1599 params.gtx_threshold = gtx_info->gtxPERThreshold;
1600 params.gtx_margin = gtx_info->gtxPERMargin;
1601 params.gtx_tpcstep = gtx_info->gtxTPCstep;
1602 params.gtx_tpcmin = gtx_info->gtxTPCMin;
1603 params.gtx_bwmask = gtx_info->gtxBWMask;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301605 return wmi_unified_vdev_set_gtx_cfg_cmd(wmi_handle,
1606 if_id, &params);
1607
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001608}
1609
1610/**
1611 * wma_update_protection_mode() - update protection mode
1612 * @wma: wma handle
1613 * @vdev_id: vdev id
1614 * @llbcoexist: protection mode info
1615 *
1616 * This function set protection mode(RTS/CTS) to fw for passed vdev id.
1617 *
1618 * Return: none
1619 */
1620void wma_update_protection_mode(tp_wma_handle wma, uint8_t vdev_id,
1621 uint8_t llbcoexist)
1622{
Govind Singhd76a5b02016-03-08 15:12:14 +05301623 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624 enum ieee80211_protmode prot_mode;
1625
1626 prot_mode = llbcoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE;
1627
Govind Singhd76a5b02016-03-08 15:12:14 +05301628 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 WMI_VDEV_PARAM_PROTECTION_MODE,
1630 prot_mode);
1631
Govind Singhd76a5b02016-03-08 15:12:14 +05301632 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633 WMA_LOGE("Failed to send wmi protection mode cmd");
1634 else
1635 WMA_LOGD("Updated protection mode %d to target", prot_mode);
1636}
1637
lifeng7c607dd2017-02-21 21:16:49 +08001638void
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001639wma_update_beacon_interval(tp_wma_handle wma, uint8_t vdev_id,
1640 uint16_t beaconInterval)
1641{
Govind Singhd76a5b02016-03-08 15:12:14 +05301642 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643
Govind Singhd76a5b02016-03-08 15:12:14 +05301644 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 WMI_VDEV_PARAM_BEACON_INTERVAL,
1646 beaconInterval);
1647
Govind Singhd76a5b02016-03-08 15:12:14 +05301648 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649 WMA_LOGE("Failed to update beacon interval");
1650 else
1651 WMA_LOGI("Updated beacon interval %d for vdev %d",
1652 beaconInterval, vdev_id);
1653}
1654
Peng Xu6363ec62017-05-15 11:06:33 -07001655#ifdef WLAN_FEATURE_11AX_BSS_COLOR
1656/**
1657 * wma_update_bss_color() - update beacon bss color in fw
1658 * @wma: wma handle
1659 * @vdev_id: vdev id
1660 * @he_ops: HE operation, only the bss_color and bss_color_disabled fields
1661 * are updated.
1662 *
1663 * Return: none
1664 */
1665static void
1666wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001667 tUpdateBeaconParams *bcn_params)
Peng Xu6363ec62017-05-15 11:06:33 -07001668{
1669 QDF_STATUS ret;
Naveen Rawatdf221b72017-11-15 11:32:31 -08001670 uint32_t dword_he_ops = 0;
Peng Xu6363ec62017-05-15 11:06:33 -07001671
Naveen Rawatdf221b72017-11-15 11:32:31 -08001672 WMI_HEOPS_COLOR_SET(dword_he_ops, bcn_params->bss_color);
1673 WMI_HEOPS_BSSCOLORDISABLE_SET(dword_he_ops,
1674 bcn_params->bss_color_disabled);
1675 WMA_LOGD("vdev: %d, update bss color, HE_OPS: 0x%x",
1676 vdev_id, dword_he_ops);
Peng Xu6363ec62017-05-15 11:06:33 -07001677 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001678 WMI_VDEV_PARAM_BSS_COLOR, dword_he_ops);
Peng Xu6363ec62017-05-15 11:06:33 -07001679 if (QDF_IS_STATUS_ERROR(ret))
1680 WMA_LOGE("Failed to update HE operations");
Peng Xu6363ec62017-05-15 11:06:33 -07001681}
1682#else
1683static void wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001684 tUpdateBeaconParams *bcn_params)
Peng Xu6363ec62017-05-15 11:06:33 -07001685{
1686}
1687#endif
1688
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689/**
1690 * wma_process_update_beacon_params() - update beacon parameters to target
1691 * @wma: wma handle
1692 * @bcn_params: beacon parameters
1693 *
1694 * Return: none
1695 */
1696void
1697wma_process_update_beacon_params(tp_wma_handle wma,
1698 tUpdateBeaconParams *bcn_params)
1699{
1700 if (!bcn_params) {
1701 WMA_LOGE("bcn_params NULL");
1702 return;
1703 }
1704
1705 if (bcn_params->smeSessionId >= wma->max_bssid) {
1706 WMA_LOGE("Invalid vdev id %d", bcn_params->smeSessionId);
1707 return;
1708 }
1709
1710 if (bcn_params->paramChangeBitmap & PARAM_BCN_INTERVAL_CHANGED) {
1711 wma_update_beacon_interval(wma, bcn_params->smeSessionId,
1712 bcn_params->beaconInterval);
1713 }
1714
1715 if (bcn_params->paramChangeBitmap & PARAM_llBCOEXIST_CHANGED)
1716 wma_update_protection_mode(wma, bcn_params->smeSessionId,
1717 bcn_params->llbCoexist);
Peng Xu6363ec62017-05-15 11:06:33 -07001718
1719 if (bcn_params->paramChangeBitmap & PARAM_BSS_COLOR_CHANGED)
1720 wma_update_bss_color(wma, bcn_params->smeSessionId,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001721 bcn_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001722}
1723
1724/**
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001725 * wma_update_rts_params() - update cfg parameters to target
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001726 * @wma: wma handle
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001727 * @value: rts_threshold
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 *
1729 * Return: none
1730 */
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001731void wma_update_rts_params(tp_wma_handle wma, uint32_t value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732{
1733 uint8_t vdev_id;
Govind Singhd76a5b02016-03-08 15:12:14 +05301734 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001735
1736 for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
1737 if (wma->interfaces[vdev_id].handle != 0) {
Govind Singhd76a5b02016-03-08 15:12:14 +05301738 ret = wma_vdev_set_param(wma->wmi_handle,
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001739 vdev_id,
1740 WMI_VDEV_PARAM_RTS_THRESHOLD,
1741 value);
1742 if (QDF_IS_STATUS_ERROR(ret))
1743 WMA_LOGE("Update cfg param fail for vdevId %d",
1744 vdev_id);
1745 }
1746 }
1747}
1748
1749/**
1750 * wma_update_frag_params() - update cfg parameters to target
1751 * @wma: wma handle
1752 * @value: frag_threshold
1753 *
1754 * Return: none
1755 */
1756void wma_update_frag_params(tp_wma_handle wma, uint32_t value)
1757{
1758 uint8_t vdev_id;
1759 QDF_STATUS ret;
1760
1761 for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
1762 if (wma->interfaces[vdev_id].handle != 0) {
1763 ret = wma_vdev_set_param(wma->wmi_handle,
1764 vdev_id,
1765 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
1766 value);
Govind Singhd76a5b02016-03-08 15:12:14 +05301767 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001768 WMA_LOGE("Update cfg params failed for vdevId %d",
1769 vdev_id);
1770 }
1771 }
1772}
1773
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001774#ifndef CRYPTO_SET_KEY_CONVERGED
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775/**
1776 * wma_read_cfg_wepkey() - fill key_info for WEP key
1777 * @wma_handle: wma handle
1778 * @key_info: key_info ptr
1779 * @def_key_idx: default key index
1780 * @num_keys: number of keys
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001781 * @vdev: vdev pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001782 *
1783 * This function reads WEP keys from cfg and fills
1784 * up key_info.
1785 *
1786 * Return: none
1787 */
1788static void wma_read_cfg_wepkey(tp_wma_handle wma_handle,
1789 tSirKeys *key_info, uint32_t *def_key_idx,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001790 uint8_t *num_keys,
1791 struct wlan_objmgr_vdev *vdev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001792{
Jeff Johnsone88dd752018-06-07 22:57:54 -07001793 QDF_STATUS status;
Pragaspathi Thilagaraj129d6972018-11-21 10:43:41 +05301794 qdf_size_t val = SIR_MAC_KEY_LENGTH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001795 uint8_t i, j;
Jeff Johnson9f18aa72018-12-02 12:05:12 -08001796 struct mac_context *mac_ctx = wma_handle->mac_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001797
1798 WMA_LOGD("Reading WEP keys from cfg");
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301799
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001800 /* NOTE:def_key_idx is initialized to 0 by the caller */
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301801 *def_key_idx = mac_ctx->mlme_cfg->wep_params.wep_default_key_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802
1803 for (i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001804 status = mlme_get_wep_key(vdev, &mac_ctx->mlme_cfg->wep_params,
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301805 (MLME_WEP_DEFAULT_KEY_1 +
Pragaspathi Thilagaraj129d6972018-11-21 10:43:41 +05301806 i), key_info[j].key, &val);
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301807 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 WMA_LOGE("WEP key is not configured at :%d", i);
1809 } else {
1810 key_info[j].keyId = i;
1811 key_info[j].keyLength = (uint16_t) val;
1812 j++;
1813 }
1814 }
1815 *num_keys = j;
1816}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001817#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818
Jinwei Chenc163f9e2018-10-29 16:37:00 +08001819#ifdef FEATURE_WLAN_WAPI
1820#define WPI_IV_LEN 16
1821#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
1822/**
1823 * wma_fill_in_wapi_key_params() - update key parameters about wapi
1824 * @key_params: wma key parameters
1825 * @params: parameters pointer to be set
1826 * @mode: operation mode
1827 *
1828 * Return: None
1829 */
1830static inline void wma_fill_in_wapi_key_params(
1831 struct wma_set_key_params *key_params,
1832 struct set_key_params *params, uint8_t mode)
1833{
1834 /*
1835 * Since MCL shares same FW with WIN for Napier/Hasting, FW WAPI logic
1836 * is fit for WIN, change it to align with WIN.
1837 */
1838 unsigned char iv_init_ap[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1839 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1840 0x5c, 0x36, 0x5c, 0x37};
1841 unsigned char iv_init_sta[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1842 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1843 0x5c, 0x36, 0x5c, 0x36};
1844
1845 if (mode == wlan_op_mode_ap) {
1846 qdf_mem_copy(params->rx_iv, iv_init_sta,
1847 WPI_IV_LEN);
1848 qdf_mem_copy(params->tx_iv, iv_init_ap,
1849 WPI_IV_LEN);
1850 } else {
1851 qdf_mem_copy(params->rx_iv, iv_init_ap,
1852 WPI_IV_LEN);
1853 qdf_mem_copy(params->tx_iv, iv_init_sta,
1854 WPI_IV_LEN);
1855 }
1856
1857 params->key_txmic_len = WMA_TXMIC_LEN;
1858 params->key_rxmic_len = WMA_RXMIC_LEN;
1859
1860 params->key_cipher = WMI_CIPHER_WAPI;
1861}
1862#else
1863static inline void wma_fill_in_wapi_key_params(
1864 struct wma_set_key_params *key_params,
1865 struct set_key_params *params, uint8_t mode)
1866{
1867 /*initialize receive and transmit IV with default values */
1868 /* **Note: tx_iv must be sent in reverse** */
1869 unsigned char tx_iv[16] = { 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
1870 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
1871 0x36, 0x5c, 0x36, 0x5c};
1872 unsigned char rx_iv[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1873 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1874 0x5c, 0x36, 0x5c, 0x37};
1875 if (mode == wlan_op_mode_ap) {
1876 /* Authenticator initializes the value of PN as
1877 * 0x5C365C365C365C365C365C365C365C36 for MCastkeyUpdate
1878 */
1879 if (key_params->unicast)
1880 tx_iv[0] = 0x37;
1881
1882 rx_iv[WPI_IV_LEN - 1] = 0x36;
1883 } else {
1884 if (!key_params->unicast)
1885 rx_iv[WPI_IV_LEN - 1] = 0x36;
1886 }
1887
1888 params->key_txmic_len = WMA_TXMIC_LEN;
1889 params->key_rxmic_len = WMA_RXMIC_LEN;
1890
1891 qdf_mem_copy(params->rx_iv, &rx_iv,
1892 WPI_IV_LEN);
1893 qdf_mem_copy(params->tx_iv, &tx_iv,
1894 WPI_IV_LEN);
1895 params->key_cipher = WMI_CIPHER_WAPI;
1896}
1897#endif
1898#endif
1899
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001900#ifndef CRYPTO_SET_KEY_CONVERGED
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001901/**
Liangwei Dongf9c09602018-12-20 05:11:26 -05001902 * wma_skip_bip_key_set() - skip the BIP key step or not
1903 * @wma_handle: wma handle
1904 * @iface: txrx node
1905 * @key_cipher: key cipher
1906 *
1907 * if target not support the BIP key cipher, skip the set key command.
1908 *
1909 * Return: true to skip set key to target, otherwise set key to target
1910 */
1911static bool
1912wma_skip_bip_key_set(tp_wma_handle wma_handle, uint32_t key_cipher)
1913{
1914 if ((key_cipher == WMI_CIPHER_AES_GMAC) &&
1915 !wmi_service_enabled(wma_handle->wmi_handle,
1916 wmi_service_gmac_offload_support))
1917 return true;
1918 return false;
1919}
1920
Abhishek Singh7c1c7432019-04-04 12:11:57 +05301921static void wma_set_peer_unicast_cipher(tp_wma_handle wma,
1922 struct set_key_params *params)
1923{
1924 struct wlan_objmgr_peer *peer;
1925
1926 peer = wlan_objmgr_get_peer(wma->psoc,
1927 wlan_objmgr_pdev_get_pdev_id(wma->pdev),
1928 params->peer_mac, WLAN_LEGACY_WMA_ID);
1929 if (!peer) {
1930 WMA_LOGE("Peer of peer_mac %pM not found", params->peer_mac);
1931 return;
1932 }
1933
1934 wlan_peer_set_unicast_cipher(peer, params->key_cipher);
1935 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1936}
1937
Liangwei Dongf9c09602018-12-20 05:11:26 -05001938/**
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301939 * wma_setup_install_key_cmd() - set key parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001940 * @wma_handle: wma handle
1941 * @key_params: key parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001942 * @mode: op mode
1943 *
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301944 * This function fills structure from information
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001945 * passed in key_params.
1946 *
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301947 * Return: QDF_STATUS_SUCCESS - success
1948 QDF_STATUS_E_FAILURE - failure
1949 QDF_STATUS_E_NOMEM - invalid request
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001950 */
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301951static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001952 struct wma_set_key_params
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301953 *key_params, uint8_t mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001954{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301955 struct set_key_params params;
1956 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001957 struct wma_txrx_node *iface = NULL;
psimha1dc65bd2018-04-02 12:33:30 -07001958 enum cdp_sec_type sec_type = cdp_sec_type_none;
psimhac2cb9462018-01-31 10:35:25 -08001959 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1960 struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
1961 struct cdp_vdev *txrx_vdev;
1962 uint32_t pn[4] = {0, 0, 0, 0};
1963 uint8_t peer_id;
1964 struct cdp_peer *peer;
Liangwei Dongf9c09602018-12-20 05:11:26 -05001965 bool skip_set_key;
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +05301966
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967 if ((key_params->key_type == eSIR_ED_NONE &&
1968 key_params->key_len) || (key_params->key_type != eSIR_ED_NONE &&
1969 !key_params->key_len)) {
1970 WMA_LOGE("%s:Invalid set key request", __func__);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301971 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001972 }
1973
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07001974 if (!wma_handle) {
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001975 WMA_LOGE(FL("Invalid wma_handle for vdev_id: %d"),
1976 key_params->vdev_id);
1977 return QDF_STATUS_E_INVAL;
1978 }
Pragaspathi Thilagaraj0d1159e2018-08-08 19:00:36 +05301979
1980 if (!wma_is_vdev_valid(key_params->vdev_id)) {
1981 WMA_LOGE("%s: vdev id:%d is not active ", __func__,
1982 key_params->vdev_id);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001983 return QDF_STATUS_E_INVAL;
1984 }
psimhac2cb9462018-01-31 10:35:25 -08001985
1986 txrx_vdev = wma_find_vdev_by_id(wma_handle,
1987 key_params->vdev_id);
1988 peer = cdp_peer_find_by_addr(soc, txrx_pdev,
1989 key_params->peer_mac, &peer_id);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001990 iface = &wma_handle->interfaces[key_params->vdev_id];
1991
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301992 params.vdev_id = key_params->vdev_id;
1993 params.key_idx = key_params->key_idx;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -08001994 qdf_mem_copy(params.peer_mac, key_params->peer_mac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001995
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301996#ifdef FEATURE_WLAN_WAPI
hangtian127c9532019-01-12 13:29:07 +08001997 qdf_mem_zero(params.tx_iv, 16);
1998 qdf_mem_zero(params.rx_iv, 16);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301999#endif
2000 params.key_txmic_len = 0;
2001 params.key_rxmic_len = 0;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002002 qdf_mem_copy(&params.key_rsc_ctr,
Krunal Soni8afae9b2017-10-20 20:15:54 -07002003 &key_params->key_rsc[0], sizeof(uint64_t));
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302004 params.key_flags = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002005 if (key_params->unicast)
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302006 params.key_flags |= PAIRWISE_USAGE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002007 else
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302008 params.key_flags |= GROUP_USAGE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002009
2010 switch (key_params->key_type) {
2011 case eSIR_ED_NONE:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302012 params.key_cipher = WMI_CIPHER_NONE;
psimha1dc65bd2018-04-02 12:33:30 -07002013 sec_type = cdp_sec_type_none;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014 break;
2015 case eSIR_ED_WEP40:
2016 case eSIR_ED_WEP104:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302017 params.key_cipher = WMI_CIPHER_WEP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 if (key_params->unicast &&
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302019 params.key_idx == key_params->def_key_idx) {
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302020 WMA_LOGD("STA Mode: cmd->key_flags |= TX_USAGE");
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302021 params.key_flags |= TX_USAGE;
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302022 } else if ((mode == wlan_op_mode_ap) &&
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302023 (params.key_idx == key_params->def_key_idx)) {
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302024 WMA_LOGD("AP Mode: cmd->key_flags |= TX_USAGE");
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302025 params.key_flags |= TX_USAGE;
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302026 }
psimha1dc65bd2018-04-02 12:33:30 -07002027 sec_type = cdp_sec_type_wep104;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002028 break;
2029 case eSIR_ED_TKIP:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302030 params.key_txmic_len = WMA_TXMIC_LEN;
2031 params.key_rxmic_len = WMA_RXMIC_LEN;
2032 params.key_cipher = WMI_CIPHER_TKIP;
psimha1dc65bd2018-04-02 12:33:30 -07002033 sec_type = cdp_sec_type_tkip;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002034 break;
2035#ifdef FEATURE_WLAN_WAPI
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002036 case eSIR_ED_WPI:
2037 {
Jinwei Chenc163f9e2018-10-29 16:37:00 +08002038 wma_fill_in_wapi_key_params(key_params, &params, mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002039 break;
2040 }
2041#endif /* FEATURE_WLAN_WAPI */
2042 case eSIR_ED_CCMP:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302043 params.key_cipher = WMI_CIPHER_AES_CCM;
psimha1dc65bd2018-04-02 12:33:30 -07002044 sec_type = cdp_sec_type_aes_ccmp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002045 break;
2046#ifdef WLAN_FEATURE_11W
2047 case eSIR_ED_AES_128_CMAC:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302048 params.key_cipher = WMI_CIPHER_AES_CMAC;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002049 break;
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +05302050 case eSIR_ED_AES_GMAC_128:
2051 case eSIR_ED_AES_GMAC_256:
2052 params.key_cipher = WMI_CIPHER_AES_GMAC;
2053 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002054#endif /* WLAN_FEATURE_11W */
Mukul Sharma05504ac2017-06-08 12:35:53 +05302055 /* Firmware uses length to detect GCMP 128/256*/
2056 case eSIR_ED_GCMP:
2057 case eSIR_ED_GCMP_256:
2058 params.key_cipher = WMI_CIPHER_AES_GCM;
2059 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002060 default:
2061 /* TODO: MFP ? */
2062 WMA_LOGE("%s:Invalid encryption type:%d", __func__,
2063 key_params->key_type);
Krunal Soni8afae9b2017-10-20 20:15:54 -07002064 status = QDF_STATUS_E_NOMEM;
2065 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 }
2067
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002068#ifdef BIG_ENDIAN_HOST
2069 {
2070 /* for big endian host, copy engine byte_swap is enabled
2071 * But the key data content is in network byte order
2072 * Need to byte swap the key data content - so when copy engine
2073 * does byte_swap - target gets key_data content in the correct
2074 * order.
2075 */
2076 int8_t i;
2077 uint32_t *destp, *srcp;
2078
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302079 destp = (uint32_t *) params.key_data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080 srcp = (uint32_t *) key_params->key_data;
2081 for (i = 0;
2082 i < roundup(key_params->key_len, sizeof(uint32_t)) / 4;
2083 i++) {
2084 *destp = le32_to_cpu(*srcp);
2085 destp++;
2086 srcp++;
2087 }
2088 }
2089#else
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302090 qdf_mem_copy((void *)params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002091 (const void *)key_params->key_data, key_params->key_len);
2092#endif /* BIG_ENDIAN_HOST */
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302093 params.key_len = key_params->key_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094
2095#ifdef WLAN_FEATURE_11W
Himanshu Agarwalfc5d6602018-04-06 17:39:37 +05302096 iface = &wma_handle->interfaces[key_params->vdev_id];
2097
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +05302098 if ((key_params->key_type == eSIR_ED_AES_128_CMAC) ||
2099 (key_params->key_type == eSIR_ED_AES_GMAC_128) ||
2100 (key_params->key_type == eSIR_ED_AES_GMAC_256)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002101 if (iface) {
2102 iface->key.key_length = key_params->key_len;
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05302103 iface->key.key_cipher = params.key_cipher;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302104 qdf_mem_copy(iface->key.key,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002105 (const void *)key_params->key_data,
2106 iface->key.key_length);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302107 if ((params.key_idx == WMA_IGTK_KEY_INDEX_4) ||
2108 (params.key_idx == WMA_IGTK_KEY_INDEX_5))
2109 qdf_mem_zero(iface->key.key_id[params.key_idx -
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002110 WMA_IGTK_KEY_INDEX_4].ipn,
2111 CMAC_IPN_LEN);
2112 }
2113 }
2114#endif /* WLAN_FEATURE_11W */
2115
Abhishek Singh7c1c7432019-04-04 12:11:57 +05302116 if (key_params->unicast)
2117 wma_set_peer_unicast_cipher(wma_handle, &params);
2118
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002119 WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d",
2120 key_params->vdev_id, key_params->key_idx,
2121 key_params->key_type, key_params->key_len);
2122 WMA_LOGD("unicast %d peer_mac %pM def_key_idx %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002123 key_params->unicast, key_params->peer_mac,
2124 key_params->def_key_idx);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002125 WMA_LOGD("keyrsc param %llu", params.key_rsc_ctr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002126
Krunal Sonibcd09fc2018-10-11 18:17:19 -07002127 /*
2128 * To prevent from any replay-attack, PN number provided by
2129 * upper layer is used.
2130 *
2131 * Plumb the PN number to HW which will be used to evaluate whether
2132 * incoming traffic is not replayed.
2133 *
2134 * supplicant would have some thing like following, example:
2135 *
2136 * num = 0x123456789ABCDEFF (64 bit number)
2137 * uint8_t keyrsc[16] would look like following
2138 *
2139 * bit 0 7 15 23 31 39 47 55 63
2140 * +------+-------+-------+-------+-------+-------+-------+-------+
2141 * byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
2142 * +------+-------+-------+-------+-------+-------+-------+-------+
2143 * value| 0xFF | 0XDE | 0xBC | 0x9A | 0x78 | 0x56 | 0x34 | 0x12 |
2144 * +------+-------+-------+-------+-------+-------+-------+-------+
2145 */
2146 qdf_mem_copy(&pn[0],
2147 &key_params->key_rsc[0], sizeof(pn));
2148 wma_debug("key_type[%s] pn[%x:%x:%x:%x]",
2149 (key_params->unicast) ? "unicast" : "group",
2150 key_params->key_rsc[3], key_params->key_rsc[2],
2151 key_params->key_rsc[1], key_params->key_rsc[0]);
psimhac2cb9462018-01-31 10:35:25 -08002152 cdp_set_pn_check(soc, txrx_vdev, peer, sec_type, pn);
psimha8696f772018-04-03 17:38:38 -07002153 cdp_set_key(soc, peer, key_params->unicast,
2154 (uint32_t *)(key_params->key_data +
2155 WMA_IV_KEY_LEN +
2156 WMA_TXMIC_LEN));
psimhac2cb9462018-01-31 10:35:25 -08002157
Liangwei Dongf9c09602018-12-20 05:11:26 -05002158 skip_set_key = wma_skip_bip_key_set(wma_handle, params.key_cipher);
2159 if (!skip_set_key)
2160 status = wmi_unified_setup_install_key_cmd(
2161 wma_handle->wmi_handle, &params);
2162
Rajeev Kumar155a3e42017-10-10 15:31:17 -07002163 if (!key_params->unicast) {
2164 /* Its GTK release the wake lock */
2165 WMA_LOGD("Release set key wake lock");
2166 wma_release_wakelock(&iface->vdev_set_key_wakelock);
2167 }
Naveen Rawatd7734142017-10-27 10:02:40 -07002168
2169 /* install key was requested */
gaurank kathpaliabcbde362017-12-11 21:11:53 +05302170 if (iface)
2171 iface->is_waiting_for_key = false;
Naveen Rawatd7734142017-10-27 10:02:40 -07002172
Krunal Soni8afae9b2017-10-20 20:15:54 -07002173end:
gaurank kathpalia6d25c972019-03-07 20:25:28 +05302174 qdf_mem_zero(&params, sizeof(struct set_key_params));
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302175 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002176}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002177#endif
2178
2179#ifdef QCA_IBSS_SUPPORT
2180/**
2181 * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer
2182 * @peer_num: number of peers
2183 *
2184 * Return: heart beat timer value
2185 */
2186static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num)
2187{
2188 /* heart beat timer value look-up table */
2189 /* entry index : (the number of currently connected peers) - 1
2190 * entry value : the heart time threshold value in seconds for
2191 * detecting ibss peer departure
2192 */
2193 static const uint16_t heart_beat_timer[MAX_PEERS] = {
2194 4, 4, 4, 4, 4, 4, 4, 4,
2195 8, 8, 8, 8, 8, 8, 8, 8,
2196 12, 12, 12, 12, 12, 12, 12, 12,
2197 16, 16, 16, 16, 16, 16, 16, 16
2198 };
2199
2200 if (peer_num < 1 || peer_num > MAX_PEERS)
2201 return 0;
2202
2203 return heart_beat_timer[peer_num - 1];
2204}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002205
2206/**
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002207 * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw.
2208 * @wma: wma handle
2209 * @vdev_id: vdev id
2210 * @peer_num_delta: peer number delta value
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002211 *
2212 * Return: none
2213 */
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002214void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
2215 uint8_t vdev_id,
2216 int8_t peer_num_delta)
2217{
2218 struct cdp_vdev *vdev;
2219 int16_t new_peer_num;
2220 uint16_t new_timer_value_sec;
2221 uint32_t new_timer_value_ms;
2222 QDF_STATUS status;
2223 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2224
2225 if (peer_num_delta != 1 && peer_num_delta != -1) {
2226 WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta);
2227 return;
2228 }
2229
2230 vdev = wma_find_vdev_by_id(wma, vdev_id);
2231 if (!vdev) {
2232 WMA_LOGE("vdev not found : vdev_id %d", vdev_id);
2233 return;
2234 }
2235
2236 /* adjust peer numbers */
2237 new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc, vdev,
2238 peer_num_delta
2239 );
2240 if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) {
2241 WMA_LOGE("new peer num %d out of valid boundary", new_peer_num);
2242 return;
2243 }
2244
2245 /* reset timer value if all peers departed */
2246 if (new_peer_num == 0) {
2247 cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0);
2248 return;
2249 }
2250
2251 /* calculate new timer value */
2252 new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num);
2253 if (new_timer_value_sec == 0) {
2254 WMA_LOGE("timer value %d is invalid for peer number %d",
2255 new_timer_value_sec, new_peer_num);
2256 return;
2257 }
2258 if (new_timer_value_sec ==
2259 cdp_set_ibss_vdev_heart_beat_timer(soc, vdev,
2260 new_timer_value_sec)) {
2261 WMA_LOGD("timer value %d stays same, no need to notify target",
2262 new_timer_value_sec);
2263 return;
2264 }
2265
2266 new_timer_value_ms = ((uint32_t)new_timer_value_sec) * 1000;
2267
2268 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
2269 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
2270 new_timer_value_ms);
2271 if (QDF_IS_STATUS_ERROR(status)) {
2272 WMA_LOGE("Failed to set IBSS link monitoring timer value");
2273 return;
2274 }
2275
2276 WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d",
2277 new_peer_num, new_timer_value_ms);
2278}
2279#endif /* QCA_IBSS_SUPPORT */
2280
2281#ifndef CRYPTO_SET_KEY_CONVERGED
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002282void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info)
2283{
2284 struct wma_set_key_params key_params;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302285 QDF_STATUS status = QDF_STATUS_SUCCESS;
2286 uint32_t i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002287 uint32_t def_key_idx = 0;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002288 uint32_t wlan_opmode;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002289 struct cdp_vdev *txrx_vdev;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002290 uint8_t *mac_addr;
Leo Chang96464902016-10-28 11:10:54 -07002291 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002292 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002293
2294 WMA_LOGD("BSS key setup");
2295 txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
2296 if (!txrx_vdev) {
2297 WMA_LOGE("%s:Invalid vdev handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302298 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002299 goto out;
2300 }
Leo Chang96464902016-10-28 11:10:54 -07002301 wlan_opmode = cdp_get_opmode(soc, txrx_vdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002302
2303 /*
2304 * For IBSS, WMI expects the BSS key to be set per peer key
2305 * So cache the BSS key in the wma_handle and re-use it when the
2306 * STA key is been setup for a peer
2307 */
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002308 if (wlan_op_mode_ibss == wlan_opmode) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302309 key_info->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002310 if (wma_handle->ibss_started > 0)
2311 goto out;
2312 WMA_LOGD("Caching IBSS Key");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302313 qdf_mem_copy(&wma_handle->ibsskey_info, key_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002314 sizeof(tSetBssKeyParams));
2315 }
2316
hangtian127c9532019-01-12 13:29:07 +08002317 qdf_mem_zero(&key_params, sizeof(key_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002318 key_params.vdev_id = key_info->smesessionId;
2319 key_params.key_type = key_info->encType;
2320 key_params.singl_tid_rc = key_info->singleTidRc;
2321 key_params.unicast = false;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002322 if (wlan_opmode == wlan_op_mode_sta) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302323 qdf_mem_copy(key_params.peer_mac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002324 wma_handle->interfaces[key_info->smesessionId].bssid,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -08002325 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002326 } else {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002327 mac_addr = cdp_get_vdev_mac_addr(soc,
2328 txrx_vdev);
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07002329 if (!mac_addr) {
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002330 WMA_LOGE("%s: mac_addr is NULL for vdev with id %d",
2331 __func__, key_info->smesessionId);
2332 goto out;
2333 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334 /* vdev mac address will be passed for all other modes */
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002335 qdf_mem_copy(key_params.peer_mac, mac_addr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -08002336 QDF_MAC_ADDR_SIZE);
Yeshwanth Sriram Guntukacbe61442018-08-23 18:08:44 +05302337 WMA_LOGD("BSS Key setup with vdev_mac %pM\n",
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002338 mac_addr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002339 }
2340
2341 if (key_info->numKeys == 0 &&
2342 (key_info->encType == eSIR_ED_WEP40 ||
2343 key_info->encType == eSIR_ED_WEP104)) {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002344 vdev =
2345 wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
2346 key_info->smesessionId,
2347 WLAN_LEGACY_WMA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002348 wma_read_cfg_wepkey(wma_handle, key_info->key,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002349 &def_key_idx, &key_info->numKeys, vdev);
2350 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
gaolez8a61fd22017-06-23 16:08:19 +08002351 } else if ((key_info->encType == eSIR_ED_WEP40) ||
2352 (key_info->encType == eSIR_ED_WEP104)) {
2353 struct wma_txrx_node *intf =
2354 &wma_handle->interfaces[key_info->smesessionId];
2355 key_params.def_key_idx = intf->wep_default_key_idx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002356 }
2357
2358 for (i = 0; i < key_info->numKeys; i++) {
2359 if (key_params.key_type != eSIR_ED_NONE &&
2360 !key_info->key[i].keyLength)
2361 continue;
2362 if (key_info->encType == eSIR_ED_WPI) {
2363 key_params.key_idx = key_info->key[i].keyId;
2364 key_params.def_key_idx = key_info->key[i].keyId;
2365 } else
2366 key_params.key_idx = key_info->key[i].keyId;
2367
2368 key_params.key_len = key_info->key[i].keyLength;
Krunal Soni8afae9b2017-10-20 20:15:54 -07002369 qdf_mem_copy(key_params.key_rsc,
2370 key_info->key[i].keyRsc,
Srinivas Girigowdacf161402019-03-14 11:37:33 -07002371 WLAN_CRYPTO_RSC_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 if (key_info->encType == eSIR_ED_TKIP) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302373 qdf_mem_copy(key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002374 key_info->key[i].key, 16);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302375 qdf_mem_copy(&key_params.key_data[16],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002376 &key_info->key[i].key[24], 8);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302377 qdf_mem_copy(&key_params.key_data[24],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378 &key_info->key[i].key[16], 8);
2379 } else
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302380 qdf_mem_copy((void *)key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381 (const void *)key_info->key[i].key,
2382 key_info->key[i].keyLength);
2383
2384 WMA_LOGD("%s: bss key[%d] length %d", __func__, i,
2385 key_info->key[i].keyLength);
2386
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302387 status = wma_setup_install_key_cmd(wma_handle, &key_params,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002388 wlan_opmode);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302389 if (status == QDF_STATUS_E_NOMEM) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390 WMA_LOGE("%s:Failed to setup install key buf",
2391 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302392 key_info->status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002393 goto out;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302394 } else if (status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002395 WMA_LOGE("%s:Failed to send install key command",
2396 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302397 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002398 goto out;
2399 }
2400 }
2401
2402 wma_handle->ibss_started++;
2403 /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302404 key_info->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405
gaurank kathpalia6d25c972019-03-07 20:25:28 +05302406 qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params));
2407
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002408out:
Abhishek Singh2d775fd2017-08-18 10:51:33 +05302409 wma_send_msg_high_priority(wma_handle, WMA_SET_BSSKEY_RSP,
2410 (void *)key_info, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002411}
2412
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413/**
2414 * wma_set_ibsskey_helper() - cached IBSS key in wma handle
2415 * @wma_handle: wma handle
2416 * @key_info: set bss key info
2417 * @peerMacAddr: peer mac address
2418 *
2419 * Return: none
2420 */
2421static void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
2422 tpSetBssKeyParams key_info,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302423 struct qdf_mac_addr peer_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002424{
2425 struct wma_set_key_params key_params;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302426 QDF_STATUS status = QDF_STATUS_SUCCESS;
2427 uint32_t i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002428 uint32_t def_key_idx = 0;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002429 struct cdp_vdev *txrx_vdev;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002430 int opmode;
Leo Chang96464902016-10-28 11:10:54 -07002431 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002432 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002433
2434 WMA_LOGD("BSS key setup for peer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002435 txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
2436 if (!txrx_vdev) {
2437 WMA_LOGE("%s:Invalid vdev handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302438 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002439 return;
2440 }
2441
hangtian127c9532019-01-12 13:29:07 +08002442 qdf_mem_zero(&key_params, sizeof(key_params));
Leo Chang96464902016-10-28 11:10:54 -07002443 opmode = cdp_get_opmode(soc, txrx_vdev);
hangtian127c9532019-01-12 13:29:07 +08002444 qdf_mem_zero(&key_params, sizeof(key_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002445 key_params.vdev_id = key_info->smesessionId;
2446 key_params.key_type = key_info->encType;
2447 key_params.singl_tid_rc = key_info->singleTidRc;
2448 key_params.unicast = false;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002449 ASSERT(wlan_op_mode_ibss == opmode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302451 qdf_mem_copy(key_params.peer_mac, peer_macaddr.bytes,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -08002452 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002453
2454 if (key_info->numKeys == 0 &&
2455 (key_info->encType == eSIR_ED_WEP40 ||
2456 key_info->encType == eSIR_ED_WEP104)) {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002457 vdev =
2458 wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
2459 key_info->smesessionId,
2460 WLAN_LEGACY_WMA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002461 wma_read_cfg_wepkey(wma_handle, key_info->key,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002462 &def_key_idx, &key_info->numKeys, vdev);
2463 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
Masti, Narayanraddiab712a72016-08-04 11:59:11 +05302464 } else if ((key_info->encType == eSIR_ED_WEP40) ||
2465 (key_info->encType == eSIR_ED_WEP104)) {
2466 struct wma_txrx_node *intf =
2467 &wma_handle->interfaces[key_info->smesessionId];
2468 key_params.def_key_idx = intf->wep_default_key_idx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 }
2470
2471 for (i = 0; i < key_info->numKeys; i++) {
2472 if (key_params.key_type != eSIR_ED_NONE &&
2473 !key_info->key[i].keyLength)
2474 continue;
2475 key_params.key_idx = key_info->key[i].keyId;
2476 key_params.key_len = key_info->key[i].keyLength;
2477 if (key_info->encType == eSIR_ED_TKIP) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302478 qdf_mem_copy(key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002479 key_info->key[i].key, 16);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302480 qdf_mem_copy(&key_params.key_data[16],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002481 &key_info->key[i].key[24], 8);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302482 qdf_mem_copy(&key_params.key_data[24],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002483 &key_info->key[i].key[16], 8);
2484 } else
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302485 qdf_mem_copy((void *)key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002486 (const void *)key_info->key[i].key,
2487 key_info->key[i].keyLength);
2488
2489 WMA_LOGD("%s: peer bcast key[%d] length %d", __func__, i,
2490 key_info->key[i].keyLength);
2491
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302492 status = wma_setup_install_key_cmd(wma_handle, &key_params,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002493 opmode);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302494 if (status == QDF_STATUS_E_NOMEM) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002495 WMA_LOGE("%s:Failed to setup install key buf",
2496 __func__);
2497 return;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302498 } else if (status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002499 WMA_LOGE("%s:Failed to send install key command",
2500 __func__);
2501 }
2502 }
2503}
2504
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002505void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info)
2506{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302507 int32_t i;
2508 QDF_STATUS status = QDF_STATUS_SUCCESS;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002509 struct cdp_pdev *txrx_pdev;
2510 struct cdp_vdev *txrx_vdev;
Leo Chang96464902016-10-28 11:10:54 -07002511 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002512 uint8_t num_keys = 0, peer_id;
2513 struct wma_set_key_params key_params;
2514 uint32_t def_key_idx = 0;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002515 int opmode;
Leo Chang96464902016-10-28 11:10:54 -07002516 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002517 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002518
2519 WMA_LOGD("STA key setup");
2520
2521 /* Get the txRx Pdev handle */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302522 txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002523 if (!txrx_pdev) {
2524 WMA_LOGE("%s:Invalid txrx pdev handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302525 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002526 goto out;
2527 }
2528
Leo Chang96464902016-10-28 11:10:54 -07002529 peer = cdp_peer_find_by_addr(soc, txrx_pdev,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002530 key_info->peer_macaddr.bytes,
2531 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532 if (!peer) {
2533 WMA_LOGE("%s:Invalid peer for key setting", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302534 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002535 goto out;
2536 }
2537
2538 txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
2539 if (!txrx_vdev) {
2540 WMA_LOGE("%s:TxRx Vdev Handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302541 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002542 goto out;
2543 }
Leo Chang96464902016-10-28 11:10:54 -07002544 opmode = cdp_get_opmode(soc, txrx_vdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002545
2546 if (key_info->defWEPIdx == WMA_INVALID_KEY_IDX &&
2547 (key_info->encType == eSIR_ED_WEP40 ||
2548 key_info->encType == eSIR_ED_WEP104) &&
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002549 opmode != wlan_op_mode_ap) {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002550 vdev =
2551 wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
2552 key_info->smesessionId,
2553 WLAN_LEGACY_WMA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002554 wma_read_cfg_wepkey(wma_handle, key_info->key,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002555 &def_key_idx, &num_keys, vdev);
2556 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002557 key_info->defWEPIdx = def_key_idx;
2558 } else {
2559 num_keys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
2560 if (key_info->encType != eSIR_ED_NONE) {
2561 for (i = 0; i < num_keys; i++) {
2562 if (key_info->key[i].keyDirection ==
2563 eSIR_TX_DEFAULT) {
2564 key_info->defWEPIdx = i;
2565 break;
2566 }
2567 }
2568 }
2569 }
hangtian127c9532019-01-12 13:29:07 +08002570 qdf_mem_zero(&key_params, sizeof(key_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002571 key_params.vdev_id = key_info->smesessionId;
2572 key_params.key_type = key_info->encType;
2573 key_params.singl_tid_rc = key_info->singleTidRc;
2574 key_params.unicast = true;
2575 key_params.def_key_idx = key_info->defWEPIdx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302576 qdf_mem_copy((void *)key_params.peer_mac,
Srinivas Girigowdad5965c42015-12-04 13:43:16 -08002577 (const void *)key_info->peer_macaddr.bytes,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -08002578 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002579 for (i = 0; i < num_keys; i++) {
2580 if (key_params.key_type != eSIR_ED_NONE &&
2581 !key_info->key[i].keyLength)
2582 continue;
2583 if (key_info->encType == eSIR_ED_TKIP) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302584 qdf_mem_copy(key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002585 key_info->key[i].key, 16);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302586 qdf_mem_copy(&key_params.key_data[16],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002587 &key_info->key[i].key[24], 8);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302588 qdf_mem_copy(&key_params.key_data[24],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002589 &key_info->key[i].key[16], 8);
2590 } else
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302591 qdf_mem_copy(key_params.key_data, key_info->key[i].key,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002592 key_info->key[i].keyLength);
2593 if (key_info->encType == eSIR_ED_WPI) {
2594 key_params.key_idx = key_info->key[i].keyId;
2595 key_params.def_key_idx = key_info->key[i].keyId;
2596 } else
2597 key_params.key_idx = i;
2598
2599 key_params.key_len = key_info->key[i].keyLength;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302600 status = wma_setup_install_key_cmd(wma_handle, &key_params,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002601 opmode);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302602 if (status == QDF_STATUS_E_NOMEM) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002603 WMA_LOGE("%s:Failed to setup install key buf",
2604 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302605 key_info->status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002606 goto out;
2607 }
2608
2609 WMA_LOGD("%s: peer unicast key[%d] %d ", __func__, i,
2610 key_info->key[i].keyLength);
2611
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302612 if (status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002613 WMA_LOGE("%s:Failed to send install key command",
2614 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302615 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 goto out;
2617 }
2618 }
2619
2620 /* In IBSS mode, set the BSS KEY for this peer
2621 * BSS key is supposed to be cache into wma_handle
2622 */
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002623 if (wlan_op_mode_ibss == opmode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002624 wma_set_ibsskey_helper(wma_handle, &wma_handle->ibsskey_info,
Srinivas Girigowdad5965c42015-12-04 13:43:16 -08002625 key_info->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002626 }
2627
2628 /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302629 key_info->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002630out:
gaurank kathpalia6d25c972019-03-07 20:25:28 +05302631 qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002632 if (key_info->sendRsp)
Abhishek Singh2d775fd2017-08-18 10:51:33 +05302633 wma_send_msg_high_priority(wma_handle, WMA_SET_STAKEY_RSP,
2634 (void *)key_info, 0);
Will Huangaaa2a052019-05-14 15:39:13 +08002635 else
2636 qdf_mem_free(key_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002637}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002638#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002639
2640/**
2641 * wma_process_update_edca_param_req() - update EDCA params
2642 * @handle: wma handle
2643 * @edca_params: edca parameters
2644 *
2645 * This function updates EDCA parameters to the target
2646 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302647 * Return: QDF Status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302649QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002650 tEdcaParams *edca_params)
2651{
2652 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002653 struct wmi_host_wme_vparams wmm_param[QCA_WLAN_AC_ALL];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002654 tSirMacEdcaParamRecord *edca_record;
2655 int ac;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002656 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002657 struct ol_tx_wmm_param_t ol_tx_wmm_param;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302658 uint8_t vdev_id;
2659 QDF_STATUS status;
Leo Chang96464902016-10-28 11:10:54 -07002660 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07002661
Pragaspathi Thilagaraje05162d2019-05-23 13:10:46 +05302662 vdev_id = edca_params->bss_idx;
Pragaspathi Thilagarajd5cb9e82019-02-04 14:13:52 +05302663 if (!wma_is_vdev_valid(vdev_id)) {
2664 WMA_LOGE("%s: vdev id:%d is not active ", __func__, vdev_id);
2665 goto fail;
2666 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002668 for (ac = 0; ac < QCA_WLAN_AC_ALL; ac++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 switch (ac) {
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002670 case QCA_WLAN_AC_BE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002671 edca_record = &edca_params->acbe;
2672 break;
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002673 case QCA_WLAN_AC_BK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002674 edca_record = &edca_params->acbk;
2675 break;
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002676 case QCA_WLAN_AC_VI:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002677 edca_record = &edca_params->acvi;
2678 break;
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002679 case QCA_WLAN_AC_VO:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680 edca_record = &edca_params->acvo;
2681 break;
2682 default:
2683 goto fail;
2684 }
2685
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -08002686 wma_update_edca_params_for_ac(edca_record, &wmm_param[ac], ac,
2687 edca_params->mu_edca_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002688
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302689 ol_tx_wmm_param.ac[ac].aifs = wmm_param[ac].aifs;
2690 ol_tx_wmm_param.ac[ac].cwmin = wmm_param[ac].cwmin;
2691 ol_tx_wmm_param.ac[ac].cwmax = wmm_param[ac].cwmax;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002692 }
2693
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302694 status = wmi_unified_process_update_edca_param(wma_handle->wmi_handle,
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -08002695 vdev_id,
2696 edca_params->mu_edca_params,
2697 wmm_param);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302698 if (status == QDF_STATUS_E_NOMEM)
2699 return status;
2700 else if (status == QDF_STATUS_E_FAILURE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701 goto fail;
2702
Anurag Chouhan6d760662016-02-20 16:05:43 +05302703 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Himanshu Agarwal94045e42015-10-19 19:16:19 +05302704 if (pdev)
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002705 cdp_set_wmm_param(soc, (struct cdp_pdev *)pdev,
2706 ol_tx_wmm_param);
Himanshu Agarwal94045e42015-10-19 19:16:19 +05302707 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302708 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002709
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302710 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002711
2712fail:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713 WMA_LOGE("%s: Failed to set WMM Paremeters", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302714 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002715}
2716
2717/**
2718 * wmi_unified_probe_rsp_tmpl_send() - send probe response template to fw
2719 * @wma: wma handle
2720 * @vdev_id: vdev id
2721 * @probe_rsp_info: probe response info
2722 *
2723 * Return: 0 for success or error code
2724 */
2725static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002726 uint8_t vdev_id,
2727 tpSendProbeRespParams probe_rsp_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 uint64_t adjusted_tsf_le;
2730 struct ieee80211_frame *wh;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302731 struct wmi_probe_resp_params params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002732
2733 WMA_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
2734
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002735 /*
2736 * Make the TSF offset negative so probe response in the same
2737 * staggered batch have the same TSF.
2738 */
2739 adjusted_tsf_le = cpu_to_le64(0ULL -
2740 wma->interfaces[vdev_id].tsfadjust);
2741 /* Update the timstamp in the probe response buffer with adjusted TSF */
Abhinav Kumar68834222018-07-18 19:06:14 +05302742 wh = (struct ieee80211_frame *)probe_rsp_info->probeRespTemplate;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743 A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
2744
Krunal Soni15650672017-11-14 15:42:01 -08002745 params.prb_rsp_template_len = probe_rsp_info->probeRespTemplateLen;
Abhinav Kumar68834222018-07-18 19:06:14 +05302746 params.prb_rsp_template_frm = probe_rsp_info->probeRespTemplate;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302748 return wmi_unified_probe_rsp_tmpl_send_cmd(wma->wmi_handle, vdev_id,
Krunal Soni15650672017-11-14 15:42:01 -08002749 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002750}
2751
2752/**
Govind Singh61ad2622016-02-22 17:25:02 +05302753 * wma_unified_bcn_tmpl_send() - send beacon template to fw
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002754 * @wma:wma handle
2755 * @vdev_id: vdev id
2756 * @bcn_info: beacon info
2757 * @bytes_to_strip: bytes to strip
2758 *
Govind Singh61ad2622016-02-22 17:25:02 +05302759 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002760 */
Govind Singh61ad2622016-02-22 17:25:02 +05302761static QDF_STATUS wma_unified_bcn_tmpl_send(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762 uint8_t vdev_id,
Govind Singh61ad2622016-02-22 17:25:02 +05302763 const tpSendbeaconParams bcn_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002764 uint8_t bytes_to_strip)
2765{
Govind Singh4ff22582017-04-25 16:01:53 +05302766 struct beacon_tmpl_params params = {0};
Govind Singh61ad2622016-02-22 17:25:02 +05302767 uint32_t tmpl_len, tmpl_len_aligned;
2768 uint8_t *frm;
2769 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002770 uint8_t *p2p_ie;
2771 uint16_t p2p_ie_len = 0;
2772 uint64_t adjusted_tsf_le;
2773 struct ieee80211_frame *wh;
2774
Pragaspathi Thilagarajd5cb9e82019-02-04 14:13:52 +05302775 if (!wma_is_vdev_valid(vdev_id)) {
2776 WMA_LOGE("%s: vdev id:%d is not active ", __func__, vdev_id);
2777 return QDF_STATUS_E_INVAL;
2778 }
2779
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 WMA_LOGD("Send beacon template for vdev %d", vdev_id);
2781
2782 if (bcn_info->p2pIeOffset) {
2783 p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
2784 p2p_ie_len = (uint16_t) p2p_ie[1] + 2;
2785 }
2786
2787 /*
2788 * XXX: The first byte of beacon buffer contains beacon length
2789 * only when UMAC in sending the beacon template. In othercases
2790 * (ex: from tbtt update) beacon length is read from beacon
2791 * information.
2792 */
2793 if (bytes_to_strip)
2794 tmpl_len = *(uint32_t *) &bcn_info->beacon[0];
2795 else
2796 tmpl_len = bcn_info->beaconLength;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002797 if (p2p_ie_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002798 tmpl_len -= (uint32_t) p2p_ie_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799 frm = bcn_info->beacon + bytes_to_strip;
2800 tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32));
2801 /*
2802 * Make the TSF offset negative so beacons in the same
2803 * staggered batch have the same TSF.
2804 */
2805 adjusted_tsf_le = cpu_to_le64(0ULL -
2806 wma->interfaces[vdev_id].tsfadjust);
2807 /* Update the timstamp in the beacon buffer with adjusted TSF */
2808 wh = (struct ieee80211_frame *)frm;
2809 A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
2810
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002812
Govind Singh61ad2622016-02-22 17:25:02 +05302813 params.vdev_id = vdev_id;
2814 params.tim_ie_offset = bcn_info->timIeOffset - bytes_to_strip;
2815 params.tmpl_len = tmpl_len;
2816 params.frm = frm;
2817 params.tmpl_len_aligned = tmpl_len_aligned;
Vignesh Viswanathan8777d3b2018-05-24 12:36:08 +05302818 if (bcn_info->csa_count_offset &&
2819 (bcn_info->csa_count_offset > bytes_to_strip))
2820 params.csa_switch_count_offset =
2821 bcn_info->csa_count_offset - bytes_to_strip;
2822 if (bcn_info->ecsa_count_offset &&
2823 (bcn_info->ecsa_count_offset > bytes_to_strip))
2824 params.ext_csa_switch_count_offset =
2825 bcn_info->ecsa_count_offset - bytes_to_strip;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002826
Govind Singh4ff22582017-04-25 16:01:53 +05302827 ret = wmi_unified_beacon_tmpl_send_cmd(wma->wmi_handle,
Govind Singh61ad2622016-02-22 17:25:02 +05302828 &params);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002829 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002830 WMA_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002831
2832 return ret;
2833}
2834
2835/**
2836 * wma_store_bcn_tmpl() - store beacon template
2837 * @wma: wma handle
2838 * @vdev_id: vdev id
2839 * @bcn_info: beacon params
2840 *
2841 * This function stores beacon template locally.
2842 * This will send to target on the reception of
2843 * SWBA event.
2844 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302845 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002846 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002847static QDF_STATUS wma_store_bcn_tmpl(tp_wma_handle wma, uint8_t vdev_id,
2848 tpSendbeaconParams bcn_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002849{
2850 struct beacon_info *bcn;
2851 uint32_t len;
2852 uint8_t *bcn_payload;
2853 struct beacon_tim_ie *tim_ie;
2854
2855 bcn = wma->interfaces[vdev_id].beacon;
2856 if (!bcn || !bcn->buf) {
2857 WMA_LOGE("%s: Memory is not allocated to hold bcn template",
2858 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302859 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002860 }
2861
Krunal Sonibd7e8932018-10-03 11:14:51 -07002862 len = *(uint32_t *) &bcn_info->beacon[0];
Krunal Soni2f5e3dd2018-10-03 11:48:27 -07002863 if (len > SIR_MAX_BEACON_SIZE - sizeof(uint32_t)) {
2864 WMA_LOGE("%s: Received beacon len %u exceeding max limit %lu",
jiad8196e0a2018-11-02 15:12:10 +08002865 __func__, len, (unsigned long)(
2866 SIR_MAX_BEACON_SIZE - sizeof(uint32_t)));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302867 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002868 }
2869 WMA_LOGD("%s: Storing received beacon template buf to local buffer",
2870 __func__);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302871 qdf_spin_lock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002872
2873 /*
2874 * Copy received beacon template content in local buffer.
2875 * this will be send to target on the reception of SWBA
2876 * event from target.
2877 */
Nirav Shahcbc6d722016-03-01 16:24:53 +05302878 qdf_nbuf_trim_tail(bcn->buf, qdf_nbuf_len(bcn->buf));
2879 memcpy(qdf_nbuf_data(bcn->buf),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002880 bcn_info->beacon + 4 /* Exclude beacon length field */,
2881 len);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002882 if (bcn_info->timIeOffset > 3)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002883 bcn->tim_ie_offset = bcn_info->timIeOffset - 4;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002884 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002885 bcn->tim_ie_offset = bcn_info->timIeOffset;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002886
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002887 if (bcn_info->p2pIeOffset > 3)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002888 bcn->p2p_ie_offset = bcn_info->p2pIeOffset - 4;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002889 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002890 bcn->p2p_ie_offset = bcn_info->p2pIeOffset;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002891
Nirav Shahcbc6d722016-03-01 16:24:53 +05302892 bcn_payload = qdf_nbuf_data(bcn->buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002893 if (bcn->tim_ie_offset) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002894 tim_ie = (struct beacon_tim_ie *)
2895 (&bcn_payload[bcn->tim_ie_offset]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896 /*
Jeff Johnsonc97816c2018-05-12 17:13:23 -07002897 * Initial Value of bcn->dtim_count will be 0.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002898 * But if the beacon gets updated then current dtim
2899 * count will be restored
2900 */
2901 tim_ie->dtim_count = bcn->dtim_count;
2902 tim_ie->tim_bitctl = 0;
2903 }
2904
Nirav Shahcbc6d722016-03-01 16:24:53 +05302905 qdf_nbuf_put_tail(bcn->buf, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002906 bcn->len = len;
2907
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302908 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002909
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302910 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911}
2912
2913/**
2914 * wma_tbttoffset_update_event_handler() - tbtt offset update handler
2915 * @handle: wma handle
2916 * @event: event buffer
2917 * @len: data length
2918 *
2919 * Return: 0 for success or error code
2920 */
2921int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event,
2922 uint32_t len)
2923{
2924 tp_wma_handle wma = (tp_wma_handle) handle;
2925 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
2926 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
2927 struct wma_txrx_node *intf;
2928 struct beacon_info *bcn;
2929 tSendbeaconParams bcn_info;
2930 uint32_t *adjusted_tsf = NULL;
2931 uint32_t if_id = 0, vdev_map;
2932
2933 if (!wma) {
2934 WMA_LOGE("Invalid wma handle");
2935 return -EINVAL;
2936 }
2937
2938 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) event;
2939 if (!param_buf) {
2940 WMA_LOGE("Invalid tbtt update event buffer");
2941 return -EINVAL;
2942 }
2943
2944 tbtt_offset_event = param_buf->fixed_param;
2945 intf = wma->interfaces;
2946 vdev_map = tbtt_offset_event->vdev_map;
2947 adjusted_tsf = param_buf->tbttoffset_list;
2948 if (!adjusted_tsf) {
2949 WMA_LOGE("%s: Invalid adjusted_tsf", __func__);
2950 return -EINVAL;
2951 }
2952
Vignesh Viswanathanadb1b652017-10-04 20:09:09 +05302953 for (; (if_id < wma->max_bssid && vdev_map); vdev_map >>= 1, if_id++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002954 if (!(vdev_map & 0x1) || (!(intf[if_id].handle)))
2955 continue;
2956
2957 bcn = intf[if_id].beacon;
2958 if (!bcn) {
2959 WMA_LOGE("%s: Invalid beacon", __func__);
2960 return -EINVAL;
2961 }
2962 if (!bcn->buf) {
2963 WMA_LOGE("%s: Invalid beacon buffer", __func__);
2964 return -EINVAL;
2965 }
2966 /* Save the adjusted TSF */
2967 intf[if_id].tsfadjust = adjusted_tsf[if_id];
2968
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302969 qdf_spin_lock_bh(&bcn->lock);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302970 qdf_mem_zero(&bcn_info, sizeof(bcn_info));
Abhinav Kumar68834222018-07-18 19:06:14 +05302971 qdf_mem_copy(bcn_info.beacon,
2972 qdf_nbuf_data(bcn->buf), bcn->len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002973 bcn_info.p2pIeOffset = bcn->p2p_ie_offset;
2974 bcn_info.beaconLength = bcn->len;
2975 bcn_info.timIeOffset = bcn->tim_ie_offset;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05302976 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002977
2978 /* Update beacon template in firmware */
Govind Singh61ad2622016-02-22 17:25:02 +05302979 wma_unified_bcn_tmpl_send(wma, if_id, &bcn_info, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002980 }
2981 return 0;
2982}
2983
2984/**
2985 * wma_p2p_go_set_beacon_ie() - set beacon IE for p2p go
2986 * @wma_handle: wma handle
2987 * @vdev_id: vdev id
2988 * @p2pIe: p2p IE
2989 *
2990 * Return: 0 for success or error code
2991 */
2992static int wma_p2p_go_set_beacon_ie(t_wma_handle *wma_handle,
2993 A_UINT32 vdev_id, uint8_t *p2pIe)
2994{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302995 if (!wma_handle) {
2996 WMA_LOGE("%s: wma handle is NULL", __func__);
2997 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002998 }
2999
Himanshu Agarwal009f1572016-03-09 17:26:02 +05303000 return wmi_unified_p2p_go_set_beacon_ie_cmd(wma_handle->wmi_handle,
3001 vdev_id, p2pIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003002}
3003
3004/**
3005 * wma_send_probe_rsp_tmpl() - send probe resp template
3006 * @wma: wma handle
3007 * @probe_rsp_info: probe response info
3008 *
3009 * This funciton sends probe response template to fw which
3010 * firmware will use in case of probe response offload.
3011 *
3012 * Return: none
3013 */
3014void wma_send_probe_rsp_tmpl(tp_wma_handle wma,
3015 tpSendProbeRespParams probe_rsp_info)
3016{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003017 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003018 uint8_t vdev_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003019 struct sAniProbeRspStruct *probe_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003020
3021 if (!probe_rsp_info) {
3022 WMA_LOGE(FL("probe_rsp_info is NULL"));
3023 return;
3024 }
3025
Abhinav Kumar68834222018-07-18 19:06:14 +05303026 probe_rsp = (struct sAniProbeRspStruct *)
3027 (probe_rsp_info->probeRespTemplate);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003028 if (!probe_rsp) {
3029 WMA_LOGE(FL("probe_rsp is NULL"));
3030 return;
3031 }
3032
3033 vdev = wma_find_vdev_by_addr(wma, probe_rsp->macHdr.sa, &vdev_id);
3034 if (!vdev) {
3035 WMA_LOGE(FL("failed to get vdev handle"));
3036 return;
3037 }
3038
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303039 if (wmi_service_enabled(wma->wmi_handle,
3040 wmi_service_beacon_offload)) {
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08003041 WMA_LOGD("Beacon Offload Enabled Sending Unified command");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003042 if (wmi_unified_probe_rsp_tmpl_send(wma, vdev_id,
3043 probe_rsp_info) < 0) {
3044 WMA_LOGE(FL("wmi_unified_probe_rsp_tmpl_send Failed "));
3045 return;
3046 }
3047 }
3048}
3049
Abhishek Singh3d30a3b2018-09-12 15:49:18 +05303050QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id)
Abhishek Singhdfa69c32018-08-30 15:39:34 +05303051{
3052 struct vdev_up_params param = {0};
Abhishek Singh3d30a3b2018-09-12 15:49:18 +05303053 QDF_STATUS status = QDF_STATUS_SUCCESS;
Abhishek Singhdfa69c32018-08-30 15:39:34 +05303054
Abhishek Singha063f1c2018-09-19 11:37:51 +05303055 param.vdev_id = vdev_id;
3056 param.assoc_id = 0;
3057 status = wma_send_vdev_up_to_fw(wma, &param,
3058 wma->interfaces[vdev_id].bssid);
3059 if (QDF_IS_STATUS_ERROR(status)) {
3060 WMA_LOGE(FL("failed to send vdev up"));
3061 policy_mgr_set_do_hw_mode_change_flag(
3062 wma->psoc, false);
3063 return status;
3064 }
3065 wma_set_sap_keepalive(wma, vdev_id);
3066 wma_set_vdev_mgmt_rate(wma, vdev_id);
3067
3068 return status;
3069}
Abhishek Singhfb5b4d32018-12-06 11:53:08 +05303070
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003071/**
3072 * wma_send_beacon() - send beacon template
3073 * @wma: wma handle
3074 * @bcn_info: beacon info
3075 *
3076 * This funciton store beacon template locally and
3077 * update keep alive parameters
3078 *
3079 * Return: none
3080 */
3081void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
3082{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003083 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003084 uint8_t vdev_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303085 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003086 uint8_t *p2p_ie;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003087 struct sAniBeaconStruct *beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003088
Abhishek Singhfc740be2018-10-12 11:34:26 +05303089 WMA_LOGD("Beacon update reason %d", bcn_info->reason);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003090 beacon = (struct sAniBeaconStruct *) (bcn_info->beacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003091 vdev = wma_find_vdev_by_addr(wma, beacon->macHdr.sa, &vdev_id);
3092 if (!vdev) {
3093 WMA_LOGE("%s : failed to get vdev handle", __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303094 status = QDF_STATUS_E_INVAL;
3095 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003096 }
3097
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303098 if (wmi_service_enabled(wma->wmi_handle,
3099 wmi_service_beacon_offload)) {
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08003100 WMA_LOGD("Beacon Offload Enabled Sending Unified command");
Govind Singh61ad2622016-02-22 17:25:02 +05303101 status = wma_unified_bcn_tmpl_send(wma, vdev_id, bcn_info, 4);
3102 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003103 WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
3104 __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303105 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003106 }
3107
3108 if (bcn_info->p2pIeOffset) {
3109 p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
Sandeep Puligilla1f1e4002018-08-18 12:15:01 -07003110 WMA_LOGD("%s: p2pIe is present - vdev_id %hu, p2p_ie = %pK, p2p ie len = %hu",
3111 __func__, vdev_id, p2p_ie, p2p_ie[1]);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003112 if (wma_p2p_go_set_beacon_ie(wma, vdev_id,
3113 p2p_ie) < 0) {
3114 WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003115 __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303116 status = QDF_STATUS_E_INVAL;
3117 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003118 }
3119 }
3120 }
3121 status = wma_store_bcn_tmpl(wma, vdev_id, bcn_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303122 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003123 WMA_LOGE("%s : wma_store_bcn_tmpl Failed", __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303124 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003125 }
Abhishek Singhfc740be2018-10-12 11:34:26 +05303126
3127send_rsp:
3128 bcn_info->status = status;
3129 wma_send_msg(wma, WMA_SEND_BCN_RSP, (void *)bcn_info, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003130}
3131
3132/**
3133 * wma_set_keepalive_req() - send keep alive request to fw
3134 * @wma: wma handle
3135 * @keepalive: keep alive parameters
3136 *
3137 * Return: none
3138 */
3139void wma_set_keepalive_req(tp_wma_handle wma,
Jeff Johnson562ccad2019-02-06 22:10:24 -08003140 struct keep_alive_req *keepalive)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003141{
3142 WMA_LOGD("KEEPALIVE:PacketType:%d", keepalive->packetType);
3143 wma_set_sta_keep_alive(wma, keepalive->sessionId,
3144 keepalive->packetType,
3145 keepalive->timePeriod,
3146 keepalive->hostIpv4Addr,
Srinivas Girigowda9c330a92015-11-24 12:28:25 -08003147 keepalive->destIpv4Addr,
3148 keepalive->dest_macaddr.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003149
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303150 qdf_mem_free(keepalive);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003151}
3152
3153/**
3154 * wma_beacon_miss_handler() - beacon miss event handler
3155 * @wma: wma handle
3156 * @vdev_id: vdev id
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05303157 * @riis: rssi value
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003158 *
3159 * This function send beacon miss indication to upper layers.
3160 *
3161 * Return: none
3162 */
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05303163void wma_beacon_miss_handler(tp_wma_handle wma, uint32_t vdev_id, int32_t rssi)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003164{
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003165 struct missed_beacon_ind *beacon_miss_ind;
Jeff Johnson9f18aa72018-12-02 12:05:12 -08003166 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003167
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003168 beacon_miss_ind = qdf_mem_malloc(sizeof(*beacon_miss_ind));
3169 if (!beacon_miss_ind)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003170 return;
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003171
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -08003172 if (mac && mac->sme.tx_queue_cb)
Jeff Johnson6aaaa992018-06-30 10:43:04 -07003173 mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id,
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -08003174 WLAN_STOP_ALL_NETIF_QUEUE,
3175 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003176 beacon_miss_ind->messageType = WMA_MISSED_BEACON_IND;
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003177 beacon_miss_ind->length = sizeof(*beacon_miss_ind);
Pragaspathi Thilagaraje05162d2019-05-23 13:10:46 +05303178 beacon_miss_ind->bss_idx = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003179
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003180 wma_send_msg(wma, WMA_MISSED_BEACON_IND, beacon_miss_ind, 0);
Yeshwanth Sriram Guntuka14ab04c2018-09-21 15:06:49 +05303181 if (!wmi_service_enabled(wma->wmi_handle,
3182 wmi_service_hw_db2dbm_support))
3183 rssi += WMA_TGT_NOISE_FLOOR_DBM;
3184 wma_lost_link_info_handler(wma, vdev_id, rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003185}
3186
3187/**
Naveen Rawat684e8b12017-09-20 15:54:44 -07003188 * wma_get_status_str() - get string of tx status from firmware
3189 * @status: tx status
3190 *
3191 * Return: converted string of tx status
3192 */
3193static const char *wma_get_status_str(uint32_t status)
3194{
3195 switch (status) {
3196 default:
3197 return "unknown";
3198 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK);
3199 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_DISCARD);
3200 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_INSPECT);
3201 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK);
3202 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_MAX);
3203 }
3204}
3205
Nirav Shah36332212018-11-20 11:48:19 +05303206#ifdef CONFIG_HL_SUPPORT
3207static inline void wma_mgmt_unmap_buf(tp_wma_handle wma_handle, qdf_nbuf_t buf)
3208{
3209}
3210#else
3211static inline void wma_mgmt_unmap_buf(tp_wma_handle wma_handle, qdf_nbuf_t buf)
3212{
3213 qdf_nbuf_unmap_single(wma_handle->qdf_dev, buf, QDF_DMA_TO_DEVICE);
3214}
3215#endif
Naveen Rawat684e8b12017-09-20 15:54:44 -07003216/**
Nirav Shah20489972016-06-16 19:20:28 +05303217 * wma_process_mgmt_tx_completion() - process mgmt completion
3218 * @wma_handle: wma handle
3219 * @desc_id: descriptor id
3220 * @status: status
3221 *
3222 * Return: 0 for success or error code
3223 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07003224static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
3225 uint32_t desc_id, uint32_t status)
Nirav Shah20489972016-06-16 19:20:28 +05303226{
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303227 struct wlan_objmgr_pdev *pdev;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303228 qdf_nbuf_t buf = NULL;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303229 QDF_STATUS ret;
Jingxiang Gebd540b12019-03-13 14:58:52 +08003230#if !defined(REMOVE_PKT_LOG)
3231 uint8_t vdev_id = 0;
3232 struct cdp_vdev *txrx_vdev;
3233 ol_txrx_pktdump_cb packetdump_cb;
3234 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
3235#endif
Leo Chang96464902016-10-28 11:10:54 -07003236
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07003237 if (!wma_handle) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303238 WMA_LOGE("%s: wma handle is NULL", __func__);
Nirav Shah20489972016-06-16 19:20:28 +05303239 return -EINVAL;
3240 }
3241
Naveen Rawat684e8b12017-09-20 15:54:44 -07003242 WMA_LOGD("%s: status: %s wmi_desc_id: %d", __func__,
3243 wma_get_status_str(status), desc_id);
Nirav Shah20489972016-06-16 19:20:28 +05303244
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303245 pdev = wma_handle->pdev;
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07003246 if (!pdev) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303247 WMA_LOGE("%s: psoc ptr is NULL", __func__);
Nirav Shah20489972016-06-16 19:20:28 +05303248 return -EINVAL;
3249 }
3250
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303251 buf = mgmt_txrx_get_nbuf(pdev, desc_id);
Jingxiang Gebd540b12019-03-13 14:58:52 +08003252
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303253
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303254 if (buf)
Nirav Shah36332212018-11-20 11:48:19 +05303255 wma_mgmt_unmap_buf(wma_handle, buf);
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05303256
Jingxiang Gebd540b12019-03-13 14:58:52 +08003257#if !defined(REMOVE_PKT_LOG)
3258 vdev_id = mgmt_txrx_get_vdev_id(pdev, desc_id);
3259 txrx_vdev = wma_find_vdev_by_id(wma_handle, vdev_id);
Himanshu Agarwalbb226bc2017-01-18 20:45:01 +05303260 packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb;
3261 if (packetdump_cb)
Jingxiang Gebd540b12019-03-13 14:58:52 +08003262 packetdump_cb(soc, txrx_vdev,
3263 buf, QDF_STATUS_SUCCESS, TX_MGMT_PKT);
3264#endif
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05303265
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303266 ret = mgmt_txrx_tx_completion_handler(pdev, desc_id, status, NULL);
Nirav Shah20489972016-06-16 19:20:28 +05303267
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303268 if (ret != QDF_STATUS_SUCCESS) {
3269 WMA_LOGE("%s: Failed to process mgmt tx completion", __func__);
3270 return -EINVAL;
3271 }
Nirav Shah20489972016-06-16 19:20:28 +05303272
Nirav Shah20489972016-06-16 19:20:28 +05303273 return 0;
3274}
3275
3276/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277 * wma_mgmt_tx_completion_handler() - wma mgmt Tx completion event handler
3278 * @handle: wma handle
3279 * @cmpl_event_params: completion event handler data
3280 * @len: length of @cmpl_event_params
3281 *
3282 * Return: 0 on success; error number otherwise
3283 */
3284
3285int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params,
3286 uint32_t len)
3287{
3288 tp_wma_handle wma_handle = (tp_wma_handle)handle;
3289 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
3290 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params;
Naveen Rawat35804772016-06-27 15:40:28 -07003291
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003292 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
3293 cmpl_event_params;
Naveen Rawat35804772016-06-27 15:40:28 -07003294 if (!param_buf || !wma_handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003295 WMA_LOGE("%s: Invalid mgmt Tx completion event", __func__);
3296 return -EINVAL;
3297 }
3298 cmpl_params = param_buf->fixed_param;
3299
Nirav Shah20489972016-06-16 19:20:28 +05303300 wma_process_mgmt_tx_completion(wma_handle,
3301 cmpl_params->desc_id, cmpl_params->status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003302
Nirav Shah20489972016-06-16 19:20:28 +05303303 return 0;
3304}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003305
Nirav Shah20489972016-06-16 19:20:28 +05303306/**
3307 * wma_mgmt_tx_bundle_completion_handler() - mgmt bundle comp handler
3308 * @handle: wma handle
3309 * @buf: buffer
3310 * @len: length
3311 *
3312 * Return: 0 for success or error code
3313 */
3314int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf,
3315 uint32_t len)
3316{
3317 tp_wma_handle wma_handle = (tp_wma_handle)handle;
3318 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *param_buf;
3319 wmi_mgmt_tx_compl_bundle_event_fixed_param *cmpl_params;
3320 uint32_t num_reports;
3321 uint32_t *desc_ids;
3322 uint32_t *status;
Vignesh Viswanathana2ef8b12017-10-24 22:32:28 +05303323 uint32_t i, buf_len;
3324 bool excess_data = false;
Nirav Shah20489972016-06-16 19:20:28 +05303325
3326 param_buf = (WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *)buf;
Arif Hussain31576d92016-10-25 14:32:12 -07003327 if (!param_buf || !wma_handle) {
Nirav Shah20489972016-06-16 19:20:28 +05303328 WMA_LOGE("%s: Invalid mgmt Tx completion event", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003329 return -EINVAL;
3330 }
Nirav Shah20489972016-06-16 19:20:28 +05303331 cmpl_params = param_buf->fixed_param;
3332 num_reports = cmpl_params->num_reports;
3333 desc_ids = (uint32_t *)(param_buf->desc_ids);
3334 status = (uint32_t *)(param_buf->status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003335
Vignesh Viswanathana2ef8b12017-10-24 22:32:28 +05303336 /* buf contains num_reports * sizeof(uint32) len of desc_ids and
3337 * num_reports * sizeof(uint32) status,
3338 * so (2 x (num_reports * sizeof(uint32)) should not exceed MAX
3339 */
3340 if (cmpl_params->num_reports > (WMI_SVC_MSG_MAX_SIZE /
3341 (2 * sizeof(uint32_t))))
3342 excess_data = true;
3343 else
3344 buf_len = cmpl_params->num_reports * (2 * sizeof(uint32_t));
3345
3346 if (excess_data || (sizeof(*cmpl_params) > (WMI_SVC_MSG_MAX_SIZE -
3347 buf_len))) {
3348 WMA_LOGE("excess wmi buffer: num_reports %d",
3349 cmpl_params->num_reports);
3350 return -EINVAL;
3351 }
3352
3353 if ((cmpl_params->num_reports > param_buf->num_desc_ids) ||
3354 (cmpl_params->num_reports > param_buf->num_status)) {
3355 WMA_LOGE("Invalid num_reports %d, num_desc_ids %d, num_status %d",
3356 cmpl_params->num_reports, param_buf->num_desc_ids,
3357 param_buf->num_status);
3358 return -EINVAL;
3359 }
3360
Nirav Shah20489972016-06-16 19:20:28 +05303361 for (i = 0; i < num_reports; i++)
3362 wma_process_mgmt_tx_completion(wma_handle,
3363 desc_ids[i], status[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003364 return 0;
3365}
3366
3367/**
3368 * wma_process_update_opmode() - process update VHT opmode cmd from UMAC
3369 * @wma_handle: wma handle
3370 * @update_vht_opmode: vht opmode
3371 *
3372 * Return: none
3373 */
3374void wma_process_update_opmode(tp_wma_handle wma_handle,
3375 tUpdateVHTOpMode *update_vht_opmode)
3376{
Kiran Kumar Lokeref7662e52018-02-05 09:04:07 -08003377 struct wma_txrx_node *iface;
Naveen Rawatf8792bd2017-11-12 21:38:05 -08003378 wmi_host_channel_width ch_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003379
Kiran Kumar Lokeref7662e52018-02-05 09:04:07 -08003380 iface = &wma_handle->interfaces[update_vht_opmode->smesessionId];
Naveen Rawatf8792bd2017-11-12 21:38:05 -08003381 ch_width = wmi_get_ch_width_from_phy_mode(wma_handle->wmi_handle,
3382 iface->chanmode);
Kiran Kumar Lokeref7662e52018-02-05 09:04:07 -08003383 if (ch_width < update_vht_opmode->opMode) {
3384 WMA_LOGE("%s: Invalid peer bw update %d, self bw %d",
3385 __func__, update_vht_opmode->opMode,
3386 ch_width);
3387 return;
3388 }
Abhishek Singhbbe23a72018-12-12 10:52:32 +05303389 WMA_LOGD("%s: phymode = %d", __func__, iface->chanmode);
3390 /* Always send phymode before BW to avoid any mismatch in FW */
3391 wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
3392 WMI_PEER_PHYMODE, iface->chanmode,
3393 update_vht_opmode->smesessionId);
Kiran Kumar Lokeref7662e52018-02-05 09:04:07 -08003394 WMA_LOGD("%s: opMode = %d", __func__, update_vht_opmode->opMode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003395 wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
3396 WMI_PEER_CHWIDTH, update_vht_opmode->opMode,
3397 update_vht_opmode->smesessionId);
3398}
3399
3400/**
3401 * wma_process_update_rx_nss() - process update RX NSS cmd from UMAC
3402 * @wma_handle: wma handle
3403 * @update_rx_nss: rx nss value
3404 *
3405 * Return: none
3406 */
3407void wma_process_update_rx_nss(tp_wma_handle wma_handle,
3408 tUpdateRxNss *update_rx_nss)
3409{
Paul Zhang7d1d5362018-07-19 17:00:18 +08003410 struct target_psoc_info *tgt_hdl;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003411 struct wma_txrx_node *intr =
3412 &wma_handle->interfaces[update_rx_nss->smesessionId];
3413 int rx_nss = update_rx_nss->rxNss;
Paul Zhang7d1d5362018-07-19 17:00:18 +08003414 int num_rf_chains;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003415
Paul Zhang7d1d5362018-07-19 17:00:18 +08003416 tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
3417 if (!tgt_hdl) {
3418 WMA_LOGE("%s: target psoc info is NULL", __func__);
3419 return;
3420 }
3421
3422 num_rf_chains = target_if_get_num_rf_chains(tgt_hdl);
3423 if (rx_nss > num_rf_chains || rx_nss > WMA_MAX_NSS)
3424 rx_nss = QDF_MIN(num_rf_chains, WMA_MAX_NSS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003425
3426 intr->nss = (uint8_t)rx_nss;
3427 update_rx_nss->rxNss = (uint32_t)rx_nss;
3428
3429 WMA_LOGD("%s: Rx Nss = %d", __func__, update_rx_nss->rxNss);
3430
3431 wma_set_peer_param(wma_handle, update_rx_nss->peer_mac,
3432 WMI_PEER_NSS, update_rx_nss->rxNss,
3433 update_rx_nss->smesessionId);
3434}
3435
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003436/**
3437 * wma_process_update_membership() - process update group membership cmd
3438 * @wma_handle: wma handle
3439 * @membership: group membership info
3440 *
3441 * Return: none
3442 */
3443void wma_process_update_membership(tp_wma_handle wma_handle,
3444 tUpdateMembership *membership)
3445{
3446 WMA_LOGD("%s: membership = %x ", __func__, membership->membership);
3447
3448 wma_set_peer_param(wma_handle, membership->peer_mac,
3449 WMI_PEER_MEMBERSHIP, membership->membership,
3450 membership->smesessionId);
3451}
3452
3453/**
3454 * wma_process_update_userpos() - process update user pos cmd from UMAC
3455 * @wma_handle: wma handle
3456 * @userpos: user pos value
3457 *
3458 * Return: none
3459 */
3460void wma_process_update_userpos(tp_wma_handle wma_handle,
3461 tUpdateUserPos *userpos)
3462{
3463 WMA_LOGD("%s: userPos = %x ", __func__, userpos->userPos);
3464
3465 wma_set_peer_param(wma_handle, userpos->peer_mac,
3466 WMI_PEER_USERPOS, userpos->userPos,
3467 userpos->smesessionId);
3468
3469 /* Now that membership/userpos is updated in fw,
3470 * enable GID PPS.
3471 */
3472 wma_set_ppsconfig(userpos->smesessionId, WMA_VHT_PPS_GID_MATCH, 1);
3473
3474}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003475
Agrawal Ashishb2d1a452016-05-05 12:23:58 +05303476QDF_STATUS wma_set_cts2self_for_p2p_go(void *wma_handle,
3477 uint32_t cts2self_for_p2p_go)
3478{
3479 int32_t ret;
3480 tp_wma_handle wma = (tp_wma_handle)wma_handle;
3481 struct pdev_params pdevparam;
3482
3483 pdevparam.param_id = WMI_PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG;
3484 pdevparam.param_value = cts2self_for_p2p_go;
3485
3486 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
3487 &pdevparam,
3488 WMA_WILDCARD_PDEV_ID);
3489 if (ret) {
3490 WMA_LOGE("Fail to Set CTS2SELF for p2p GO %d",
3491 cts2self_for_p2p_go);
3492 return QDF_STATUS_E_FAILURE;
3493 }
3494
3495 WMA_LOGD("Successfully Set CTS2SELF for p2p GO %d",
3496 cts2self_for_p2p_go);
3497
3498 return QDF_STATUS_SUCCESS;
3499}
3500
3501
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003502/**
3503 * wma_set_htconfig() - set ht config parameters to target
3504 * @vdev_id: vdev id
3505 * @ht_capab: ht capablity
3506 * @value: value of ht param
3507 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303508 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003509 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303510QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003511{
Anurag Chouhan6d760662016-02-20 16:05:43 +05303512 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Govind Singhd76a5b02016-03-08 15:12:14 +05303513 QDF_STATUS ret = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003514
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07003515 if (!wma) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003516 WMA_LOGE("%s: Failed to get wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303517 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003518 }
3519
3520 switch (ht_capab) {
3521 case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
Govind Singhd76a5b02016-03-08 15:12:14 +05303522 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003523 WMI_VDEV_PARAM_LDPC,
3524 value);
3525 break;
3526 case WNI_CFG_HT_CAP_INFO_TX_STBC:
Govind Singhd76a5b02016-03-08 15:12:14 +05303527 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003528 WMI_VDEV_PARAM_TX_STBC,
3529 value);
3530 break;
3531 case WNI_CFG_HT_CAP_INFO_RX_STBC:
Govind Singhd76a5b02016-03-08 15:12:14 +05303532 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003533 WMI_VDEV_PARAM_RX_STBC,
3534 value);
3535 break;
3536 case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
3537 case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
3538 WMA_LOGE("%s: ht_capab = %d, value = %d", __func__, ht_capab,
3539 value);
Govind Singhd76a5b02016-03-08 15:12:14 +05303540 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003541 WMI_VDEV_PARAM_SGI, value);
Govind Singhd76a5b02016-03-08 15:12:14 +05303542 if (ret == QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003543 wma->interfaces[vdev_id].config.shortgi = value;
3544 break;
3545 default:
3546 WMA_LOGE("%s:INVALID HT CONFIG", __func__);
3547 }
3548
Govind Singhd76a5b02016-03-08 15:12:14 +05303549 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003550}
3551
3552/**
3553 * wma_hidden_ssid_vdev_restart() - vdev restart for hidden ssid
3554 * @wma_handle: wma handle
3555 * @pReq: hidden ssid vdev restart request
3556 *
3557 * Return: none
3558 */
Abhishek Singhf06214b2018-08-17 12:16:39 +05303559void wma_hidden_ssid_vdev_restart(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003560 tHalHiddenSsidVdevRestart *pReq)
3561{
Abhishek Singhf06214b2018-08-17 12:16:39 +05303562 struct wma_txrx_node *intr = wma->interfaces;
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05303563 struct wma_target_req *msg;
Abhishek Singhf06214b2018-08-17 12:16:39 +05303564 struct hidden_ssid_vdev_restart_params params;
3565 QDF_STATUS status;
3566 uint8_t vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003567
Abhishek Singhf06214b2018-08-17 12:16:39 +05303568 vdev_id = pReq->sessionId;
3569 if ((vdev_id != intr[vdev_id].vdev_restart_params.vdev_id)
3570 || !((intr[vdev_id].type == WMI_VDEV_TYPE_AP)
3571 && (intr[vdev_id].sub_type == 0))) {
3572 WMA_LOGE(FL("invalid vdev_id %d"), vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003573 return;
3574 }
3575
Abhishek Singhf06214b2018-08-17 12:16:39 +05303576 intr[vdev_id].vdev_restart_params.ssidHidden = pReq->ssidHidden;
Abhishek Singhf06214b2018-08-17 12:16:39 +05303577 WMA_LOGD(FL("hidden ssid set using IOCTL for vdev %d ssid_hidden %d"),
3578 vdev_id, pReq->ssidHidden);
3579
3580 msg = wma_fill_vdev_req(wma, vdev_id,
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05303581 WMA_HIDDEN_SSID_VDEV_RESTART,
Abhishek Singhf06214b2018-08-17 12:16:39 +05303582 WMA_TARGET_REQ_TYPE_VDEV_START,
3583 pReq,
3584 WMA_VDEV_START_REQUEST_TIMEOUT);
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05303585 if (!msg) {
Abhishek Singhf06214b2018-08-17 12:16:39 +05303586 WMA_LOGE(FL("Failed to fill vdev request, vdev_id %d"),
3587 vdev_id);
Abhishek Singhf06214b2018-08-17 12:16:39 +05303588 qdf_mem_free(pReq);
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05303589 return;
3590 }
3591
Jeff Johnsonfc0969f2019-02-22 14:19:02 -08003592 params.vdev_id = vdev_id;
Abhishek Singhf06214b2018-08-17 12:16:39 +05303593 params.ssid_len = intr[vdev_id].vdev_restart_params.ssid.ssid_len;
3594 qdf_mem_copy(params.ssid,
3595 intr[vdev_id].vdev_restart_params.ssid.ssid,
3596 params.ssid_len);
3597 params.flags = intr[vdev_id].vdev_restart_params.flags;
3598 if (intr[vdev_id].vdev_restart_params.ssidHidden)
3599 params.flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
3600 else
3601 params.flags &= (0xFFFFFFFE);
3602 params.requestor_id = intr[vdev_id].vdev_restart_params.requestor_id;
3603 params.disable_hw_ack =
3604 intr[vdev_id].vdev_restart_params.disable_hw_ack;
3605
3606 params.mhz = intr[vdev_id].vdev_restart_params.chan.mhz;
3607 params.band_center_freq1 =
3608 intr[vdev_id].vdev_restart_params.chan.band_center_freq1;
3609 params.band_center_freq2 =
3610 intr[vdev_id].vdev_restart_params.chan.band_center_freq2;
3611 params.info = intr[vdev_id].vdev_restart_params.chan.info;
3612 params.reg_info_1 = intr[vdev_id].vdev_restart_params.chan.reg_info_1;
3613 params.reg_info_2 = intr[vdev_id].vdev_restart_params.chan.reg_info_2;
3614
Abhishek Singhf06214b2018-08-17 12:16:39 +05303615 status = wmi_unified_hidden_ssid_vdev_restart_send(wma->wmi_handle,
3616 &params);
3617 if (QDF_IS_STATUS_ERROR(status)) {
3618 WMA_LOGE(FL("Failed to send vdev restart command"));
Abhishek Singhf06214b2018-08-17 12:16:39 +05303619 wma_remove_vdev_req(wma, vdev_id,
3620 WMA_TARGET_REQ_TYPE_VDEV_START);
3621 qdf_mem_free(pReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003622 }
3623}
3624
3625
3626#ifdef WLAN_FEATURE_11W
3627
3628/**
3629 * wma_extract_ccmp_pn() - extract 6 byte PN from the CCMP header
3630 * @ccmp_ptr: CCMP header
3631 *
3632 * Return: PN extracted from header.
3633 */
3634static uint64_t wma_extract_ccmp_pn(uint8_t *ccmp_ptr)
3635{
3636 uint8_t rsvd, key, pn[6];
3637 uint64_t new_pn;
3638
3639 /*
3640 * +-----+-----+------+----------+-----+-----+-----+-----+
3641 * | PN0 | PN1 | rsvd | rsvd/key | PN2 | PN3 | PN4 | PN5 |
3642 * +-----+-----+------+----------+-----+-----+-----+-----+
3643 * CCMP Header Format
3644 */
3645
3646 /* Extract individual bytes */
3647 pn[0] = (uint8_t) *ccmp_ptr;
3648 pn[1] = (uint8_t) *(ccmp_ptr + 1);
3649 rsvd = (uint8_t) *(ccmp_ptr + 2);
3650 key = (uint8_t) *(ccmp_ptr + 3);
3651 pn[2] = (uint8_t) *(ccmp_ptr + 4);
3652 pn[3] = (uint8_t) *(ccmp_ptr + 5);
3653 pn[4] = (uint8_t) *(ccmp_ptr + 6);
3654 pn[5] = (uint8_t) *(ccmp_ptr + 7);
3655
3656 /* Form 6 byte PN with 6 individual bytes of PN */
3657 new_pn = ((uint64_t) pn[5] << 40) |
3658 ((uint64_t) pn[4] << 32) |
3659 ((uint64_t) pn[3] << 24) |
3660 ((uint64_t) pn[2] << 16) |
3661 ((uint64_t) pn[1] << 8) | ((uint64_t) pn[0] << 0);
3662
3663 WMA_LOGE("PN of received packet is %llu", new_pn);
3664 return new_pn;
3665}
3666
3667/**
3668 * wma_is_ccmp_pn_replay_attack() - detect replay attacking using PN in CCMP
3669 * @cds_ctx: cds context
3670 * @wh: 802.11 frame header
3671 * @ccmp_ptr: CCMP frame header
3672 *
3673 * Return: true/false
3674 */
3675static bool
3676wma_is_ccmp_pn_replay_attack(void *cds_ctx, struct ieee80211_frame *wh,
3677 uint8_t *ccmp_ptr)
3678{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003679 struct cdp_pdev *pdev;
3680 struct cdp_vdev *vdev;
Leo Chang96464902016-10-28 11:10:54 -07003681 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003682 uint8_t vdev_id, peer_id;
Zhang Qian610a1a72018-04-27 17:03:30 +08003683 uint8_t *last_pn_valid = NULL;
3684 uint64_t *last_pn = NULL, new_pn;
3685 uint32_t *rmf_pn_replays = NULL;
Leo Chang96464902016-10-28 11:10:54 -07003686 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Abhishek Singh38da9802018-06-20 16:25:09 +05303687 bool ret = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003688
Anurag Chouhan6d760662016-02-20 16:05:43 +05303689 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003690 if (!pdev) {
3691 WMA_LOGE("%s: Failed to find pdev", __func__);
3692 return true;
3693 }
3694
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05303695 vdev = wma_find_vdev_by_bssid(cds_ctx, wh->i_addr3, &vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003696 if (!vdev) {
3697 WMA_LOGE("%s: Failed to find vdev", __func__);
3698 return true;
3699 }
3700
3701 /* Retrieve the peer based on vdev and addr */
Abhishek Singh38da9802018-06-20 16:25:09 +05303702 peer = cdp_peer_get_ref_by_addr(soc, pdev, wh->i_addr2, &peer_id,
3703 PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003704
Abhishek Singh38da9802018-06-20 16:25:09 +05303705 if (!peer) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003706 WMA_LOGE("%s: Failed to find peer, Not able to validate PN",
3707 __func__);
3708 return true;
3709 }
3710
3711 new_pn = wma_extract_ccmp_pn(ccmp_ptr);
Zhang Qian610a1a72018-04-27 17:03:30 +08003712
Leo Chang96464902016-10-28 11:10:54 -07003713 cdp_get_pn_info(soc, peer, &last_pn_valid, &last_pn, &rmf_pn_replays);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003714
Zhang Qian610a1a72018-04-27 17:03:30 +08003715 if (!last_pn_valid || !last_pn || !rmf_pn_replays) {
3716 WMA_LOGE("%s: PN validation seems not supported", __func__);
Abhishek Singh38da9802018-06-20 16:25:09 +05303717 goto rel_peer_ref;
Zhang Qian610a1a72018-04-27 17:03:30 +08003718 }
3719
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003720 if (*last_pn_valid) {
3721 if (new_pn > *last_pn) {
3722 *last_pn = new_pn;
3723 WMA_LOGE("%s: PN validation successful", __func__);
3724 } else {
3725 WMA_LOGE("%s: PN Replay attack detected", __func__);
3726 /* per 11W amendment, keeping track of replay attacks */
3727 *rmf_pn_replays += 1;
Abhishek Singh38da9802018-06-20 16:25:09 +05303728 ret = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003729 }
3730 } else {
3731 *last_pn_valid = 1;
3732 *last_pn = new_pn;
3733 }
3734
Abhishek Singh38da9802018-06-20 16:25:09 +05303735rel_peer_ref:
3736 cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
3737 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003738}
3739
3740/**
mukul sharma72c8b222015-09-04 17:02:01 +05303741 * wma_process_bip() - process mmie in rmf frame
3742 * @wma_handle: wma handle
3743 * @iface: txrx node
3744 * @wh: 80211 frame
3745 * @wbuf: Buffer
3746 *
3747 * Return: 0 for success or error code
3748 */
3749
3750static
3751int wma_process_bip(tp_wma_handle wma_handle,
3752 struct wma_txrx_node *iface,
3753 struct ieee80211_frame *wh,
Nirav Shahcbc6d722016-03-01 16:24:53 +05303754 qdf_nbuf_t wbuf
mukul sharma72c8b222015-09-04 17:02:01 +05303755)
3756{
Jianmin Zhud46bc462018-07-11 19:14:10 +08003757 uint16_t mmie_size;
mukul sharma72c8b222015-09-04 17:02:01 +05303758 uint16_t key_id;
3759 uint8_t *efrm;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003760 uint8_t *igtk;
3761 uint16_t key_len;
mukul sharma72c8b222015-09-04 17:02:01 +05303762
Nirav Shahcbc6d722016-03-01 16:24:53 +05303763 efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf);
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303764
3765 if (iface->key.key_cipher == WMI_CIPHER_AES_CMAC) {
Jianmin Zhud46bc462018-07-11 19:14:10 +08003766 mmie_size = cds_get_mmie_size();
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303767 } else if (iface->key.key_cipher == WMI_CIPHER_AES_GMAC) {
Jianmin Zhud46bc462018-07-11 19:14:10 +08003768 mmie_size = cds_get_gmac_mmie_size();
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303769 } else {
3770 WMA_LOGE(FL("Invalid key cipher %d"), iface->key.key_cipher);
3771 return -EINVAL;
3772 }
mukul sharma72c8b222015-09-04 17:02:01 +05303773
Jianmin Zhud46bc462018-07-11 19:14:10 +08003774 /* Check if frame is invalid length */
3775 if (efrm - (uint8_t *)wh < sizeof(*wh) + mmie_size) {
3776 WMA_LOGE(FL("Invalid frame length"));
3777 return -EINVAL;
3778 }
3779
3780 key_id = (uint16_t)*(efrm - mmie_size + 2);
mukul sharma72c8b222015-09-04 17:02:01 +05303781 if (!((key_id == WMA_IGTK_KEY_INDEX_4)
3782 || (key_id == WMA_IGTK_KEY_INDEX_5))) {
3783 WMA_LOGE(FL("Invalid KeyID(%d) dropping the frame"), key_id);
3784 return -EINVAL;
3785 }
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303786
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303787 WMA_LOGD(FL("key_cipher %d key_id %d"), iface->key.key_cipher, key_id);
3788
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003789 igtk = wma_get_igtk(iface, &key_len);
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303790 switch (iface->key.key_cipher) {
3791 case WMI_CIPHER_AES_CMAC:
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303792 if (wmi_service_enabled(wma_handle->wmi_handle,
3793 wmi_service_sta_pmf_offload)) {
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303794 /*
3795 * if 11w offload is enabled then mmie validation is
3796 * performed in firmware, host just need to trim the
3797 * mmie.
3798 */
Nirav Shahcbc6d722016-03-01 16:24:53 +05303799 qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
mukul sharma72c8b222015-09-04 17:02:01 +05303800 } else {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003801 if (cds_is_mmie_valid(igtk, iface->key.key_id[
3802 key_id -
3803 WMA_IGTK_KEY_INDEX_4].ipn,
3804 (uint8_t *)wh, efrm)) {
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303805 WMA_LOGD(FL("Protected BC/MC frame MMIE validation successful"));
3806 /* Remove MMIE */
3807 qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
3808 } else {
3809 WMA_LOGD(FL("BC/MC MIC error or MMIE not present, dropping the frame"));
3810 return -EINVAL;
3811 }
3812 }
3813 break;
3814
3815 case WMI_CIPHER_AES_GMAC:
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303816 if (wmi_service_enabled(wma_handle->wmi_handle,
3817 wmi_service_gmac_offload_support)) {
3818 /*
3819 * if gmac offload is enabled then mmie validation is
3820 * performed in firmware, host just need to trim the
3821 * mmie.
3822 */
3823 WMA_LOGD(FL("Trim GMAC MMIE"));
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303824 qdf_nbuf_trim_tail(wbuf, cds_get_gmac_mmie_size());
3825 } else {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003826 if (cds_is_gmac_mmie_valid(igtk,
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303827 iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003828 (uint8_t *) wh, efrm, key_len)) {
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303829 WMA_LOGD(FL("Protected BC/MC frame GMAC MMIE validation successful"));
3830 /* Remove MMIE */
3831 qdf_nbuf_trim_tail(wbuf,
3832 cds_get_gmac_mmie_size());
3833 } else {
3834 WMA_LOGD(FL("BC/MC GMAC MIC error or MMIE not present, dropping the frame"));
3835 return -EINVAL;
3836 }
mukul sharma72c8b222015-09-04 17:02:01 +05303837 }
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303838 break;
3839
3840 default:
3841 WMA_LOGE(FL("Unsupported key cipher %d"),
3842 iface->key.key_cipher);
mukul sharma72c8b222015-09-04 17:02:01 +05303843 }
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303844
3845
mukul sharma72c8b222015-09-04 17:02:01 +05303846 return 0;
3847}
3848
3849/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003850 * wma_process_rmf_frame() - process rmf frame
3851 * @wma_handle: wma handle
3852 * @iface: txrx node
3853 * @wh: 80211 frame
3854 * @rx_pkt: rx packet
3855 * @wbuf: Buffer
3856 *
3857 * Return: 0 for success or error code
3858 */
3859static
3860int wma_process_rmf_frame(tp_wma_handle wma_handle,
3861 struct wma_txrx_node *iface,
3862 struct ieee80211_frame *wh,
3863 cds_pkt_t *rx_pkt,
Nirav Shahcbc6d722016-03-01 16:24:53 +05303864 qdf_nbuf_t wbuf)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003865{
mukul sharma72c8b222015-09-04 17:02:01 +05303866 uint8_t *orig_hdr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003867 uint8_t *ccmp;
Abhishek Singh7c1c7432019-04-04 12:11:57 +05303868 uint8_t mic_len, hdr_len, pdev_id;
3869 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003870
3871 if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) {
Srinivas Girigowda9cd6c342019-02-09 13:06:12 -08003872 if (QDF_IS_ADDR_BROADCAST(wh->i_addr1) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873 IEEE80211_IS_MULTICAST(wh->i_addr1)) {
3874 WMA_LOGE("Encrypted BC/MC frame dropping the frame");
3875 cds_pkt_return_packet(rx_pkt);
3876 return -EINVAL;
3877 }
Abhishek Singh7c1c7432019-04-04 12:11:57 +05303878
3879 pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev);
3880 status = mlme_get_peer_mic_len(wma_handle->psoc, pdev_id,
3881 wh->i_addr2, &mic_len,
3882 &hdr_len);
3883 if (QDF_IS_STATUS_ERROR(status)) {
3884 WMA_LOGE("Failed to get mic hdr and length");
3885 cds_pkt_return_packet(rx_pkt);
3886 return -EINVAL;
3887 }
3888
3889 if (qdf_nbuf_len(wbuf) < (sizeof(*wh) + hdr_len + mic_len)) {
3890 WMA_LOGE("Buffer length less than expected %d",
3891 (int)qdf_nbuf_len(wbuf));
3892 cds_pkt_return_packet(rx_pkt);
3893 return -EINVAL;
3894 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003895
Nirav Shahcbc6d722016-03-01 16:24:53 +05303896 orig_hdr = (uint8_t *) qdf_nbuf_data(wbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003897 /* Pointer to head of CCMP header */
3898 ccmp = orig_hdr + sizeof(*wh);
3899 if (wma_is_ccmp_pn_replay_attack(
3900 wma_handle, wh, ccmp)) {
3901 WMA_LOGE("Dropping the frame");
3902 cds_pkt_return_packet(rx_pkt);
3903 return -EINVAL;
3904 }
3905
3906 /* Strip privacy headers (and trailer)
3907 * for a received frame
3908 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303909 qdf_mem_move(orig_hdr +
Himanshu Agarwalfc5d6602018-04-06 17:39:37 +05303910 hdr_len, wh,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003911 sizeof(*wh));
Nirav Shahcbc6d722016-03-01 16:24:53 +05303912 qdf_nbuf_pull_head(wbuf,
Himanshu Agarwalfc5d6602018-04-06 17:39:37 +05303913 hdr_len);
3914 qdf_nbuf_trim_tail(wbuf, mic_len);
Krunal Soni54da0c62016-08-01 17:04:25 -07003915 /*
3916 * CCMP header has been pulled off
3917 * reinitialize the start pointer of mac header
3918 * to avoid accessing incorrect address
3919 */
3920 wh = (struct ieee80211_frame *) qdf_nbuf_data(wbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003921 rx_pkt->pkt_meta.mpdu_hdr_ptr =
Nirav Shahcbc6d722016-03-01 16:24:53 +05303922 qdf_nbuf_data(wbuf);
3923 rx_pkt->pkt_meta.mpdu_len = qdf_nbuf_len(wbuf);
Arif Hussain3d731ab2017-10-12 12:40:16 -07003924 rx_pkt->pkt_buf = wbuf;
3925 if (rx_pkt->pkt_meta.mpdu_len >=
3926 rx_pkt->pkt_meta.mpdu_hdr_len) {
3927 rx_pkt->pkt_meta.mpdu_data_len =
3928 rx_pkt->pkt_meta.mpdu_len -
3929 rx_pkt->pkt_meta.mpdu_hdr_len;
3930 } else {
3931 WMA_LOGE("mpdu len %d less than hdr %d, dropping frame",
3932 rx_pkt->pkt_meta.mpdu_len,
3933 rx_pkt->pkt_meta.mpdu_hdr_len);
3934 cds_pkt_return_packet(rx_pkt);
3935 return -EINVAL;
3936 }
3937
3938 if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
3939 WMA_LOGE("Data Len %d greater than max, dropping frame",
3940 rx_pkt->pkt_meta.mpdu_data_len);
3941 cds_pkt_return_packet(rx_pkt);
3942 return -EINVAL;
3943 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003944 rx_pkt->pkt_meta.mpdu_data_ptr =
3945 rx_pkt->pkt_meta.mpdu_hdr_ptr +
3946 rx_pkt->pkt_meta.mpdu_hdr_len;
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003947 wma_debug("BSSID: "QDF_MAC_ADDR_STR" tsf_delta: %u",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003948 QDF_MAC_ADDR_ARRAY(wh->i_addr3),
3949 rx_pkt->pkt_meta.tsf_delta);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003950 } else {
Srinivas Girigowda9cd6c342019-02-09 13:06:12 -08003951 if (QDF_IS_ADDR_BROADCAST(wh->i_addr1) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003952 IEEE80211_IS_MULTICAST(wh->i_addr1)) {
mukul sharma72c8b222015-09-04 17:02:01 +05303953 if (0 != wma_process_bip(wma_handle, iface, wh, wbuf)) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003954 cds_pkt_return_packet(rx_pkt);
3955 return -EINVAL;
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05303956 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003957 } else {
3958 WMA_LOGE("Rx unprotected unicast mgmt frame");
3959 rx_pkt->pkt_meta.dpuFeedback =
3960 DPU_FEEDBACK_UNPROTECTED_ERROR;
3961 }
3962 }
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003963 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003964}
Abhishek Singhcfb44482017-03-10 12:42:37 +05303965#else
3966static inline int wma_process_rmf_frame(tp_wma_handle wma_handle,
3967 struct wma_txrx_node *iface,
3968 struct ieee80211_frame *wh,
3969 cds_pkt_t *rx_pkt,
3970 qdf_nbuf_t wbuf)
3971{
3972 return 0;
3973}
3974
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003975#endif
3976
3977/**
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07003978 * wma_is_pkt_drop_candidate() - check if the mgmt frame should be droppped
3979 * @wma_handle: wma handle
3980 * @peer_addr: peer MAC address
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07003981 * @bssid: BSSID Address
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07003982 * @subtype: Management frame subtype
3983 *
3984 * This function is used to decide if a particular management frame should be
3985 * dropped to prevent DOS attack. Timestamp is used to decide the DOS attack.
3986 *
3987 * Return: true if the packet should be dropped and false oterwise
3988 */
3989static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle,
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07003990 uint8_t *peer_addr, uint8_t *bssid,
3991 uint8_t subtype)
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07003992{
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07003993 bool should_drop = false;
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07003994 uint8_t nan_addr[] = {0x50, 0x6F, 0x9A, 0x01, 0x00, 0x00};
3995
3996 /* Drop the beacons from NAN device */
Srinivas Girigowdadf90cea2019-03-07 16:03:25 -08003997 if ((subtype == MGMT_SUBTYPE_BEACON) &&
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07003998 (!qdf_mem_cmp(nan_addr, bssid, NAN_CLUSTER_ID_BYTES))) {
3999 should_drop = true;
4000 goto end;
4001 }
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004002end:
4003 return should_drop;
4004}
4005
Naveen Rawat73532d62017-05-22 10:37:52 -07004006#define RATE_LIMIT 16
4007
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304008int wma_form_rx_packet(qdf_nbuf_t buf,
Himanshu Agarwald2e6cde2017-01-10 14:47:04 +05304009 struct mgmt_rx_event_params *mgmt_rx_params,
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304010 cds_pkt_t *rx_pkt)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004011{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004012 struct wma_txrx_node *iface = NULL;
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304013 uint8_t vdev_id = WMA_INVALID_VDEV_ID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004014 struct ieee80211_frame *wh;
4015 uint8_t mgt_type, mgt_subtype;
4016 int status;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304017 tp_wma_handle wma_handle = (tp_wma_handle)
4018 cds_get_context(QDF_MODULE_ID_WMA);
Jingxiang Gebd540b12019-03-13 14:58:52 +08004019#if !defined(REMOVE_PKT_LOG)
4020 ol_txrx_pktdump_cb packetdump_cb;
4021 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4022 struct cdp_vdev *txrx_vdev;
4023#endif
Naveen Rawat73532d62017-05-22 10:37:52 -07004024 static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1;
4025 static uint8_t limit_prints_load_unload = RATE_LIMIT - 1;
4026 static uint8_t limit_prints_recovery = RATE_LIMIT - 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004027
4028 if (!wma_handle) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304029 WMA_LOGE(FL("wma handle is NULL"));
4030 qdf_nbuf_free(buf);
4031 qdf_mem_free(rx_pkt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004032 return -EINVAL;
4033 }
4034
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304035 if (!mgmt_rx_params) {
Naveen Rawat73532d62017-05-22 10:37:52 -07004036 limit_prints_invalid_len++;
4037 if (limit_prints_invalid_len == RATE_LIMIT) {
4038 WMA_LOGD(FL("mgmt rx params is NULL"));
4039 limit_prints_invalid_len = 0;
4040 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304041 qdf_nbuf_free(buf);
4042 qdf_mem_free(rx_pkt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004043 return -EINVAL;
4044 }
4045
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08004046 if (cds_is_load_or_unload_in_progress()) {
Naveen Rawat73532d62017-05-22 10:37:52 -07004047 limit_prints_load_unload++;
4048 if (limit_prints_load_unload == RATE_LIMIT) {
4049 WMA_LOGD(FL("Load/Unload in progress"));
4050 limit_prints_load_unload = 0;
4051 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304052 qdf_nbuf_free(buf);
4053 qdf_mem_free(rx_pkt);
Naveen Rawat10ccf872015-11-03 14:15:55 -08004054 return -EINVAL;
4055 }
4056
Mukul Sharma80edc782016-09-12 15:59:24 +05304057 if (cds_is_driver_recovering()) {
Naveen Rawat73532d62017-05-22 10:37:52 -07004058 limit_prints_recovery++;
4059 if (limit_prints_recovery == RATE_LIMIT) {
4060 WMA_LOGD(FL("Recovery in progress"));
4061 limit_prints_recovery = 0;
4062 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304063 qdf_nbuf_free(buf);
4064 qdf_mem_free(rx_pkt);
Mukul Sharma80edc782016-09-12 15:59:24 +05304065 return -EINVAL;
4066 }
4067
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05304068 if (cds_is_driver_in_bad_state()) {
4069 limit_prints_recovery++;
4070 if (limit_prints_recovery == RATE_LIMIT) {
4071 WMA_LOGD(FL("Driver in bad state"));
4072 limit_prints_recovery = 0;
4073 }
4074 qdf_nbuf_free(buf);
4075 qdf_mem_free(rx_pkt);
4076 return -EINVAL;
4077 }
4078
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004079 /*
4080 * Fill in meta information needed by pe/lim
4081 * TODO: Try to maintain rx metainfo as part of skb->data.
4082 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304083 rx_pkt->pkt_meta.channel = mgmt_rx_params->channel;
4084 rx_pkt->pkt_meta.scan_src = mgmt_rx_params->flags;
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -07004085
4086 /*
4087 * Get the rssi value from the current snr value
4088 * using standard noise floor of -96.
4089 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304090 rx_pkt->pkt_meta.rssi = mgmt_rx_params->snr +
4091 WMA_NOISE_FLOOR_DBM_DEFAULT;
4092 rx_pkt->pkt_meta.snr = mgmt_rx_params->snr;
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -07004093
4094 /* If absolute rssi is available from firmware, use it */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304095 if (mgmt_rx_params->rssi != 0)
4096 rx_pkt->pkt_meta.rssi_raw = mgmt_rx_params->rssi;
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -07004097 else
4098 rx_pkt->pkt_meta.rssi_raw = rx_pkt->pkt_meta.rssi;
4099
4100
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004101 /*
4102 * FIXME: Assigning the local timestamp as hw timestamp is not
4103 * available. Need to see if pe/lim really uses this data.
4104 */
4105 rx_pkt->pkt_meta.timestamp = (uint32_t) jiffies;
4106 rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304107 rx_pkt->pkt_meta.mpdu_len = mgmt_rx_params->buf_len;
Vignesh Viswanathanea432dd2018-04-30 14:06:15 +05304108
4109 /*
4110 * The buf_len should be at least 802.11 header len
4111 */
4112 if (mgmt_rx_params->buf_len < rx_pkt->pkt_meta.mpdu_hdr_len) {
4113 WMA_LOGE("MPDU Len %d lesser than header len %d",
4114 mgmt_rx_params->buf_len,
4115 rx_pkt->pkt_meta.mpdu_hdr_len);
4116 qdf_nbuf_free(buf);
4117 qdf_mem_free(rx_pkt);
4118 return -EINVAL;
4119 }
4120
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304121 rx_pkt->pkt_meta.mpdu_data_len = mgmt_rx_params->buf_len -
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004122 rx_pkt->pkt_meta.mpdu_hdr_len;
4123
4124 rx_pkt->pkt_meta.roamCandidateInd = 0;
4125
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304126 wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004127
Vignesh Viswanathan56f26252017-08-31 15:26:01 +05304128 /*
4129 * If the mpdu_data_len is greater than Max (2k), drop the frame
4130 */
4131 if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004132 wma_err("Data Len %d greater than max, dropping frame from "QDF_MAC_ADDR_STR,
Vignesh Viswanathan56f26252017-08-31 15:26:01 +05304133 rx_pkt->pkt_meta.mpdu_data_len,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004134 QDF_MAC_ADDR_ARRAY(wh->i_addr3));
Vignesh Viswanathan56f26252017-08-31 15:26:01 +05304135 qdf_nbuf_free(buf);
4136 qdf_mem_free(rx_pkt);
4137 return -EINVAL;
4138 }
4139
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304140 rx_pkt->pkt_meta.mpdu_hdr_ptr = qdf_nbuf_data(buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr +
4142 rx_pkt->pkt_meta.mpdu_hdr_len;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304143 rx_pkt->pkt_meta.tsf_delta = mgmt_rx_params->tsf_delta;
4144 rx_pkt->pkt_buf = buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004145
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004146 /* If it is a beacon/probe response, save it for future use */
4147 mgt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4148 mgt_subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
4149
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004150 if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
Srinivas Girigowdadf90cea2019-03-07 16:03:25 -08004151 (mgt_subtype == MGMT_SUBTYPE_DISASSOC ||
4152 mgt_subtype == MGMT_SUBTYPE_DEAUTH ||
4153 mgt_subtype == MGMT_SUBTYPE_ACTION)) {
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304154 if (wma_find_vdev_by_bssid(
4155 wma_handle, wh->i_addr3, &vdev_id)) {
4156 iface = &(wma_handle->interfaces[vdev_id]);
4157 if (iface->rmfEnabled) {
4158 status = wma_process_rmf_frame(wma_handle,
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304159 iface, wh, rx_pkt, buf);
4160 if (status != 0)
4161 return status;
Krunal Soni54da0c62016-08-01 17:04:25 -07004162 /*
4163 * CCMP header might have been pulled off
4164 * reinitialize the start pointer of mac header
4165 */
4166 wh = (struct ieee80211_frame *)
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304167 qdf_nbuf_data(buf);
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304168 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004169 }
4170 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304171
Jingxiang Ge45a24332019-03-11 10:46:47 +08004172 rx_pkt->pkt_meta.session_id =
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304173 (vdev_id == WMA_INVALID_VDEV_ID ? 0 : vdev_id);
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004174
Sandeep Puligilla2a206c52017-05-25 01:05:49 -07004175 if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
Srinivas Girigowdadf90cea2019-03-07 16:03:25 -08004176 (mgt_subtype == MGMT_SUBTYPE_BEACON ||
4177 mgt_subtype == MGMT_SUBTYPE_PROBE_RESP)) {
Sandeep Puligilla2a206c52017-05-25 01:05:49 -07004178 if (mgmt_rx_params->buf_len <=
4179 (sizeof(struct ieee80211_frame) +
4180 offsetof(struct wlan_bcn_frame, ie))) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004181 wma_debug("Dropping frame from "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004182 QDF_MAC_ADDR_ARRAY(wh->i_addr3));
Sandeep Puligilla2a206c52017-05-25 01:05:49 -07004183 cds_pkt_return_packet(rx_pkt);
4184 return -EINVAL;
4185 }
4186 }
4187
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07004188 if (wma_is_pkt_drop_candidate(wma_handle, wh->i_addr2, wh->i_addr3,
4189 mgt_subtype)) {
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004190 cds_pkt_return_packet(rx_pkt);
4191 return -EINVAL;
4192 }
4193
Jingxiang Gebd540b12019-03-13 14:58:52 +08004194#if !defined(REMOVE_PKT_LOG)
Himanshu Agarwalbb226bc2017-01-18 20:45:01 +05304195 packetdump_cb = wma_handle->wma_mgmt_rx_packetdump_cb;
Jingxiang Gebd540b12019-03-13 14:58:52 +08004196 txrx_vdev = wma_find_vdev_by_id(wma_handle,
4197 rx_pkt->pkt_meta.session_id);
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304198 if ((mgt_type == IEEE80211_FC0_TYPE_MGT &&
Jingxiang Gebd540b12019-03-13 14:58:52 +08004199 mgt_subtype != MGMT_SUBTYPE_BEACON) &&
4200 packetdump_cb)
4201 packetdump_cb(soc, txrx_vdev, rx_pkt->pkt_buf,
4202 QDF_STATUS_SUCCESS, RX_MGMT_PKT);
4203#endif
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304204 return 0;
4205}
4206
4207/**
4208 * wma_mem_endianness_based_copy() - does memory copy from src to dst
4209 * @dst: destination address
4210 * @src: source address
4211 * @size: size to be copied
4212 *
4213 * This function copies the memory of size passed from source
4214 * address to destination address.
4215 *
4216 * Return: Nothing
4217 */
4218#ifdef BIG_ENDIAN_HOST
4219static void wma_mem_endianness_based_copy(
4220 uint8_t *dst, uint8_t *src, uint32_t size)
4221{
4222 /*
4223 * For big endian host, copy engine byte_swap is enabled
4224 * But the rx mgmt frame buffer content is in network byte order
4225 * Need to byte swap the mgmt frame buffer content - so when
4226 * copy engine does byte_swap - host gets buffer content in the
4227 * correct byte order.
4228 */
4229
4230 uint32_t i;
4231 uint32_t *destp, *srcp;
4232
4233 destp = (uint32_t *) dst;
4234 srcp = (uint32_t *) src;
4235 for (i = 0; i < (roundup(size, sizeof(uint32_t)) / 4); i++) {
4236 *destp = cpu_to_le32(*srcp);
4237 destp++;
4238 srcp++;
4239 }
4240}
4241#else
4242static void wma_mem_endianness_based_copy(
4243 uint8_t *dst, uint8_t *src, uint32_t size)
4244{
4245 qdf_mem_copy(dst, src, size);
4246}
4247#endif
4248
gaurank kathpaliad84b0052018-05-08 17:39:44 +05304249#define RESERVE_BYTES 100
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304250/**
4251 * wma_mgmt_rx_process() - process management rx frame.
4252 * @handle: wma handle
4253 * @data: rx data
4254 * @data_len: data length
4255 *
4256 * Return: 0 for success or error code
4257 */
4258static int wma_mgmt_rx_process(void *handle, uint8_t *data,
4259 uint32_t data_len)
4260{
4261 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Himanshu Agarwald2e6cde2017-01-10 14:47:04 +05304262 struct mgmt_rx_event_params *mgmt_rx_params;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304263 struct wlan_objmgr_psoc *psoc;
4264 uint8_t *bufp;
4265 qdf_nbuf_t wbuf;
4266 QDF_STATUS status;
4267
4268 if (!wma_handle) {
4269 WMA_LOGE("%s: Failed to get WMA context", __func__);
4270 return -EINVAL;
4271 }
4272
4273 mgmt_rx_params = qdf_mem_malloc(sizeof(*mgmt_rx_params));
4274 if (!mgmt_rx_params) {
4275 WMA_LOGE("%s: memory allocation failed", __func__);
4276 return -ENOMEM;
4277 }
4278
4279 if (wmi_extract_mgmt_rx_params(wma_handle->wmi_handle,
4280 data, mgmt_rx_params, &bufp) != QDF_STATUS_SUCCESS) {
4281 WMA_LOGE("%s: Extraction of mgmt rx params failed", __func__);
4282 qdf_mem_free(mgmt_rx_params);
4283 return -EINVAL;
4284 }
4285
Jingxiang Ge04c94502017-10-18 17:05:40 +08004286 if (mgmt_rx_params->buf_len > data_len) {
4287 WMA_LOGE("%s: Invalid rx mgmt packet, data_len %u, mgmt_rx_params->buf_len %u",
4288 __func__, data_len, mgmt_rx_params->buf_len);
Jiachao Wu418b7ae2018-02-02 16:01:04 +08004289 qdf_mem_free(mgmt_rx_params);
Jingxiang Ge04c94502017-10-18 17:05:40 +08004290 return -EINVAL;
4291 }
4292
Himanshu Agarwald2e6cde2017-01-10 14:47:04 +05304293 mgmt_rx_params->pdev_id = 0;
4294 mgmt_rx_params->rx_params = NULL;
4295
gaurank kathpaliad84b0052018-05-08 17:39:44 +05304296 /*
4297 * Allocate the memory for this rx packet, add extra 100 bytes for:-
4298 *
4299 * 1. Filling the missing RSN capabilites by some APs, which fill the
4300 * RSN IE length as extra 2 bytes but dont fill the IE data with
4301 * capabilities, resulting in failure in unpack core due to length
4302 * mismatch. Check sir_validate_and_rectify_ies for more info.
4303 *
4304 * 2. In the API wma_process_rmf_frame(), the driver trims the CCMP
4305 * header by overwriting the IEEE header to memory occupied by CCMP
4306 * header, but an overflow is possible if the memory allocated to
4307 * frame is less than the sizeof(struct ieee80211_frame) +CCMP
4308 * HEADER len, so allocating 100 bytes would solve this issue too.
4309 *
4310 * 3. CCMP header is pointing to orig_hdr +
4311 * sizeof(struct ieee80211_frame) which could also result in OOB
4312 * access, if the data len is less than
4313 * sizeof(struct ieee80211_frame), allocating extra bytes would
4314 * result in solving this issue too.
4315 */
4316 wbuf = qdf_nbuf_alloc(NULL, roundup(mgmt_rx_params->buf_len +
4317 RESERVE_BYTES,
4318 4), 0, 4, false);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304319 if (!wbuf) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304320 qdf_mem_free(mgmt_rx_params);
4321 return -ENOMEM;
4322 }
4323
4324 qdf_nbuf_put_tail(wbuf, mgmt_rx_params->buf_len);
4325 qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL);
4326
Pragaspathi Thilagarajb3bceade2018-06-05 17:11:35 +05304327 qdf_mem_zero(((uint8_t *)qdf_nbuf_data(wbuf) + mgmt_rx_params->buf_len),
4328 (roundup(mgmt_rx_params->buf_len + RESERVE_BYTES, 4) -
4329 mgmt_rx_params->buf_len));
4330
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304331 wma_mem_endianness_based_copy(qdf_nbuf_data(wbuf),
4332 bufp, mgmt_rx_params->buf_len);
4333
4334 psoc = (struct wlan_objmgr_psoc *)
4335 wma_handle->psoc;
4336 if (!psoc) {
4337 WMA_LOGE("%s: psoc ctx is NULL", __func__);
4338 qdf_nbuf_free(wbuf);
4339 qdf_mem_free(mgmt_rx_params);
4340 return -EINVAL;
4341 }
4342
Himanshu Agarwal795b7f72017-01-17 21:19:43 +05304343 status = mgmt_txrx_rx_handler(psoc, wbuf, mgmt_rx_params);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304344 if (status != QDF_STATUS_SUCCESS) {
Amar Singhaldc5ae4d2018-10-02 14:29:37 -07004345 wma_err_rl("Failed to process mgmt rx frame");
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304346 qdf_mem_free(mgmt_rx_params);
4347 return -EINVAL;
4348 }
4349
4350 qdf_mem_free(mgmt_rx_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004351 return 0;
4352}
4353
4354/**
4355 * wma_de_register_mgmt_frm_client() - deregister management frame
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304356 *
4357 * This function deregisters the event handler registered for
4358 * WMI_MGMT_RX_EVENTID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004359 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304360 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004361 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304362QDF_STATUS wma_de_register_mgmt_frm_client(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004363{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304364 tp_wma_handle wma_handle = (tp_wma_handle)
4365 cds_get_context(QDF_MODULE_ID_WMA);
4366
4367 if (!wma_handle) {
4368 WMA_LOGE("%s: Failed to get WMA context", __func__);
4369 return QDF_STATUS_E_NULL_VALUE;
4370 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004371
4372#ifdef QCA_WIFI_FTM
Anurag Chouhan6d760662016-02-20 16:05:43 +05304373 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304374 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004375#endif
4376
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004377 if (wmi_unified_unregister_event_handler(wma_handle->wmi_handle,
Mukul Sharma228223a2017-11-03 19:25:39 +05304378 wmi_mgmt_rx_event_id) != 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004379 WMA_LOGE("Failed to Unregister rx mgmt handler with wmi");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304380 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004381 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304382 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004383}
4384
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08004385#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004386/**
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004387 * wma_register_roaming_callbacks() - Register roaming callbacks
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004388 * @csr_roam_synch_cb: CSR roam synch callback routine pointer
4389 * @pe_roam_synch_cb: PE roam synch callback routine pointer
4390 *
4391 * Register the SME and PE callback routines with WMA for
4392 * handling roaming
4393 *
4394 * Return: Success or Failure Status
4395 */
Jeff Johnsona9b66572017-09-02 12:41:21 -07004396QDF_STATUS wma_register_roaming_callbacks(
Jeff Johnson9f18aa72018-12-02 12:05:12 -08004397 QDF_STATUS (*csr_roam_synch_cb)(struct mac_context *mac,
Jeff Johnsona7f41dd2019-02-06 22:54:55 -08004398 struct roam_offload_synch_ind *roam_synch_data,
Pragaspathi Thilagaraj1d8e2ab2019-03-04 23:59:21 +05304399 struct bss_description *bss_desc_ptr,
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07004400 enum sir_roam_op_code reason),
Jeff Johnson9f18aa72018-12-02 12:05:12 -08004401 QDF_STATUS (*pe_roam_synch_cb)(struct mac_context *mac,
Jeff Johnsona7f41dd2019-02-06 22:54:55 -08004402 struct roam_offload_synch_ind *roam_synch_data,
Pragaspathi Thilagaraj1d8e2ab2019-03-04 23:59:21 +05304403 struct bss_description *bss_desc_ptr,
Pragaspathi Thilagarajb0176502019-04-26 02:33:13 +05304404 enum sir_roam_op_code reason),
4405 QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
4406 uint8_t vdev_id))
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004407{
4408
Anurag Chouhan6d760662016-02-20 16:05:43 +05304409 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004410
4411 if (!wma) {
4412 WMA_LOGE("%s: Failed to get WMA context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304413 return QDF_STATUS_E_FAILURE;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004414 }
4415 wma->csr_roam_synch_cb = csr_roam_synch_cb;
4416 wma->pe_roam_synch_cb = pe_roam_synch_cb;
Pragaspathi Thilagarajb0176502019-04-26 02:33:13 +05304417 wma->pe_disconnect_cb = pe_disconnect_cb;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004418 WMA_LOGD("Registered roam synch callbacks with WMA successfully");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304419 return QDF_STATUS_SUCCESS;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004420}
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08004421#endif
4422
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004423/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004424 * wma_register_mgmt_frm_client() - register management frame callback
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304425 *
4426 * This function registers event handler for WMI_MGMT_RX_EVENTID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004427 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304428 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004429 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304430QDF_STATUS wma_register_mgmt_frm_client(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004431{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304432 tp_wma_handle wma_handle = (tp_wma_handle)
4433 cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004434
4435 if (!wma_handle) {
4436 WMA_LOGE("%s: Failed to get WMA context", __func__);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304437 return QDF_STATUS_E_NULL_VALUE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004438 }
4439
4440 if (wmi_unified_register_event_handler(wma_handle->wmi_handle,
Mukul Sharma228223a2017-11-03 19:25:39 +05304441 wmi_mgmt_rx_event_id,
Govind Singhd76a5b02016-03-08 15:12:14 +05304442 wma_mgmt_rx_process,
4443 WMA_RX_WORK_CTX) != 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004444 WMA_LOGE("Failed to register rx mgmt handler with wmi");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304445 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004446 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004447
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304448 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004449}
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304450
4451/**
4452 * wma_register_packetdump_callback() - stores tx and rx mgmt packet dump
4453 * callback handler
Jingxiang Gebd540b12019-03-13 14:58:52 +08004454 * @tx_cb: tx mgmt packetdump cb
4455 * @rx_cb: rx mgmt packetdump cb
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304456 *
4457 * This function is used to store tx and rx mgmt. packet dump callback
4458 *
4459 * Return: None
4460 *
4461 */
4462void wma_register_packetdump_callback(
Jingxiang Gebd540b12019-03-13 14:58:52 +08004463 ol_txrx_pktdump_cb tx_cb,
4464 ol_txrx_pktdump_cb rx_cb)
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304465{
4466 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4467
4468 if (!wma_handle) {
4469 WMA_LOGE("wma handle is NULL");
4470 return;
4471 }
4472
Jingxiang Gebd540b12019-03-13 14:58:52 +08004473 wma_handle->wma_mgmt_tx_packetdump_cb = tx_cb;
4474 wma_handle->wma_mgmt_rx_packetdump_cb = rx_cb;
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304475}
4476
4477/**
4478 * wma_deregister_packetdump_callback() - removes tx and rx mgmt packet dump
4479 * callback handler
4480 *
4481 * This function is used to remove tx and rx mgmt. packet dump callback
4482 *
4483 * Return: None
4484 *
4485 */
4486void wma_deregister_packetdump_callback(void)
4487{
4488 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4489
4490 if (!wma_handle) {
4491 WMA_LOGE("wma handle is NULL");
4492 return;
4493 }
4494
4495 wma_handle->wma_mgmt_tx_packetdump_cb = NULL;
4496 wma_handle->wma_mgmt_rx_packetdump_cb = NULL;
4497}
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304498
4499QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev,
4500 qdf_nbuf_t buf, uint32_t desc_id,
4501 void *mgmt_tx_params)
4502{
4503 tp_wma_handle wma_handle;
Wu Gaob422f772018-07-05 11:34:36 +08004504 int ret;
4505 QDF_STATUS status = QDF_STATUS_E_INVAL;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304506 struct wmi_mgmt_params *mgmt_params =
4507 (struct wmi_mgmt_params *)mgmt_tx_params;
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304508 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4509 struct cdp_vdev *txrx_vdev;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304510
4511 if (!mgmt_params) {
4512 WMA_LOGE("%s: mgmt_params ptr passed is NULL", __func__);
4513 return QDF_STATUS_E_INVAL;
4514 }
4515 mgmt_params->desc_id = desc_id;
4516
4517 if (!vdev) {
4518 WMA_LOGE("%s: vdev ptr passed is NULL", __func__);
4519 return QDF_STATUS_E_INVAL;
4520 }
4521
4522 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4523 if (!wma_handle) {
4524 WMA_LOGE("%s: wma handle is NULL", __func__);
4525 return QDF_STATUS_E_INVAL;
4526 }
4527
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304528 txrx_vdev = wma_handle->interfaces[mgmt_params->vdev_id].handle;
4529
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304530 if (wmi_service_enabled(wma_handle->wmi_handle,
4531 wmi_service_mgmt_tx_wmi)) {
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304532 status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle,
4533 mgmt_params);
Wu Gaob422f772018-07-05 11:34:36 +08004534 } else if (txrx_vdev) {
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304535 QDF_NBUF_CB_MGMT_TXRX_DESC_ID(buf)
4536 = mgmt_params->desc_id;
4537
Wu Gaob422f772018-07-05 11:34:36 +08004538 ret = cdp_mgmt_send_ext(soc, txrx_vdev, buf,
4539 mgmt_params->tx_type,
4540 mgmt_params->use_6mbps,
4541 mgmt_params->chanfreq);
4542 status = qdf_status_from_os_return(ret);
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304543 }
4544
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304545 if (status != QDF_STATUS_SUCCESS) {
4546 WMA_LOGE("%s: mgmt tx failed", __func__);
4547 return status;
4548 }
4549
4550 return QDF_STATUS_SUCCESS;
4551}
4552
Ajit Pal Singh6190ca22018-11-08 16:37:43 +05304553#ifndef CONFIG_HL_SUPPORT
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304554void wma_mgmt_nbuf_unmap_cb(struct wlan_objmgr_pdev *pdev,
4555 qdf_nbuf_t buf)
4556{
Sravan Kumar Kairam0ebf4532018-09-19 14:12:59 +05304557 struct wlan_objmgr_psoc *psoc;
4558 qdf_device_t dev;
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304559
4560 if (!buf)
4561 return;
4562
Sravan Kumar Kairam0ebf4532018-09-19 14:12:59 +05304563 psoc = wlan_pdev_get_psoc(pdev);
4564 if (!psoc) {
4565 WMA_LOGE("%s: Psoc handle NULL", __func__);
4566 return;
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304567 }
Sravan Kumar Kairam0ebf4532018-09-19 14:12:59 +05304568
4569 dev = wlan_psoc_get_qdf_dev(psoc);
4570 if (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_WMI_MGMT_REF))
4571 qdf_nbuf_unmap_single(dev, buf, QDF_DMA_TO_DEVICE);
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304572}
Ajit Pal Singh6190ca22018-11-08 16:37:43 +05304573#endif