blob: 8b125b3514899b4518750a6ff69f0556b2d6985e [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>
Jianmin Zhudd405692019-09-08 10:32:55 +080081#include <../../core/src/vdev_mgr_ops.h>
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070082
Alok Kumar1ff46df2019-07-17 15:01:47 +053083#if !defined(REMOVE_PKT_LOG)
84#include <wlan_logging_sock_svc.h>
85#endif
86
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087/**
88 * wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL
89 * @wma: wma handle
90 * @pdev: txrx pdev
91 * @vdev_id: vdev id
92 * @param_buf: SWBA parameters
93 *
94 * Return: none
95 */
Liangwei Dong03e080c2019-07-02 17:06:39 +080096#ifdef WLAN_WMI_BCN
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097static void wma_send_bcn_buf_ll(tp_wma_handle wma,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080098 struct cdp_pdev *pdev,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099 uint8_t vdev_id,
100 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf)
101{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102 struct ieee80211_frame *wh;
103 struct beacon_info *bcn;
104 wmi_tim_info *tim_info = param_buf->tim_info;
105 uint8_t *bcn_payload;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530106 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107 struct beacon_tim_ie *tim_ie;
108 wmi_p2p_noa_info *p2p_noa_info = param_buf->p2p_noa_info;
109 struct p2p_sub_element_noa noa_ie;
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530110 struct wmi_bcn_send_from_host params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800111 uint8_t i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800112
113 bcn = wma->interfaces[vdev_id].beacon;
Bala Venkateshd267bf82018-10-26 13:56:25 +0530114 if (!bcn || !bcn->buf) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 WMA_LOGE("%s: Invalid beacon buffer", __func__);
116 return;
117 }
Abhinav Kumare48f34d2018-10-12 14:44:44 +0530118
119 if (!param_buf->tim_info || !param_buf->p2p_noa_info) {
120 WMA_LOGE("%s: Invalid tim info or p2p noa info", __func__);
121 return;
122 }
123
Varun Reddy Yeturu0a2c3102017-09-27 21:17:54 -0700124 if (WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info) >
125 WMI_P2P_MAX_NOA_DESCRIPTORS) {
126 WMA_LOGE("%s: Too many descriptors %d", __func__,
127 WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info));
128 return;
129 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800130
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530131 qdf_spin_lock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800132
Nirav Shahcbc6d722016-03-01 16:24:53 +0530133 bcn_payload = qdf_nbuf_data(bcn->buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800134
135 tim_ie = (struct beacon_tim_ie *)(&bcn_payload[bcn->tim_ie_offset]);
136
137 if (tim_info->tim_changed) {
138 if (tim_info->tim_num_ps_pending)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530139 qdf_mem_copy(&tim_ie->tim_bitmap, tim_info->tim_bitmap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800140 WMA_TIM_SUPPORTED_PVB_LENGTH);
141 else
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530142 qdf_mem_zero(&tim_ie->tim_bitmap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800143 WMA_TIM_SUPPORTED_PVB_LENGTH);
144 /*
145 * Currently we support fixed number of
146 * peers as limited by HAL_NUM_STA.
147 * tim offset is always 0
148 */
149 tim_ie->tim_bitctl = 0;
150 }
151
152 /* Update DTIM Count */
153 if (tim_ie->dtim_count == 0)
154 tim_ie->dtim_count = tim_ie->dtim_period - 1;
155 else
156 tim_ie->dtim_count--;
157
158 /*
159 * DTIM count needs to be backedup so that
160 * when umac updates the beacon template
161 * current dtim count can be updated properly
162 */
163 bcn->dtim_count = tim_ie->dtim_count;
164
165 /* update state for buffered multicast frames on DTIM */
166 if (tim_info->tim_mcast && (tim_ie->dtim_count == 0 ||
167 tim_ie->dtim_period == 1))
168 tim_ie->tim_bitctl |= 1;
169 else
170 tim_ie->tim_bitctl &= ~1;
171
172 /* To avoid sw generated frame sequence the same as H/W generated frame,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700173 * the value lower than min_sw_seq is reserved for HW generated frame
174 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800175 if ((bcn->seq_no & IEEE80211_SEQ_MASK) < MIN_SW_SEQ)
176 bcn->seq_no = MIN_SW_SEQ;
177
178 wh = (struct ieee80211_frame *)bcn_payload;
179 *(uint16_t *) &wh->i_seq[0] = htole16(bcn->seq_no
180 << IEEE80211_SEQ_SEQ_SHIFT);
181 bcn->seq_no++;
182
183 if (WMI_UNIFIED_NOA_ATTR_IS_MODIFIED(p2p_noa_info)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530184 qdf_mem_zero(&noa_ie, sizeof(noa_ie));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800185
186 noa_ie.index =
187 (uint8_t) WMI_UNIFIED_NOA_ATTR_INDEX_GET(p2p_noa_info);
188 noa_ie.oppPS =
189 (uint8_t) WMI_UNIFIED_NOA_ATTR_OPP_PS_GET(p2p_noa_info);
190 noa_ie.ctwindow =
191 (uint8_t) WMI_UNIFIED_NOA_ATTR_CTWIN_GET(p2p_noa_info);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700192 noa_ie.num_descriptors = (uint8_t)
193 WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
194 WMA_LOGI("%s: index %u, oppPs %u, ctwindow %u, num_descriptors = %u",
195 __func__, noa_ie.index,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800196 noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
197 for (i = 0; i < noa_ie.num_descriptors; i++) {
198 noa_ie.noa_descriptors[i].type_count =
199 (uint8_t) p2p_noa_info->noa_descriptors[i].
200 type_count;
201 noa_ie.noa_descriptors[i].duration =
202 p2p_noa_info->noa_descriptors[i].duration;
203 noa_ie.noa_descriptors[i].interval =
204 p2p_noa_info->noa_descriptors[i].interval;
205 noa_ie.noa_descriptors[i].start_time =
206 p2p_noa_info->noa_descriptors[i].start_time;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700207 WMA_LOGI("%s: NoA descriptor[%d] type_count %u, duration %u, interval %u, start_time = %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208 __func__, i,
209 noa_ie.noa_descriptors[i].type_count,
210 noa_ie.noa_descriptors[i].duration,
211 noa_ie.noa_descriptors[i].interval,
212 noa_ie.noa_descriptors[i].start_time);
213 }
214 wma_update_noa(bcn, &noa_ie);
215
216 /* Send a msg to LIM to update the NoA IE in probe response
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700217 * frames transmitted by the host
218 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219 wma_update_probe_resp_noa(wma, &noa_ie);
220 }
221
222 if (bcn->dma_mapped) {
Leo Chang96464902016-10-28 11:10:54 -0700223 qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224 bcn->dma_mapped = 0;
225 }
Leo Chang96464902016-10-28 11:10:54 -0700226 ret = qdf_nbuf_map_single(wma->qdf_dev, bcn->buf, QDF_DMA_TO_DEVICE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530227 if (ret != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 WMA_LOGE("%s: failed map beacon buf to DMA region", __func__);
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530229 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230 return;
231 }
232
233 bcn->dma_mapped = 1;
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530234 params.vdev_id = vdev_id;
235 params.data_len = bcn->len;
236 params.frame_ctrl = *((A_UINT16 *) wh->i_fc);
237 params.frag_ptr = qdf_nbuf_get_frag_paddr(bcn->buf, 0);
238 params.dtim_flag = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239 /* notify Firmware of DTM and mcast/bcast traffic */
240 if (tim_ie->dtim_count == 0) {
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530241 params.dtim_flag |= WMI_BCN_SEND_DTIM_ZERO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242 /* deliver mcast/bcast traffic in next DTIM beacon */
243 if (tim_ie->tim_bitctl & 0x01)
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530244 params.dtim_flag |= WMI_BCN_SEND_DTIM_BITCTL_SET;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800245 }
246
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530247 wmi_unified_bcn_buf_ll_cmd(wma->wmi_handle,
248 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800249
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530250 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251}
Harprit Chhabada98225f62018-12-11 15:29:55 -0800252#else
253static inline void
254wma_send_bcn_buf_ll(tp_wma_handle wma,
255 struct cdp_pdev *pdev,
256 uint8_t vdev_id,
257 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf)
258{
259}
260#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800261/**
262 * wma_beacon_swba_handler() - swba event handler
263 * @handle: wma handle
264 * @event: event data
265 * @len: data length
266 *
267 * SWBA event is alert event to Host requesting host to Queue a beacon
268 * for transmission use only in host beacon mode
269 *
270 * Return: 0 for success or error code
271 */
Liangwei Dong03e080c2019-07-02 17:06:39 +0800272#ifdef WLAN_WMI_BCN
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800273int wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len)
274{
275 tp_wma_handle wma = (tp_wma_handle) handle;
276 WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
277 wmi_host_swba_event_fixed_param *swba_event;
278 uint32_t vdev_map;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800279 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800280 uint8_t vdev_id = 0;
Leo Chang96464902016-10-28 11:10:54 -0700281 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800282
283 param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *) event;
284 if (!param_buf) {
285 WMA_LOGE("Invalid swba event buffer");
286 return -EINVAL;
287 }
288 swba_event = param_buf->fixed_param;
289 vdev_map = swba_event->vdev_map;
290
Anurag Chouhan6d760662016-02-20 16:05:43 +0530291 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800292 if (!pdev) {
293 WMA_LOGE("%s: pdev is NULL", __func__);
294 return -EINVAL;
295 }
296
Varun Reddy Yeturu4353e4f2017-10-03 18:22:42 -0700297 WMA_LOGD("vdev_map = %d", vdev_map);
298 for (; vdev_map && vdev_id < wma->max_bssid;
299 vdev_id++, vdev_map >>= 1) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800300 if (!(vdev_map & 0x1))
301 continue;
Leo Chang96464902016-10-28 11:10:54 -0700302 if (!cdp_cfg_is_high_latency(soc,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800303 (struct cdp_cfg *)cds_get_context(QDF_MODULE_ID_CFG)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800304 wma_send_bcn_buf_ll(wma, pdev, vdev_id, param_buf);
305 break;
306 }
307 return 0;
308}
Harprit Chhabada98225f62018-12-11 15:29:55 -0800309#else
310static inline int
311wma_beacon_swba_handler(void *handle, uint8_t *event, uint32_t len)
312{
313 return 0;
314}
315#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800316
Sen, Devendra154b3c42017-02-13 20:44:15 +0530317#ifdef FEATURE_WLAN_DIAG_SUPPORT
318void wma_sta_kickout_event(uint32_t kickout_reason, uint8_t vdev_id,
319 uint8_t *macaddr)
320{
321 WLAN_HOST_DIAG_EVENT_DEF(sta_kickout, struct host_event_wlan_kickout);
322 qdf_mem_zero(&sta_kickout, sizeof(sta_kickout));
323 sta_kickout.reasoncode = kickout_reason;
324 sta_kickout.vdev_id = vdev_id;
325 if (macaddr)
326 qdf_mem_copy(sta_kickout.peer_mac, macaddr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800327 QDF_MAC_ADDR_SIZE);
Sen, Devendra154b3c42017-02-13 20:44:15 +0530328 WLAN_HOST_DIAG_EVENT_REPORT(&sta_kickout, EVENT_WLAN_STA_KICKOUT);
329}
330#endif
331
Krunal Sonibd7e8932018-10-03 11:14:51 -0700332int wma_peer_sta_kickout_event_handler(void *handle, uint8_t *event,
333 uint32_t len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800334{
335 tp_wma_handle wma = (tp_wma_handle) handle;
336 WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *param_buf = NULL;
337 wmi_peer_sta_kickout_event_fixed_param *kickout_event = NULL;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800338 uint8_t vdev_id, peer_id, macaddr[QDF_MAC_ADDR_SIZE];
Leo Chang96464902016-10-28 11:10:54 -0700339 void *peer;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800340 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341 tpDeleteStaContext del_sta_ctx;
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800342 struct ibss_peer_inactivity_ind *inactivity;
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530343 uint8_t *addr, *bssid;
344 struct wlan_objmgr_vdev *vdev;
Leo Chang96464902016-10-28 11:10:54 -0700345 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346
347 WMA_LOGD("%s: Enter", __func__);
348 param_buf = (WMI_PEER_STA_KICKOUT_EVENTID_param_tlvs *) event;
349 kickout_event = param_buf->fixed_param;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530350 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800351 if (!pdev) {
352 WMA_LOGE("%s: pdev is NULL", __func__);
353 return -EINVAL;
354 }
355 WMI_MAC_ADDR_TO_CHAR_ARRAY(&kickout_event->peer_macaddr, macaddr);
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800356 peer = cdp_peer_find_by_addr(soc, pdev, macaddr, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800357 if (!peer) {
358 WMA_LOGE("PEER [%pM] not found", macaddr);
359 return -EINVAL;
360 }
361
Leo Chang96464902016-10-28 11:10:54 -0700362 if (cdp_peer_get_vdevid(soc, peer, &vdev_id) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800363 WMA_LOGE("Not able to find BSSID for peer [%pM]", macaddr);
364 return -EINVAL;
365 }
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530366 vdev = wma->interfaces[vdev_id].vdev;
367 if (!vdev) {
368 WMA_LOGE("Not able to find vdev for VDEV_%d", vdev_id);
369 return -EINVAL;
370 }
371 addr = wlan_vdev_mlme_get_macaddr(vdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800372
373 WMA_LOGA("%s: PEER:[%pM], ADDR:[%pN], INTERFACE:%d, peer_id:%d, reason:%d",
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530374 __func__, macaddr, addr, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800375 peer_id, kickout_event->reason);
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -0800376 if (wma->interfaces[vdev_id].roaming_in_progress) {
377 WMA_LOGE("Ignore STA kick out since roaming is in progress");
378 return -EINVAL;
379 }
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530380 bssid = wma_get_vdev_bssid(wma->interfaces[vdev_id].vdev);
381 if (!bssid) {
382 WMA_LOGE("%s: Failed to get bssid for vdev_%d",
383 __func__, vdev_id);
384 return -ENOMEM;
385 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800386
387 switch (kickout_event->reason) {
388 case WMI_PEER_STA_KICKOUT_REASON_IBSS_DISCONNECT:
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800389 inactivity = qdf_mem_malloc(sizeof(*inactivity));
390 if (!inactivity) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530391 WMA_LOGE("QDF MEM Alloc Failed for tSirIbssPeerInactivity");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800392 return -ENOMEM;
393 }
394
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800395 inactivity->staIdx = peer_id;
396 qdf_mem_copy(inactivity->peer_addr.bytes, macaddr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800397 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 wma_send_msg(wma, WMA_IBSS_PEER_INACTIVITY_IND,
Jeff Johnson834dcdd2019-02-06 12:04:41 -0800399 inactivity, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400 goto exit_handler;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800401#ifdef FEATURE_WLAN_TDLS
402 case WMI_PEER_STA_KICKOUT_REASON_TDLS_DISCONNECT:
403 del_sta_ctx = (tpDeleteStaContext)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530404 qdf_mem_malloc(sizeof(tDeleteStaContext));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800405 if (!del_sta_ctx) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700406 WMA_LOGE("%s: mem alloc failed for struct del_sta_context for TDLS peer: %pM",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800407 __func__, macaddr);
408 return -ENOMEM;
409 }
410
Naveen Rawat9801ac02016-06-22 11:02:50 -0700411 del_sta_ctx->is_tdls = true;
412 del_sta_ctx->vdev_id = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413 del_sta_ctx->staId = peer_id;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800414 qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE);
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530415 qdf_mem_copy(del_sta_ctx->bssId, bssid,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800416 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800417 del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
418 wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND,
419 (void *)del_sta_ctx, 0);
420 goto exit_handler;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421#endif /* FEATURE_WLAN_TDLS */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800422 case WMI_PEER_STA_KICKOUT_REASON_XRETRY:
423 if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA &&
424 (wma->interfaces[vdev_id].sub_type == 0 ||
425 wma->interfaces[vdev_id].sub_type ==
426 WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530427 !qdf_mem_cmp(bssid,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800428 macaddr, QDF_MAC_ADDR_SIZE)) {
Sen, Devendra154b3c42017-02-13 20:44:15 +0530429 wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_XRETRY,
430 vdev_id, macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 /*
432 * KICKOUT event is for current station-AP connection.
433 * Treat it like final beacon miss. Station may not have
434 * missed beacons but not able to transmit frames to AP
435 * for a long time. Must disconnect to get out of
436 * this sticky situation.
437 * In future implementation, roaming module will also
438 * handle this event and perform a scan.
439 */
440 WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_XRETRY event for STA",
441 __func__);
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +0530442 wma_beacon_miss_handler(wma, vdev_id,
443 kickout_event->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444 goto exit_handler;
445 }
446 break;
447
448 case WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED:
449 /*
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700450 * Default legacy value used by original firmware implementation
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 */
452 if (wma->interfaces[vdev_id].type == WMI_VDEV_TYPE_STA &&
453 (wma->interfaces[vdev_id].sub_type == 0 ||
454 wma->interfaces[vdev_id].sub_type ==
455 WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) &&
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530456 !qdf_mem_cmp(bssid,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800457 macaddr, QDF_MAC_ADDR_SIZE)) {
Sen, Devendra154b3c42017-02-13 20:44:15 +0530458 wma_sta_kickout_event(
459 HOST_STA_KICKOUT_REASON_UNSPECIFIED, vdev_id, macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 /*
461 * KICKOUT event is for current station-AP connection.
462 * Treat it like final beacon miss. Station may not have
463 * missed beacons but not able to transmit frames to AP
464 * for a long time. Must disconnect to get out of
465 * this sticky situation.
466 * In future implementation, roaming module will also
467 * handle this event and perform a scan.
468 */
469 WMA_LOGW("%s: WMI_PEER_STA_KICKOUT_REASON_UNSPECIFIED event for STA",
470 __func__);
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +0530471 wma_beacon_miss_handler(wma, vdev_id,
472 kickout_event->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800473 goto exit_handler;
474 }
475 break;
476
477 case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY:
Naveen Rawat9801ac02016-06-22 11:02:50 -0700478 /*
479 * Handle SA query kickout is same as inactivity kickout.
480 * This could be for STA or SAP role
481 */
mukul sharma72c8b222015-09-04 17:02:01 +0530482 case WMI_PEER_STA_KICKOUT_REASON_SA_QUERY_TIMEOUT:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800483 default:
484 break;
485 }
486
487 /*
488 * default action is to send delete station context indication to LIM
489 */
490 del_sta_ctx =
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700491 (tDeleteStaContext *) qdf_mem_malloc(sizeof(tDeleteStaContext));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800492 if (!del_sta_ctx) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700493 WMA_LOGE("QDF MEM Alloc Failed for struct del_sta_context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800494 return -ENOMEM;
495 }
496
Naveen Rawat9801ac02016-06-22 11:02:50 -0700497 del_sta_ctx->is_tdls = false;
498 del_sta_ctx->vdev_id = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800499 del_sta_ctx->staId = peer_id;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -0800500 qdf_mem_copy(del_sta_ctx->addr2, macaddr, QDF_MAC_ADDR_SIZE);
Abhishek Ambure3ee80882019-09-20 16:32:12 +0530501 qdf_mem_copy(del_sta_ctx->bssId, addr, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800502 del_sta_ctx->reasonCode = HAL_DEL_STA_REASON_CODE_KEEP_ALIVE;
Yeshwanth Sriram Guntuka14ab04c2018-09-21 15:06:49 +0530503 if (wmi_service_enabled(wma->wmi_handle,
504 wmi_service_hw_db2dbm_support))
505 del_sta_ctx->rssi = kickout_event->rssi;
506 else
507 del_sta_ctx->rssi = kickout_event->rssi +
508 WMA_TGT_NOISE_FLOOR_DBM;
Sen, Devendra154b3c42017-02-13 20:44:15 +0530509 wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_KEEP_ALIVE,
510 vdev_id, macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800511 wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND, (void *)del_sta_ctx,
512 0);
Yeshwanth Sriram Guntuka14ab04c2018-09-21 15:06:49 +0530513 wma_lost_link_info_handler(wma, vdev_id, del_sta_ctx->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514exit_handler:
515 WMA_LOGD("%s: Exit", __func__);
516 return 0;
517}
518
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519int wma_unified_bcntx_status_event_handler(void *handle,
520 uint8_t *cmd_param_info,
521 uint32_t len)
522{
523 tp_wma_handle wma = (tp_wma_handle) handle;
524 WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *param_buf;
525 wmi_offload_bcn_tx_status_event_fixed_param *resp_event;
526 tSirFirstBeaconTxCompleteInd *beacon_tx_complete_ind;
Abhishek Ambure0b2ea322019-09-23 19:25:39 +0530527 struct cdp_vdev *dp_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528
529 param_buf =
530 (WMI_OFFLOAD_BCN_TX_STATUS_EVENTID_param_tlvs *) cmd_param_info;
531 if (!param_buf) {
532 WMA_LOGE("Invalid bcn tx response event buffer");
533 return -EINVAL;
534 }
535
536 resp_event = param_buf->fixed_param;
537
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +0530538 WMA_LOGD("%s", __func__);
539
Vignesh Viswanathan07db59e2017-10-04 18:24:08 +0530540 if (resp_event->vdev_id >= wma->max_bssid) {
541 WMA_LOGE("%s: received invalid vdev_id %d",
542 __func__, resp_event->vdev_id);
543 return -EINVAL;
544 }
545
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546 /* Check for valid handle to ensure session is not
547 * deleted in any race
548 */
Abhishek Ambure24cff9e2019-10-01 12:09:55 +0530549 if (!wma->interfaces[resp_event->vdev_id].vdev) {
550 WMA_LOGE("%s: vdev is NULL for vdev_%d",
551 __func__, resp_event->vdev_id);
552 return -EINVAL;
553 }
Abhishek Ambure0b2ea322019-09-23 19:25:39 +0530554 dp_handle = wlan_vdev_get_dp_handle
555 (wma->interfaces[resp_event->vdev_id].vdev);
556 if (!dp_handle) {
Abhishek Amburec0069162019-10-01 14:10:23 +0530557 WMA_LOGE("%s: Failed to get dp handle for vdev id %d",
558 __func__, resp_event->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559 return -EINVAL;
560 }
561
562 /* Beacon Tx Indication supports only AP mode. Ignore in other modes */
563 if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) == false) {
564 WMA_LOGI("%s: Beacon Tx Indication does not support type %d and sub_type %d",
565 __func__, wma->interfaces[resp_event->vdev_id].type,
566 wma->interfaces[resp_event->vdev_id].sub_type);
567 return 0;
568 }
569
570 beacon_tx_complete_ind = (tSirFirstBeaconTxCompleteInd *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530571 qdf_mem_malloc(sizeof(tSirFirstBeaconTxCompleteInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 if (!beacon_tx_complete_ind) {
573 WMA_LOGE("%s: Failed to alloc beacon_tx_complete_ind",
574 __func__);
575 return -ENOMEM;
576 }
577
578 beacon_tx_complete_ind->messageType = WMA_DFS_BEACON_TX_SUCCESS_IND;
579 beacon_tx_complete_ind->length = sizeof(tSirFirstBeaconTxCompleteInd);
Pragaspathi Thilagaraje05162d2019-05-23 13:10:46 +0530580 beacon_tx_complete_ind->bss_idx = resp_event->vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800581
582 wma_send_msg(wma, WMA_DFS_BEACON_TX_SUCCESS_IND,
583 (void *)beacon_tx_complete_ind, 0);
584 return 0;
585}
586
587/**
Wu Gao3365e782018-07-27 18:19:35 +0800588 * wma_get_go_probe_timeout() - get P2P GO probe timeout
589 * @mac: UMAC handler
590 * @max_inactive_time: return max inactive time
591 * @max_unresponsive_time: return max unresponsive time
592 *
593 * Return: none
594 */
595#ifdef CONVERGED_P2P_ENABLE
596static inline void
Jeff Johnson009c40f2018-11-05 09:54:37 -0800597wma_get_go_probe_timeout(struct mac_context *mac,
Wu Gao3365e782018-07-27 18:19:35 +0800598 uint32_t *max_inactive_time,
599 uint32_t *max_unresponsive_time)
600{
601 uint32_t keep_alive;
602 QDF_STATUS status;
603
604 status = cfg_p2p_get_go_link_monitor_period(mac->psoc,
605 max_inactive_time);
606 if (QDF_IS_STATUS_ERROR(status)) {
607 WMA_LOGE("Failed to go monitor period");
608 *max_inactive_time = WMA_LINK_MONITOR_DEFAULT_TIME_SECS;
609 }
610 status = cfg_p2p_get_go_keepalive_period(mac->psoc,
611 &keep_alive);
612 if (QDF_IS_STATUS_ERROR(status)) {
613 WMA_LOGE("Failed to read go keep alive");
614 keep_alive = WMA_KEEP_ALIVE_DEFAULT_TIME_SECS;
615 }
616
617 *max_unresponsive_time = *max_inactive_time + keep_alive;
618}
619#else
620static inline void
Jeff Johnson009c40f2018-11-05 09:54:37 -0800621wma_get_go_probe_timeout(struct mac_context *mac,
Wu Gao3365e782018-07-27 18:19:35 +0800622 uint32_t *max_inactive_time,
623 uint32_t *max_unresponsive_time)
624{
625}
626#endif
627
628/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800629 * wma_get_link_probe_timeout() - get link timeout based on sub type
630 * @mac: UMAC handler
631 * @sub_type: vdev syb type
632 * @max_inactive_time: return max inactive time
633 * @max_unresponsive_time: return max unresponsive time
634 *
635 * Return: none
636 */
Wu Gao3365e782018-07-27 18:19:35 +0800637static inline void
Jeff Johnson009c40f2018-11-05 09:54:37 -0800638wma_get_link_probe_timeout(struct mac_context *mac,
Wu Gao3365e782018-07-27 18:19:35 +0800639 uint32_t sub_type,
640 uint32_t *max_inactive_time,
641 uint32_t *max_unresponsive_time)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800642{
Arif Hussain43e09712018-09-18 19:31:57 -0700643 if (sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) {
Wu Gao3365e782018-07-27 18:19:35 +0800644 wma_get_go_probe_timeout(mac, max_inactive_time,
645 max_unresponsive_time);
Arif Hussain43e09712018-09-18 19:31:57 -0700646 } else {
647 *max_inactive_time =
648 mac->mlme_cfg->timeouts.ap_link_monitor_timeout;
649 *max_unresponsive_time = *max_inactive_time +
650 mac->mlme_cfg->timeouts.ap_keep_alive_timeout;
651 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652}
653
654/**
Hong Shi2d384fd2017-05-22 18:38:41 +0800655 * wma_verify_rate_code() - verify if rate code is valid.
656 * @rate_code: rate code
gaolezd1a229d2018-03-28 17:26:40 +0800657 * @band: band information
Hong Shi2d384fd2017-05-22 18:38:41 +0800658 *
659 * Return: verify result
660 */
gaolezd1a229d2018-03-28 17:26:40 +0800661static bool wma_verify_rate_code(u_int32_t rate_code, enum cds_band_type band)
Hong Shi2d384fd2017-05-22 18:38:41 +0800662{
663 uint8_t preamble, nss, rate;
664 bool valid = true;
665
666 preamble = (rate_code & 0xc0) >> 6;
667 nss = (rate_code & 0x30) >> 4;
668 rate = rate_code & 0xf;
669
670 switch (preamble) {
671 case WMI_RATE_PREAMBLE_CCK:
gaolezd1a229d2018-03-28 17:26:40 +0800672 if (nss != 0 || rate > 3 || band == CDS_BAND_5GHZ)
Hong Shi2d384fd2017-05-22 18:38:41 +0800673 valid = false;
674 break;
675 case WMI_RATE_PREAMBLE_OFDM:
676 if (nss != 0 || rate > 7)
677 valid = false;
678 break;
679 case WMI_RATE_PREAMBLE_HT:
gaolezd1a229d2018-03-28 17:26:40 +0800680 if (nss != 0 || rate > 7)
Hong Shi2d384fd2017-05-22 18:38:41 +0800681 valid = false;
682 break;
683 case WMI_RATE_PREAMBLE_VHT:
gaolezd1a229d2018-03-28 17:26:40 +0800684 if (nss != 0 || rate > 9)
Hong Shi2d384fd2017-05-22 18:38:41 +0800685 valid = false;
686 break;
687 default:
688 break;
689 }
690 return valid;
691}
692
693#define TX_MGMT_RATE_2G_ENABLE_OFFSET 30
694#define TX_MGMT_RATE_5G_ENABLE_OFFSET 31
695#define TX_MGMT_RATE_2G_OFFSET 0
696#define TX_MGMT_RATE_5G_OFFSET 12
697
698/**
Hong Shib90718f2017-02-20 00:57:22 +0800699 * wma_set_mgmt_rate() - set vdev mgmt rate.
700 * @wma: wma handle
701 * @vdev_id: vdev id
702 *
703 * Return: None
704 */
705void wma_set_vdev_mgmt_rate(tp_wma_handle wma, uint8_t vdev_id)
706{
707 uint32_t cfg_val;
708 int ret;
Hong Shi2d384fd2017-05-22 18:38:41 +0800709 uint32_t per_band_mgmt_tx_rate = 0;
gaolezd1a229d2018-03-28 17:26:40 +0800710 enum cds_band_type band = 0;
Jeff Johnson009c40f2018-11-05 09:54:37 -0800711 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Hong Shib90718f2017-02-20 00:57:22 +0800712
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -0700713 if (!mac) {
Hong Shib90718f2017-02-20 00:57:22 +0800714 WMA_LOGE("%s: Failed to get mac", __func__);
715 return;
716 }
717
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530718 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
719 band = CDS_BAND_ALL;
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530720 if ((cfg_val == MLME_CFG_TX_MGMT_RATE_DEF) ||
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530721 !wma_verify_rate_code(cfg_val, band)) {
722 WMA_LOGD("default WNI_CFG_RATE_FOR_TX_MGMT, ignore");
Hong Shib90718f2017-02-20 00:57:22 +0800723 } else {
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530724 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
725 WMI_VDEV_PARAM_MGMT_TX_RATE,
726 cfg_val);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530727 if (ret)
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530728 WMA_LOGE("Failed to set WMI_VDEV_PARAM_MGMT_TX_RATE");
Hong Shib90718f2017-02-20 00:57:22 +0800729 }
Hong Shi2d384fd2017-05-22 18:38:41 +0800730
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530731 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt_2g;
732 band = CDS_BAND_2GHZ;
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530733 if ((cfg_val == MLME_CFG_TX_MGMT_2G_RATE_DEF) ||
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530734 !wma_verify_rate_code(cfg_val, band)) {
735 WMA_LOGD("use default 2G MGMT rate.");
736 per_band_mgmt_tx_rate &=
737 ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800738 } else {
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530739 per_band_mgmt_tx_rate |=
740 (1 << TX_MGMT_RATE_2G_ENABLE_OFFSET);
741 per_band_mgmt_tx_rate |=
742 ((cfg_val & 0x7FF) << TX_MGMT_RATE_2G_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800743 }
744
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530745 cfg_val = mac->mlme_cfg->sap_cfg.rate_tx_mgmt;
746 band = CDS_BAND_5GHZ;
Pragaspathi Thilagaraj3cf0f652018-10-29 16:40:35 +0530747 if ((cfg_val == MLME_CFG_TX_MGMT_5G_RATE_DEF) ||
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530748 !wma_verify_rate_code(cfg_val, band)) {
749 WMA_LOGD("use default 5G MGMT rate.");
750 per_band_mgmt_tx_rate &=
751 ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800752 } else {
Bala Venkatesh2fde2c62018-09-11 20:33:24 +0530753 per_band_mgmt_tx_rate |=
754 (1 << TX_MGMT_RATE_5G_ENABLE_OFFSET);
755 per_band_mgmt_tx_rate |=
756 ((cfg_val & 0x7FF) << TX_MGMT_RATE_5G_OFFSET);
Hong Shi2d384fd2017-05-22 18:38:41 +0800757 }
758
759 ret = wma_vdev_set_param(
760 wma->wmi_handle,
761 vdev_id,
762 WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE,
763 per_band_mgmt_tx_rate);
764 if (ret)
765 WMA_LOGE("Failed to set WMI_VDEV_PARAM_PER_BAND_MGMT_TX_RATE");
766
Hong Shib90718f2017-02-20 00:57:22 +0800767}
768
769/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 * wma_set_sap_keepalive() - set SAP keep alive parameters to fw
771 * @wma: wma handle
772 * @vdev_id: vdev id
773 *
774 * Return: none
775 */
776void wma_set_sap_keepalive(tp_wma_handle wma, uint8_t vdev_id)
777{
778 uint32_t min_inactive_time, max_inactive_time, max_unresponsive_time;
Jeff Johnson009c40f2018-11-05 09:54:37 -0800779 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Govind Singhd76a5b02016-03-08 15:12:14 +0530780 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -0700782 if (!mac) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800783 WMA_LOGE("%s: Failed to get mac", __func__);
784 return;
785 }
786
787 wma_get_link_probe_timeout(mac, wma->interfaces[vdev_id].sub_type,
788 &max_inactive_time, &max_unresponsive_time);
789
790 min_inactive_time = max_inactive_time / 2;
791
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700792 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
793 WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
794 min_inactive_time);
Govind Singhd76a5b02016-03-08 15:12:14 +0530795 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800796 WMA_LOGE("Failed to Set AP MIN IDLE INACTIVE TIME");
797
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700798 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
799 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
800 max_inactive_time);
Govind Singhd76a5b02016-03-08 15:12:14 +0530801 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800802 WMA_LOGE("Failed to Set AP MAX IDLE INACTIVE TIME");
803
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700804 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
805 WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
806 max_unresponsive_time);
Govind Singhd76a5b02016-03-08 15:12:14 +0530807 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808 WMA_LOGE("Failed to Set MAX UNRESPONSIVE TIME");
809
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700810 WMA_LOGD("%s:vdev_id:%d min_inactive_time: %u max_inactive_time: %u max_unresponsive_time: %u",
811 __func__, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800812 min_inactive_time, max_inactive_time, max_unresponsive_time);
813}
814
815/**
mukul sharma72c8b222015-09-04 17:02:01 +0530816 * wma_set_sta_sa_query_param() - set sta sa query parameters
817 * @wma: wma handle
818 * @vdev_id: vdev id
819
820 * This function sets sta query related parameters in fw.
821 *
822 * Return: none
823 */
824
825void wma_set_sta_sa_query_param(tp_wma_handle wma,
826 uint8_t vdev_id)
827{
Jeff Johnson009c40f2018-11-05 09:54:37 -0800828 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Karthik Kantamneni24f71bc2018-09-11 19:08:38 +0530829 uint8_t max_retries;
830 uint16_t retry_interval;
mukul sharma72c8b222015-09-04 17:02:01 +0530831
832 WMA_LOGD(FL("Enter:"));
mukul sharma72c8b222015-09-04 17:02:01 +0530833
Krunal Sonifea06802017-04-13 14:44:48 -0700834 if (!mac) {
835 WMA_LOGE(FL("mac context is NULL"));
836 return;
837 }
Karthik Kantamneni24f71bc2018-09-11 19:08:38 +0530838
839 max_retries = mac->mlme_cfg->gen.pmf_sa_query_max_retries;
840 retry_interval = mac->mlme_cfg->gen.pmf_sa_query_retry_interval;
mukul sharma72c8b222015-09-04 17:02:01 +0530841
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530842 wmi_unified_set_sta_sa_query_param_cmd(wma->wmi_handle,
843 vdev_id,
844 max_retries,
845 retry_interval);
mukul sharma72c8b222015-09-04 17:02:01 +0530846
847 WMA_LOGD(FL("Exit :"));
mukul sharma72c8b222015-09-04 17:02:01 +0530848}
849
850/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851 * wma_set_sta_keep_alive() - set sta keep alive parameters
852 * @wma: wma handle
853 * @vdev_id: vdev id
854 * @method: method for keep alive
855 * @timeperiod: time period
856 * @hostv4addr: host ipv4 address
857 * @destv4addr: dst ipv4 address
858 * @destmac: destination mac
859 *
860 * This function sets keep alive related parameters in fw.
861 *
862 * Return: none
863 */
864void wma_set_sta_keep_alive(tp_wma_handle wma, uint8_t vdev_id,
865 uint32_t method, uint32_t timeperiod,
866 uint8_t *hostv4addr, uint8_t *destv4addr,
867 uint8_t *destmac)
868{
Jeff Johnson4c2837f2019-02-28 13:42:20 -0800869 struct sta_keep_alive_params params = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870
871 WMA_LOGD("%s: Enter", __func__);
872
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530873 if (!wma) {
874 WMA_LOGE("%s: wma handle is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875 return;
876 }
877
Wu Gao93816212018-08-31 16:49:54 +0800878 if (timeperiod > cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD)) {
Govind Singhfe9ab252016-06-21 14:35:35 +0530879 WMI_LOGE("Invalid period %d Max limit %d", timeperiod,
Wu Gao93816212018-08-31 16:49:54 +0800880 cfg_max(CFG_INFRA_STA_KEEP_ALIVE_PERIOD));
Govind Singhfe9ab252016-06-21 14:35:35 +0530881 return;
882 }
883
Himanshu Agarwal009f1572016-03-09 17:26:02 +0530884 params.vdev_id = vdev_id;
885 params.method = method;
886 params.timeperiod = timeperiod;
Jeff Johnson4c2837f2019-02-28 13:42:20 -0800887 if (hostv4addr)
888 qdf_mem_copy(params.hostv4addr, hostv4addr, QDF_IPV4_ADDR_SIZE);
889 if (destv4addr)
890 qdf_mem_copy(params.destv4addr, destv4addr, QDF_IPV4_ADDR_SIZE);
891 if (destmac)
892 qdf_mem_copy(params.destmac, destmac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800893
Jeff Johnsonf32bf012019-02-25 11:37:32 -0800894 wmi_unified_set_sta_keep_alive_cmd(wma->wmi_handle, &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800895 WMA_LOGD("%s: Exit", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896}
897
898/**
899 * wma_vdev_install_key_complete_event_handler() - install key complete handler
900 * @handle: wma handle
901 * @event: event data
902 * @len: data length
903 *
904 * This event is sent by fw once WPA/WPA2 keys are installed in fw.
905 *
906 * Return: 0 for success or error code
907 */
908int wma_vdev_install_key_complete_event_handler(void *handle,
909 uint8_t *event,
910 uint32_t len)
911{
912 WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *param_buf = NULL;
913 wmi_vdev_install_key_complete_event_fixed_param *key_fp = NULL;
914
915 if (!event) {
916 WMA_LOGE("%s: event param null", __func__);
917 return -EINVAL;
918 }
919
920 param_buf = (WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID_param_tlvs *) event;
921 if (!param_buf) {
922 WMA_LOGE("%s: received null buf from target", __func__);
923 return -EINVAL;
924 }
925
926 key_fp = param_buf->fixed_param;
927 if (!key_fp) {
928 WMA_LOGE("%s: received null event data from target", __func__);
929 return -EINVAL;
930 }
931 /*
932 * Do nothing for now. Completion of set key is already indicated to lim
933 */
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800934 WMA_LOGD("%s: WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 return 0;
936}
937/*
938 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
939 * 0 for no restriction
940 * 1 for 1/4 us - Our lower layer calculations limit our precision to 1 msec
941 * 2 for 1/2 us - Our lower layer calculations limit our precision to 1 msec
942 * 3 for 1 us
943 * 4 for 2 us
944 * 5 for 4 us
945 * 6 for 8 us
946 * 7 for 16 us
947 */
948static const uint8_t wma_mpdu_spacing[] = { 0, 1, 1, 1, 2, 4, 8, 16 };
949
950/**
951 * wma_parse_mpdudensity() - give mpdu spacing from mpdu density
952 * @mpdudensity: mpdu density
953 *
954 * Return: mpdu spacing or 0 for error
955 */
956static inline uint8_t wma_parse_mpdudensity(uint8_t mpdudensity)
957{
958 if (mpdudensity < sizeof(wma_mpdu_spacing))
959 return wma_mpdu_spacing[mpdudensity];
960 else
961 return 0;
962}
963
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530964#if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
965
966/**
967 * wma_unified_peer_state_update() - update peer state
968 * @pdev: pdev handle
969 * @sta_mac: pointer to sta mac addr
970 * @bss_addr: bss address
971 * @sta_type: sta entry type
972 *
973 *
974 * Return: None
975 */
976static void
977wma_unified_peer_state_update(
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800978 struct cdp_pdev *pdev,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530979 uint8_t *sta_mac,
980 uint8_t *bss_addr,
981 uint8_t sta_type)
982{
Leo Chang96464902016-10-28 11:10:54 -0700983 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
984
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530985 if (STA_ENTRY_TDLS_PEER == sta_type)
Leo Chang96464902016-10-28 11:10:54 -0700986 cdp_peer_state_update(soc, pdev, sta_mac,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530987 OL_TXRX_PEER_STATE_AUTH);
988 else
Leo Chang96464902016-10-28 11:10:54 -0700989 cdp_peer_state_update(soc, pdev, bss_addr,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530990 OL_TXRX_PEER_STATE_AUTH);
991}
992#else
993
994static inline void
995wma_unified_peer_state_update(
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800996 struct cdp_pdev *pdev,
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +0530997 uint8_t *sta_mac,
998 uint8_t *bss_addr,
999 uint8_t sta_type)
1000{
Leo Chang96464902016-10-28 11:10:54 -07001001 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1002
1003 cdp_peer_state_update(soc, pdev, bss_addr, OL_TXRX_PEER_STATE_AUTH);
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05301004}
1005#endif
1006
Hong Shi417824f2017-01-12 02:31:14 +08001007#define CFG_CTRL_MASK 0xFF00
1008#define CFG_DATA_MASK 0x00FF
1009
1010/**
1011 * wma_mask_tx_ht_rate() - mask tx ht rate based on config
1012 * @wma: wma handle
1013 * @mcs_set mcs set buffer
1014 *
1015 * Return: None
1016 */
1017static void wma_mask_tx_ht_rate(tp_wma_handle wma, uint8_t *mcs_set)
1018{
Karthik Kantamneni22dd0f62018-08-07 14:53:50 +05301019 uint32_t i, j;
1020 uint16_t mcs_limit;
Hong Shi417824f2017-01-12 02:31:14 +08001021 uint8_t *rate_pos = mcs_set;
Abhinav Kumar18285932019-08-08 16:50:06 +05301022 struct mac_context *mac = wma->mac_context;
Hong Shi417824f2017-01-12 02:31:14 +08001023
1024 /*
1025 * Get MCS limit from ini configure, and map it to rate parameters
1026 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
1027 * check whether ini config is enabled and CFG_DATA_MASK to get the
1028 * MCS value.
1029 */
Karthik Kantamneni22dd0f62018-08-07 14:53:50 +05301030 mcs_limit = mac->mlme_cfg->rates.max_htmcs_txdata;
Hong Shi417824f2017-01-12 02:31:14 +08001031
1032 if (mcs_limit & CFG_CTRL_MASK) {
1033 WMA_LOGD("%s: set mcs_limit %x", __func__, mcs_limit);
1034
1035 mcs_limit &= CFG_DATA_MASK;
1036 for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
1037 if (j < mcs_limit / 8) {
1038 rate_pos[j] = 0xff;
1039 j++;
1040 i += 8;
1041 } else if (j < mcs_limit / 8 + 1) {
1042 if (i <= mcs_limit)
1043 rate_pos[i / 8] |= 1 << (i % 8);
1044 else
1045 rate_pos[i / 8] &= ~(1 << (i % 8));
1046 i++;
1047
1048 if (i >= (j + 1) * 8)
1049 j++;
1050 } else {
1051 rate_pos[j++] = 0;
1052 i += 8;
1053 }
1054 }
1055 }
1056}
1057
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001058#if SUPPORT_11AX
1059/**
bings672207d2019-06-20 17:39:39 +08001060 * wma_fw_to_host_phymode_11ax() - convert fw to host phymode for 11ax phymodes
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001061 * @phymode: phymode to convert
1062 *
wadesongd3f8d3a2019-09-16 17:26:07 +08001063 * Return: one of the 11ax values defined in enum wlan_phymode;
1064 * or WLAN_PHYMODE_AUTO if the input is not an 11ax phymode
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001065 */
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301066static enum wlan_phymode
1067wma_fw_to_host_phymode_11ax(WMI_HOST_WLAN_PHY_MODE phymode)
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001068{
1069 switch (phymode) {
1070 default:
1071 return WLAN_PHYMODE_AUTO;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301072 case WMI_HOST_MODE_11AX_HE20:
bings672207d2019-06-20 17:39:39 +08001073 return WLAN_PHYMODE_11AXA_HE20;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301074 case WMI_HOST_MODE_11AX_HE40:
bings672207d2019-06-20 17:39:39 +08001075 return WLAN_PHYMODE_11AXA_HE40;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301076 case WMI_HOST_MODE_11AX_HE80:
bings672207d2019-06-20 17:39:39 +08001077 return WLAN_PHYMODE_11AXA_HE80;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301078 case WMI_HOST_MODE_11AX_HE80_80:
bings672207d2019-06-20 17:39:39 +08001079 return WLAN_PHYMODE_11AXA_HE80_80;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301080 case WMI_HOST_MODE_11AX_HE160:
bings672207d2019-06-20 17:39:39 +08001081 return WLAN_PHYMODE_11AXA_HE160;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301082 case WMI_HOST_MODE_11AX_HE20_2G:
bings672207d2019-06-20 17:39:39 +08001083 return WLAN_PHYMODE_11AXG_HE20;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301084 case WMI_HOST_MODE_11AX_HE40_2G:
bings672207d2019-06-20 17:39:39 +08001085 return WLAN_PHYMODE_11AXG_HE40;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301086 case WMI_HOST_MODE_11AX_HE80_2G:
1087 return WLAN_PHYMODE_11AXG_HE80;
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001088 }
1089 return WLAN_PHYMODE_AUTO;
1090}
1091#else
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301092static enum wlan_phymode
1093wma_fw_to_host_phymode_11ax(WMI_HOST_WLAN_PHY_MODE phymode)
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001094{
1095 return WLAN_PHYMODE_AUTO;
1096}
1097#endif
1098
1099#ifdef CONFIG_160MHZ_SUPPORT
1100/**
1101 * wma_fw_to_host_phymode_160() - convert fw to host phymode for 160 mhz
1102 * phymodes
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001103 * @phymode: phymode to convert
1104 *
wadesongd3f8d3a2019-09-16 17:26:07 +08001105 * Return: one of the 160 mhz values defined in enum wlan_phymode;
1106 * or WLAN_PHYMODE_AUTO if the input is not a 160 mhz phymode
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001107 */
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301108static enum wlan_phymode
1109wma_fw_to_host_phymode_160(WMI_HOST_WLAN_PHY_MODE phymode)
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001110{
1111 switch (phymode) {
1112 default:
1113 return WLAN_PHYMODE_AUTO;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301114 case WMI_HOST_MODE_11AC_VHT80_80:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001115 return WLAN_PHYMODE_11AC_VHT80_80;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301116 case WMI_HOST_MODE_11AC_VHT160:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001117 return WLAN_PHYMODE_11AC_VHT160;
1118 }
1119}
1120#else
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301121static enum wlan_phymode
1122wma_fw_to_host_phymode_160(WMI_HOST_WLAN_PHY_MODE phymode)
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001123{
1124 return WLAN_PHYMODE_AUTO;
1125}
1126#endif
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301127
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301128enum wlan_phymode wma_fw_to_host_phymode(WMI_HOST_WLAN_PHY_MODE phymode)
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001129{
1130 enum wlan_phymode host_phymode;
1131 switch (phymode) {
1132 default:
1133 host_phymode = wma_fw_to_host_phymode_160(phymode);
1134 if (host_phymode != WLAN_PHYMODE_AUTO)
1135 return host_phymode;
bings672207d2019-06-20 17:39:39 +08001136 return wma_fw_to_host_phymode_11ax(phymode);
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301137 case WMI_HOST_MODE_11A:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001138 return WLAN_PHYMODE_11A;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301139 case WMI_HOST_MODE_11G:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001140 return WLAN_PHYMODE_11G;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301141 case WMI_HOST_MODE_11B:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001142 return WLAN_PHYMODE_11B;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301143 case WMI_HOST_MODE_11GONLY:
1144 return WLAN_PHYMODE_11G_ONLY;
1145 case WMI_HOST_MODE_11NA_HT20:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001146 return WLAN_PHYMODE_11NA_HT20;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301147 case WMI_HOST_MODE_11NG_HT20:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001148 return WLAN_PHYMODE_11NG_HT20;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301149 case WMI_HOST_MODE_11NA_HT40:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001150 return WLAN_PHYMODE_11NA_HT40;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301151 case WMI_HOST_MODE_11NG_HT40:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001152 return WLAN_PHYMODE_11NG_HT40;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301153 case WMI_HOST_MODE_11AC_VHT20:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001154 return WLAN_PHYMODE_11AC_VHT20;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301155 case WMI_HOST_MODE_11AC_VHT40:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001156 return WLAN_PHYMODE_11AC_VHT40;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301157 case WMI_HOST_MODE_11AC_VHT80:
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001158 return WLAN_PHYMODE_11AC_VHT80;
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301159 case WMI_HOST_MODE_11AC_VHT20_2G:
1160 return WLAN_PHYMODE_11AC_VHT20_2G;
1161 case WMI_HOST_MODE_11AC_VHT40_2G:
1162 return WLAN_PHYMODE_11AC_VHT40_2G;
1163 case WMI_HOST_MODE_11AC_VHT80_2G:
1164 return WLAN_PHYMODE_11AC_VHT80_2G;
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001165 }
1166}
1167
wadesongd3f8d3a2019-09-16 17:26:07 +08001168#ifdef CONFIG_160MHZ_SUPPORT
1169/**
1170 * wma_host_to_fw_phymode_160() - convert host to fw phymode for 160 mhz
1171 * @host_phymode: phymode to convert
1172 *
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301173 * Return: one of the 160 mhz values defined in enum WMI_HOST_WLAN_PHY_MODE;
1174 * or WMI_HOST_MODE_UNKNOWN if the input is not a 160 mhz phymode
wadesongd3f8d3a2019-09-16 17:26:07 +08001175 */
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301176static WMI_HOST_WLAN_PHY_MODE
1177wma_host_to_fw_phymode_160(enum wlan_phymode host_phymode)
wadesongd3f8d3a2019-09-16 17:26:07 +08001178{
1179 switch (host_phymode) {
1180 case WLAN_PHYMODE_11AC_VHT80_80:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301181 return WMI_HOST_MODE_11AC_VHT80_80;
wadesongd3f8d3a2019-09-16 17:26:07 +08001182 case WLAN_PHYMODE_11AC_VHT160:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301183 return WMI_HOST_MODE_11AC_VHT160;
wadesongd3f8d3a2019-09-16 17:26:07 +08001184 default:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301185 return WMI_HOST_MODE_UNKNOWN;
wadesongd3f8d3a2019-09-16 17:26:07 +08001186 }
1187}
1188#else
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301189static WMI_HOST_WLAN_PHY_MODE
1190wma_host_to_fw_phymode_160(enum wlan_phymode host_phymode)
wadesongd3f8d3a2019-09-16 17:26:07 +08001191{
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301192 return WMI_HOST_MODE_UNKNOWN;
wadesongd3f8d3a2019-09-16 17:26:07 +08001193}
1194#endif
1195
1196#if SUPPORT_11AX
1197/**
1198 * wma_host_to_fw_phymode_11ax() - convert host to fw phymode for 11ax phymode
1199 * @host_phymode: phymode to convert
1200 *
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301201 * Return: one of the 11ax values defined in enum WMI_HOST_WLAN_PHY_MODE;
1202 * or WMI_HOST_MODE_UNKNOWN if the input is not an 11ax phymode
wadesongd3f8d3a2019-09-16 17:26:07 +08001203 */
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301204static WMI_HOST_WLAN_PHY_MODE
1205wma_host_to_fw_phymode_11ax(enum wlan_phymode host_phymode)
wadesongd3f8d3a2019-09-16 17:26:07 +08001206{
1207 switch (host_phymode) {
1208 case WLAN_PHYMODE_11AXA_HE20:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301209 return WMI_HOST_MODE_11AX_HE20;
wadesongd3f8d3a2019-09-16 17:26:07 +08001210 case WLAN_PHYMODE_11AXA_HE40:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301211 return WMI_HOST_MODE_11AX_HE40;
wadesongd3f8d3a2019-09-16 17:26:07 +08001212 case WLAN_PHYMODE_11AXA_HE80:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301213 return WMI_HOST_MODE_11AX_HE80;
wadesongd3f8d3a2019-09-16 17:26:07 +08001214 case WLAN_PHYMODE_11AXA_HE80_80:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301215 return WMI_HOST_MODE_11AX_HE80_80;
wadesongd3f8d3a2019-09-16 17:26:07 +08001216 case WLAN_PHYMODE_11AXA_HE160:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301217 return WMI_HOST_MODE_11AX_HE160;
1218 case WLAN_PHYMODE_11AXG_HE20:
1219 return WMI_HOST_MODE_11AX_HE20_2G;
1220 case WLAN_PHYMODE_11AXG_HE40:
1221 case WLAN_PHYMODE_11AXG_HE40PLUS:
1222 case WLAN_PHYMODE_11AXG_HE40MINUS:
1223 return WMI_HOST_MODE_11AX_HE40_2G;
1224 case WLAN_PHYMODE_11AXG_HE80:
1225 return WMI_HOST_MODE_11AX_HE80_2G;
wadesongd3f8d3a2019-09-16 17:26:07 +08001226 default:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301227 return WMI_HOST_MODE_UNKNOWN;
wadesongd3f8d3a2019-09-16 17:26:07 +08001228 }
1229}
1230#else
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301231static WMI_HOST_WLAN_PHY_MODE
1232wma_host_to_fw_phymode_11ax(enum wlan_phymode host_phymode)
wadesongd3f8d3a2019-09-16 17:26:07 +08001233{
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301234 return WMI_HOST_MODE_UNKNOWN;
wadesongd3f8d3a2019-09-16 17:26:07 +08001235}
1236#endif
1237
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301238WMI_HOST_WLAN_PHY_MODE wma_host_to_fw_phymode(enum wlan_phymode host_phymode)
wadesongd3f8d3a2019-09-16 17:26:07 +08001239{
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301240 WMI_HOST_WLAN_PHY_MODE fw_phymode;
wadesongd3f8d3a2019-09-16 17:26:07 +08001241
1242 switch (host_phymode) {
1243 case WLAN_PHYMODE_11A:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301244 return WMI_HOST_MODE_11A;
wadesongd3f8d3a2019-09-16 17:26:07 +08001245 case WLAN_PHYMODE_11G:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301246 return WMI_HOST_MODE_11G;
wadesongd3f8d3a2019-09-16 17:26:07 +08001247 case WLAN_PHYMODE_11B:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301248 return WMI_HOST_MODE_11B;
1249 case WLAN_PHYMODE_11G_ONLY:
1250 return WMI_HOST_MODE_11GONLY;
wadesongd3f8d3a2019-09-16 17:26:07 +08001251 case WLAN_PHYMODE_11NA_HT20:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301252 return WMI_HOST_MODE_11NA_HT20;
wadesongd3f8d3a2019-09-16 17:26:07 +08001253 case WLAN_PHYMODE_11NG_HT20:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301254 return WMI_HOST_MODE_11NG_HT20;
wadesongd3f8d3a2019-09-16 17:26:07 +08001255 case WLAN_PHYMODE_11NA_HT40:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301256 return WMI_HOST_MODE_11NA_HT40;
wadesongd3f8d3a2019-09-16 17:26:07 +08001257 case WLAN_PHYMODE_11NG_HT40:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301258 case WLAN_PHYMODE_11NG_HT40PLUS:
1259 case WLAN_PHYMODE_11NG_HT40MINUS:
1260 return WMI_HOST_MODE_11NG_HT40;
wadesongd3f8d3a2019-09-16 17:26:07 +08001261 case WLAN_PHYMODE_11AC_VHT20:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301262 return WMI_HOST_MODE_11AC_VHT20;
wadesongd3f8d3a2019-09-16 17:26:07 +08001263 case WLAN_PHYMODE_11AC_VHT40:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301264 return WMI_HOST_MODE_11AC_VHT40;
wadesongd3f8d3a2019-09-16 17:26:07 +08001265 case WLAN_PHYMODE_11AC_VHT80:
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301266 return WMI_HOST_MODE_11AC_VHT80;
1267 case WLAN_PHYMODE_11AC_VHT20_2G:
1268 return WMI_HOST_MODE_11AC_VHT20_2G;
1269 case WLAN_PHYMODE_11AC_VHT40PLUS_2G:
1270 case WLAN_PHYMODE_11AC_VHT40MINUS_2G:
1271 case WLAN_PHYMODE_11AC_VHT40_2G:
1272 return WMI_HOST_MODE_11AC_VHT40_2G;
1273 case WLAN_PHYMODE_11AC_VHT80_2G:
1274 return WMI_HOST_MODE_11AC_VHT80_2G;
wadesongd3f8d3a2019-09-16 17:26:07 +08001275 default:
1276 fw_phymode = wma_host_to_fw_phymode_160(host_phymode);
Abhishek Singh7b2fb962019-09-20 13:58:37 +05301277 if (fw_phymode != WMI_HOST_MODE_UNKNOWN)
wadesongd3f8d3a2019-09-16 17:26:07 +08001278 return fw_phymode;
1279 return wma_host_to_fw_phymode_11ax(host_phymode);
1280 }
1281}
1282
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001283/**
1284 * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object
1285 * @wma: wma handle
1286 * @mac_addr: mac addr of peer
1287 * @phymode: phymode value to set
1288 *
1289 * Return: None
1290 */
1291static void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma,
1292 uint8_t *mac_addr,
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301293 enum wlan_phymode phymode)
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001294{
1295 uint8_t pdev_id;
1296 struct wlan_objmgr_peer *peer;
1297 struct wlan_objmgr_psoc *psoc = wma->psoc;
1298
1299 pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1300 peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1301 WLAN_LEGACY_WMA_ID);
1302 if (!peer) {
1303 WMA_LOGE(FL("peer object null"));
1304 return;
1305 }
1306
1307 wlan_peer_obj_lock(peer);
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301308 wlan_peer_set_phymode(peer, phymode);
Naveen Rawatfa2a1002018-05-17 16:06:37 -07001309 wlan_peer_obj_unlock(peer);
1310 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1311}
1312
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001313/**
Jayachandran Sreekumaran2613f322019-03-01 19:05:59 +05301314 * wma_objmgr_set_peer_mlme_type() - set peer type to peer object
1315 * @wma: wma handle
1316 * @mac_addr: mac addr of peer
1317 * @peer_type: peer type value to set
1318 *
1319 * Return: None
1320 */
1321static void wma_objmgr_set_peer_mlme_type(tp_wma_handle wma,
1322 uint8_t *mac_addr,
1323 enum wlan_peer_type peer_type)
1324{
1325 uint8_t pdev_id;
1326 struct wlan_objmgr_peer *peer;
1327 struct wlan_objmgr_psoc *psoc = wma->psoc;
1328
1329 pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
1330 peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1331 WLAN_LEGACY_WMA_ID);
1332 if (!peer) {
1333 WMA_LOGE(FL("peer object null"));
1334 return;
1335 }
1336
1337 wlan_peer_obj_lock(peer);
1338 wlan_peer_set_peer_type(peer, peer_type);
1339 wlan_peer_obj_unlock(peer);
1340 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
1341}
1342
1343/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 * wmi_unified_send_peer_assoc() - send peer assoc command to fw
1345 * @wma: wma handle
1346 * @nw_type: nw type
1347 * @params: add sta params
1348 *
1349 * This function send peer assoc command to firmware with
1350 * different parameters.
1351 *
Govind Singhb30d4c02016-03-24 11:01:23 +05301352 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 */
Govind Singhb30d4c02016-03-24 11:01:23 +05301354QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355 tSirNwType nw_type,
1356 tpAddStaParams params)
1357{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001358 struct cdp_pdev *pdev;
Govind Singhb30d4c02016-03-24 11:01:23 +05301359 struct peer_assoc_params *cmd;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 int32_t ret, max_rates, i;
Govind Singhb30d4c02016-03-24 11:01:23 +05301361 uint8_t *rate_pos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362 wmi_rate_set peer_legacy_rates, peer_ht_rates;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001363 uint32_t num_peer_11b_rates = 0;
1364 uint32_t num_peer_11a_rates = 0;
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301365 enum wlan_phymode phymode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001366 uint32_t peer_nss = 1;
1367 struct wma_txrx_node *intr = NULL;
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001368 bool is_he;
Govind Singhb30d4c02016-03-24 11:01:23 +05301369 QDF_STATUS status;
Abhinav Kumar18285932019-08-08 16:50:06 +05301370 struct mac_context *mac = wma->mac_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001371
Govind Singhb30d4c02016-03-24 11:01:23 +05301372 cmd = qdf_mem_malloc(sizeof(struct peer_assoc_params));
1373 if (!cmd) {
1374 WMA_LOGE("Failed to allocate peer_assoc_params param");
1375 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001376 }
Govind Singhb30d4c02016-03-24 11:01:23 +05301377
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001378 intr = &wma->interfaces[params->smesessionId];
1379
Anurag Chouhan6d760662016-02-20 16:05:43 +05301380 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001381
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07001382 if (!pdev) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001383 WMA_LOGE("%s: Failed to get pdev", __func__);
Govind Singhb30d4c02016-03-24 11:01:23 +05301384 qdf_mem_free(cmd);
1385 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 }
1387
Hong Shi417824f2017-01-12 02:31:14 +08001388 wma_mask_tx_ht_rate(wma, params->supportedRates.supportedMCSSet);
1389
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301390 qdf_mem_zero(&peer_legacy_rates, sizeof(wmi_rate_set));
1391 qdf_mem_zero(&peer_ht_rates, sizeof(wmi_rate_set));
Govind Singhb30d4c02016-03-24 11:01:23 +05301392 qdf_mem_zero(cmd, sizeof(struct peer_assoc_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001394 is_he = wma_is_peer_he_capable(params);
Abhishek Singh1d8bd622018-11-13 11:43:55 +05301395 if ((params->ch_width > CH_WIDTH_40MHZ) &&
1396 ((nw_type == eSIR_11G_NW_TYPE) ||
1397 (nw_type == eSIR_11B_NW_TYPE))) {
1398 WMA_LOGE("ch_width %d sent in 11G, configure to 40MHz",
1399 params->ch_width);
1400 params->ch_width = CH_WIDTH_40MHZ;
1401 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001402 phymode = wma_peer_phymode(nw_type, params->staType,
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001403 params->htCapable, params->ch_width,
1404 params->vhtCapable, is_he);
Wu Gaoefd73542019-08-21 14:32:40 +08001405 if ((intr->type == WMI_VDEV_TYPE_AP) && (phymode > intr->chanmode)) {
1406 WMA_LOGD("Peer phymode %d is not allowed. Set it equal to sap/go phymode %d",
tinlin7db7a5d2019-08-02 17:48:08 +08001407 phymode, intr->chanmode);
1408 phymode = intr->chanmode;
1409 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001410
Karthik Kantamneni22dd0f62018-08-07 14:53:50 +05301411 if (!mac->mlme_cfg->rates.disable_abg_rate_txdata) {
Hong Shia9ef8712017-02-19 21:54:02 +08001412 /* Legacy Rateset */
1413 rate_pos = (uint8_t *) peer_legacy_rates.rates;
1414 for (i = 0; i < SIR_NUM_11B_RATES; i++) {
1415 if (!params->supportedRates.llbRates[i])
1416 continue;
1417 rate_pos[peer_legacy_rates.num_rates++] =
1418 params->supportedRates.llbRates[i];
1419 num_peer_11b_rates++;
1420 }
1421 for (i = 0; i < SIR_NUM_11A_RATES; i++) {
1422 if (!params->supportedRates.llaRates[i])
1423 continue;
1424 rate_pos[peer_legacy_rates.num_rates++] =
1425 params->supportedRates.llaRates[i];
1426 num_peer_11a_rates++;
1427 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 }
1429
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301430 if ((phymode == WLAN_PHYMODE_11A && num_peer_11a_rates == 0) ||
1431 (phymode == WLAN_PHYMODE_11B && num_peer_11b_rates == 0)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001432 WMA_LOGW("%s: Invalid phy rates. phymode 0x%x, 11b_rates %d, 11a_rates %d",
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001433 __func__, phymode, num_peer_11b_rates,
1434 num_peer_11a_rates);
Govind Singhb30d4c02016-03-24 11:01:23 +05301435 qdf_mem_free(cmd);
1436 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001438
1439 /* HT Rateset */
1440 max_rates = sizeof(peer_ht_rates.rates) /
1441 sizeof(peer_ht_rates.rates[0]);
1442 rate_pos = (uint8_t *) peer_ht_rates.rates;
1443 for (i = 0; i < MAX_SUPPORTED_RATES; i++) {
1444 if (params->supportedRates.supportedMCSSet[i / 8] &
1445 (1 << (i % 8))) {
1446 rate_pos[peer_ht_rates.num_rates++] = i;
1447 if (i >= 8) {
1448 /* MCS8 or higher rate is present, must be 2x2 */
1449 peer_nss = 2;
1450 }
1451 }
1452 if (peer_ht_rates.num_rates == max_rates)
1453 break;
1454 }
1455
1456 if (params->htCapable && !peer_ht_rates.num_rates) {
1457 uint8_t temp_ni_rates[8] = { 0x0, 0x1, 0x2, 0x3,
1458 0x4, 0x5, 0x6, 0x7};
1459 /*
1460 * Workaround for EV 116382: The peer is marked HT but with
1461 * supported rx mcs set is set to 0. 11n spec mandates MCS0-7
1462 * for a HT STA. So forcing the supported rx mcs rate to
1463 * MCS 0-7. This workaround will be removed once we get
1464 * clarification from WFA regarding this STA behavior.
1465 */
1466
1467 /* TODO: Do we really need this? */
1468 WMA_LOGW("Peer is marked as HT capable but supported mcs rate is 0");
1469 peer_ht_rates.num_rates = sizeof(temp_ni_rates);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301470 qdf_mem_copy((uint8_t *) peer_ht_rates.rates, temp_ni_rates,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471 peer_ht_rates.num_rates);
1472 }
1473
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474 /* in ap/ibss mode and for tdls peer, use mac address of the peer in
1475 * the other end as the new peer address; in sta mode, use bss id to
1476 * be the new peer address
1477 */
1478 if ((wma_is_vdev_in_ap_mode(wma, params->smesessionId))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 || (wma_is_vdev_in_ibss_mode(wma, params->smesessionId))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001480#ifdef FEATURE_WLAN_TDLS
1481 || (STA_ENTRY_TDLS_PEER == params->staType)
1482#endif /* FEATURE_WLAN_TDLS */
bings672207d2019-06-20 17:39:39 +08001483 ) {
gaurank kathpaliac3803832019-01-28 19:47:44 +05301484 qdf_mem_copy(cmd->peer_mac, params->staMac,
1485 sizeof(cmd->peer_mac));
bings672207d2019-06-20 17:39:39 +08001486 } else {
gaurank kathpaliac3803832019-01-28 19:47:44 +05301487 qdf_mem_copy(cmd->peer_mac, params->bssId,
1488 sizeof(cmd->peer_mac));
bings672207d2019-06-20 17:39:39 +08001489 }
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301490 wma_objmgr_set_peer_mlme_phymode(wma, cmd->peer_mac, phymode);
gaurank kathpaliac3803832019-01-28 19:47:44 +05301491
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001492 cmd->vdev_id = params->smesessionId;
1493 cmd->peer_new_assoc = 1;
1494 cmd->peer_associd = params->assocId;
1495
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301496 cmd->is_wme_set = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001497
1498 if (params->wmmEnabled)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301499 cmd->qos_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500
1501 if (params->uAPSD) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301502 cmd->apsd_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001503 WMA_LOGD("Set WMI_PEER_APSD: uapsd Mask %d", params->uAPSD);
1504 }
1505
1506 if (params->htCapable) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301507 cmd->ht_flag = 1;
1508 cmd->qos_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509 cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510
Krishna Kumaar Natarajan59f546c2016-02-16 10:31:55 -08001511 if (params->ch_width) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301512 cmd->bw_40 = 1;
Krishna Kumaar Natarajan59f546c2016-02-16 10:31:55 -08001513 cmd->peer_rate_caps |= WMI_RC_CW40_FLAG;
1514 if (params->fShortGI40Mhz)
1515 cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
1516 } else if (params->fShortGI20Mhz) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001517 cmd->peer_rate_caps |= WMI_RC_SGI_FLAG;
Krishna Kumaar Natarajan59f546c2016-02-16 10:31:55 -08001518 }
1519 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 if (params->vhtCapable) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301522 cmd->ht_flag = 1;
1523 cmd->qos_flag = 1;
1524 cmd->vht_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525 cmd->peer_rate_caps |= WMI_RC_HT_FLAG;
1526 }
1527
1528 if (params->ch_width == CH_WIDTH_80MHZ)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301529 cmd->bw_80 = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001530 else if (params->ch_width == CH_WIDTH_160MHZ)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301531 cmd->bw_160 = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532 else if (params->ch_width == CH_WIDTH_80P80MHZ)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301533 cmd->bw_160 = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534
1535 cmd->peer_vht_caps = params->vht_caps;
Jayachandran Sreekumaran2613f322019-03-01 19:05:59 +05301536 if (params->p2pCapableSta) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301537 cmd->p2p_capable_sta = 1;
Jayachandran Sreekumaran2613f322019-03-01 19:05:59 +05301538 wma_objmgr_set_peer_mlme_type(wma, params->staMac,
1539 WLAN_PEER_P2P_CLI);
1540 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541
1542 if (params->rmfEnabled)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301543 cmd->is_pmf_enabled = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544
Arif Hussain53cf5692018-04-05 16:35:54 -07001545 if (params->stbc_capable)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301546 cmd->stbc_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547
1548 if (params->htLdpcCapable || params->vhtLdpcCapable)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301549 cmd->ldpc_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550
1551 switch (params->mimoPS) {
1552 case eSIR_HT_MIMO_PS_STATIC:
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301553 cmd->static_mimops_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554 break;
1555 case eSIR_HT_MIMO_PS_DYNAMIC:
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301556 cmd->dynamic_mimops_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 break;
1558 case eSIR_HT_MIMO_PS_NO_LIMIT:
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301559 cmd->spatial_mux_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560 break;
1561 default:
1562 break;
1563 }
1564
Varun Reddy Yeturu4f849e52018-06-15 18:08:37 -07001565 wma_set_twt_peer_caps(params, cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001566#ifdef FEATURE_WLAN_TDLS
1567 if (STA_ENTRY_TDLS_PEER == params->staType)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301568 cmd->auth_flag = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001569#endif /* FEATURE_WLAN_TDLS */
1570
1571 if (params->wpa_rsn
1572#ifdef FEATURE_WLAN_WAPI
1573 || params->encryptType == eSIR_ED_WPI
1574#endif /* FEATURE_WLAN_WAPI */
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001575 ) {
bings11172832019-05-23 16:41:25 +08001576 if (!params->no_ptk_4_way) {
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301577 cmd->need_ptk_4_way = 1;
bings11172832019-05-23 16:41:25 +08001578 WMA_LOGD("no ptk 4 way %d", params->no_ptk_4_way);
1579 }
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001580 WMA_LOGD("Acquire set key wake lock for %d ms",
Dustin Brownd0a76562017-10-13 14:48:37 -07001581 WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001582 wma_acquire_wakelock(&intr->vdev_set_key_wakelock,
Dustin Brownd0a76562017-10-13 14:48:37 -07001583 WMA_VDEV_SET_KEY_WAKELOCK_TIMEOUT);
Alan Chen34250b72019-08-12 16:06:35 -07001584 qdf_runtime_pm_prevent_suspend(
1585 &intr->vdev_set_key_runtime_wakelock);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07001586 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 if (params->wpa_rsn >> 1)
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301588 cmd->need_gtk_2_way = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05301590 wma_unified_peer_state_update(pdev, params->staMac,
1591 params->bssId, params->staType);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592
1593#ifdef FEATURE_WLAN_WAPI
1594 if (params->encryptType == eSIR_ED_WPI) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001595 ret = wma_vdev_set_param(wma->wmi_handle, params->smesessionId,
1596 WMI_VDEV_PARAM_DROP_UNENCRY, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597 if (ret) {
1598 WMA_LOGE
1599 ("Set WMI_VDEV_PARAM_DROP_UNENCRY Param status:%d\n",
1600 ret);
Govind Singhb30d4c02016-03-24 11:01:23 +05301601 qdf_mem_free(cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001602 return ret;
1603 }
1604 }
1605#endif /* FEATURE_WLAN_WAPI */
1606
1607 cmd->peer_caps = params->capab_info;
1608 cmd->peer_listen_intval = params->listenInterval;
1609 cmd->peer_ht_caps = params->ht_caps;
1610 cmd->peer_max_mpdu = (1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
1611 params->maxAmpduSize)) - 1;
1612 cmd->peer_mpdu_density = wma_parse_mpdudensity(params->maxAmpduDensity);
1613
1614 if (params->supportedRates.supportedMCSSet[1] &&
1615 params->supportedRates.supportedMCSSet[2])
1616 cmd->peer_rate_caps |= WMI_RC_TS_FLAG;
1617 else if (params->supportedRates.supportedMCSSet[1])
1618 cmd->peer_rate_caps |= WMI_RC_DS_FLAG;
1619
1620 /* Update peer legacy rate information */
Govind Singhb30d4c02016-03-24 11:01:23 +05301621 cmd->peer_legacy_rates.num_rates = peer_legacy_rates.num_rates;
1622 qdf_mem_copy(cmd->peer_legacy_rates.rates, peer_legacy_rates.rates,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623 peer_legacy_rates.num_rates);
1624
1625 /* Update peer HT rate information */
Govind Singhb30d4c02016-03-24 11:01:23 +05301626 cmd->peer_ht_rates.num_rates = peer_ht_rates.num_rates;
1627 qdf_mem_copy(cmd->peer_ht_rates.rates, peer_ht_rates.rates,
1628 peer_ht_rates.num_rates);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629
1630 /* VHT Rates */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631
1632 cmd->peer_nss = peer_nss;
Naveen Rawatb14cab32015-11-02 17:01:51 -08001633 /*
1634 * Because of DBS a vdev may come up in any of the two MACs with
1635 * different capabilities. STBC capab should be fetched for given
1636 * hard_mode->MAC_id combo. It is planned that firmware should provide
1637 * these dev capabilities. But for now number of tx streams can be used
1638 * to identify if Tx STBC needs to be disabled.
1639 */
1640 if (intr->tx_streams < 2) {
1641 cmd->peer_vht_caps &= ~(1 << SIR_MAC_VHT_CAP_TXSTBC);
1642 WMA_LOGD("Num tx_streams: %d, Disabled txSTBC",
1643 intr->tx_streams);
1644 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 WMA_LOGD("peer_nss %d peer_ht_rates.num_rates %d ", cmd->peer_nss,
1646 peer_ht_rates.num_rates);
1647
Govind Singhb30d4c02016-03-24 11:01:23 +05301648 cmd->vht_capable = params->vhtCapable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649 if (params->vhtCapable) {
1650#define VHT2x2MCSMASK 0xc
Govind Singhb30d4c02016-03-24 11:01:23 +05301651 cmd->rx_max_rate = params->supportedRates.vhtRxHighestDataRate;
1652 cmd->rx_mcs_set = params->supportedRates.vhtRxMCSMap;
1653 cmd->tx_max_rate = params->supportedRates.vhtTxHighestDataRate;
1654 cmd->tx_mcs_set = params->supportedRates.vhtTxMCSMap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655
1656 if (params->vhtSupportedRxNss) {
1657 cmd->peer_nss = params->vhtSupportedRxNss;
1658 } else {
Govind Singhb30d4c02016-03-24 11:01:23 +05301659 cmd->peer_nss = ((cmd->rx_mcs_set & VHT2x2MCSMASK)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001660 == VHT2x2MCSMASK) ? 1 : 2;
1661 }
Kiran Kumar Lokere89f01f02019-08-06 18:22:39 -07001662
1663 if (params->vht_mcs_10_11_supp) {
1664 WMI_SET_BITS(cmd->tx_mcs_set, 16, cmd->peer_nss,
1665 ((1 << cmd->peer_nss) - 1));
1666 WMI_VHT_MCS_NOTIFY_EXT_SS_SET(cmd->tx_mcs_set, 1);
1667 }
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001668 if (params->vht_extended_nss_bw_cap) {
1669 /*
1670 * bit[2:0] : Represents value of Rx NSS for 160 MHz
1671 * bit[5:3] : Represents value of Rx NSS for 80_80 MHz
1672 * Extended NSS support
1673 * bit[30:6]: Reserved
1674 * bit[31] : MSB(0/1): 1 in case of valid data
1675 */
1676 cmd->peer_bw_rxnss_override |= (1 << 31);
1677 cmd->peer_bw_rxnss_override |= params->vht_160mhz_nss;
1678 cmd->peer_bw_rxnss_override |=
1679 (params->vht_80p80mhz_nss << 3);
1680 WMA_LOGD(FL("peer_bw_rxnss_override %0X"),
1681 cmd->peer_bw_rxnss_override);
1682 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001683 }
1684
Krishna Kumaar Natarajand1cd56e2016-09-30 08:43:03 -07001685 WMA_LOGD(FL("rx_max_rate: %d, rx_mcs: %x, tx_max_rate: %d, tx_mcs: %x"),
1686 cmd->rx_max_rate, cmd->rx_mcs_set, cmd->tx_max_rate,
1687 cmd->tx_mcs_set);
1688
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689 /*
1690 * Limit nss to max number of rf chain supported by target
1691 * Otherwise Fw will crash
1692 */
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001693 if (cmd->peer_nss > WMA_MAX_NSS) {
1694 WMA_LOGE(FL("peer Nss %d is more than supported"),
1695 cmd->peer_nss);
Abhishek Singh9100cc82017-04-17 11:03:55 +05301696 cmd->peer_nss = WMA_MAX_NSS;
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001697 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001698
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001699 wma_populate_peer_he_cap(cmd, params);
1700
Pragaspathi Thilagarajb3472f02019-06-04 14:10:44 +05301701 if (!wma_is_vdev_in_ap_mode(wma, params->smesessionId))
1702 intr->nss = cmd->peer_nss;
1703
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301704 /* Till conversion is not done in WMI we need to fill fw phy mode */
1705 cmd->peer_phymode = wma_host_to_fw_phymode(phymode);
Yeshwanth Sriram Guntuka28284412019-05-27 14:22:24 +05301706 WMA_LOGD("%s: vdev_id %d associd %d rate_caps %x peer_caps %x",
1707 __func__, cmd->vdev_id, cmd->peer_associd,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001708 cmd->peer_rate_caps, cmd->peer_caps);
Abhishek Ambure6a2773e2019-10-14 15:15:42 +05301709 WMA_LOGD("%s:listen_intval %d ht_caps %x max_mpdu %d nss %d fw_phymode %d",
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001710 __func__, cmd->peer_listen_intval, cmd->peer_ht_caps,
1711 cmd->peer_max_mpdu, cmd->peer_nss, cmd->peer_phymode);
1712 WMA_LOGD("%s: peer_mpdu_density %d encr_type %d cmd->peer_vht_caps %x",
1713 __func__, cmd->peer_mpdu_density, params->encryptType,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714 cmd->peer_vht_caps);
1715
Govind Singhb30d4c02016-03-24 11:01:23 +05301716 status = wmi_unified_peer_assoc_send(wma->wmi_handle,
1717 cmd);
1718 if (QDF_IS_STATUS_ERROR(status))
Arif Hussain49a5ffc2016-07-19 10:11:58 -07001719 WMA_LOGP(FL("Failed to send peer assoc command status = %d"),
1720 status);
Govind Singhb30d4c02016-03-24 11:01:23 +05301721 qdf_mem_free(cmd);
1722
1723 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724}
1725
1726/**
1727 * wmi_unified_vdev_set_gtx_cfg_send() - set GTX params
1728 * @wmi_handle: wmi handle
1729 * @if_id: vdev id
1730 * @gtx_info: GTX config params
1731 *
1732 * This function set GTX related params in firmware.
1733 *
1734 * Return: 0 for success or error code
1735 */
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301736QDF_STATUS wmi_unified_vdev_set_gtx_cfg_send(wmi_unified_t wmi_handle,
1737 uint32_t if_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738 gtx_config_t *gtx_info)
1739{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301740 struct wmi_gtx_config params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301742 params.gtx_rt_mask[0] = gtx_info->gtxRTMask[0];
1743 params.gtx_rt_mask[1] = gtx_info->gtxRTMask[1];
1744 params.gtx_usrcfg = gtx_info->gtxUsrcfg;
1745 params.gtx_threshold = gtx_info->gtxPERThreshold;
1746 params.gtx_margin = gtx_info->gtxPERMargin;
1747 params.gtx_tpcstep = gtx_info->gtxTPCstep;
1748 params.gtx_tpcmin = gtx_info->gtxTPCMin;
1749 params.gtx_bwmask = gtx_info->gtxBWMask;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001750
Himanshu Agarwal009f1572016-03-09 17:26:02 +05301751 return wmi_unified_vdev_set_gtx_cfg_cmd(wmi_handle,
1752 if_id, &params);
1753
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754}
1755
1756/**
1757 * wma_update_protection_mode() - update protection mode
1758 * @wma: wma handle
1759 * @vdev_id: vdev id
1760 * @llbcoexist: protection mode info
1761 *
1762 * This function set protection mode(RTS/CTS) to fw for passed vdev id.
1763 *
1764 * Return: none
1765 */
1766void wma_update_protection_mode(tp_wma_handle wma, uint8_t vdev_id,
1767 uint8_t llbcoexist)
1768{
Govind Singhd76a5b02016-03-08 15:12:14 +05301769 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001770 enum ieee80211_protmode prot_mode;
1771
1772 prot_mode = llbcoexist ? IEEE80211_PROT_CTSONLY : IEEE80211_PROT_NONE;
1773
Govind Singhd76a5b02016-03-08 15:12:14 +05301774 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775 WMI_VDEV_PARAM_PROTECTION_MODE,
1776 prot_mode);
1777
Govind Singhd76a5b02016-03-08 15:12:14 +05301778 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001779 WMA_LOGE("Failed to send wmi protection mode cmd");
1780 else
1781 WMA_LOGD("Updated protection mode %d to target", prot_mode);
1782}
1783
lifeng7c607dd2017-02-21 21:16:49 +08001784void
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785wma_update_beacon_interval(tp_wma_handle wma, uint8_t vdev_id,
1786 uint16_t beaconInterval)
1787{
Govind Singhd76a5b02016-03-08 15:12:14 +05301788 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001789
Govind Singhd76a5b02016-03-08 15:12:14 +05301790 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001791 WMI_VDEV_PARAM_BEACON_INTERVAL,
1792 beaconInterval);
1793
Govind Singhd76a5b02016-03-08 15:12:14 +05301794 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001795 WMA_LOGE("Failed to update beacon interval");
1796 else
1797 WMA_LOGI("Updated beacon interval %d for vdev %d",
1798 beaconInterval, vdev_id);
1799}
1800
Peng Xu6363ec62017-05-15 11:06:33 -07001801#ifdef WLAN_FEATURE_11AX_BSS_COLOR
1802/**
1803 * wma_update_bss_color() - update beacon bss color in fw
1804 * @wma: wma handle
1805 * @vdev_id: vdev id
1806 * @he_ops: HE operation, only the bss_color and bss_color_disabled fields
1807 * are updated.
1808 *
1809 * Return: none
1810 */
1811static void
1812wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001813 tUpdateBeaconParams *bcn_params)
Peng Xu6363ec62017-05-15 11:06:33 -07001814{
1815 QDF_STATUS ret;
Naveen Rawatdf221b72017-11-15 11:32:31 -08001816 uint32_t dword_he_ops = 0;
Peng Xu6363ec62017-05-15 11:06:33 -07001817
Naveen Rawatdf221b72017-11-15 11:32:31 -08001818 WMI_HEOPS_COLOR_SET(dword_he_ops, bcn_params->bss_color);
1819 WMI_HEOPS_BSSCOLORDISABLE_SET(dword_he_ops,
1820 bcn_params->bss_color_disabled);
1821 WMA_LOGD("vdev: %d, update bss color, HE_OPS: 0x%x",
1822 vdev_id, dword_he_ops);
Peng Xu6363ec62017-05-15 11:06:33 -07001823 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001824 WMI_VDEV_PARAM_BSS_COLOR, dword_he_ops);
Peng Xu6363ec62017-05-15 11:06:33 -07001825 if (QDF_IS_STATUS_ERROR(ret))
1826 WMA_LOGE("Failed to update HE operations");
Peng Xu6363ec62017-05-15 11:06:33 -07001827}
1828#else
1829static void wma_update_bss_color(tp_wma_handle wma, uint8_t vdev_id,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001830 tUpdateBeaconParams *bcn_params)
Peng Xu6363ec62017-05-15 11:06:33 -07001831{
1832}
1833#endif
1834
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835/**
1836 * wma_process_update_beacon_params() - update beacon parameters to target
1837 * @wma: wma handle
1838 * @bcn_params: beacon parameters
1839 *
1840 * Return: none
1841 */
1842void
1843wma_process_update_beacon_params(tp_wma_handle wma,
1844 tUpdateBeaconParams *bcn_params)
1845{
1846 if (!bcn_params) {
1847 WMA_LOGE("bcn_params NULL");
1848 return;
1849 }
1850
1851 if (bcn_params->smeSessionId >= wma->max_bssid) {
1852 WMA_LOGE("Invalid vdev id %d", bcn_params->smeSessionId);
1853 return;
1854 }
1855
1856 if (bcn_params->paramChangeBitmap & PARAM_BCN_INTERVAL_CHANGED) {
1857 wma_update_beacon_interval(wma, bcn_params->smeSessionId,
1858 bcn_params->beaconInterval);
1859 }
1860
1861 if (bcn_params->paramChangeBitmap & PARAM_llBCOEXIST_CHANGED)
1862 wma_update_protection_mode(wma, bcn_params->smeSessionId,
1863 bcn_params->llbCoexist);
Peng Xu6363ec62017-05-15 11:06:33 -07001864
1865 if (bcn_params->paramChangeBitmap & PARAM_BSS_COLOR_CHANGED)
1866 wma_update_bss_color(wma, bcn_params->smeSessionId,
Naveen Rawatdf221b72017-11-15 11:32:31 -08001867 bcn_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868}
1869
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001870void wma_update_rts_params(tp_wma_handle wma, uint32_t value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871{
1872 uint8_t vdev_id;
Govind Singhd76a5b02016-03-08 15:12:14 +05301873 QDF_STATUS ret;
Abhishek Ambure0b2ea322019-09-23 19:25:39 +05301874 struct cdp_vdev *handle;
1875 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001876
1877 for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
Abhishek Ambure0b2ea322019-09-23 19:25:39 +05301878 vdev = wma->interfaces[vdev_id].vdev;
1879 if (!vdev)
1880 continue;
1881 handle = wlan_vdev_get_dp_handle(vdev);
1882 if (handle) {
Govind Singhd76a5b02016-03-08 15:12:14 +05301883 ret = wma_vdev_set_param(wma->wmi_handle,
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001884 vdev_id,
1885 WMI_VDEV_PARAM_RTS_THRESHOLD,
1886 value);
1887 if (QDF_IS_STATUS_ERROR(ret))
1888 WMA_LOGE("Update cfg param fail for vdevId %d",
1889 vdev_id);
1890 }
1891 }
1892}
1893
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001894void wma_update_frag_params(tp_wma_handle wma, uint32_t value)
1895{
1896 uint8_t vdev_id;
1897 QDF_STATUS ret;
Abhishek Ambure0b2ea322019-09-23 19:25:39 +05301898 struct cdp_vdev *handle;
1899 struct wlan_objmgr_vdev *vdev;
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001900
1901 for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
Abhishek Ambure0b2ea322019-09-23 19:25:39 +05301902 vdev = wma->interfaces[vdev_id].vdev;
1903 if (!vdev)
1904 continue;
1905 handle = wlan_vdev_get_dp_handle(vdev);
1906 if (handle) {
Harprit Chhabadabec6de42018-09-10 10:21:15 -07001907 ret = wma_vdev_set_param(wma->wmi_handle,
1908 vdev_id,
1909 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
1910 value);
Govind Singhd76a5b02016-03-08 15:12:14 +05301911 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001912 WMA_LOGE("Update cfg params failed for vdevId %d",
1913 vdev_id);
1914 }
1915 }
1916}
1917
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001918#ifndef CRYPTO_SET_KEY_CONVERGED
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001919/**
1920 * wma_read_cfg_wepkey() - fill key_info for WEP key
1921 * @wma_handle: wma handle
1922 * @key_info: key_info ptr
1923 * @def_key_idx: default key index
1924 * @num_keys: number of keys
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001925 * @vdev: vdev pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001926 *
1927 * This function reads WEP keys from cfg and fills
1928 * up key_info.
1929 *
1930 * Return: none
1931 */
1932static void wma_read_cfg_wepkey(tp_wma_handle wma_handle,
1933 tSirKeys *key_info, uint32_t *def_key_idx,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001934 uint8_t *num_keys,
1935 struct wlan_objmgr_vdev *vdev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001936{
Jeff Johnsone88dd752018-06-07 22:57:54 -07001937 QDF_STATUS status;
Pragaspathi Thilagaraj129d6972018-11-21 10:43:41 +05301938 qdf_size_t val = SIR_MAC_KEY_LENGTH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001939 uint8_t i, j;
Jeff Johnson9f18aa72018-12-02 12:05:12 -08001940 struct mac_context *mac_ctx = wma_handle->mac_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001941
1942 WMA_LOGD("Reading WEP keys from cfg");
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301943
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001944 /* NOTE:def_key_idx is initialized to 0 by the caller */
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301945 *def_key_idx = mac_ctx->mlme_cfg->wep_params.wep_default_key_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001946
1947 for (i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001948 status = mlme_get_wep_key(vdev, &mac_ctx->mlme_cfg->wep_params,
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301949 (MLME_WEP_DEFAULT_KEY_1 +
Pragaspathi Thilagaraj129d6972018-11-21 10:43:41 +05301950 i), key_info[j].key, &val);
Pragaspathi Thilagarajda3b5e22018-09-23 01:55:57 +05301951 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001952 WMA_LOGE("WEP key is not configured at :%d", i);
1953 } else {
1954 key_info[j].keyId = i;
1955 key_info[j].keyLength = (uint16_t) val;
1956 j++;
1957 }
1958 }
1959 *num_keys = j;
1960}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07001961#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001962
Jinwei Chenc163f9e2018-10-29 16:37:00 +08001963#ifdef FEATURE_WLAN_WAPI
1964#define WPI_IV_LEN 16
Manjunathappa Prakash458f6fe2019-05-13 18:33:01 -07001965#if defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
1966 defined(QCA_WIFI_QCA6490)
Jinwei Chenc163f9e2018-10-29 16:37:00 +08001967/**
1968 * wma_fill_in_wapi_key_params() - update key parameters about wapi
1969 * @key_params: wma key parameters
1970 * @params: parameters pointer to be set
1971 * @mode: operation mode
1972 *
1973 * Return: None
1974 */
1975static inline void wma_fill_in_wapi_key_params(
1976 struct wma_set_key_params *key_params,
1977 struct set_key_params *params, uint8_t mode)
1978{
1979 /*
1980 * Since MCL shares same FW with WIN for Napier/Hasting, FW WAPI logic
1981 * is fit for WIN, change it to align with WIN.
1982 */
1983 unsigned char iv_init_ap[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1984 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1985 0x5c, 0x36, 0x5c, 0x37};
1986 unsigned char iv_init_sta[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1987 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
1988 0x5c, 0x36, 0x5c, 0x36};
1989
1990 if (mode == wlan_op_mode_ap) {
1991 qdf_mem_copy(params->rx_iv, iv_init_sta,
1992 WPI_IV_LEN);
1993 qdf_mem_copy(params->tx_iv, iv_init_ap,
1994 WPI_IV_LEN);
1995 } else {
1996 qdf_mem_copy(params->rx_iv, iv_init_ap,
1997 WPI_IV_LEN);
1998 qdf_mem_copy(params->tx_iv, iv_init_sta,
1999 WPI_IV_LEN);
2000 }
2001
2002 params->key_txmic_len = WMA_TXMIC_LEN;
2003 params->key_rxmic_len = WMA_RXMIC_LEN;
2004
2005 params->key_cipher = WMI_CIPHER_WAPI;
2006}
2007#else
2008static inline void wma_fill_in_wapi_key_params(
2009 struct wma_set_key_params *key_params,
2010 struct set_key_params *params, uint8_t mode)
2011{
2012 /*initialize receive and transmit IV with default values */
2013 /* **Note: tx_iv must be sent in reverse** */
2014 unsigned char tx_iv[16] = { 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
2015 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c,
2016 0x36, 0x5c, 0x36, 0x5c};
2017 unsigned char rx_iv[16] = { 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
2018 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
2019 0x5c, 0x36, 0x5c, 0x37};
2020 if (mode == wlan_op_mode_ap) {
2021 /* Authenticator initializes the value of PN as
2022 * 0x5C365C365C365C365C365C365C365C36 for MCastkeyUpdate
2023 */
2024 if (key_params->unicast)
2025 tx_iv[0] = 0x37;
2026
2027 rx_iv[WPI_IV_LEN - 1] = 0x36;
2028 } else {
2029 if (!key_params->unicast)
2030 rx_iv[WPI_IV_LEN - 1] = 0x36;
2031 }
2032
2033 params->key_txmic_len = WMA_TXMIC_LEN;
2034 params->key_rxmic_len = WMA_RXMIC_LEN;
2035
2036 qdf_mem_copy(params->rx_iv, &rx_iv,
2037 WPI_IV_LEN);
2038 qdf_mem_copy(params->tx_iv, &tx_iv,
2039 WPI_IV_LEN);
2040 params->key_cipher = WMI_CIPHER_WAPI;
2041}
2042#endif
2043#endif
2044
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002045#ifndef CRYPTO_SET_KEY_CONVERGED
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046/**
Liangwei Dongf9c09602018-12-20 05:11:26 -05002047 * wma_skip_bip_key_set() - skip the BIP key step or not
2048 * @wma_handle: wma handle
2049 * @iface: txrx node
2050 * @key_cipher: key cipher
2051 *
2052 * if target not support the BIP key cipher, skip the set key command.
2053 *
2054 * Return: true to skip set key to target, otherwise set key to target
2055 */
2056static bool
2057wma_skip_bip_key_set(tp_wma_handle wma_handle, uint32_t key_cipher)
2058{
2059 if ((key_cipher == WMI_CIPHER_AES_GMAC) &&
2060 !wmi_service_enabled(wma_handle->wmi_handle,
2061 wmi_service_gmac_offload_support))
2062 return true;
2063 return false;
2064}
2065
Abhishek Singh7c1c7432019-04-04 12:11:57 +05302066static void wma_set_peer_unicast_cipher(tp_wma_handle wma,
2067 struct set_key_params *params)
2068{
2069 struct wlan_objmgr_peer *peer;
2070
2071 peer = wlan_objmgr_get_peer(wma->psoc,
2072 wlan_objmgr_pdev_get_pdev_id(wma->pdev),
2073 params->peer_mac, WLAN_LEGACY_WMA_ID);
2074 if (!peer) {
2075 WMA_LOGE("Peer of peer_mac %pM not found", params->peer_mac);
2076 return;
2077 }
2078
2079 wlan_peer_set_unicast_cipher(peer, params->key_cipher);
2080 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
2081}
2082
Liangwei Dongf9c09602018-12-20 05:11:26 -05002083/**
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302084 * wma_setup_install_key_cmd() - set key parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002085 * @wma_handle: wma handle
2086 * @key_params: key parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087 * @mode: op mode
2088 *
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302089 * This function fills structure from information
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090 * passed in key_params.
2091 *
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302092 * Return: QDF_STATUS_SUCCESS - success
2093 QDF_STATUS_E_FAILURE - failure
2094 QDF_STATUS_E_NOMEM - invalid request
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095 */
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302096static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097 struct wma_set_key_params
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302098 *key_params, uint8_t mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302100 struct set_key_params params;
2101 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002102 struct wma_txrx_node *iface = NULL;
psimha1dc65bd2018-04-02 12:33:30 -07002103 enum cdp_sec_type sec_type = cdp_sec_type_none;
psimhac2cb9462018-01-31 10:35:25 -08002104 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2105 struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
2106 struct cdp_vdev *txrx_vdev;
2107 uint32_t pn[4] = {0, 0, 0, 0};
2108 uint8_t peer_id;
2109 struct cdp_peer *peer;
Liangwei Dongf9c09602018-12-20 05:11:26 -05002110 bool skip_set_key;
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +05302111
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002112 if ((key_params->key_type == eSIR_ED_NONE &&
2113 key_params->key_len) || (key_params->key_type != eSIR_ED_NONE &&
2114 !key_params->key_len)) {
2115 WMA_LOGE("%s:Invalid set key request", __func__);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302116 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002117 }
2118
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07002119 if (!wma_handle) {
Rajeev Kumar155a3e42017-10-10 15:31:17 -07002120 WMA_LOGE(FL("Invalid wma_handle for vdev_id: %d"),
2121 key_params->vdev_id);
2122 return QDF_STATUS_E_INVAL;
2123 }
Pragaspathi Thilagaraj0d1159e2018-08-08 19:00:36 +05302124
2125 if (!wma_is_vdev_valid(key_params->vdev_id)) {
2126 WMA_LOGE("%s: vdev id:%d is not active ", __func__,
2127 key_params->vdev_id);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07002128 return QDF_STATUS_E_INVAL;
2129 }
psimhac2cb9462018-01-31 10:35:25 -08002130
2131 txrx_vdev = wma_find_vdev_by_id(wma_handle,
2132 key_params->vdev_id);
2133 peer = cdp_peer_find_by_addr(soc, txrx_pdev,
2134 key_params->peer_mac, &peer_id);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07002135 iface = &wma_handle->interfaces[key_params->vdev_id];
2136
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302137 params.vdev_id = key_params->vdev_id;
2138 params.key_idx = key_params->key_idx;
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -08002139 qdf_mem_copy(params.peer_mac, key_params->peer_mac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002140
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302141#ifdef FEATURE_WLAN_WAPI
hangtian127c9532019-01-12 13:29:07 +08002142 qdf_mem_zero(params.tx_iv, 16);
2143 qdf_mem_zero(params.rx_iv, 16);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302144#endif
2145 params.key_txmic_len = 0;
2146 params.key_rxmic_len = 0;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002147 qdf_mem_copy(&params.key_rsc_ctr,
Krunal Soni8afae9b2017-10-20 20:15:54 -07002148 &key_params->key_rsc[0], sizeof(uint64_t));
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302149 params.key_flags = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 if (key_params->unicast)
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302151 params.key_flags |= PAIRWISE_USAGE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152 else
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302153 params.key_flags |= GROUP_USAGE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002154
2155 switch (key_params->key_type) {
2156 case eSIR_ED_NONE:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302157 params.key_cipher = WMI_CIPHER_NONE;
psimha1dc65bd2018-04-02 12:33:30 -07002158 sec_type = cdp_sec_type_none;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002159 break;
2160 case eSIR_ED_WEP40:
2161 case eSIR_ED_WEP104:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302162 params.key_cipher = WMI_CIPHER_WEP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002163 if (key_params->unicast &&
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302164 params.key_idx == key_params->def_key_idx) {
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302165 WMA_LOGD("STA Mode: cmd->key_flags |= TX_USAGE");
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302166 params.key_flags |= TX_USAGE;
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302167 } else if ((mode == wlan_op_mode_ap) &&
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302168 (params.key_idx == key_params->def_key_idx)) {
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302169 WMA_LOGD("AP Mode: cmd->key_flags |= TX_USAGE");
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302170 params.key_flags |= TX_USAGE;
Ganesh Kondabattini59a4a952015-11-30 11:55:40 +05302171 }
psimha1dc65bd2018-04-02 12:33:30 -07002172 sec_type = cdp_sec_type_wep104;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002173 break;
2174 case eSIR_ED_TKIP:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302175 params.key_txmic_len = WMA_TXMIC_LEN;
2176 params.key_rxmic_len = WMA_RXMIC_LEN;
2177 params.key_cipher = WMI_CIPHER_TKIP;
psimha1dc65bd2018-04-02 12:33:30 -07002178 sec_type = cdp_sec_type_tkip;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002179 break;
2180#ifdef FEATURE_WLAN_WAPI
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002181 case eSIR_ED_WPI:
2182 {
Jinwei Chenc163f9e2018-10-29 16:37:00 +08002183 wma_fill_in_wapi_key_params(key_params, &params, mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002184 break;
2185 }
2186#endif /* FEATURE_WLAN_WAPI */
2187 case eSIR_ED_CCMP:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302188 params.key_cipher = WMI_CIPHER_AES_CCM;
psimha1dc65bd2018-04-02 12:33:30 -07002189 sec_type = cdp_sec_type_aes_ccmp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002190 break;
2191#ifdef WLAN_FEATURE_11W
2192 case eSIR_ED_AES_128_CMAC:
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302193 params.key_cipher = WMI_CIPHER_AES_CMAC;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002194 break;
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +05302195 case eSIR_ED_AES_GMAC_128:
2196 case eSIR_ED_AES_GMAC_256:
2197 params.key_cipher = WMI_CIPHER_AES_GMAC;
2198 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002199#endif /* WLAN_FEATURE_11W */
Mukul Sharma05504ac2017-06-08 12:35:53 +05302200 /* Firmware uses length to detect GCMP 128/256*/
2201 case eSIR_ED_GCMP:
2202 case eSIR_ED_GCMP_256:
2203 params.key_cipher = WMI_CIPHER_AES_GCM;
2204 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002205 default:
2206 /* TODO: MFP ? */
2207 WMA_LOGE("%s:Invalid encryption type:%d", __func__,
2208 key_params->key_type);
Krunal Soni8afae9b2017-10-20 20:15:54 -07002209 status = QDF_STATUS_E_NOMEM;
2210 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002211 }
2212
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002213#ifdef BIG_ENDIAN_HOST
2214 {
2215 /* for big endian host, copy engine byte_swap is enabled
2216 * But the key data content is in network byte order
2217 * Need to byte swap the key data content - so when copy engine
2218 * does byte_swap - target gets key_data content in the correct
2219 * order.
2220 */
2221 int8_t i;
2222 uint32_t *destp, *srcp;
2223
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302224 destp = (uint32_t *) params.key_data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002225 srcp = (uint32_t *) key_params->key_data;
2226 for (i = 0;
2227 i < roundup(key_params->key_len, sizeof(uint32_t)) / 4;
2228 i++) {
2229 *destp = le32_to_cpu(*srcp);
2230 destp++;
2231 srcp++;
2232 }
2233 }
2234#else
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302235 qdf_mem_copy((void *)params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002236 (const void *)key_params->key_data, key_params->key_len);
2237#endif /* BIG_ENDIAN_HOST */
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302238 params.key_len = key_params->key_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002239
2240#ifdef WLAN_FEATURE_11W
Himanshu Agarwalfc5d6602018-04-06 17:39:37 +05302241 iface = &wma_handle->interfaces[key_params->vdev_id];
2242
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +05302243 if ((key_params->key_type == eSIR_ED_AES_128_CMAC) ||
2244 (key_params->key_type == eSIR_ED_AES_GMAC_128) ||
2245 (key_params->key_type == eSIR_ED_AES_GMAC_256)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002246 if (iface) {
2247 iface->key.key_length = key_params->key_len;
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05302248 iface->key.key_cipher = params.key_cipher;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302249 qdf_mem_copy(iface->key.key,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002250 (const void *)key_params->key_data,
2251 iface->key.key_length);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302252 if ((params.key_idx == WMA_IGTK_KEY_INDEX_4) ||
2253 (params.key_idx == WMA_IGTK_KEY_INDEX_5))
2254 qdf_mem_zero(iface->key.key_id[params.key_idx -
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002255 WMA_IGTK_KEY_INDEX_4].ipn,
2256 CMAC_IPN_LEN);
2257 }
2258 }
2259#endif /* WLAN_FEATURE_11W */
2260
Abhishek Singh7c1c7432019-04-04 12:11:57 +05302261 if (key_params->unicast)
2262 wma_set_peer_unicast_cipher(wma_handle, &params);
2263
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002264 WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d",
2265 key_params->vdev_id, key_params->key_idx,
2266 key_params->key_type, key_params->key_len);
2267 WMA_LOGD("unicast %d peer_mac %pM def_key_idx %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 key_params->unicast, key_params->peer_mac,
2269 key_params->def_key_idx);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002270 WMA_LOGD("keyrsc param %llu", params.key_rsc_ctr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002271
Krunal Sonibcd09fc2018-10-11 18:17:19 -07002272 /*
2273 * To prevent from any replay-attack, PN number provided by
2274 * upper layer is used.
2275 *
2276 * Plumb the PN number to HW which will be used to evaluate whether
2277 * incoming traffic is not replayed.
2278 *
2279 * supplicant would have some thing like following, example:
2280 *
2281 * num = 0x123456789ABCDEFF (64 bit number)
2282 * uint8_t keyrsc[16] would look like following
2283 *
2284 * bit 0 7 15 23 31 39 47 55 63
2285 * +------+-------+-------+-------+-------+-------+-------+-------+
2286 * byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
2287 * +------+-------+-------+-------+-------+-------+-------+-------+
2288 * value| 0xFF | 0XDE | 0xBC | 0x9A | 0x78 | 0x56 | 0x34 | 0x12 |
2289 * +------+-------+-------+-------+-------+-------+-------+-------+
2290 */
2291 qdf_mem_copy(&pn[0],
2292 &key_params->key_rsc[0], sizeof(pn));
2293 wma_debug("key_type[%s] pn[%x:%x:%x:%x]",
2294 (key_params->unicast) ? "unicast" : "group",
2295 key_params->key_rsc[3], key_params->key_rsc[2],
2296 key_params->key_rsc[1], key_params->key_rsc[0]);
psimhac2cb9462018-01-31 10:35:25 -08002297 cdp_set_pn_check(soc, txrx_vdev, peer, sec_type, pn);
psimha8696f772018-04-03 17:38:38 -07002298 cdp_set_key(soc, peer, key_params->unicast,
2299 (uint32_t *)(key_params->key_data +
2300 WMA_IV_KEY_LEN +
2301 WMA_TXMIC_LEN));
psimhac2cb9462018-01-31 10:35:25 -08002302
Liangwei Dongf9c09602018-12-20 05:11:26 -05002303 skip_set_key = wma_skip_bip_key_set(wma_handle, params.key_cipher);
2304 if (!skip_set_key)
2305 status = wmi_unified_setup_install_key_cmd(
2306 wma_handle->wmi_handle, &params);
2307
Rajeev Kumar155a3e42017-10-10 15:31:17 -07002308 if (!key_params->unicast) {
2309 /* Its GTK release the wake lock */
2310 WMA_LOGD("Release set key wake lock");
Alan Chen34250b72019-08-12 16:06:35 -07002311 qdf_runtime_pm_allow_suspend(
2312 &iface->vdev_set_key_runtime_wakelock);
Rajeev Kumar155a3e42017-10-10 15:31:17 -07002313 wma_release_wakelock(&iface->vdev_set_key_wakelock);
2314 }
Naveen Rawatd7734142017-10-27 10:02:40 -07002315
2316 /* install key was requested */
gaurank kathpaliabcbde362017-12-11 21:11:53 +05302317 if (iface)
2318 iface->is_waiting_for_key = false;
Naveen Rawatd7734142017-10-27 10:02:40 -07002319
Krunal Soni8afae9b2017-10-20 20:15:54 -07002320end:
gaurank kathpalia6d25c972019-03-07 20:25:28 +05302321 qdf_mem_zero(&params, sizeof(struct set_key_params));
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302322 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002323}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002324#endif
2325
2326#ifdef QCA_IBSS_SUPPORT
2327/**
2328 * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer
2329 * @peer_num: number of peers
2330 *
2331 * Return: heart beat timer value
2332 */
2333static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num)
2334{
2335 /* heart beat timer value look-up table */
2336 /* entry index : (the number of currently connected peers) - 1
2337 * entry value : the heart time threshold value in seconds for
2338 * detecting ibss peer departure
2339 */
2340 static const uint16_t heart_beat_timer[MAX_PEERS] = {
2341 4, 4, 4, 4, 4, 4, 4, 4,
2342 8, 8, 8, 8, 8, 8, 8, 8,
2343 12, 12, 12, 12, 12, 12, 12, 12,
2344 16, 16, 16, 16, 16, 16, 16, 16
2345 };
2346
2347 if (peer_num < 1 || peer_num > MAX_PEERS)
2348 return 0;
2349
2350 return heart_beat_timer[peer_num - 1];
2351}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002353void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
2354 uint8_t vdev_id,
2355 int8_t peer_num_delta)
2356{
2357 struct cdp_vdev *vdev;
2358 int16_t new_peer_num;
2359 uint16_t new_timer_value_sec;
2360 uint32_t new_timer_value_ms;
2361 QDF_STATUS status;
2362 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2363
2364 if (peer_num_delta != 1 && peer_num_delta != -1) {
2365 WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta);
2366 return;
2367 }
2368
2369 vdev = wma_find_vdev_by_id(wma, vdev_id);
2370 if (!vdev) {
2371 WMA_LOGE("vdev not found : vdev_id %d", vdev_id);
2372 return;
2373 }
2374
2375 /* adjust peer numbers */
2376 new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc, vdev,
2377 peer_num_delta
2378 );
2379 if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) {
2380 WMA_LOGE("new peer num %d out of valid boundary", new_peer_num);
2381 return;
2382 }
2383
2384 /* reset timer value if all peers departed */
2385 if (new_peer_num == 0) {
2386 cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0);
2387 return;
2388 }
2389
2390 /* calculate new timer value */
2391 new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num);
2392 if (new_timer_value_sec == 0) {
2393 WMA_LOGE("timer value %d is invalid for peer number %d",
2394 new_timer_value_sec, new_peer_num);
2395 return;
2396 }
2397 if (new_timer_value_sec ==
2398 cdp_set_ibss_vdev_heart_beat_timer(soc, vdev,
2399 new_timer_value_sec)) {
2400 WMA_LOGD("timer value %d stays same, no need to notify target",
2401 new_timer_value_sec);
2402 return;
2403 }
2404
2405 new_timer_value_ms = ((uint32_t)new_timer_value_sec) * 1000;
2406
2407 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
2408 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
2409 new_timer_value_ms);
2410 if (QDF_IS_STATUS_ERROR(status)) {
2411 WMA_LOGE("Failed to set IBSS link monitoring timer value");
2412 return;
2413 }
2414
2415 WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d",
2416 new_peer_num, new_timer_value_ms);
2417}
Abhishek Ambure23beaf52019-09-24 12:40:56 +05302418#endif /* QCA_IBSS_SUPPORT */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002419
Abhishek Ambure23beaf52019-09-24 12:40:56 +05302420#ifndef CRYPTO_SET_KEY_CONVERGED
2421#ifdef QCA_IBSS_SUPPORT
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002422/**
2423 * wma_set_ibsskey_helper() - cached IBSS key in wma handle
2424 * @wma_handle: wma handle
2425 * @key_info: set bss key info
2426 * @peerMacAddr: peer mac address
2427 *
2428 * Return: none
2429 */
2430static void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
2431 tpSetBssKeyParams key_info,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302432 struct qdf_mac_addr peer_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002433{
2434 struct wma_set_key_params key_params;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302435 QDF_STATUS status = QDF_STATUS_SUCCESS;
2436 uint32_t i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002437 uint32_t def_key_idx = 0;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002438 struct cdp_vdev *txrx_vdev;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002439 int opmode;
Leo Chang96464902016-10-28 11:10:54 -07002440 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002441 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002442
2443 WMA_LOGD("BSS key setup for peer");
Abhishek Singhefe21e62019-09-20 10:03:24 +05302444 txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002445 if (!txrx_vdev) {
2446 WMA_LOGE("%s:Invalid vdev handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302447 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002448 return;
2449 }
2450
hangtian127c9532019-01-12 13:29:07 +08002451 qdf_mem_zero(&key_params, sizeof(key_params));
Leo Chang96464902016-10-28 11:10:54 -07002452 opmode = cdp_get_opmode(soc, txrx_vdev);
hangtian127c9532019-01-12 13:29:07 +08002453 qdf_mem_zero(&key_params, sizeof(key_params));
Abhishek Singhefe21e62019-09-20 10:03:24 +05302454 key_params.vdev_id = key_info->vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002455 key_params.key_type = key_info->encType;
2456 key_params.singl_tid_rc = key_info->singleTidRc;
2457 key_params.unicast = false;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002458 ASSERT(wlan_op_mode_ibss == opmode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002459
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302460 qdf_mem_copy(key_params.peer_mac, peer_macaddr.bytes,
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302461 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462
2463 if (key_info->numKeys == 0 &&
2464 (key_info->encType == eSIR_ED_WEP40 ||
2465 key_info->encType == eSIR_ED_WEP104)) {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002466 vdev =
2467 wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
Abhishek Singhefe21e62019-09-20 10:03:24 +05302468 key_info->vdev_id,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002469 WLAN_LEGACY_WMA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002470 wma_read_cfg_wepkey(wma_handle, key_info->key,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002471 &def_key_idx, &key_info->numKeys, vdev);
2472 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
Masti, Narayanraddiab712a72016-08-04 11:59:11 +05302473 } else if ((key_info->encType == eSIR_ED_WEP40) ||
2474 (key_info->encType == eSIR_ED_WEP104)) {
2475 struct wma_txrx_node *intf =
Abhishek Singhefe21e62019-09-20 10:03:24 +05302476 &wma_handle->interfaces[key_info->vdev_id];
Masti, Narayanraddiab712a72016-08-04 11:59:11 +05302477 key_params.def_key_idx = intf->wep_default_key_idx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002478 }
2479
2480 for (i = 0; i < key_info->numKeys; i++) {
2481 if (key_params.key_type != eSIR_ED_NONE &&
2482 !key_info->key[i].keyLength)
2483 continue;
2484 key_params.key_idx = key_info->key[i].keyId;
2485 key_params.key_len = key_info->key[i].keyLength;
2486 if (key_info->encType == eSIR_ED_TKIP) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302487 qdf_mem_copy(key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002488 key_info->key[i].key, 16);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302489 qdf_mem_copy(&key_params.key_data[16],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490 &key_info->key[i].key[24], 8);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302491 qdf_mem_copy(&key_params.key_data[24],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492 &key_info->key[i].key[16], 8);
2493 } else
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302494 qdf_mem_copy((void *)key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002495 (const void *)key_info->key[i].key,
2496 key_info->key[i].keyLength);
2497
2498 WMA_LOGD("%s: peer bcast key[%d] length %d", __func__, i,
2499 key_info->key[i].keyLength);
2500
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302501 status = wma_setup_install_key_cmd(wma_handle, &key_params,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002502 opmode);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302503 if (status == QDF_STATUS_E_NOMEM) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002504 WMA_LOGE("%s:Failed to setup install key buf",
2505 __func__);
2506 return;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302507 } else if (status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002508 WMA_LOGE("%s:Failed to send install key command",
2509 __func__);
2510 }
2511 }
2512}
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302513#else
2514static inline
2515void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
2516 tpSetBssKeyParams key_info,
2517 struct qdf_mac_addr peer_macaddr)
2518{
2519}
2520#endif /* QCA_IBSS_SUPPORT */
2521
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302522void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info)
2523{
2524 struct wma_set_key_params key_params;
2525 QDF_STATUS status = QDF_STATUS_SUCCESS;
2526 uint32_t i;
2527 uint32_t def_key_idx = 0;
2528 uint32_t wlan_opmode;
2529 struct cdp_vdev *txrx_vdev;
Abhishek Ambure3ee80882019-09-20 16:32:12 +05302530 uint8_t *mac_addr, *bssid;
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302531 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2532 struct wlan_objmgr_vdev *vdev;
2533
2534 WMA_LOGD("BSS key setup");
Abhishek Singhefe21e62019-09-20 10:03:24 +05302535 txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->vdev_id);
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302536 if (!txrx_vdev) {
2537 WMA_LOGE("%s:Invalid vdev handle", __func__);
2538 key_info->status = QDF_STATUS_E_FAILURE;
2539 goto out;
2540 }
2541 wlan_opmode = cdp_get_opmode(soc, txrx_vdev);
2542
2543 /*
2544 * For IBSS, WMI expects the BSS key to be set per peer key
2545 * So cache the BSS key in the wma_handle and re-use it when the
2546 * STA key is been setup for a peer
2547 */
2548 if (wlan_op_mode_ibss == wlan_opmode) {
2549 key_info->status = QDF_STATUS_SUCCESS;
2550 if (wma_handle->ibss_started > 0)
2551 goto out;
2552 WMA_LOGD("Caching IBSS Key");
2553 qdf_mem_copy(&wma_handle->ibsskey_info, key_info,
2554 sizeof(tSetBssKeyParams));
2555 }
2556
2557 qdf_mem_zero(&key_params, sizeof(key_params));
Abhishek Singhefe21e62019-09-20 10:03:24 +05302558 key_params.vdev_id = key_info->vdev_id;
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302559 key_params.key_type = key_info->encType;
2560 key_params.singl_tid_rc = key_info->singleTidRc;
2561 key_params.unicast = false;
2562 if (wlan_opmode == wlan_op_mode_sta) {
Abhishek Ambure3ee80882019-09-20 16:32:12 +05302563 bssid = wma_get_vdev_bssid
2564 (wma_handle->interfaces[key_info->vdev_id].vdev);
2565 if (!bssid) {
2566 WMA_LOGE("%s: Failed to get bssid for vdev_%d",
2567 __func__, key_info->vdev_id);
2568 key_info->status = QDF_STATUS_E_FAILURE;
2569 goto out;
2570 }
2571 qdf_mem_copy(key_params.peer_mac, bssid, QDF_MAC_ADDR_SIZE);
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302572 } else {
2573 mac_addr = cdp_get_vdev_mac_addr(soc, txrx_vdev);
2574 if (!mac_addr) {
2575 WMA_LOGE("%s: mac_addr is NULL for vdev with id %d",
Abhishek Singhefe21e62019-09-20 10:03:24 +05302576 __func__, key_info->vdev_id);
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302577 goto out;
2578 }
2579 /* vdev mac address will be passed for all other modes */
2580 qdf_mem_copy(key_params.peer_mac, mac_addr,
2581 QDF_MAC_ADDR_SIZE);
2582 WMA_LOGD("BSS Key setup with vdev_mac %pM\n",
2583 mac_addr);
2584 }
2585
2586 if (key_info->numKeys == 0 &&
2587 (key_info->encType == eSIR_ED_WEP40 ||
2588 key_info->encType == eSIR_ED_WEP104)) {
2589 vdev =
2590 wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
Abhishek Singhefe21e62019-09-20 10:03:24 +05302591 key_info->vdev_id,
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302592 WLAN_LEGACY_WMA_ID);
2593 wma_read_cfg_wepkey(wma_handle, key_info->key,
2594 &def_key_idx, &key_info->numKeys, vdev);
2595 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
2596 } else if ((key_info->encType == eSIR_ED_WEP40) ||
2597 (key_info->encType == eSIR_ED_WEP104)) {
2598 struct wma_txrx_node *intf =
Abhishek Singhefe21e62019-09-20 10:03:24 +05302599 &wma_handle->interfaces[key_info->vdev_id];
Abhishek Ambure8ed62cb2019-09-11 19:03:57 +05302600 key_params.def_key_idx = intf->wep_default_key_idx;
2601 }
2602
2603 for (i = 0; i < key_info->numKeys; i++) {
2604 if (key_params.key_type != eSIR_ED_NONE &&
2605 !key_info->key[i].keyLength)
2606 continue;
2607 if (key_info->encType == eSIR_ED_WPI) {
2608 key_params.key_idx = key_info->key[i].keyId;
2609 key_params.def_key_idx = key_info->key[i].keyId;
2610 } else {
2611 key_params.key_idx = key_info->key[i].keyId;
2612 }
2613
2614 key_params.key_len = key_info->key[i].keyLength;
2615 qdf_mem_copy(key_params.key_rsc,
2616 key_info->key[i].keyRsc,
2617 WLAN_CRYPTO_RSC_SIZE);
2618 if (key_info->encType == eSIR_ED_TKIP) {
2619 qdf_mem_copy(key_params.key_data,
2620 key_info->key[i].key, 16);
2621 qdf_mem_copy(&key_params.key_data[16],
2622 &key_info->key[i].key[24], 8);
2623 qdf_mem_copy(&key_params.key_data[24],
2624 &key_info->key[i].key[16], 8);
2625 } else
2626 qdf_mem_copy((void *)key_params.key_data,
2627 (const void *)key_info->key[i].key,
2628 key_info->key[i].keyLength);
2629
2630 WMA_LOGD("%s: bss key[%d] length %d", __func__, i,
2631 key_info->key[i].keyLength);
2632
2633 status = wma_setup_install_key_cmd(wma_handle, &key_params,
2634 wlan_opmode);
2635 if (status == QDF_STATUS_E_NOMEM) {
2636 WMA_LOGE("%s:Failed to setup install key buf",
2637 __func__);
2638 key_info->status = QDF_STATUS_E_NOMEM;
2639 goto out;
2640 } else if (status == QDF_STATUS_E_FAILURE) {
2641 WMA_LOGE("%s:Failed to send install key command",
2642 __func__);
2643 key_info->status = QDF_STATUS_E_FAILURE;
2644 goto out;
2645 }
2646 }
2647
2648 wma_handle->ibss_started++;
2649 /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */
2650 key_info->status = QDF_STATUS_SUCCESS;
2651
2652 qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params));
2653
2654out:
2655 wma_send_msg_high_priority(wma_handle, WMA_SET_BSSKEY_RSP,
2656 (void *)key_info, 0);
2657}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002658
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002659void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info)
2660{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302661 int32_t i;
2662 QDF_STATUS status = QDF_STATUS_SUCCESS;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002663 struct cdp_pdev *txrx_pdev;
2664 struct cdp_vdev *txrx_vdev;
Leo Chang96464902016-10-28 11:10:54 -07002665 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666 uint8_t num_keys = 0, peer_id;
2667 struct wma_set_key_params key_params;
2668 uint32_t def_key_idx = 0;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002669 int opmode;
Leo Chang96464902016-10-28 11:10:54 -07002670 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002671 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002672
2673 WMA_LOGD("STA key setup");
2674
2675 /* Get the txRx Pdev handle */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302676 txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002677 if (!txrx_pdev) {
2678 WMA_LOGE("%s:Invalid txrx pdev handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302679 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680 goto out;
2681 }
2682
Leo Chang96464902016-10-28 11:10:54 -07002683 peer = cdp_peer_find_by_addr(soc, txrx_pdev,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002684 key_info->peer_macaddr.bytes,
2685 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002686 if (!peer) {
2687 WMA_LOGE("%s:Invalid peer for key setting", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302688 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002689 goto out;
2690 }
2691
Abhishek Singhefe21e62019-09-20 10:03:24 +05302692 txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693 if (!txrx_vdev) {
2694 WMA_LOGE("%s:TxRx Vdev Handle is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302695 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696 goto out;
2697 }
Leo Chang96464902016-10-28 11:10:54 -07002698 opmode = cdp_get_opmode(soc, txrx_vdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002699
2700 if (key_info->defWEPIdx == WMA_INVALID_KEY_IDX &&
2701 (key_info->encType == eSIR_ED_WEP40 ||
2702 key_info->encType == eSIR_ED_WEP104) &&
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002703 opmode != wlan_op_mode_ap) {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002704 vdev =
2705 wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
Abhishek Singhefe21e62019-09-20 10:03:24 +05302706 key_info->vdev_id,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002707 WLAN_LEGACY_WMA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002708 wma_read_cfg_wepkey(wma_handle, key_info->key,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002709 &def_key_idx, &num_keys, vdev);
2710 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002711 key_info->defWEPIdx = def_key_idx;
2712 } else {
2713 num_keys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
2714 if (key_info->encType != eSIR_ED_NONE) {
2715 for (i = 0; i < num_keys; i++) {
2716 if (key_info->key[i].keyDirection ==
2717 eSIR_TX_DEFAULT) {
2718 key_info->defWEPIdx = i;
2719 break;
2720 }
2721 }
2722 }
2723 }
hangtian127c9532019-01-12 13:29:07 +08002724 qdf_mem_zero(&key_params, sizeof(key_params));
Abhishek Singhefe21e62019-09-20 10:03:24 +05302725 key_params.vdev_id = key_info->vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002726 key_params.key_type = key_info->encType;
2727 key_params.singl_tid_rc = key_info->singleTidRc;
2728 key_params.unicast = true;
2729 key_params.def_key_idx = key_info->defWEPIdx;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302730 qdf_mem_copy((void *)key_params.peer_mac,
Srinivas Girigowdad5965c42015-12-04 13:43:16 -08002731 (const void *)key_info->peer_macaddr.bytes,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -08002732 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002733 for (i = 0; i < num_keys; i++) {
2734 if (key_params.key_type != eSIR_ED_NONE &&
2735 !key_info->key[i].keyLength)
2736 continue;
2737 if (key_info->encType == eSIR_ED_TKIP) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302738 qdf_mem_copy(key_params.key_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002739 key_info->key[i].key, 16);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302740 qdf_mem_copy(&key_params.key_data[16],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002741 &key_info->key[i].key[24], 8);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302742 qdf_mem_copy(&key_params.key_data[24],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743 &key_info->key[i].key[16], 8);
2744 } else
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302745 qdf_mem_copy(key_params.key_data, key_info->key[i].key,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002746 key_info->key[i].keyLength);
2747 if (key_info->encType == eSIR_ED_WPI) {
2748 key_params.key_idx = key_info->key[i].keyId;
2749 key_params.def_key_idx = key_info->key[i].keyId;
2750 } else
2751 key_params.key_idx = i;
2752
2753 key_params.key_len = key_info->key[i].keyLength;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302754 status = wma_setup_install_key_cmd(wma_handle, &key_params,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002755 opmode);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302756 if (status == QDF_STATUS_E_NOMEM) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002757 WMA_LOGE("%s:Failed to setup install key buf",
2758 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302759 key_info->status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002760 goto out;
2761 }
2762
2763 WMA_LOGD("%s: peer unicast key[%d] %d ", __func__, i,
2764 key_info->key[i].keyLength);
2765
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302766 if (status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002767 WMA_LOGE("%s:Failed to send install key command",
2768 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302769 key_info->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002770 goto out;
2771 }
2772 }
2773
2774 /* In IBSS mode, set the BSS KEY for this peer
2775 * BSS key is supposed to be cache into wma_handle
2776 */
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07002777 if (wlan_op_mode_ibss == opmode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002778 wma_set_ibsskey_helper(wma_handle, &wma_handle->ibsskey_info,
Srinivas Girigowdad5965c42015-12-04 13:43:16 -08002779 key_info->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 }
2781
2782 /* TODO: Should we wait till we get HTT_T2H_MSG_TYPE_SEC_IND? */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302783 key_info->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002784out:
gaurank kathpalia6d25c972019-03-07 20:25:28 +05302785 qdf_mem_zero(&key_params, sizeof(struct wma_set_key_params));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002786 if (key_info->sendRsp)
Abhishek Singh2d775fd2017-08-18 10:51:33 +05302787 wma_send_msg_high_priority(wma_handle, WMA_SET_STAKEY_RSP,
2788 (void *)key_info, 0);
Will Huangaaa2a052019-05-14 15:39:13 +08002789 else
2790 qdf_mem_free(key_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002791}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07002792#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002793
2794/**
2795 * wma_process_update_edca_param_req() - update EDCA params
2796 * @handle: wma handle
2797 * @edca_params: edca parameters
2798 *
2799 * This function updates EDCA parameters to the target
2800 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302801 * Return: QDF Status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002802 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302803QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002804 tEdcaParams *edca_params)
2805{
2806 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002807 struct wmi_host_wme_vparams wmm_param[QCA_WLAN_AC_ALL];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002808 tSirMacEdcaParamRecord *edca_record;
2809 int ac;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002810 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 struct ol_tx_wmm_param_t ol_tx_wmm_param;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302812 uint8_t vdev_id;
2813 QDF_STATUS status;
Leo Chang96464902016-10-28 11:10:54 -07002814 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07002815
Abhishek Singh78b97402019-09-19 14:19:36 +05302816 vdev_id = edca_params->vdev_id;
Pragaspathi Thilagarajd5cb9e82019-02-04 14:13:52 +05302817 if (!wma_is_vdev_valid(vdev_id)) {
2818 WMA_LOGE("%s: vdev id:%d is not active ", __func__, vdev_id);
2819 goto fail;
2820 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002821
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002822 for (ac = 0; ac < QCA_WLAN_AC_ALL; ac++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002823 switch (ac) {
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002824 case QCA_WLAN_AC_BE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002825 edca_record = &edca_params->acbe;
2826 break;
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002827 case QCA_WLAN_AC_BK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002828 edca_record = &edca_params->acbk;
2829 break;
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002830 case QCA_WLAN_AC_VI:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002831 edca_record = &edca_params->acvi;
2832 break;
Srinivas Girigowda167ea822019-03-21 17:19:30 -07002833 case QCA_WLAN_AC_VO:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002834 edca_record = &edca_params->acvo;
2835 break;
2836 default:
2837 goto fail;
2838 }
2839
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -08002840 wma_update_edca_params_for_ac(edca_record, &wmm_param[ac], ac,
2841 edca_params->mu_edca_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002842
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302843 ol_tx_wmm_param.ac[ac].aifs = wmm_param[ac].aifs;
2844 ol_tx_wmm_param.ac[ac].cwmin = wmm_param[ac].cwmin;
2845 ol_tx_wmm_param.ac[ac].cwmax = wmm_param[ac].cwmax;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002846 }
2847
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302848 status = wmi_unified_process_update_edca_param(wma_handle->wmi_handle,
Kiran Kumar Lokere27026ae2018-03-09 11:38:19 -08002849 vdev_id,
2850 edca_params->mu_edca_params,
2851 wmm_param);
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302852 if (status == QDF_STATUS_E_NOMEM)
2853 return status;
2854 else if (status == QDF_STATUS_E_FAILURE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002855 goto fail;
2856
Anurag Chouhan6d760662016-02-20 16:05:43 +05302857 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Himanshu Agarwal94045e42015-10-19 19:16:19 +05302858 if (pdev)
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002859 cdp_set_wmm_param(soc, (struct cdp_pdev *)pdev,
2860 ol_tx_wmm_param);
Himanshu Agarwal94045e42015-10-19 19:16:19 +05302861 else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302862 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002863
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302864 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002865
2866fail:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002867 WMA_LOGE("%s: Failed to set WMM Paremeters", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302868 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002869}
2870
2871/**
2872 * wmi_unified_probe_rsp_tmpl_send() - send probe response template to fw
2873 * @wma: wma handle
2874 * @vdev_id: vdev id
2875 * @probe_rsp_info: probe response info
2876 *
2877 * Return: 0 for success or error code
2878 */
2879static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002880 uint8_t vdev_id,
2881 tpSendProbeRespParams probe_rsp_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002882{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002883 uint64_t adjusted_tsf_le;
2884 struct ieee80211_frame *wh;
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302885 struct wmi_probe_resp_params params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002886
2887 WMA_LOGD(FL("Send probe response template for vdev %d"), vdev_id);
2888
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002889 /*
2890 * Make the TSF offset negative so probe response in the same
2891 * staggered batch have the same TSF.
2892 */
2893 adjusted_tsf_le = cpu_to_le64(0ULL -
2894 wma->interfaces[vdev_id].tsfadjust);
2895 /* Update the timstamp in the probe response buffer with adjusted TSF */
Abhinav Kumar68834222018-07-18 19:06:14 +05302896 wh = (struct ieee80211_frame *)probe_rsp_info->probeRespTemplate;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002897 A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
2898
Krunal Soni15650672017-11-14 15:42:01 -08002899 params.prb_rsp_template_len = probe_rsp_info->probeRespTemplateLen;
Abhinav Kumar68834222018-07-18 19:06:14 +05302900 params.prb_rsp_template_frm = probe_rsp_info->probeRespTemplate;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002901
Himanshu Agarwal009f1572016-03-09 17:26:02 +05302902 return wmi_unified_probe_rsp_tmpl_send_cmd(wma->wmi_handle, vdev_id,
Krunal Soni15650672017-11-14 15:42:01 -08002903 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002904}
2905
2906/**
Govind Singh61ad2622016-02-22 17:25:02 +05302907 * wma_unified_bcn_tmpl_send() - send beacon template to fw
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908 * @wma:wma handle
2909 * @vdev_id: vdev id
2910 * @bcn_info: beacon info
2911 * @bytes_to_strip: bytes to strip
2912 *
Govind Singh61ad2622016-02-22 17:25:02 +05302913 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002914 */
Govind Singh61ad2622016-02-22 17:25:02 +05302915static QDF_STATUS wma_unified_bcn_tmpl_send(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002916 uint8_t vdev_id,
Govind Singh61ad2622016-02-22 17:25:02 +05302917 const tpSendbeaconParams bcn_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002918 uint8_t bytes_to_strip)
2919{
Govind Singh4ff22582017-04-25 16:01:53 +05302920 struct beacon_tmpl_params params = {0};
Govind Singh61ad2622016-02-22 17:25:02 +05302921 uint32_t tmpl_len, tmpl_len_aligned;
2922 uint8_t *frm;
2923 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002924 uint8_t *p2p_ie;
2925 uint16_t p2p_ie_len = 0;
2926 uint64_t adjusted_tsf_le;
2927 struct ieee80211_frame *wh;
2928
Pragaspathi Thilagarajd5cb9e82019-02-04 14:13:52 +05302929 if (!wma_is_vdev_valid(vdev_id)) {
2930 WMA_LOGE("%s: vdev id:%d is not active ", __func__, vdev_id);
2931 return QDF_STATUS_E_INVAL;
2932 }
2933
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002934 WMA_LOGD("Send beacon template for vdev %d", vdev_id);
2935
2936 if (bcn_info->p2pIeOffset) {
2937 p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
2938 p2p_ie_len = (uint16_t) p2p_ie[1] + 2;
2939 }
2940
2941 /*
2942 * XXX: The first byte of beacon buffer contains beacon length
2943 * only when UMAC in sending the beacon template. In othercases
2944 * (ex: from tbtt update) beacon length is read from beacon
2945 * information.
2946 */
2947 if (bytes_to_strip)
2948 tmpl_len = *(uint32_t *) &bcn_info->beacon[0];
2949 else
2950 tmpl_len = bcn_info->beaconLength;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002951 if (p2p_ie_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002952 tmpl_len -= (uint32_t) p2p_ie_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002953 frm = bcn_info->beacon + bytes_to_strip;
2954 tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32));
2955 /*
2956 * Make the TSF offset negative so beacons in the same
2957 * staggered batch have the same TSF.
2958 */
2959 adjusted_tsf_le = cpu_to_le64(0ULL -
2960 wma->interfaces[vdev_id].tsfadjust);
2961 /* Update the timstamp in the beacon buffer with adjusted TSF */
2962 wh = (struct ieee80211_frame *)frm;
2963 A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le));
2964
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002965
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002966
Govind Singh61ad2622016-02-22 17:25:02 +05302967 params.vdev_id = vdev_id;
2968 params.tim_ie_offset = bcn_info->timIeOffset - bytes_to_strip;
2969 params.tmpl_len = tmpl_len;
2970 params.frm = frm;
2971 params.tmpl_len_aligned = tmpl_len_aligned;
Vignesh Viswanathan8777d3b2018-05-24 12:36:08 +05302972 if (bcn_info->csa_count_offset &&
2973 (bcn_info->csa_count_offset > bytes_to_strip))
2974 params.csa_switch_count_offset =
2975 bcn_info->csa_count_offset - bytes_to_strip;
2976 if (bcn_info->ecsa_count_offset &&
2977 (bcn_info->ecsa_count_offset > bytes_to_strip))
2978 params.ext_csa_switch_count_offset =
2979 bcn_info->ecsa_count_offset - bytes_to_strip;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002980
Govind Singh4ff22582017-04-25 16:01:53 +05302981 ret = wmi_unified_beacon_tmpl_send_cmd(wma->wmi_handle,
Govind Singh61ad2622016-02-22 17:25:02 +05302982 &params);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002983 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002984 WMA_LOGE("%s: Failed to send bcn tmpl: %d", __func__, ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002985
2986 return ret;
2987}
2988
2989/**
2990 * wma_store_bcn_tmpl() - store beacon template
2991 * @wma: wma handle
2992 * @vdev_id: vdev id
2993 * @bcn_info: beacon params
2994 *
2995 * This function stores beacon template locally.
2996 * This will send to target on the reception of
2997 * SWBA event.
2998 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302999 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003000 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07003001static QDF_STATUS wma_store_bcn_tmpl(tp_wma_handle wma, uint8_t vdev_id,
3002 tpSendbeaconParams bcn_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003003{
3004 struct beacon_info *bcn;
3005 uint32_t len;
3006 uint8_t *bcn_payload;
3007 struct beacon_tim_ie *tim_ie;
3008
3009 bcn = wma->interfaces[vdev_id].beacon;
3010 if (!bcn || !bcn->buf) {
3011 WMA_LOGE("%s: Memory is not allocated to hold bcn template",
3012 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303013 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003014 }
3015
Krunal Sonibd7e8932018-10-03 11:14:51 -07003016 len = *(uint32_t *) &bcn_info->beacon[0];
Krunal Soni2f5e3dd2018-10-03 11:48:27 -07003017 if (len > SIR_MAX_BEACON_SIZE - sizeof(uint32_t)) {
3018 WMA_LOGE("%s: Received beacon len %u exceeding max limit %lu",
jiad8196e0a2018-11-02 15:12:10 +08003019 __func__, len, (unsigned long)(
3020 SIR_MAX_BEACON_SIZE - sizeof(uint32_t)));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303021 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003022 }
3023 WMA_LOGD("%s: Storing received beacon template buf to local buffer",
3024 __func__);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303025 qdf_spin_lock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003026
3027 /*
3028 * Copy received beacon template content in local buffer.
3029 * this will be send to target on the reception of SWBA
3030 * event from target.
3031 */
Nirav Shahcbc6d722016-03-01 16:24:53 +05303032 qdf_nbuf_trim_tail(bcn->buf, qdf_nbuf_len(bcn->buf));
3033 memcpy(qdf_nbuf_data(bcn->buf),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003034 bcn_info->beacon + 4 /* Exclude beacon length field */,
3035 len);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003036 if (bcn_info->timIeOffset > 3)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003037 bcn->tim_ie_offset = bcn_info->timIeOffset - 4;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003038 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003039 bcn->tim_ie_offset = bcn_info->timIeOffset;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003040
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003041 if (bcn_info->p2pIeOffset > 3)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003042 bcn->p2p_ie_offset = bcn_info->p2pIeOffset - 4;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003043 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003044 bcn->p2p_ie_offset = bcn_info->p2pIeOffset;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003045
Nirav Shahcbc6d722016-03-01 16:24:53 +05303046 bcn_payload = qdf_nbuf_data(bcn->buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003047 if (bcn->tim_ie_offset) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003048 tim_ie = (struct beacon_tim_ie *)
3049 (&bcn_payload[bcn->tim_ie_offset]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003050 /*
Jeff Johnsonc97816c2018-05-12 17:13:23 -07003051 * Initial Value of bcn->dtim_count will be 0.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003052 * But if the beacon gets updated then current dtim
3053 * count will be restored
3054 */
3055 tim_ie->dtim_count = bcn->dtim_count;
3056 tim_ie->tim_bitctl = 0;
3057 }
3058
Nirav Shahcbc6d722016-03-01 16:24:53 +05303059 qdf_nbuf_put_tail(bcn->buf, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003060 bcn->len = len;
3061
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303062 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303064 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065}
3066
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003067int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event,
3068 uint32_t len)
3069{
3070 tp_wma_handle wma = (tp_wma_handle) handle;
3071 WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *param_buf;
3072 wmi_tbtt_offset_event_fixed_param *tbtt_offset_event;
3073 struct wma_txrx_node *intf;
3074 struct beacon_info *bcn;
3075 tSendbeaconParams bcn_info;
3076 uint32_t *adjusted_tsf = NULL;
3077 uint32_t if_id = 0, vdev_map;
3078
3079 if (!wma) {
3080 WMA_LOGE("Invalid wma handle");
3081 return -EINVAL;
3082 }
3083
3084 param_buf = (WMI_TBTTOFFSET_UPDATE_EVENTID_param_tlvs *) event;
3085 if (!param_buf) {
3086 WMA_LOGE("Invalid tbtt update event buffer");
3087 return -EINVAL;
3088 }
3089
3090 tbtt_offset_event = param_buf->fixed_param;
3091 intf = wma->interfaces;
3092 vdev_map = tbtt_offset_event->vdev_map;
3093 adjusted_tsf = param_buf->tbttoffset_list;
3094 if (!adjusted_tsf) {
3095 WMA_LOGE("%s: Invalid adjusted_tsf", __func__);
3096 return -EINVAL;
3097 }
3098
Vignesh Viswanathanadb1b652017-10-04 20:09:09 +05303099 for (; (if_id < wma->max_bssid && vdev_map); vdev_map >>= 1, if_id++) {
Abhishek Ambure0b2ea322019-09-23 19:25:39 +05303100 if (!intf[if_id].vdev)
3101 continue;
3102
3103 if (!(vdev_map & 0x1) ||
3104 (!wlan_vdev_get_dp_handle(intf[if_id].vdev)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003105 continue;
3106
3107 bcn = intf[if_id].beacon;
3108 if (!bcn) {
3109 WMA_LOGE("%s: Invalid beacon", __func__);
3110 return -EINVAL;
3111 }
3112 if (!bcn->buf) {
3113 WMA_LOGE("%s: Invalid beacon buffer", __func__);
3114 return -EINVAL;
3115 }
3116 /* Save the adjusted TSF */
3117 intf[if_id].tsfadjust = adjusted_tsf[if_id];
3118
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303119 qdf_spin_lock_bh(&bcn->lock);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303120 qdf_mem_zero(&bcn_info, sizeof(bcn_info));
Abhinav Kumar68834222018-07-18 19:06:14 +05303121 qdf_mem_copy(bcn_info.beacon,
3122 qdf_nbuf_data(bcn->buf), bcn->len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003123 bcn_info.p2pIeOffset = bcn->p2p_ie_offset;
3124 bcn_info.beaconLength = bcn->len;
3125 bcn_info.timIeOffset = bcn->tim_ie_offset;
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303126 qdf_spin_unlock_bh(&bcn->lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003127
3128 /* Update beacon template in firmware */
Govind Singh61ad2622016-02-22 17:25:02 +05303129 wma_unified_bcn_tmpl_send(wma, if_id, &bcn_info, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003130 }
3131 return 0;
3132}
3133
3134/**
3135 * wma_p2p_go_set_beacon_ie() - set beacon IE for p2p go
3136 * @wma_handle: wma handle
3137 * @vdev_id: vdev id
3138 * @p2pIe: p2p IE
3139 *
3140 * Return: 0 for success or error code
3141 */
3142static int wma_p2p_go_set_beacon_ie(t_wma_handle *wma_handle,
3143 A_UINT32 vdev_id, uint8_t *p2pIe)
3144{
Himanshu Agarwal009f1572016-03-09 17:26:02 +05303145 if (!wma_handle) {
3146 WMA_LOGE("%s: wma handle is NULL", __func__);
3147 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003148 }
3149
Himanshu Agarwal009f1572016-03-09 17:26:02 +05303150 return wmi_unified_p2p_go_set_beacon_ie_cmd(wma_handle->wmi_handle,
3151 vdev_id, p2pIe);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003152}
3153
3154/**
3155 * wma_send_probe_rsp_tmpl() - send probe resp template
3156 * @wma: wma handle
3157 * @probe_rsp_info: probe response info
3158 *
3159 * This funciton sends probe response template to fw which
3160 * firmware will use in case of probe response offload.
3161 *
3162 * Return: none
3163 */
3164void wma_send_probe_rsp_tmpl(tp_wma_handle wma,
3165 tpSendProbeRespParams probe_rsp_info)
3166{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003167 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003168 uint8_t vdev_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003169 struct sAniProbeRspStruct *probe_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003170
3171 if (!probe_rsp_info) {
3172 WMA_LOGE(FL("probe_rsp_info is NULL"));
3173 return;
3174 }
3175
Abhinav Kumar68834222018-07-18 19:06:14 +05303176 probe_rsp = (struct sAniProbeRspStruct *)
3177 (probe_rsp_info->probeRespTemplate);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003178 if (!probe_rsp) {
3179 WMA_LOGE(FL("probe_rsp is NULL"));
3180 return;
3181 }
3182
3183 vdev = wma_find_vdev_by_addr(wma, probe_rsp->macHdr.sa, &vdev_id);
3184 if (!vdev) {
3185 WMA_LOGE(FL("failed to get vdev handle"));
3186 return;
3187 }
3188
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303189 if (wmi_service_enabled(wma->wmi_handle,
3190 wmi_service_beacon_offload)) {
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08003191 WMA_LOGD("Beacon Offload Enabled Sending Unified command");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003192 if (wmi_unified_probe_rsp_tmpl_send(wma, vdev_id,
3193 probe_rsp_info) < 0) {
3194 WMA_LOGE(FL("wmi_unified_probe_rsp_tmpl_send Failed "));
3195 return;
3196 }
3197 }
3198}
3199
Abhishek Singh3d30a3b2018-09-12 15:49:18 +05303200QDF_STATUS wma_set_ap_vdev_up(tp_wma_handle wma, uint8_t vdev_id)
Abhishek Singhdfa69c32018-08-30 15:39:34 +05303201{
Abhishek Singh3d30a3b2018-09-12 15:49:18 +05303202 QDF_STATUS status = QDF_STATUS_SUCCESS;
Jianmin Zhudd405692019-09-08 10:32:55 +08003203 struct vdev_mlme_obj *mlme_obj;
3204 struct wlan_objmgr_vdev *vdev;
3205 struct wma_txrx_node *iface;
Abhishek Singhdfa69c32018-08-30 15:39:34 +05303206
Jianmin Zhudd405692019-09-08 10:32:55 +08003207 iface = &wma->interfaces[vdev_id];
3208 vdev = iface->vdev;
3209 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
3210 mlme_obj->proto.sta.assoc_id = 0;
Jianmin Zhudd405692019-09-08 10:32:55 +08003211
3212 status = vdev_mgr_up_send(mlme_obj);
Abhishek Singha063f1c2018-09-19 11:37:51 +05303213 if (QDF_IS_STATUS_ERROR(status)) {
3214 WMA_LOGE(FL("failed to send vdev up"));
3215 policy_mgr_set_do_hw_mode_change_flag(
3216 wma->psoc, false);
3217 return status;
3218 }
3219 wma_set_sap_keepalive(wma, vdev_id);
3220 wma_set_vdev_mgmt_rate(wma, vdev_id);
3221
3222 return status;
3223}
Abhishek Singhfb5b4d32018-12-06 11:53:08 +05303224
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225/**
3226 * wma_send_beacon() - send beacon template
3227 * @wma: wma handle
3228 * @bcn_info: beacon info
3229 *
3230 * This funciton store beacon template locally and
3231 * update keep alive parameters
3232 *
3233 * Return: none
3234 */
3235void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
3236{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003237 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003238 uint8_t vdev_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303239 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003240 uint8_t *p2p_ie;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003241 struct sAniBeaconStruct *beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003242
Abhishek Singhfc740be2018-10-12 11:34:26 +05303243 WMA_LOGD("Beacon update reason %d", bcn_info->reason);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003244 beacon = (struct sAniBeaconStruct *) (bcn_info->beacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003245 vdev = wma_find_vdev_by_addr(wma, beacon->macHdr.sa, &vdev_id);
3246 if (!vdev) {
3247 WMA_LOGE("%s : failed to get vdev handle", __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303248 status = QDF_STATUS_E_INVAL;
3249 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003250 }
3251
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303252 if (wmi_service_enabled(wma->wmi_handle,
3253 wmi_service_beacon_offload)) {
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08003254 WMA_LOGD("Beacon Offload Enabled Sending Unified command");
Govind Singh61ad2622016-02-22 17:25:02 +05303255 status = wma_unified_bcn_tmpl_send(wma, vdev_id, bcn_info, 4);
3256 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003257 WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
3258 __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303259 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003260 }
3261
3262 if (bcn_info->p2pIeOffset) {
3263 p2p_ie = bcn_info->beacon + bcn_info->p2pIeOffset;
Sandeep Puligilla1f1e4002018-08-18 12:15:01 -07003264 WMA_LOGD("%s: p2pIe is present - vdev_id %hu, p2p_ie = %pK, p2p ie len = %hu",
3265 __func__, vdev_id, p2p_ie, p2p_ie[1]);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003266 if (wma_p2p_go_set_beacon_ie(wma, vdev_id,
3267 p2p_ie) < 0) {
3268 WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003269 __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303270 status = QDF_STATUS_E_INVAL;
3271 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003272 }
3273 }
3274 }
3275 status = wma_store_bcn_tmpl(wma, vdev_id, bcn_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303276 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277 WMA_LOGE("%s : wma_store_bcn_tmpl Failed", __func__);
Abhishek Singhfc740be2018-10-12 11:34:26 +05303278 goto send_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279 }
Abhishek Singhfc740be2018-10-12 11:34:26 +05303280
3281send_rsp:
3282 bcn_info->status = status;
3283 wma_send_msg(wma, WMA_SEND_BCN_RSP, (void *)bcn_info, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003284}
3285
3286/**
3287 * wma_set_keepalive_req() - send keep alive request to fw
3288 * @wma: wma handle
3289 * @keepalive: keep alive parameters
3290 *
3291 * Return: none
3292 */
3293void wma_set_keepalive_req(tp_wma_handle wma,
Jeff Johnson562ccad2019-02-06 22:10:24 -08003294 struct keep_alive_req *keepalive)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003295{
3296 WMA_LOGD("KEEPALIVE:PacketType:%d", keepalive->packetType);
3297 wma_set_sta_keep_alive(wma, keepalive->sessionId,
3298 keepalive->packetType,
3299 keepalive->timePeriod,
3300 keepalive->hostIpv4Addr,
Srinivas Girigowda9c330a92015-11-24 12:28:25 -08003301 keepalive->destIpv4Addr,
3302 keepalive->dest_macaddr.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003303
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303304 qdf_mem_free(keepalive);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003305}
3306
3307/**
3308 * wma_beacon_miss_handler() - beacon miss event handler
3309 * @wma: wma handle
3310 * @vdev_id: vdev id
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05303311 * @riis: rssi value
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003312 *
3313 * This function send beacon miss indication to upper layers.
3314 *
3315 * Return: none
3316 */
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05303317void wma_beacon_miss_handler(tp_wma_handle wma, uint32_t vdev_id, int32_t rssi)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003318{
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003319 struct missed_beacon_ind *beacon_miss_ind;
Jeff Johnson9f18aa72018-12-02 12:05:12 -08003320 struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003321
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003322 beacon_miss_ind = qdf_mem_malloc(sizeof(*beacon_miss_ind));
3323 if (!beacon_miss_ind)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003324 return;
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003325
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -08003326 if (mac && mac->sme.tx_queue_cb)
Jeff Johnson6aaaa992018-06-30 10:43:04 -07003327 mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id,
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -08003328 WLAN_STOP_ALL_NETIF_QUEUE,
3329 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003330 beacon_miss_ind->messageType = WMA_MISSED_BEACON_IND;
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003331 beacon_miss_ind->length = sizeof(*beacon_miss_ind);
Pragaspathi Thilagaraje05162d2019-05-23 13:10:46 +05303332 beacon_miss_ind->bss_idx = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003333
Jeff Johnsoncbc85322019-02-04 19:47:17 -08003334 wma_send_msg(wma, WMA_MISSED_BEACON_IND, beacon_miss_ind, 0);
Yeshwanth Sriram Guntuka14ab04c2018-09-21 15:06:49 +05303335 if (!wmi_service_enabled(wma->wmi_handle,
3336 wmi_service_hw_db2dbm_support))
3337 rssi += WMA_TGT_NOISE_FLOOR_DBM;
3338 wma_lost_link_info_handler(wma, vdev_id, rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003339}
3340
3341/**
Naveen Rawat684e8b12017-09-20 15:54:44 -07003342 * wma_get_status_str() - get string of tx status from firmware
3343 * @status: tx status
3344 *
3345 * Return: converted string of tx status
3346 */
3347static const char *wma_get_status_str(uint32_t status)
3348{
3349 switch (status) {
3350 default:
3351 return "unknown";
3352 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK);
3353 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_DISCARD);
3354 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_INSPECT);
3355 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK);
3356 CASE_RETURN_STRING(WMI_MGMT_TX_COMP_TYPE_MAX);
3357 }
3358}
3359
Nirav Shah36332212018-11-20 11:48:19 +05303360#ifdef CONFIG_HL_SUPPORT
3361static inline void wma_mgmt_unmap_buf(tp_wma_handle wma_handle, qdf_nbuf_t buf)
3362{
3363}
3364#else
3365static inline void wma_mgmt_unmap_buf(tp_wma_handle wma_handle, qdf_nbuf_t buf)
3366{
3367 qdf_nbuf_unmap_single(wma_handle->qdf_dev, buf, QDF_DMA_TO_DEVICE);
3368}
3369#endif
Alok Kumar1ff46df2019-07-17 15:01:47 +05303370
3371#if !defined(REMOVE_PKT_LOG)
3372/**
3373 * wma_mgmt_pktdump_status_map() - map MGMT Tx completion status with
3374 * packet dump Tx status
3375 * @status: MGMT Tx completion status
3376 *
3377 * Return: packet dump tx_status enum
3378 */
3379static inline enum tx_status
3380wma_mgmt_pktdump_status_map(WMI_MGMT_TX_COMP_STATUS_TYPE status)
3381{
3382 enum tx_status pktdump_status;
3383
3384 switch (status) {
3385 case WMI_MGMT_TX_COMP_TYPE_COMPLETE_OK:
3386 pktdump_status = tx_status_ok;
3387 break;
3388 case WMI_MGMT_TX_COMP_TYPE_DISCARD:
3389 pktdump_status = tx_status_discard;
3390 break;
3391 case WMI_MGMT_TX_COMP_TYPE_COMPLETE_NO_ACK:
3392 pktdump_status = tx_status_no_ack;
3393 break;
3394 default:
3395 pktdump_status = tx_status_discard;
3396 break;
3397 }
3398 return pktdump_status;
3399}
3400#endif
3401
Naveen Rawat684e8b12017-09-20 15:54:44 -07003402/**
Nirav Shah20489972016-06-16 19:20:28 +05303403 * wma_process_mgmt_tx_completion() - process mgmt completion
3404 * @wma_handle: wma handle
3405 * @desc_id: descriptor id
3406 * @status: status
3407 *
3408 * Return: 0 for success or error code
3409 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07003410static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
3411 uint32_t desc_id, uint32_t status)
Nirav Shah20489972016-06-16 19:20:28 +05303412{
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303413 struct wlan_objmgr_pdev *pdev;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303414 qdf_nbuf_t buf = NULL;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303415 QDF_STATUS ret;
Jingxiang Gebd540b12019-03-13 14:58:52 +08003416#if !defined(REMOVE_PKT_LOG)
3417 uint8_t vdev_id = 0;
3418 struct cdp_vdev *txrx_vdev;
3419 ol_txrx_pktdump_cb packetdump_cb;
3420 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Alok Kumar1ff46df2019-07-17 15:01:47 +05303421 enum tx_status pktdump_status;
Jingxiang Gebd540b12019-03-13 14:58:52 +08003422#endif
Leo Chang96464902016-10-28 11:10:54 -07003423
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07003424 if (!wma_handle) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303425 WMA_LOGE("%s: wma handle is NULL", __func__);
Nirav Shah20489972016-06-16 19:20:28 +05303426 return -EINVAL;
3427 }
3428
Naveen Rawat684e8b12017-09-20 15:54:44 -07003429 WMA_LOGD("%s: status: %s wmi_desc_id: %d", __func__,
3430 wma_get_status_str(status), desc_id);
Nirav Shah20489972016-06-16 19:20:28 +05303431
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303432 pdev = wma_handle->pdev;
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07003433 if (!pdev) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303434 WMA_LOGE("%s: psoc ptr is NULL", __func__);
Nirav Shah20489972016-06-16 19:20:28 +05303435 return -EINVAL;
3436 }
3437
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303438 buf = mgmt_txrx_get_nbuf(pdev, desc_id);
Jingxiang Gebd540b12019-03-13 14:58:52 +08003439
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303440
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303441 if (buf)
Nirav Shah36332212018-11-20 11:48:19 +05303442 wma_mgmt_unmap_buf(wma_handle, buf);
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05303443
Jingxiang Gebd540b12019-03-13 14:58:52 +08003444#if !defined(REMOVE_PKT_LOG)
3445 vdev_id = mgmt_txrx_get_vdev_id(pdev, desc_id);
3446 txrx_vdev = wma_find_vdev_by_id(wma_handle, vdev_id);
Himanshu Agarwalbb226bc2017-01-18 20:45:01 +05303447 packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb;
Alok Kumar1ff46df2019-07-17 15:01:47 +05303448 pktdump_status = wma_mgmt_pktdump_status_map(status);
Himanshu Agarwalbb226bc2017-01-18 20:45:01 +05303449 if (packetdump_cb)
Jingxiang Gebd540b12019-03-13 14:58:52 +08003450 packetdump_cb(soc, txrx_vdev,
Alok Kumar1ff46df2019-07-17 15:01:47 +05303451 buf, pktdump_status, TX_MGMT_PKT);
Jingxiang Gebd540b12019-03-13 14:58:52 +08003452#endif
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05303453
Himanshu Agarwalc733bd32017-11-18 18:35:42 +05303454 ret = mgmt_txrx_tx_completion_handler(pdev, desc_id, status, NULL);
Nirav Shah20489972016-06-16 19:20:28 +05303455
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303456 if (ret != QDF_STATUS_SUCCESS) {
3457 WMA_LOGE("%s: Failed to process mgmt tx completion", __func__);
3458 return -EINVAL;
3459 }
Nirav Shah20489972016-06-16 19:20:28 +05303460
Nirav Shah20489972016-06-16 19:20:28 +05303461 return 0;
3462}
3463
3464/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003465 * wma_mgmt_tx_completion_handler() - wma mgmt Tx completion event handler
3466 * @handle: wma handle
3467 * @cmpl_event_params: completion event handler data
3468 * @len: length of @cmpl_event_params
3469 *
3470 * Return: 0 on success; error number otherwise
3471 */
3472
3473int wma_mgmt_tx_completion_handler(void *handle, uint8_t *cmpl_event_params,
3474 uint32_t len)
3475{
3476 tp_wma_handle wma_handle = (tp_wma_handle)handle;
3477 WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *param_buf;
3478 wmi_mgmt_tx_compl_event_fixed_param *cmpl_params;
Naveen Rawat35804772016-06-27 15:40:28 -07003479
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003480 param_buf = (WMI_MGMT_TX_COMPLETION_EVENTID_param_tlvs *)
3481 cmpl_event_params;
Naveen Rawat35804772016-06-27 15:40:28 -07003482 if (!param_buf || !wma_handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003483 WMA_LOGE("%s: Invalid mgmt Tx completion event", __func__);
3484 return -EINVAL;
3485 }
3486 cmpl_params = param_buf->fixed_param;
3487
Nirav Shah20489972016-06-16 19:20:28 +05303488 wma_process_mgmt_tx_completion(wma_handle,
3489 cmpl_params->desc_id, cmpl_params->status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003490
Nirav Shah20489972016-06-16 19:20:28 +05303491 return 0;
3492}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003493
Nirav Shah20489972016-06-16 19:20:28 +05303494/**
3495 * wma_mgmt_tx_bundle_completion_handler() - mgmt bundle comp handler
3496 * @handle: wma handle
3497 * @buf: buffer
3498 * @len: length
3499 *
3500 * Return: 0 for success or error code
3501 */
3502int wma_mgmt_tx_bundle_completion_handler(void *handle, uint8_t *buf,
3503 uint32_t len)
3504{
3505 tp_wma_handle wma_handle = (tp_wma_handle)handle;
3506 WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *param_buf;
3507 wmi_mgmt_tx_compl_bundle_event_fixed_param *cmpl_params;
3508 uint32_t num_reports;
3509 uint32_t *desc_ids;
3510 uint32_t *status;
Vignesh Viswanathana2ef8b12017-10-24 22:32:28 +05303511 uint32_t i, buf_len;
3512 bool excess_data = false;
Nirav Shah20489972016-06-16 19:20:28 +05303513
3514 param_buf = (WMI_MGMT_TX_BUNDLE_COMPLETION_EVENTID_param_tlvs *)buf;
Arif Hussain31576d92016-10-25 14:32:12 -07003515 if (!param_buf || !wma_handle) {
Nirav Shah20489972016-06-16 19:20:28 +05303516 WMA_LOGE("%s: Invalid mgmt Tx completion event", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003517 return -EINVAL;
3518 }
Nirav Shah20489972016-06-16 19:20:28 +05303519 cmpl_params = param_buf->fixed_param;
3520 num_reports = cmpl_params->num_reports;
3521 desc_ids = (uint32_t *)(param_buf->desc_ids);
3522 status = (uint32_t *)(param_buf->status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003523
Vignesh Viswanathana2ef8b12017-10-24 22:32:28 +05303524 /* buf contains num_reports * sizeof(uint32) len of desc_ids and
3525 * num_reports * sizeof(uint32) status,
3526 * so (2 x (num_reports * sizeof(uint32)) should not exceed MAX
3527 */
3528 if (cmpl_params->num_reports > (WMI_SVC_MSG_MAX_SIZE /
3529 (2 * sizeof(uint32_t))))
3530 excess_data = true;
3531 else
3532 buf_len = cmpl_params->num_reports * (2 * sizeof(uint32_t));
3533
3534 if (excess_data || (sizeof(*cmpl_params) > (WMI_SVC_MSG_MAX_SIZE -
3535 buf_len))) {
3536 WMA_LOGE("excess wmi buffer: num_reports %d",
3537 cmpl_params->num_reports);
3538 return -EINVAL;
3539 }
3540
3541 if ((cmpl_params->num_reports > param_buf->num_desc_ids) ||
3542 (cmpl_params->num_reports > param_buf->num_status)) {
3543 WMA_LOGE("Invalid num_reports %d, num_desc_ids %d, num_status %d",
3544 cmpl_params->num_reports, param_buf->num_desc_ids,
3545 param_buf->num_status);
3546 return -EINVAL;
3547 }
3548
Nirav Shah20489972016-06-16 19:20:28 +05303549 for (i = 0; i < num_reports; i++)
3550 wma_process_mgmt_tx_completion(wma_handle,
3551 desc_ids[i], status[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003552 return 0;
3553}
3554
3555/**
3556 * wma_process_update_opmode() - process update VHT opmode cmd from UMAC
3557 * @wma_handle: wma handle
3558 * @update_vht_opmode: vht opmode
3559 *
3560 * Return: none
3561 */
3562void wma_process_update_opmode(tp_wma_handle wma_handle,
3563 tUpdateVHTOpMode *update_vht_opmode)
3564{
Naveen Rawatf8792bd2017-11-12 21:38:05 -08003565 wmi_host_channel_width ch_width;
wadesongd3f8d3a2019-09-16 17:26:07 +08003566 uint8_t pdev_id;
3567 struct wlan_objmgr_peer *peer;
3568 struct wlan_objmgr_psoc *psoc = wma_handle->psoc;
3569 enum wlan_phymode peer_phymode;
Abhishek Singh89c36742019-09-26 10:06:27 +05303570 uint32_t fw_phymode;
wadesongd3f8d3a2019-09-16 17:26:07 +08003571 enum wlan_peer_type peer_type;
Abhishek Singh89c36742019-09-26 10:06:27 +05303572 struct wma_txrx_node *iface;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003573
Abhishek Singh89c36742019-09-26 10:06:27 +05303574 iface = &wma_handle->interfaces[update_vht_opmode->smesessionId];
wadesongd3f8d3a2019-09-16 17:26:07 +08003575
Abhishek Singh89c36742019-09-26 10:06:27 +05303576 if (iface->type == WMI_VDEV_TYPE_STA) {
3577 fw_phymode = iface->chanmode;
3578 } else {
3579 pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev);
3580 peer = wlan_objmgr_get_peer(psoc, pdev_id,
3581 update_vht_opmode->peer_mac,
3582 WLAN_LEGACY_WMA_ID);
3583 if (!peer) {
3584 WMA_LOGE("peer object invalid");
3585 return;
3586 }
3587
3588 peer_type = wlan_peer_get_peer_type(peer);
3589 if (peer_type == WLAN_PEER_SELF) {
3590 WMA_LOGE("self peer wrongly used");
3591 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
3592 return;
3593 }
3594
3595 wlan_peer_obj_lock(peer);
3596 peer_phymode = wlan_peer_get_phymode(peer);
3597 wlan_peer_obj_unlock(peer);
wadesongd3f8d3a2019-09-16 17:26:07 +08003598 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
Abhishek Singh89c36742019-09-26 10:06:27 +05303599
3600 fw_phymode = wma_host_to_fw_phymode(peer_phymode);
wadesongd3f8d3a2019-09-16 17:26:07 +08003601 }
3602
Naveen Rawatf8792bd2017-11-12 21:38:05 -08003603 ch_width = wmi_get_ch_width_from_phy_mode(wma_handle->wmi_handle,
wadesongd3f8d3a2019-09-16 17:26:07 +08003604 fw_phymode);
Abhishek Singh89c36742019-09-26 10:06:27 +05303605 WMA_LOGD("%s: ch_width: %d, fw phymode: %d", __func__,
3606 ch_width, fw_phymode);
Kiran Kumar Lokeref7662e52018-02-05 09:04:07 -08003607 if (ch_width < update_vht_opmode->opMode) {
3608 WMA_LOGE("%s: Invalid peer bw update %d, self bw %d",
3609 __func__, update_vht_opmode->opMode,
3610 ch_width);
3611 return;
3612 }
wadesongd3f8d3a2019-09-16 17:26:07 +08003613
Kiran Kumar Lokeref7662e52018-02-05 09:04:07 -08003614 WMA_LOGD("%s: opMode = %d", __func__, update_vht_opmode->opMode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003615 wma_set_peer_param(wma_handle, update_vht_opmode->peer_mac,
3616 WMI_PEER_CHWIDTH, update_vht_opmode->opMode,
3617 update_vht_opmode->smesessionId);
3618}
3619
3620/**
3621 * wma_process_update_rx_nss() - process update RX NSS cmd from UMAC
3622 * @wma_handle: wma handle
3623 * @update_rx_nss: rx nss value
3624 *
3625 * Return: none
3626 */
3627void wma_process_update_rx_nss(tp_wma_handle wma_handle,
3628 tUpdateRxNss *update_rx_nss)
3629{
Paul Zhang7d1d5362018-07-19 17:00:18 +08003630 struct target_psoc_info *tgt_hdl;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003631 struct wma_txrx_node *intr =
3632 &wma_handle->interfaces[update_rx_nss->smesessionId];
3633 int rx_nss = update_rx_nss->rxNss;
Paul Zhang7d1d5362018-07-19 17:00:18 +08003634 int num_rf_chains;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003635
Paul Zhang7d1d5362018-07-19 17:00:18 +08003636 tgt_hdl = wlan_psoc_get_tgt_if_handle(wma_handle->psoc);
3637 if (!tgt_hdl) {
3638 WMA_LOGE("%s: target psoc info is NULL", __func__);
3639 return;
3640 }
3641
3642 num_rf_chains = target_if_get_num_rf_chains(tgt_hdl);
3643 if (rx_nss > num_rf_chains || rx_nss > WMA_MAX_NSS)
3644 rx_nss = QDF_MIN(num_rf_chains, WMA_MAX_NSS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003645
3646 intr->nss = (uint8_t)rx_nss;
3647 update_rx_nss->rxNss = (uint32_t)rx_nss;
3648
3649 WMA_LOGD("%s: Rx Nss = %d", __func__, update_rx_nss->rxNss);
3650
3651 wma_set_peer_param(wma_handle, update_rx_nss->peer_mac,
3652 WMI_PEER_NSS, update_rx_nss->rxNss,
3653 update_rx_nss->smesessionId);
3654}
3655
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003656/**
3657 * wma_process_update_membership() - process update group membership cmd
3658 * @wma_handle: wma handle
3659 * @membership: group membership info
3660 *
3661 * Return: none
3662 */
3663void wma_process_update_membership(tp_wma_handle wma_handle,
3664 tUpdateMembership *membership)
3665{
3666 WMA_LOGD("%s: membership = %x ", __func__, membership->membership);
3667
3668 wma_set_peer_param(wma_handle, membership->peer_mac,
3669 WMI_PEER_MEMBERSHIP, membership->membership,
3670 membership->smesessionId);
3671}
3672
3673/**
3674 * wma_process_update_userpos() - process update user pos cmd from UMAC
3675 * @wma_handle: wma handle
3676 * @userpos: user pos value
3677 *
3678 * Return: none
3679 */
3680void wma_process_update_userpos(tp_wma_handle wma_handle,
3681 tUpdateUserPos *userpos)
3682{
3683 WMA_LOGD("%s: userPos = %x ", __func__, userpos->userPos);
3684
3685 wma_set_peer_param(wma_handle, userpos->peer_mac,
3686 WMI_PEER_USERPOS, userpos->userPos,
3687 userpos->smesessionId);
3688
3689 /* Now that membership/userpos is updated in fw,
3690 * enable GID PPS.
3691 */
3692 wma_set_ppsconfig(userpos->smesessionId, WMA_VHT_PPS_GID_MATCH, 1);
3693
3694}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003695
Agrawal Ashishb2d1a452016-05-05 12:23:58 +05303696QDF_STATUS wma_set_cts2self_for_p2p_go(void *wma_handle,
3697 uint32_t cts2self_for_p2p_go)
3698{
3699 int32_t ret;
3700 tp_wma_handle wma = (tp_wma_handle)wma_handle;
3701 struct pdev_params pdevparam;
3702
3703 pdevparam.param_id = WMI_PDEV_PARAM_CTS2SELF_FOR_P2P_GO_CONFIG;
3704 pdevparam.param_value = cts2self_for_p2p_go;
3705
3706 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
3707 &pdevparam,
3708 WMA_WILDCARD_PDEV_ID);
3709 if (ret) {
3710 WMA_LOGE("Fail to Set CTS2SELF for p2p GO %d",
3711 cts2self_for_p2p_go);
3712 return QDF_STATUS_E_FAILURE;
3713 }
3714
3715 WMA_LOGD("Successfully Set CTS2SELF for p2p GO %d",
3716 cts2self_for_p2p_go);
3717
3718 return QDF_STATUS_SUCCESS;
3719}
3720
3721
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003722/**
3723 * wma_set_htconfig() - set ht config parameters to target
3724 * @vdev_id: vdev id
3725 * @ht_capab: ht capablity
3726 * @value: value of ht param
3727 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303728 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003729 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303730QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003731{
Anurag Chouhan6d760662016-02-20 16:05:43 +05303732 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Govind Singhd76a5b02016-03-08 15:12:14 +05303733 QDF_STATUS ret = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003734
Jeff Johnsonfb6d0ca2019-03-18 13:38:29 -07003735 if (!wma) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736 WMA_LOGE("%s: Failed to get wma", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303737 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003738 }
3739
3740 switch (ht_capab) {
3741 case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING:
Govind Singhd76a5b02016-03-08 15:12:14 +05303742 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003743 WMI_VDEV_PARAM_LDPC,
3744 value);
3745 break;
3746 case WNI_CFG_HT_CAP_INFO_TX_STBC:
Govind Singhd76a5b02016-03-08 15:12:14 +05303747 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003748 WMI_VDEV_PARAM_TX_STBC,
3749 value);
3750 break;
3751 case WNI_CFG_HT_CAP_INFO_RX_STBC:
Govind Singhd76a5b02016-03-08 15:12:14 +05303752 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003753 WMI_VDEV_PARAM_RX_STBC,
3754 value);
3755 break;
3756 case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ:
3757 case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ:
3758 WMA_LOGE("%s: ht_capab = %d, value = %d", __func__, ht_capab,
3759 value);
Govind Singhd76a5b02016-03-08 15:12:14 +05303760 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003761 WMI_VDEV_PARAM_SGI, value);
Govind Singhd76a5b02016-03-08 15:12:14 +05303762 if (ret == QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003763 wma->interfaces[vdev_id].config.shortgi = value;
3764 break;
3765 default:
3766 WMA_LOGE("%s:INVALID HT CONFIG", __func__);
3767 }
3768
Govind Singhd76a5b02016-03-08 15:12:14 +05303769 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003770}
3771
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003772#ifdef WLAN_FEATURE_11W
3773
3774/**
3775 * wma_extract_ccmp_pn() - extract 6 byte PN from the CCMP header
3776 * @ccmp_ptr: CCMP header
3777 *
3778 * Return: PN extracted from header.
3779 */
3780static uint64_t wma_extract_ccmp_pn(uint8_t *ccmp_ptr)
3781{
3782 uint8_t rsvd, key, pn[6];
3783 uint64_t new_pn;
3784
3785 /*
3786 * +-----+-----+------+----------+-----+-----+-----+-----+
3787 * | PN0 | PN1 | rsvd | rsvd/key | PN2 | PN3 | PN4 | PN5 |
3788 * +-----+-----+------+----------+-----+-----+-----+-----+
3789 * CCMP Header Format
3790 */
3791
3792 /* Extract individual bytes */
3793 pn[0] = (uint8_t) *ccmp_ptr;
3794 pn[1] = (uint8_t) *(ccmp_ptr + 1);
3795 rsvd = (uint8_t) *(ccmp_ptr + 2);
3796 key = (uint8_t) *(ccmp_ptr + 3);
3797 pn[2] = (uint8_t) *(ccmp_ptr + 4);
3798 pn[3] = (uint8_t) *(ccmp_ptr + 5);
3799 pn[4] = (uint8_t) *(ccmp_ptr + 6);
3800 pn[5] = (uint8_t) *(ccmp_ptr + 7);
3801
3802 /* Form 6 byte PN with 6 individual bytes of PN */
3803 new_pn = ((uint64_t) pn[5] << 40) |
3804 ((uint64_t) pn[4] << 32) |
3805 ((uint64_t) pn[3] << 24) |
3806 ((uint64_t) pn[2] << 16) |
3807 ((uint64_t) pn[1] << 8) | ((uint64_t) pn[0] << 0);
3808
3809 WMA_LOGE("PN of received packet is %llu", new_pn);
3810 return new_pn;
3811}
3812
3813/**
3814 * wma_is_ccmp_pn_replay_attack() - detect replay attacking using PN in CCMP
3815 * @cds_ctx: cds context
3816 * @wh: 802.11 frame header
3817 * @ccmp_ptr: CCMP frame header
3818 *
3819 * Return: true/false
3820 */
3821static bool
3822wma_is_ccmp_pn_replay_attack(void *cds_ctx, struct ieee80211_frame *wh,
3823 uint8_t *ccmp_ptr)
3824{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003825 struct cdp_pdev *pdev;
3826 struct cdp_vdev *vdev;
Leo Chang96464902016-10-28 11:10:54 -07003827 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003828 uint8_t vdev_id, peer_id;
Zhang Qian610a1a72018-04-27 17:03:30 +08003829 uint8_t *last_pn_valid = NULL;
3830 uint64_t *last_pn = NULL, new_pn;
3831 uint32_t *rmf_pn_replays = NULL;
Leo Chang96464902016-10-28 11:10:54 -07003832 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Abhishek Singh38da9802018-06-20 16:25:09 +05303833 bool ret = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003834
Anurag Chouhan6d760662016-02-20 16:05:43 +05303835 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003836 if (!pdev) {
3837 WMA_LOGE("%s: Failed to find pdev", __func__);
3838 return true;
3839 }
3840
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05303841 vdev = wma_find_vdev_by_bssid(cds_ctx, wh->i_addr3, &vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003842 if (!vdev) {
3843 WMA_LOGE("%s: Failed to find vdev", __func__);
3844 return true;
3845 }
3846
3847 /* Retrieve the peer based on vdev and addr */
Abhishek Singh38da9802018-06-20 16:25:09 +05303848 peer = cdp_peer_get_ref_by_addr(soc, pdev, wh->i_addr2, &peer_id,
3849 PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003850
Abhishek Singh38da9802018-06-20 16:25:09 +05303851 if (!peer) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003852 WMA_LOGE("%s: Failed to find peer, Not able to validate PN",
3853 __func__);
3854 return true;
3855 }
3856
3857 new_pn = wma_extract_ccmp_pn(ccmp_ptr);
Zhang Qian610a1a72018-04-27 17:03:30 +08003858
Leo Chang96464902016-10-28 11:10:54 -07003859 cdp_get_pn_info(soc, peer, &last_pn_valid, &last_pn, &rmf_pn_replays);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003860
Zhang Qian610a1a72018-04-27 17:03:30 +08003861 if (!last_pn_valid || !last_pn || !rmf_pn_replays) {
3862 WMA_LOGE("%s: PN validation seems not supported", __func__);
Abhishek Singh38da9802018-06-20 16:25:09 +05303863 goto rel_peer_ref;
Zhang Qian610a1a72018-04-27 17:03:30 +08003864 }
3865
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003866 if (*last_pn_valid) {
3867 if (new_pn > *last_pn) {
3868 *last_pn = new_pn;
3869 WMA_LOGE("%s: PN validation successful", __func__);
3870 } else {
3871 WMA_LOGE("%s: PN Replay attack detected", __func__);
3872 /* per 11W amendment, keeping track of replay attacks */
3873 *rmf_pn_replays += 1;
Abhishek Singh38da9802018-06-20 16:25:09 +05303874 ret = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003875 }
3876 } else {
3877 *last_pn_valid = 1;
3878 *last_pn = new_pn;
3879 }
3880
Abhishek Singh38da9802018-06-20 16:25:09 +05303881rel_peer_ref:
3882 cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK);
3883 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003884}
3885
3886/**
mukul sharma72c8b222015-09-04 17:02:01 +05303887 * wma_process_bip() - process mmie in rmf frame
3888 * @wma_handle: wma handle
3889 * @iface: txrx node
3890 * @wh: 80211 frame
3891 * @wbuf: Buffer
3892 *
3893 * Return: 0 for success or error code
3894 */
3895
3896static
3897int wma_process_bip(tp_wma_handle wma_handle,
3898 struct wma_txrx_node *iface,
3899 struct ieee80211_frame *wh,
Nirav Shahcbc6d722016-03-01 16:24:53 +05303900 qdf_nbuf_t wbuf
mukul sharma72c8b222015-09-04 17:02:01 +05303901)
3902{
Jianmin Zhud46bc462018-07-11 19:14:10 +08003903 uint16_t mmie_size;
mukul sharma72c8b222015-09-04 17:02:01 +05303904 uint16_t key_id;
3905 uint8_t *efrm;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003906 uint8_t *igtk;
3907 uint16_t key_len;
mukul sharma72c8b222015-09-04 17:02:01 +05303908
Nirav Shahcbc6d722016-03-01 16:24:53 +05303909 efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf);
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303910
3911 if (iface->key.key_cipher == WMI_CIPHER_AES_CMAC) {
Jianmin Zhud46bc462018-07-11 19:14:10 +08003912 mmie_size = cds_get_mmie_size();
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303913 } else if (iface->key.key_cipher == WMI_CIPHER_AES_GMAC) {
Jianmin Zhud46bc462018-07-11 19:14:10 +08003914 mmie_size = cds_get_gmac_mmie_size();
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303915 } else {
3916 WMA_LOGE(FL("Invalid key cipher %d"), iface->key.key_cipher);
3917 return -EINVAL;
3918 }
mukul sharma72c8b222015-09-04 17:02:01 +05303919
Jianmin Zhud46bc462018-07-11 19:14:10 +08003920 /* Check if frame is invalid length */
3921 if (efrm - (uint8_t *)wh < sizeof(*wh) + mmie_size) {
3922 WMA_LOGE(FL("Invalid frame length"));
3923 return -EINVAL;
3924 }
3925
3926 key_id = (uint16_t)*(efrm - mmie_size + 2);
mukul sharma72c8b222015-09-04 17:02:01 +05303927 if (!((key_id == WMA_IGTK_KEY_INDEX_4)
3928 || (key_id == WMA_IGTK_KEY_INDEX_5))) {
3929 WMA_LOGE(FL("Invalid KeyID(%d) dropping the frame"), key_id);
3930 return -EINVAL;
3931 }
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303932
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303933 WMA_LOGD(FL("key_cipher %d key_id %d"), iface->key.key_cipher, key_id);
3934
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003935 igtk = wma_get_igtk(iface, &key_len);
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303936 switch (iface->key.key_cipher) {
3937 case WMI_CIPHER_AES_CMAC:
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303938 if (wmi_service_enabled(wma_handle->wmi_handle,
3939 wmi_service_sta_pmf_offload)) {
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303940 /*
3941 * if 11w offload is enabled then mmie validation is
3942 * performed in firmware, host just need to trim the
3943 * mmie.
3944 */
Nirav Shahcbc6d722016-03-01 16:24:53 +05303945 qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
mukul sharma72c8b222015-09-04 17:02:01 +05303946 } else {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003947 if (cds_is_mmie_valid(igtk, iface->key.key_id[
3948 key_id -
3949 WMA_IGTK_KEY_INDEX_4].ipn,
3950 (uint8_t *)wh, efrm)) {
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303951 WMA_LOGD(FL("Protected BC/MC frame MMIE validation successful"));
3952 /* Remove MMIE */
3953 qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
3954 } else {
3955 WMA_LOGD(FL("BC/MC MIC error or MMIE not present, dropping the frame"));
3956 return -EINVAL;
3957 }
3958 }
3959 break;
3960
3961 case WMI_CIPHER_AES_GMAC:
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303962 if (wmi_service_enabled(wma_handle->wmi_handle,
3963 wmi_service_gmac_offload_support)) {
3964 /*
3965 * if gmac offload is enabled then mmie validation is
3966 * performed in firmware, host just need to trim the
3967 * mmie.
3968 */
3969 WMA_LOGD(FL("Trim GMAC MMIE"));
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303970 qdf_nbuf_trim_tail(wbuf, cds_get_gmac_mmie_size());
3971 } else {
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003972 if (cds_is_gmac_mmie_valid(igtk,
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303973 iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -07003974 (uint8_t *) wh, efrm, key_len)) {
Padma, Santhosh Kumar96682402018-02-02 18:16:27 +05303975 WMA_LOGD(FL("Protected BC/MC frame GMAC MMIE validation successful"));
3976 /* Remove MMIE */
3977 qdf_nbuf_trim_tail(wbuf,
3978 cds_get_gmac_mmie_size());
3979 } else {
3980 WMA_LOGD(FL("BC/MC GMAC MIC error or MMIE not present, dropping the frame"));
3981 return -EINVAL;
3982 }
mukul sharma72c8b222015-09-04 17:02:01 +05303983 }
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303984 break;
3985
3986 default:
3987 WMA_LOGE(FL("Unsupported key cipher %d"),
3988 iface->key.key_cipher);
mukul sharma72c8b222015-09-04 17:02:01 +05303989 }
Padma, Santhosh Kumar0ab78172017-12-18 19:26:17 +05303990
3991
mukul sharma72c8b222015-09-04 17:02:01 +05303992 return 0;
3993}
3994
3995/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003996 * wma_process_rmf_frame() - process rmf frame
3997 * @wma_handle: wma handle
3998 * @iface: txrx node
3999 * @wh: 80211 frame
4000 * @rx_pkt: rx packet
4001 * @wbuf: Buffer
4002 *
4003 * Return: 0 for success or error code
4004 */
4005static
4006int wma_process_rmf_frame(tp_wma_handle wma_handle,
4007 struct wma_txrx_node *iface,
4008 struct ieee80211_frame *wh,
4009 cds_pkt_t *rx_pkt,
Nirav Shahcbc6d722016-03-01 16:24:53 +05304010 qdf_nbuf_t wbuf)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004011{
mukul sharma72c8b222015-09-04 17:02:01 +05304012 uint8_t *orig_hdr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004013 uint8_t *ccmp;
Abhishek Singh7c1c7432019-04-04 12:11:57 +05304014 uint8_t mic_len, hdr_len, pdev_id;
4015 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004016
4017 if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) {
Srinivas Girigowda9cd6c342019-02-09 13:06:12 -08004018 if (QDF_IS_ADDR_BROADCAST(wh->i_addr1) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004019 IEEE80211_IS_MULTICAST(wh->i_addr1)) {
4020 WMA_LOGE("Encrypted BC/MC frame dropping the frame");
4021 cds_pkt_return_packet(rx_pkt);
4022 return -EINVAL;
4023 }
Abhishek Singh7c1c7432019-04-04 12:11:57 +05304024
4025 pdev_id = wlan_objmgr_pdev_get_pdev_id(wma_handle->pdev);
4026 status = mlme_get_peer_mic_len(wma_handle->psoc, pdev_id,
4027 wh->i_addr2, &mic_len,
4028 &hdr_len);
4029 if (QDF_IS_STATUS_ERROR(status)) {
4030 WMA_LOGE("Failed to get mic hdr and length");
4031 cds_pkt_return_packet(rx_pkt);
4032 return -EINVAL;
4033 }
4034
4035 if (qdf_nbuf_len(wbuf) < (sizeof(*wh) + hdr_len + mic_len)) {
4036 WMA_LOGE("Buffer length less than expected %d",
4037 (int)qdf_nbuf_len(wbuf));
4038 cds_pkt_return_packet(rx_pkt);
4039 return -EINVAL;
4040 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004041
Nirav Shahcbc6d722016-03-01 16:24:53 +05304042 orig_hdr = (uint8_t *) qdf_nbuf_data(wbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004043 /* Pointer to head of CCMP header */
4044 ccmp = orig_hdr + sizeof(*wh);
4045 if (wma_is_ccmp_pn_replay_attack(
4046 wma_handle, wh, ccmp)) {
4047 WMA_LOGE("Dropping the frame");
4048 cds_pkt_return_packet(rx_pkt);
4049 return -EINVAL;
4050 }
4051
4052 /* Strip privacy headers (and trailer)
4053 * for a received frame
4054 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304055 qdf_mem_move(orig_hdr +
Himanshu Agarwalfc5d6602018-04-06 17:39:37 +05304056 hdr_len, wh,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004057 sizeof(*wh));
Nirav Shahcbc6d722016-03-01 16:24:53 +05304058 qdf_nbuf_pull_head(wbuf,
Himanshu Agarwalfc5d6602018-04-06 17:39:37 +05304059 hdr_len);
4060 qdf_nbuf_trim_tail(wbuf, mic_len);
Krunal Soni54da0c62016-08-01 17:04:25 -07004061 /*
4062 * CCMP header has been pulled off
4063 * reinitialize the start pointer of mac header
4064 * to avoid accessing incorrect address
4065 */
4066 wh = (struct ieee80211_frame *) qdf_nbuf_data(wbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004067 rx_pkt->pkt_meta.mpdu_hdr_ptr =
Nirav Shahcbc6d722016-03-01 16:24:53 +05304068 qdf_nbuf_data(wbuf);
4069 rx_pkt->pkt_meta.mpdu_len = qdf_nbuf_len(wbuf);
Arif Hussain3d731ab2017-10-12 12:40:16 -07004070 rx_pkt->pkt_buf = wbuf;
4071 if (rx_pkt->pkt_meta.mpdu_len >=
4072 rx_pkt->pkt_meta.mpdu_hdr_len) {
4073 rx_pkt->pkt_meta.mpdu_data_len =
4074 rx_pkt->pkt_meta.mpdu_len -
4075 rx_pkt->pkt_meta.mpdu_hdr_len;
4076 } else {
4077 WMA_LOGE("mpdu len %d less than hdr %d, dropping frame",
4078 rx_pkt->pkt_meta.mpdu_len,
4079 rx_pkt->pkt_meta.mpdu_hdr_len);
4080 cds_pkt_return_packet(rx_pkt);
4081 return -EINVAL;
4082 }
4083
4084 if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
4085 WMA_LOGE("Data Len %d greater than max, dropping frame",
4086 rx_pkt->pkt_meta.mpdu_data_len);
4087 cds_pkt_return_packet(rx_pkt);
4088 return -EINVAL;
4089 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004090 rx_pkt->pkt_meta.mpdu_data_ptr =
4091 rx_pkt->pkt_meta.mpdu_hdr_ptr +
4092 rx_pkt->pkt_meta.mpdu_hdr_len;
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004093 wma_debug("BSSID: "QDF_MAC_ADDR_STR" tsf_delta: %u",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004094 QDF_MAC_ADDR_ARRAY(wh->i_addr3),
4095 rx_pkt->pkt_meta.tsf_delta);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004096 } else {
Srinivas Girigowda9cd6c342019-02-09 13:06:12 -08004097 if (QDF_IS_ADDR_BROADCAST(wh->i_addr1) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004098 IEEE80211_IS_MULTICAST(wh->i_addr1)) {
mukul sharma72c8b222015-09-04 17:02:01 +05304099 if (0 != wma_process_bip(wma_handle, iface, wh, wbuf)) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004100 cds_pkt_return_packet(rx_pkt);
4101 return -EINVAL;
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304102 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004103 } else {
4104 WMA_LOGE("Rx unprotected unicast mgmt frame");
4105 rx_pkt->pkt_meta.dpuFeedback =
4106 DPU_FEEDBACK_UNPROTECTED_ERROR;
4107 }
4108 }
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004109 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004110}
Srinivas Dasaricc863f02019-09-05 17:18:48 +05304111
4112/**
4113 * wma_get_peer_pmf_status() - Get the PMF capability of peer
4114 * @wma: wma handle
4115 * @peer_mac: peer mac addr
4116 *
4117 * Return: True if PMF is enabled, false otherwise.
4118 */
4119static bool
4120wma_get_peer_pmf_status(tp_wma_handle wma, uint8_t *peer_mac)
4121{
4122 struct wlan_objmgr_peer *peer;
4123 bool is_pmf_enabled;
4124
4125 if (!peer_mac) {
4126 WMA_LOGE("peer_mac is NULL");
4127 return false;
4128 }
4129
4130 peer = wlan_objmgr_get_peer(wma->psoc,
4131 wlan_objmgr_pdev_get_pdev_id(wma->pdev),
4132 peer_mac, WLAN_LEGACY_WMA_ID);
4133 if (!peer) {
4134 WMA_LOGE("Peer of peer_mac %pM not found",
4135 peer_mac);
4136 return false;
4137 }
4138 is_pmf_enabled = mlme_get_peer_pmf_status(peer);
4139 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
4140 WMA_LOGD("get is_pmf_enabled %d for %pM", is_pmf_enabled, peer_mac);
4141
4142 return is_pmf_enabled;
4143}
4144
4145/**
4146 * wma_check_and_process_rmf_frame() - Process the frame if it is of rmf type
4147 * @wma_handle: wma handle
4148 * @vdev_id: vdev id
4149 * @wh: double pointer to 802.11 frame header which will be updated if the
4150 * frame is of rmf type.
4151 * @rx_pkt: rx packet
4152 * @buf: Buffer
4153 *
4154 * Process the frame as rmf frame only if both DUT and peer are of PMF capable
4155 *
4156 * Return: 0 for success or error code
4157 */
4158static int
4159wma_check_and_process_rmf_frame(tp_wma_handle wma_handle,
4160 uint8_t vdev_id,
4161 struct ieee80211_frame **wh,
4162 cds_pkt_t *rx_pkt,
4163 qdf_nbuf_t buf)
4164{
4165 int status;
4166 struct wma_txrx_node *iface;
4167 struct ieee80211_frame *hdr = *wh;
4168
4169 iface = &(wma_handle->interfaces[vdev_id]);
4170 if (!iface->rmfEnabled)
4171 return 0;
4172
4173 if (qdf_is_macaddr_group((struct qdf_mac_addr *)(hdr->i_addr1)) ||
4174 qdf_is_macaddr_broadcast((struct qdf_mac_addr *)(hdr->i_addr1)) ||
4175 wma_get_peer_pmf_status(wma_handle, hdr->i_addr2)) {
4176 status = wma_process_rmf_frame(wma_handle, iface, hdr,
4177 rx_pkt, buf);
4178 if (status)
4179 return status;
4180 /*
4181 * CCMP header might have been pulled off reinitialize the
4182 * start pointer of mac header
4183 */
4184 *wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
4185 }
4186
4187 return 0;
4188}
Abhishek Singhcfb44482017-03-10 12:42:37 +05304189#else
Srinivas Dasaricc863f02019-09-05 17:18:48 +05304190static inline int
4191wma_check_and_process_rmf_frame(tp_wma_handle wma_handle,
4192 uint8_t vdev_id,
4193 struct ieee80211_frame **wh,
4194 cds_pkt_t *rx_pkt,
4195 qdf_nbuf_t buf)
Abhishek Singhcfb44482017-03-10 12:42:37 +05304196{
4197 return 0;
4198}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004199#endif
4200
4201/**
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004202 * wma_is_pkt_drop_candidate() - check if the mgmt frame should be droppped
4203 * @wma_handle: wma handle
4204 * @peer_addr: peer MAC address
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07004205 * @bssid: BSSID Address
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004206 * @subtype: Management frame subtype
4207 *
4208 * This function is used to decide if a particular management frame should be
4209 * dropped to prevent DOS attack. Timestamp is used to decide the DOS attack.
4210 *
4211 * Return: true if the packet should be dropped and false oterwise
4212 */
4213static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle,
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07004214 uint8_t *peer_addr, uint8_t *bssid,
4215 uint8_t subtype)
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004216{
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004217 bool should_drop = false;
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07004218 uint8_t nan_addr[] = {0x50, 0x6F, 0x9A, 0x01, 0x00, 0x00};
4219
4220 /* Drop the beacons from NAN device */
Srinivas Girigowdadf90cea2019-03-07 16:03:25 -08004221 if ((subtype == MGMT_SUBTYPE_BEACON) &&
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07004222 (!qdf_mem_cmp(nan_addr, bssid, NAN_CLUSTER_ID_BYTES))) {
4223 should_drop = true;
4224 goto end;
4225 }
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004226end:
4227 return should_drop;
4228}
4229
Naveen Rawat73532d62017-05-22 10:37:52 -07004230#define RATE_LIMIT 16
4231
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304232int wma_form_rx_packet(qdf_nbuf_t buf,
Himanshu Agarwald2e6cde2017-01-10 14:47:04 +05304233 struct mgmt_rx_event_params *mgmt_rx_params,
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304234 cds_pkt_t *rx_pkt)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004235{
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304236 uint8_t vdev_id = WMA_INVALID_VDEV_ID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004237 struct ieee80211_frame *wh;
4238 uint8_t mgt_type, mgt_subtype;
4239 int status;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304240 tp_wma_handle wma_handle = (tp_wma_handle)
4241 cds_get_context(QDF_MODULE_ID_WMA);
Jingxiang Gebd540b12019-03-13 14:58:52 +08004242#if !defined(REMOVE_PKT_LOG)
4243 ol_txrx_pktdump_cb packetdump_cb;
4244 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4245 struct cdp_vdev *txrx_vdev;
4246#endif
Naveen Rawat73532d62017-05-22 10:37:52 -07004247 static uint8_t limit_prints_invalid_len = RATE_LIMIT - 1;
4248 static uint8_t limit_prints_load_unload = RATE_LIMIT - 1;
4249 static uint8_t limit_prints_recovery = RATE_LIMIT - 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004250
4251 if (!wma_handle) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304252 WMA_LOGE(FL("wma handle is NULL"));
4253 qdf_nbuf_free(buf);
4254 qdf_mem_free(rx_pkt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004255 return -EINVAL;
4256 }
4257
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304258 if (!mgmt_rx_params) {
Naveen Rawat73532d62017-05-22 10:37:52 -07004259 limit_prints_invalid_len++;
4260 if (limit_prints_invalid_len == RATE_LIMIT) {
4261 WMA_LOGD(FL("mgmt rx params is NULL"));
4262 limit_prints_invalid_len = 0;
4263 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304264 qdf_nbuf_free(buf);
4265 qdf_mem_free(rx_pkt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004266 return -EINVAL;
4267 }
4268
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08004269 if (cds_is_load_or_unload_in_progress()) {
Naveen Rawat73532d62017-05-22 10:37:52 -07004270 limit_prints_load_unload++;
4271 if (limit_prints_load_unload == RATE_LIMIT) {
4272 WMA_LOGD(FL("Load/Unload in progress"));
4273 limit_prints_load_unload = 0;
4274 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304275 qdf_nbuf_free(buf);
4276 qdf_mem_free(rx_pkt);
Naveen Rawat10ccf872015-11-03 14:15:55 -08004277 return -EINVAL;
4278 }
4279
Mukul Sharma80edc782016-09-12 15:59:24 +05304280 if (cds_is_driver_recovering()) {
Naveen Rawat73532d62017-05-22 10:37:52 -07004281 limit_prints_recovery++;
4282 if (limit_prints_recovery == RATE_LIMIT) {
4283 WMA_LOGD(FL("Recovery in progress"));
4284 limit_prints_recovery = 0;
4285 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304286 qdf_nbuf_free(buf);
4287 qdf_mem_free(rx_pkt);
Mukul Sharma80edc782016-09-12 15:59:24 +05304288 return -EINVAL;
4289 }
4290
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05304291 if (cds_is_driver_in_bad_state()) {
4292 limit_prints_recovery++;
4293 if (limit_prints_recovery == RATE_LIMIT) {
4294 WMA_LOGD(FL("Driver in bad state"));
4295 limit_prints_recovery = 0;
4296 }
4297 qdf_nbuf_free(buf);
4298 qdf_mem_free(rx_pkt);
4299 return -EINVAL;
4300 }
4301
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004302 /*
4303 * Fill in meta information needed by pe/lim
4304 * TODO: Try to maintain rx metainfo as part of skb->data.
4305 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304306 rx_pkt->pkt_meta.channel = mgmt_rx_params->channel;
4307 rx_pkt->pkt_meta.scan_src = mgmt_rx_params->flags;
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -07004308
4309 /*
4310 * Get the rssi value from the current snr value
4311 * using standard noise floor of -96.
4312 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304313 rx_pkt->pkt_meta.rssi = mgmt_rx_params->snr +
4314 WMA_NOISE_FLOOR_DBM_DEFAULT;
4315 rx_pkt->pkt_meta.snr = mgmt_rx_params->snr;
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -07004316
4317 /* If absolute rssi is available from firmware, use it */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304318 if (mgmt_rx_params->rssi != 0)
4319 rx_pkt->pkt_meta.rssi_raw = mgmt_rx_params->rssi;
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -07004320 else
4321 rx_pkt->pkt_meta.rssi_raw = rx_pkt->pkt_meta.rssi;
4322
4323
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004324 /*
4325 * FIXME: Assigning the local timestamp as hw timestamp is not
4326 * available. Need to see if pe/lim really uses this data.
4327 */
4328 rx_pkt->pkt_meta.timestamp = (uint32_t) jiffies;
4329 rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304330 rx_pkt->pkt_meta.mpdu_len = mgmt_rx_params->buf_len;
Vignesh Viswanathanea432dd2018-04-30 14:06:15 +05304331
4332 /*
4333 * The buf_len should be at least 802.11 header len
4334 */
4335 if (mgmt_rx_params->buf_len < rx_pkt->pkt_meta.mpdu_hdr_len) {
4336 WMA_LOGE("MPDU Len %d lesser than header len %d",
4337 mgmt_rx_params->buf_len,
4338 rx_pkt->pkt_meta.mpdu_hdr_len);
4339 qdf_nbuf_free(buf);
4340 qdf_mem_free(rx_pkt);
4341 return -EINVAL;
4342 }
4343
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304344 rx_pkt->pkt_meta.mpdu_data_len = mgmt_rx_params->buf_len -
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004345 rx_pkt->pkt_meta.mpdu_hdr_len;
4346
4347 rx_pkt->pkt_meta.roamCandidateInd = 0;
4348
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304349 wh = (struct ieee80211_frame *)qdf_nbuf_data(buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004350
Vignesh Viswanathan56f26252017-08-31 15:26:01 +05304351 /*
4352 * If the mpdu_data_len is greater than Max (2k), drop the frame
4353 */
4354 if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004355 wma_err("Data Len %d greater than max, dropping frame from "QDF_MAC_ADDR_STR,
Vignesh Viswanathan56f26252017-08-31 15:26:01 +05304356 rx_pkt->pkt_meta.mpdu_data_len,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004357 QDF_MAC_ADDR_ARRAY(wh->i_addr3));
Vignesh Viswanathan56f26252017-08-31 15:26:01 +05304358 qdf_nbuf_free(buf);
4359 qdf_mem_free(rx_pkt);
4360 return -EINVAL;
4361 }
4362
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304363 rx_pkt->pkt_meta.mpdu_hdr_ptr = qdf_nbuf_data(buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004364 rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr +
4365 rx_pkt->pkt_meta.mpdu_hdr_len;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304366 rx_pkt->pkt_meta.tsf_delta = mgmt_rx_params->tsf_delta;
4367 rx_pkt->pkt_buf = buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004368
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004369 /* If it is a beacon/probe response, save it for future use */
4370 mgt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
4371 mgt_subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
4372
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004373 if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
Srinivas Girigowdadf90cea2019-03-07 16:03:25 -08004374 (mgt_subtype == MGMT_SUBTYPE_DISASSOC ||
4375 mgt_subtype == MGMT_SUBTYPE_DEAUTH ||
4376 mgt_subtype == MGMT_SUBTYPE_ACTION)) {
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304377 if (wma_find_vdev_by_bssid(
4378 wma_handle, wh->i_addr3, &vdev_id)) {
Srinivas Dasaricc863f02019-09-05 17:18:48 +05304379 status = wma_check_and_process_rmf_frame(wma_handle,
4380 vdev_id,
4381 &wh,
4382 rx_pkt,
4383 buf);
4384 if (status)
4385 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004386 }
4387 }
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304388
Jingxiang Ge45a24332019-03-11 10:46:47 +08004389 rx_pkt->pkt_meta.session_id =
Mukul Sharmaa748fbb2015-12-01 19:51:36 +05304390 (vdev_id == WMA_INVALID_VDEV_ID ? 0 : vdev_id);
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004391
Sandeep Puligilla2a206c52017-05-25 01:05:49 -07004392 if (mgt_type == IEEE80211_FC0_TYPE_MGT &&
Srinivas Girigowdadf90cea2019-03-07 16:03:25 -08004393 (mgt_subtype == MGMT_SUBTYPE_BEACON ||
4394 mgt_subtype == MGMT_SUBTYPE_PROBE_RESP)) {
Sandeep Puligilla2a206c52017-05-25 01:05:49 -07004395 if (mgmt_rx_params->buf_len <=
4396 (sizeof(struct ieee80211_frame) +
4397 offsetof(struct wlan_bcn_frame, ie))) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004398 wma_debug("Dropping frame from "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004399 QDF_MAC_ADDR_ARRAY(wh->i_addr3));
Sandeep Puligilla2a206c52017-05-25 01:05:49 -07004400 cds_pkt_return_packet(rx_pkt);
4401 return -EINVAL;
4402 }
4403 }
4404
Sandeep Puligilla4a58f7f2017-05-16 16:36:56 -07004405 if (wma_is_pkt_drop_candidate(wma_handle, wh->i_addr2, wh->i_addr3,
4406 mgt_subtype)) {
Krishna Kumaar Natarajanb7f9a352016-03-18 11:40:07 -07004407 cds_pkt_return_packet(rx_pkt);
4408 return -EINVAL;
4409 }
4410
Jingxiang Gebd540b12019-03-13 14:58:52 +08004411#if !defined(REMOVE_PKT_LOG)
Himanshu Agarwalbb226bc2017-01-18 20:45:01 +05304412 packetdump_cb = wma_handle->wma_mgmt_rx_packetdump_cb;
Jingxiang Gebd540b12019-03-13 14:58:52 +08004413 txrx_vdev = wma_find_vdev_by_id(wma_handle,
4414 rx_pkt->pkt_meta.session_id);
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304415 if ((mgt_type == IEEE80211_FC0_TYPE_MGT &&
Jingxiang Gebd540b12019-03-13 14:58:52 +08004416 mgt_subtype != MGMT_SUBTYPE_BEACON) &&
4417 packetdump_cb)
4418 packetdump_cb(soc, txrx_vdev, rx_pkt->pkt_buf,
4419 QDF_STATUS_SUCCESS, RX_MGMT_PKT);
4420#endif
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304421 return 0;
4422}
4423
4424/**
4425 * wma_mem_endianness_based_copy() - does memory copy from src to dst
4426 * @dst: destination address
4427 * @src: source address
4428 * @size: size to be copied
4429 *
4430 * This function copies the memory of size passed from source
4431 * address to destination address.
4432 *
4433 * Return: Nothing
4434 */
4435#ifdef BIG_ENDIAN_HOST
4436static void wma_mem_endianness_based_copy(
4437 uint8_t *dst, uint8_t *src, uint32_t size)
4438{
4439 /*
4440 * For big endian host, copy engine byte_swap is enabled
4441 * But the rx mgmt frame buffer content is in network byte order
4442 * Need to byte swap the mgmt frame buffer content - so when
4443 * copy engine does byte_swap - host gets buffer content in the
4444 * correct byte order.
4445 */
4446
4447 uint32_t i;
4448 uint32_t *destp, *srcp;
4449
4450 destp = (uint32_t *) dst;
4451 srcp = (uint32_t *) src;
4452 for (i = 0; i < (roundup(size, sizeof(uint32_t)) / 4); i++) {
4453 *destp = cpu_to_le32(*srcp);
4454 destp++;
4455 srcp++;
4456 }
4457}
4458#else
4459static void wma_mem_endianness_based_copy(
4460 uint8_t *dst, uint8_t *src, uint32_t size)
4461{
4462 qdf_mem_copy(dst, src, size);
4463}
4464#endif
4465
gaurank kathpaliad84b0052018-05-08 17:39:44 +05304466#define RESERVE_BYTES 100
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304467/**
4468 * wma_mgmt_rx_process() - process management rx frame.
4469 * @handle: wma handle
4470 * @data: rx data
4471 * @data_len: data length
4472 *
4473 * Return: 0 for success or error code
4474 */
4475static int wma_mgmt_rx_process(void *handle, uint8_t *data,
4476 uint32_t data_len)
4477{
4478 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Himanshu Agarwald2e6cde2017-01-10 14:47:04 +05304479 struct mgmt_rx_event_params *mgmt_rx_params;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304480 struct wlan_objmgr_psoc *psoc;
4481 uint8_t *bufp;
4482 qdf_nbuf_t wbuf;
4483 QDF_STATUS status;
4484
4485 if (!wma_handle) {
4486 WMA_LOGE("%s: Failed to get WMA context", __func__);
4487 return -EINVAL;
4488 }
4489
4490 mgmt_rx_params = qdf_mem_malloc(sizeof(*mgmt_rx_params));
4491 if (!mgmt_rx_params) {
4492 WMA_LOGE("%s: memory allocation failed", __func__);
4493 return -ENOMEM;
4494 }
4495
4496 if (wmi_extract_mgmt_rx_params(wma_handle->wmi_handle,
4497 data, mgmt_rx_params, &bufp) != QDF_STATUS_SUCCESS) {
4498 WMA_LOGE("%s: Extraction of mgmt rx params failed", __func__);
4499 qdf_mem_free(mgmt_rx_params);
4500 return -EINVAL;
4501 }
4502
bings12895972019-06-19 17:38:10 +08004503 if (mgmt_rx_params->buf_len > data_len ||
4504 !mgmt_rx_params->buf_len ||
4505 !bufp) {
4506 WMA_LOGE("Invalid data_len %u, buf_len %u bufp %pK",
4507 data_len, mgmt_rx_params->buf_len, bufp);
Jiachao Wu418b7ae2018-02-02 16:01:04 +08004508 qdf_mem_free(mgmt_rx_params);
Jingxiang Ge04c94502017-10-18 17:05:40 +08004509 return -EINVAL;
4510 }
4511
Ashish Kumar Dhanotiya285213c2019-08-22 19:30:27 +05304512 if (!mgmt_rx_params->chan_freq) {
4513 /*
4514 * It indicates that FW is legacy and is operating on
4515 * channel numbers and it also indicates that BAND_6G support
4516 * is not there as BAND_6G works only on frequencies and channel
4517 * numbers can be treated as unique.
4518 */
4519 if (mgmt_rx_params->channel >= WLAN_REG_MIN_24GHZ_CH_NUM &&
4520 mgmt_rx_params->channel <= WLAN_REG_MAX_24GHZ_CH_NUM)
4521 mgmt_rx_params->chan_freq =
4522 wlan_reg_chan_to_freq(
4523 wma_handle->pdev,
4524 mgmt_rx_params->channel);
4525 else
4526 mgmt_rx_params->chan_freq =
4527 wlan_reg_chan_to_freq(
4528 wma_handle->pdev,
4529 mgmt_rx_params->channel);
4530 }
4531
Himanshu Agarwald2e6cde2017-01-10 14:47:04 +05304532 mgmt_rx_params->pdev_id = 0;
4533 mgmt_rx_params->rx_params = NULL;
4534
gaurank kathpaliad84b0052018-05-08 17:39:44 +05304535 /*
4536 * Allocate the memory for this rx packet, add extra 100 bytes for:-
4537 *
4538 * 1. Filling the missing RSN capabilites by some APs, which fill the
4539 * RSN IE length as extra 2 bytes but dont fill the IE data with
4540 * capabilities, resulting in failure in unpack core due to length
4541 * mismatch. Check sir_validate_and_rectify_ies for more info.
4542 *
4543 * 2. In the API wma_process_rmf_frame(), the driver trims the CCMP
4544 * header by overwriting the IEEE header to memory occupied by CCMP
4545 * header, but an overflow is possible if the memory allocated to
4546 * frame is less than the sizeof(struct ieee80211_frame) +CCMP
4547 * HEADER len, so allocating 100 bytes would solve this issue too.
4548 *
4549 * 3. CCMP header is pointing to orig_hdr +
4550 * sizeof(struct ieee80211_frame) which could also result in OOB
4551 * access, if the data len is less than
4552 * sizeof(struct ieee80211_frame), allocating extra bytes would
4553 * result in solving this issue too.
4554 */
4555 wbuf = qdf_nbuf_alloc(NULL, roundup(mgmt_rx_params->buf_len +
4556 RESERVE_BYTES,
4557 4), 0, 4, false);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304558 if (!wbuf) {
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304559 qdf_mem_free(mgmt_rx_params);
4560 return -ENOMEM;
4561 }
4562
4563 qdf_nbuf_put_tail(wbuf, mgmt_rx_params->buf_len);
4564 qdf_nbuf_set_protocol(wbuf, ETH_P_CONTROL);
4565
Pragaspathi Thilagarajb3bceade2018-06-05 17:11:35 +05304566 qdf_mem_zero(((uint8_t *)qdf_nbuf_data(wbuf) + mgmt_rx_params->buf_len),
4567 (roundup(mgmt_rx_params->buf_len + RESERVE_BYTES, 4) -
4568 mgmt_rx_params->buf_len));
4569
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304570 wma_mem_endianness_based_copy(qdf_nbuf_data(wbuf),
4571 bufp, mgmt_rx_params->buf_len);
4572
4573 psoc = (struct wlan_objmgr_psoc *)
4574 wma_handle->psoc;
4575 if (!psoc) {
4576 WMA_LOGE("%s: psoc ctx is NULL", __func__);
4577 qdf_nbuf_free(wbuf);
4578 qdf_mem_free(mgmt_rx_params);
4579 return -EINVAL;
4580 }
4581
Himanshu Agarwal795b7f72017-01-17 21:19:43 +05304582 status = mgmt_txrx_rx_handler(psoc, wbuf, mgmt_rx_params);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304583 if (status != QDF_STATUS_SUCCESS) {
Amar Singhaldc5ae4d2018-10-02 14:29:37 -07004584 wma_err_rl("Failed to process mgmt rx frame");
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304585 qdf_mem_free(mgmt_rx_params);
4586 return -EINVAL;
4587 }
4588
4589 qdf_mem_free(mgmt_rx_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004590 return 0;
4591}
4592
4593/**
4594 * wma_de_register_mgmt_frm_client() - deregister management frame
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304595 *
4596 * This function deregisters the event handler registered for
4597 * WMI_MGMT_RX_EVENTID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004598 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304599 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004600 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304601QDF_STATUS wma_de_register_mgmt_frm_client(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004602{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304603 tp_wma_handle wma_handle = (tp_wma_handle)
4604 cds_get_context(QDF_MODULE_ID_WMA);
4605
4606 if (!wma_handle) {
4607 WMA_LOGE("%s: Failed to get WMA context", __func__);
4608 return QDF_STATUS_E_NULL_VALUE;
4609 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004610
4611#ifdef QCA_WIFI_FTM
Anurag Chouhan6d760662016-02-20 16:05:43 +05304612 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304613 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004614#endif
4615
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004616 if (wmi_unified_unregister_event_handler(wma_handle->wmi_handle,
Mukul Sharma228223a2017-11-03 19:25:39 +05304617 wmi_mgmt_rx_event_id) != 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004618 WMA_LOGE("Failed to Unregister rx mgmt handler with wmi");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304619 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004620 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304621 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004622}
4623
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08004624#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004625/**
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004626 * wma_register_roaming_callbacks() - Register roaming callbacks
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004627 * @csr_roam_synch_cb: CSR roam synch callback routine pointer
4628 * @pe_roam_synch_cb: PE roam synch callback routine pointer
Pragaspathi Thilagaraj7a7163b2019-07-14 22:47:09 +05304629 * @csr_roam_auth_event_handle_cb: CSR callback routine pointer
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004630 *
4631 * Register the SME and PE callback routines with WMA for
4632 * handling roaming
4633 *
4634 * Return: Success or Failure Status
4635 */
Jeff Johnsona9b66572017-09-02 12:41:21 -07004636QDF_STATUS wma_register_roaming_callbacks(
Jeff Johnson9f18aa72018-12-02 12:05:12 -08004637 QDF_STATUS (*csr_roam_synch_cb)(struct mac_context *mac,
Jeff Johnsona7f41dd2019-02-06 22:54:55 -08004638 struct roam_offload_synch_ind *roam_synch_data,
Pragaspathi Thilagaraj1d8e2ab2019-03-04 23:59:21 +05304639 struct bss_description *bss_desc_ptr,
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07004640 enum sir_roam_op_code reason),
Pragaspathi Thilagaraj7a7163b2019-07-14 22:47:09 +05304641 QDF_STATUS (*csr_roam_auth_event_handle_cb)(struct mac_context *mac,
4642 uint8_t vdev_id,
4643 struct qdf_mac_addr bssid),
Jeff Johnson9f18aa72018-12-02 12:05:12 -08004644 QDF_STATUS (*pe_roam_synch_cb)(struct mac_context *mac,
Jeff Johnsona7f41dd2019-02-06 22:54:55 -08004645 struct roam_offload_synch_ind *roam_synch_data,
Pragaspathi Thilagaraj1d8e2ab2019-03-04 23:59:21 +05304646 struct bss_description *bss_desc_ptr,
Pragaspathi Thilagarajb0176502019-04-26 02:33:13 +05304647 enum sir_roam_op_code reason),
4648 QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
Srinivas Dasariea472272019-06-30 11:35:07 +05304649 uint8_t vdev_id,
4650 uint8_t *deauth_disassoc_frame,
4651 uint16_t deauth_disassoc_frame_len))
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004652{
4653
Anurag Chouhan6d760662016-02-20 16:05:43 +05304654 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004655
4656 if (!wma) {
4657 WMA_LOGE("%s: Failed to get WMA context", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304658 return QDF_STATUS_E_FAILURE;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004659 }
4660 wma->csr_roam_synch_cb = csr_roam_synch_cb;
Pragaspathi Thilagaraj7a7163b2019-07-14 22:47:09 +05304661 wma->csr_roam_auth_event_handle_cb = csr_roam_auth_event_handle_cb;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004662 wma->pe_roam_synch_cb = pe_roam_synch_cb;
Pragaspathi Thilagarajb0176502019-04-26 02:33:13 +05304663 wma->pe_disconnect_cb = pe_disconnect_cb;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004664 WMA_LOGD("Registered roam synch callbacks with WMA successfully");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304665 return QDF_STATUS_SUCCESS;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004666}
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08004667#endif
4668
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004669/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004670 * wma_register_mgmt_frm_client() - register management frame callback
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304671 *
4672 * This function registers event handler for WMI_MGMT_RX_EVENTID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004673 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304674 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004675 */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304676QDF_STATUS wma_register_mgmt_frm_client(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004677{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304678 tp_wma_handle wma_handle = (tp_wma_handle)
4679 cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004680
4681 if (!wma_handle) {
4682 WMA_LOGE("%s: Failed to get WMA context", __func__);
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304683 return QDF_STATUS_E_NULL_VALUE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004684 }
4685
4686 if (wmi_unified_register_event_handler(wma_handle->wmi_handle,
Mukul Sharma228223a2017-11-03 19:25:39 +05304687 wmi_mgmt_rx_event_id,
Govind Singhd76a5b02016-03-08 15:12:14 +05304688 wma_mgmt_rx_process,
4689 WMA_RX_WORK_CTX) != 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004690 WMA_LOGE("Failed to register rx mgmt handler with wmi");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304691 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004692 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004693
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304694 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004695}
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304696
4697/**
4698 * wma_register_packetdump_callback() - stores tx and rx mgmt packet dump
4699 * callback handler
Jingxiang Gebd540b12019-03-13 14:58:52 +08004700 * @tx_cb: tx mgmt packetdump cb
4701 * @rx_cb: rx mgmt packetdump cb
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304702 *
4703 * This function is used to store tx and rx mgmt. packet dump callback
4704 *
4705 * Return: None
4706 *
4707 */
4708void wma_register_packetdump_callback(
Jingxiang Gebd540b12019-03-13 14:58:52 +08004709 ol_txrx_pktdump_cb tx_cb,
4710 ol_txrx_pktdump_cb rx_cb)
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304711{
4712 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4713
4714 if (!wma_handle) {
4715 WMA_LOGE("wma handle is NULL");
4716 return;
4717 }
4718
Jingxiang Gebd540b12019-03-13 14:58:52 +08004719 wma_handle->wma_mgmt_tx_packetdump_cb = tx_cb;
4720 wma_handle->wma_mgmt_rx_packetdump_cb = rx_cb;
Himanshu Agarwalf65bd4c2016-12-05 17:21:12 +05304721}
4722
4723/**
4724 * wma_deregister_packetdump_callback() - removes tx and rx mgmt packet dump
4725 * callback handler
4726 *
4727 * This function is used to remove tx and rx mgmt. packet dump callback
4728 *
4729 * Return: None
4730 *
4731 */
4732void wma_deregister_packetdump_callback(void)
4733{
4734 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4735
4736 if (!wma_handle) {
4737 WMA_LOGE("wma handle is NULL");
4738 return;
4739 }
4740
4741 wma_handle->wma_mgmt_tx_packetdump_cb = NULL;
4742 wma_handle->wma_mgmt_rx_packetdump_cb = NULL;
4743}
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304744
4745QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev,
4746 qdf_nbuf_t buf, uint32_t desc_id,
4747 void *mgmt_tx_params)
4748{
4749 tp_wma_handle wma_handle;
Wu Gaob422f772018-07-05 11:34:36 +08004750 int ret;
4751 QDF_STATUS status = QDF_STATUS_E_INVAL;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304752 struct wmi_mgmt_params *mgmt_params =
4753 (struct wmi_mgmt_params *)mgmt_tx_params;
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304754 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4755 struct cdp_vdev *txrx_vdev;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304756
4757 if (!mgmt_params) {
4758 WMA_LOGE("%s: mgmt_params ptr passed is NULL", __func__);
4759 return QDF_STATUS_E_INVAL;
4760 }
4761 mgmt_params->desc_id = desc_id;
4762
4763 if (!vdev) {
4764 WMA_LOGE("%s: vdev ptr passed is NULL", __func__);
4765 return QDF_STATUS_E_INVAL;
4766 }
4767
4768 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
4769 if (!wma_handle) {
4770 WMA_LOGE("%s: wma handle is NULL", __func__);
4771 return QDF_STATUS_E_INVAL;
4772 }
4773
Abhishek Ambure24cff9e2019-10-01 12:09:55 +05304774 if (!wma_handle->interfaces[mgmt_params->vdev_id].vdev) {
4775 WMA_LOGE("%s: vdev is NULL for vdev_%d",
4776 __func__, mgmt_params->vdev_id);
4777 return QDF_STATUS_E_INVAL;
4778 }
Abhishek Ambure0b2ea322019-09-23 19:25:39 +05304779 txrx_vdev = wlan_vdev_get_dp_handle
4780 (wma_handle->interfaces[mgmt_params->vdev_id].vdev);
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304781
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304782 if (wmi_service_enabled(wma_handle->wmi_handle,
4783 wmi_service_mgmt_tx_wmi)) {
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304784 status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle,
4785 mgmt_params);
Wu Gaob422f772018-07-05 11:34:36 +08004786 } else if (txrx_vdev) {
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304787 QDF_NBUF_CB_MGMT_TXRX_DESC_ID(buf)
4788 = mgmt_params->desc_id;
4789
Wu Gaob422f772018-07-05 11:34:36 +08004790 ret = cdp_mgmt_send_ext(soc, txrx_vdev, buf,
4791 mgmt_params->tx_type,
4792 mgmt_params->use_6mbps,
4793 mgmt_params->chanfreq);
4794 status = qdf_status_from_os_return(ret);
Sravan Kumar Kairam905b4c52017-10-17 19:38:14 +05304795 }
4796
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05304797 if (status != QDF_STATUS_SUCCESS) {
4798 WMA_LOGE("%s: mgmt tx failed", __func__);
4799 return status;
4800 }
4801
4802 return QDF_STATUS_SUCCESS;
4803}
4804
Ajit Pal Singh6190ca22018-11-08 16:37:43 +05304805#ifndef CONFIG_HL_SUPPORT
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304806void wma_mgmt_nbuf_unmap_cb(struct wlan_objmgr_pdev *pdev,
4807 qdf_nbuf_t buf)
4808{
Sravan Kumar Kairam0ebf4532018-09-19 14:12:59 +05304809 struct wlan_objmgr_psoc *psoc;
4810 qdf_device_t dev;
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304811
4812 if (!buf)
4813 return;
4814
Sravan Kumar Kairam0ebf4532018-09-19 14:12:59 +05304815 psoc = wlan_pdev_get_psoc(pdev);
4816 if (!psoc) {
4817 WMA_LOGE("%s: Psoc handle NULL", __func__);
4818 return;
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304819 }
Sravan Kumar Kairam0ebf4532018-09-19 14:12:59 +05304820
4821 dev = wlan_psoc_get_qdf_dev(psoc);
4822 if (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_WMI_MGMT_REF))
4823 qdf_nbuf_unmap_single(dev, buf, QDF_DMA_TO_DEVICE);
Sravan Kumar Kairam0fbaefe2018-09-10 16:57:50 +05304824}
Ajit Pal Singh6190ca22018-11-08 16:37:43 +05304825#endif