blob: 82e9fdd33e01126d751c6baa4455323b6ebd4310 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwalfc4dab92017-12-28 21:46:29 +05302 * Copyright (c) 2013-2018 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_dev_if.c
21 * This file contains vdev & peer related operations.
22 */
23
24/* Header files */
25
26#include "wma.h"
27#include "wma_api.h"
28#include "cds_api.h"
29#include "wmi_unified_api.h"
30#include "wlan_qct_sys.h"
31#include "wni_api.h"
32#include "ani_global.h"
33#include "wmi_unified.h"
34#include "wni_cfg.h"
35#include "cfg_api.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"
49#endif /* REMOVE_PKT_LOG */
50
51#include "dbglog_host.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052#include "csr_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080053
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054#include "wma_internal.h"
55
56#include "wma_ocb.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080057#include "cdp_txrx_cfg.h"
58#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_cfg.h>
61#include <cdp_txrx_cmn.h>
Leo Chang96464902016-10-28 11:10:54 -070062#include <cdp_txrx_misc.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -070064#include "wlan_policy_mgr_api.h"
Deepak Dhamdheree2dd5442016-05-27 15:05:51 -070065#include "wma_nan_datapath.h"
Leo Chang96464902016-10-28 11:10:54 -070066#include "wlan_tgt_def_config.h"
bings1f98e9f2018-01-24 16:13:41 +080067#include <wlan_dfs_tgt_api.h>
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080068#include <cdp_txrx_handle.h>
Mukul Sharma00058692017-01-28 19:04:32 +053069#include "wlan_pmo_ucfg_api.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070070#include "wlan_reg_services_api.h"
Leo Chang96464902016-10-28 11:10:54 -070071
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -080072#include "wma_he.h"
Deepak Dhamdheref918d422017-07-06 12:56:29 -070073#include "wlan_roam_debug.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +080074#include "wlan_ocb_ucfg_api.h"
Sourav Mohapatracf632572018-04-02 11:01:35 +053075#include "init_deinit_lmac.h"
Arunk Khandavallicfde2712018-01-25 11:27:42 +053076#include <target_if.h>
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -080077
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080078/**
79 * wma_find_vdev_by_addr() - find vdev_id from mac address
80 * @wma: wma handle
81 * @addr: mac address
82 * @vdev_id: return vdev_id
83 *
84 * Return: Returns vdev handle or NULL if mac address don't match
85 */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080086struct cdp_vdev *wma_find_vdev_by_addr(tp_wma_handle wma, uint8_t *addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087 uint8_t *vdev_id)
88{
89 uint8_t i;
90
91 for (i = 0; i < wma->max_bssid; i++) {
Anurag Chouhanc5548422016-02-24 18:33:27 +053092 if (qdf_is_macaddr_equal(
Anurag Chouhan6d760662016-02-20 16:05:43 +053093 (struct qdf_mac_addr *) wma->interfaces[i].addr,
94 (struct qdf_mac_addr *) addr) == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080095 *vdev_id = i;
96 return wma->interfaces[i].handle;
97 }
98 }
99 return NULL;
100}
101
102
103/**
104 * wma_is_vdev_in_ap_mode() - check that vdev is in ap mode or not
105 * @wma: wma handle
106 * @vdev_id: vdev id
107 *
108 * Helper function to know whether given vdev id
109 * is in AP mode or not.
110 *
111 * Return: True/False
112 */
113bool wma_is_vdev_in_ap_mode(tp_wma_handle wma, uint8_t vdev_id)
114{
115 struct wma_txrx_node *intf = wma->interfaces;
116
Naveen Rawatf2bd42d2017-06-29 14:51:43 -0700117 if (vdev_id >= wma->max_bssid) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -0700118 WMA_LOGE("%s: Invalid vdev_id %hu", __func__, vdev_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530119 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800120 return false;
121 }
122
123 if ((intf[vdev_id].type == WMI_VDEV_TYPE_AP) &&
124 ((intf[vdev_id].sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO) ||
125 (intf[vdev_id].sub_type == 0)))
126 return true;
127
128 return false;
129}
130
131#ifdef QCA_IBSS_SUPPORT
132/**
133 * wma_is_vdev_in_ibss_mode() - check that vdev is in ibss mode or not
134 * @wma: wma handle
135 * @vdev_id: vdev id
136 *
137 * Helper function to know whether given vdev id
138 * is in IBSS mode or not.
139 *
140 * Return: True/False
141 */
142bool wma_is_vdev_in_ibss_mode(tp_wma_handle wma, uint8_t vdev_id)
143{
144 struct wma_txrx_node *intf = wma->interfaces;
145
Naveen Rawatf2bd42d2017-06-29 14:51:43 -0700146 if (vdev_id >= wma->max_bssid) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -0700147 WMA_LOGE("%s: Invalid vdev_id %hu", __func__, vdev_id);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530148 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800149 return false;
150 }
151
152 if (intf[vdev_id].type == WMI_VDEV_TYPE_IBSS)
153 return true;
154
155 return false;
156}
157#endif /* QCA_IBSS_SUPPORT */
158
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800159/**
160 * wma_find_vdev_by_bssid() - Get the corresponding vdev_id from BSSID
161 * @wma - wma handle
162 * @vdev_id - vdev ID
163 *
164 * Return: fill vdev_id with appropriate vdev id and return vdev
165 * handle or NULL if not found.
166 */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800167struct cdp_vdev *wma_find_vdev_by_bssid(tp_wma_handle wma, uint8_t *bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800168 uint8_t *vdev_id)
169{
170 int i;
171
172 for (i = 0; i < wma->max_bssid; i++) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530173 if (qdf_is_macaddr_equal(
Anurag Chouhan6d760662016-02-20 16:05:43 +0530174 (struct qdf_mac_addr *) wma->interfaces[i].bssid,
175 (struct qdf_mac_addr *) bssid) == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800176 *vdev_id = i;
177 return wma->interfaces[i].handle;
178 }
179 }
180
181 return NULL;
182}
183
184/**
185 * wma_get_txrx_vdev_type() - return operating mode of vdev
186 * @type: vdev_type
187 *
188 * Return: return operating mode as enum wlan_op_mode type
189 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700190static enum wlan_op_mode wma_get_txrx_vdev_type(uint32_t type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800191{
192 enum wlan_op_mode vdev_type = wlan_op_mode_unknown;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700193
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800194 switch (type) {
195 case WMI_VDEV_TYPE_AP:
196 vdev_type = wlan_op_mode_ap;
197 break;
198 case WMI_VDEV_TYPE_STA:
199 vdev_type = wlan_op_mode_sta;
200 break;
201#ifdef QCA_IBSS_SUPPORT
202 case WMI_VDEV_TYPE_IBSS:
203 vdev_type = wlan_op_mode_ibss;
204 break;
205#endif /* QCA_IBSS_SUPPORT */
206 case WMI_VDEV_TYPE_OCB:
207 vdev_type = wlan_op_mode_ocb;
208 break;
209 case WMI_VDEV_TYPE_MONITOR:
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -0700210 vdev_type = wlan_op_mode_monitor;
211 break;
Deepak Dhamdheree2dd5442016-05-27 15:05:51 -0700212 case WMI_VDEV_TYPE_NDI:
213 vdev_type = wlan_op_mode_ndi;
214 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800215 default:
216 WMA_LOGE("Invalid vdev type %u", type);
217 vdev_type = wlan_op_mode_unknown;
218 }
219
220 return vdev_type;
221}
222
223/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224 * wma_find_req() - find target request for vdev id
225 * @wma: wma handle
226 * @vdev_id: vdev id
227 * @type: request type
228 *
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800229 * Find target request for given vdev id & type of request.
230 * Remove that request from active list.
231 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800232 * Return: return target request if found or NULL.
233 */
234static struct wma_target_req *wma_find_req(tp_wma_handle wma,
235 uint8_t vdev_id, uint8_t type)
236{
237 struct wma_target_req *req_msg = NULL;
238 bool found = false;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530239 qdf_list_node_t *node1 = NULL, *node2 = NULL;
240 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800241
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530242 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +0530243 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800244 &node2)) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530245 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246 WMA_LOGE(FL("unable to get msg node from request queue"));
247 return NULL;
248 }
249
250 do {
251 node1 = node2;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530252 req_msg = qdf_container_of(node1, struct wma_target_req, node);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800253 if (req_msg->vdev_id != vdev_id)
254 continue;
255 if (req_msg->type != type)
256 continue;
257
258 found = true;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530259 status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
260 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530261 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262 WMA_LOGD(FL("Failed to remove request for vdev_id %d type %d"),
263 vdev_id, type);
264 return NULL;
265 }
266 break;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530267 } while (QDF_STATUS_SUCCESS ==
268 qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800269 &node2));
270
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530271 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272 if (!found) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800273 WMA_LOGE(FL("target request not found for vdev_id %d type %d"),
274 vdev_id, type);
275 return NULL;
276 }
277
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800278 WMA_LOGD(FL("target request found for vdev id: %d type %d"),
279 vdev_id, type);
280
281 return req_msg;
282}
283
284/**
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800285 * wma_find_remove_req_msgtype() - find and remove request for vdev id
286 * @wma: wma handle
287 * @vdev_id: vdev id
288 * @msg_type: message request type
289 *
290 * Find target request for given vdev id & sub type of request.
291 * Remove the same from active list.
292 *
293 * Return: Success if request found, failure other wise
294 */
295static struct wma_target_req *wma_find_remove_req_msgtype(tp_wma_handle wma,
296 uint8_t vdev_id, uint32_t msg_type)
297{
298 struct wma_target_req *req_msg = NULL;
299 bool found = false;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530300 qdf_list_node_t *node1 = NULL, *node2 = NULL;
301 QDF_STATUS status;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800302
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530303 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +0530304 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->wma_hold_req_queue,
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800305 &node2)) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530306 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800307 WMA_LOGE(FL("unable to get msg node from request queue"));
308 return NULL;
309 }
310
311 do {
312 node1 = node2;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530313 req_msg = qdf_container_of(node1, struct wma_target_req, node);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800314 if (req_msg->vdev_id != vdev_id)
315 continue;
316 if (req_msg->msg_type != msg_type)
317 continue;
318
319 found = true;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530320 status = qdf_list_remove_node(&wma->wma_hold_req_queue, node1);
321 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530322 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800323 WMA_LOGD(FL("Failed to remove request. vdev_id %d type %d"),
324 vdev_id, msg_type);
325 return NULL;
326 }
327 break;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530328 } while (QDF_STATUS_SUCCESS ==
329 qdf_list_peek_next(&wma->wma_hold_req_queue, node1,
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800330 &node2));
331
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530332 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800333 if (!found) {
334 WMA_LOGE(FL("target request not found for vdev_id %d type %d"),
335 vdev_id, msg_type);
336 return NULL;
337 }
338
339 WMA_LOGD(FL("target request found for vdev id: %d type %d"),
340 vdev_id, msg_type);
341
342 return req_msg;
343}
344
345
346/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800347 * wma_find_vdev_req() - find target request for vdev id
348 * @wma: wma handle
349 * @vdev_id: vdev id
350 * @type: request type
Kiran Kumar Lokere20804162017-07-17 16:09:04 -0700351 * @remove_req_from_list: flag to indicate remove req or not.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352 *
353 * Return: return target request if found or NULL.
354 */
355static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma,
Kiran Kumar Lokere20804162017-07-17 16:09:04 -0700356 uint8_t vdev_id, uint8_t type,
357 bool remove_req_from_list)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800358{
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -0700359 struct wma_target_req *req_msg = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800360 bool found = false;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530361 qdf_list_node_t *node1 = NULL, *node2 = NULL;
362 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800363
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530364 qdf_spin_lock_bh(&wma->vdev_respq_lock);
Anurag Chouhanffb21542016-02-17 14:33:03 +0530365 if (QDF_STATUS_SUCCESS != qdf_list_peek_front(&wma->vdev_resp_queue,
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -0700366 &node2)) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530367 qdf_spin_unlock_bh(&wma->vdev_respq_lock);
Srinivas Girigowda2b5d47c2017-03-29 00:28:46 -0700368 WMA_LOGD(FL("unable to get target req from vdev resp queue vdev_id: %d type: %d"),
369 vdev_id, type);
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -0700370 return NULL;
371 }
372
373 do {
374 node1 = node2;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530375 req_msg = qdf_container_of(node1, struct wma_target_req, node);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800376 if (req_msg->vdev_id != vdev_id)
377 continue;
378 if (req_msg->type != type)
379 continue;
380
381 found = true;
Kiran Kumar Lokere20804162017-07-17 16:09:04 -0700382 if (remove_req_from_list) {
383 status = qdf_list_remove_node(&wma->vdev_resp_queue,
384 node1);
385 if (QDF_STATUS_SUCCESS != status) {
386 qdf_spin_unlock_bh(&wma->vdev_respq_lock);
387 WMA_LOGD(FL(
388 "Failed to target req for vdev_id %d type %d"),
389 vdev_id, type);
390 return NULL;
391 }
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -0700392 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800393 break;
Anurag Chouhanffb21542016-02-17 14:33:03 +0530394 } while (QDF_STATUS_SUCCESS ==
395 qdf_list_peek_next(&wma->vdev_resp_queue,
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -0700396 node1, &node2));
397
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530398 qdf_spin_unlock_bh(&wma->vdev_respq_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 if (!found) {
Srinivas Girigowda2b5d47c2017-03-29 00:28:46 -0700400 WMA_LOGD(FL("target request not found for vdev_id %d type %d"),
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -0700401 vdev_id, type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 return NULL;
403 }
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -0700404 WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"),
405 vdev_id, type, req_msg->msg_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 return req_msg;
407}
408
409/**
Abhishek Singhc614ec42017-04-25 16:17:34 +0530410 * wma_send_del_sta_self_resp() - send del sta self resp to Upper layer
411 * @param: params of del sta resp
412 *
413 * Return: none
414 */
415static inline void wma_send_del_sta_self_resp(struct del_sta_self_params *param)
416{
417 struct scheduler_msg sme_msg = {0};
418 QDF_STATUS status;
419
420 sme_msg.type = eWNI_SME_DEL_STA_SELF_RSP;
421 sme_msg.bodyptr = param;
422
423 status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
424 if (!QDF_IS_STATUS_SUCCESS(status)) {
425 WMA_LOGE("Failed to post eWNI_SME_DEL_STA_SELF_RSP");
426 qdf_mem_free(param);
427 }
428}
429
430/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 * wma_vdev_detach_callback() - send vdev detach response to upper layer
432 * @ctx: txrx node ptr
433 *
434 * Return: none
435 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -0700436static void wma_vdev_detach_callback(void *ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800437{
438 tp_wma_handle wma;
439 struct wma_txrx_node *iface = (struct wma_txrx_node *)ctx;
440 struct del_sta_self_params *param;
441 struct wma_target_req *req_msg;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442
Anurag Chouhan6d760662016-02-20 16:05:43 +0530443 wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444
445 if (!wma || !iface->del_staself_req) {
Jeff Johnsonadba3962017-09-18 08:12:35 -0700446 WMA_LOGE("%s: wma %pK iface %pK", __func__, wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 iface->del_staself_req);
448 return;
449 }
450 param = (struct del_sta_self_params *) iface->del_staself_req;
Sandeep Puligilla88de6fb2016-09-23 17:08:44 -0700451 iface->del_staself_req = NULL;
Srinivas Girigowdada0e8482017-03-19 23:15:45 -0700452 WMA_LOGD("%s: sending eWNI_SME_DEL_STA_SELF_RSP for vdev %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453 __func__, param->session_id);
Sourav Mohapatra89c85d12017-12-01 09:17:54 +0530454 if (!wmi_service_enabled(wma->wmi_handle,
455 wmi_service_sync_delete_cmds)) {
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800456 req_msg = wma_find_vdev_req(wma, param->session_id,
Kiran Kumar Lokere20804162017-07-17 16:09:04 -0700457 WMA_TARGET_REQ_TYPE_VDEV_DEL,
458 true);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800459 if (req_msg) {
460 WMA_LOGD("%s: Found vdev request for vdev id %d",
461 __func__, param->session_id);
Anurag Chouhan210db072016-02-22 18:42:15 +0530462 qdf_mc_timer_stop(&req_msg->event_timeout);
463 qdf_mc_timer_destroy(&req_msg->event_timeout);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530464 qdf_mem_free(req_msg);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800465 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466 }
467 if (iface->addBssStaContext)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530468 qdf_mem_free(iface->addBssStaContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800469
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800470
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800471 if (iface->staKeyParams)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530472 qdf_mem_free(iface->staKeyParams);
Naveen Rawat3c49d192017-03-02 18:43:16 -0800473
474 if (iface->stats_rsp)
475 qdf_mem_free(iface->stats_rsp);
476
Dustin Brownec2c92e2017-07-26 11:13:49 -0700477 wma_vdev_deinit(iface);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530478 qdf_mem_zero(iface, sizeof(*iface));
Dustin Brownec2c92e2017-07-26 11:13:49 -0700479 wma_vdev_init(iface);
480
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530481 param->status = QDF_STATUS_SUCCESS;
Abhishek Singhc614ec42017-04-25 16:17:34 +0530482 wma_send_del_sta_self_resp(param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800483}
484
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800485
486/**
487 * wma_self_peer_remove() - Self peer remove handler
488 * @wma: wma handle
489 * @del_sta_self_req_param: vdev id
490 * @generate_vdev_rsp: request type
491 *
492 * Return: success if peer delete command sent to firmware, else failure.
493 */
494
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530495static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle,
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800496 struct del_sta_self_params *del_sta_self_req_param,
497 uint8_t generate_vdev_rsp)
498{
Leo Chang96464902016-10-28 11:10:54 -0700499 void *peer;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800500 struct cdp_pdev *pdev;
Krunal Soni1b5debd2018-02-27 15:34:30 -0800501 QDF_STATUS qdf_status;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800502 uint8_t peer_id;
503 uint8_t vdev_id = del_sta_self_req_param->session_id;
504 struct wma_target_req *msg = NULL;
505 struct del_sta_self_rsp_params *sta_self_wmi_rsp;
Leo Chang96464902016-10-28 11:10:54 -0700506 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800507
Srinivas Girigowdada0e8482017-03-19 23:15:45 -0700508 WMA_LOGD("P2P Device: removing self peer %pM",
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800509 del_sta_self_req_param->self_mac_addr);
510
Anurag Chouhan6d760662016-02-20 16:05:43 +0530511 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800512 if (NULL == pdev) {
513 WMA_LOGE("%s: Failed to get pdev", __func__);
Krunal Soni1b5debd2018-02-27 15:34:30 -0800514 qdf_status = QDF_STATUS_E_FAULT;
515 goto error;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800516 }
517
Leo Chang96464902016-10-28 11:10:54 -0700518 peer = cdp_peer_find_by_addr(soc, pdev,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800519 del_sta_self_req_param->self_mac_addr,
520 &peer_id);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800521 if (!peer) {
522 WMA_LOGE("%s Failed to find peer %pM", __func__,
523 del_sta_self_req_param->self_mac_addr);
Krunal Soni40c5e442018-02-28 11:40:15 -0800524 qdf_status = QDF_STATUS_E_FAULT;
Krunal Soni1b5debd2018-02-27 15:34:30 -0800525 goto error;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800526 }
527 wma_remove_peer(wma_handle,
528 del_sta_self_req_param->self_mac_addr,
529 vdev_id, peer, false);
530
Sourav Mohapatra89c85d12017-12-01 09:17:54 +0530531 if (wmi_service_enabled(wma_handle->wmi_handle,
532 wmi_service_sync_delete_cmds)) {
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800533 sta_self_wmi_rsp =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530534 qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params));
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800535 if (sta_self_wmi_rsp == NULL) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -0700536 WMA_LOGE(FL("Failed to allocate memory"));
Krunal Soni1b5debd2018-02-27 15:34:30 -0800537 qdf_status = QDF_STATUS_E_NOMEM;
538 goto error;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800539 }
540 sta_self_wmi_rsp->self_sta_param = del_sta_self_req_param;
541 sta_self_wmi_rsp->generate_rsp = generate_vdev_rsp;
542 msg = wma_fill_hold_req(wma_handle, vdev_id,
543 WMA_DELETE_STA_REQ,
544 WMA_DEL_P2P_SELF_STA_RSP_START,
545 sta_self_wmi_rsp,
546 WMA_DELETE_STA_TIMEOUT);
547 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -0700548 WMA_LOGE(FL("Failed to allocate request for vdev_id %d"),
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800549 vdev_id);
550 wma_remove_req(wma_handle, vdev_id,
551 WMA_DEL_P2P_SELF_STA_RSP_START);
Krunal Soni1b5debd2018-02-27 15:34:30 -0800552 qdf_status = QDF_STATUS_E_FAILURE;
553 goto error;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800554 }
555 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530556 return QDF_STATUS_SUCCESS;
Krunal Soni1b5debd2018-02-27 15:34:30 -0800557error:
558 return qdf_status;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800559}
560
Jingxiang Gedf9292a2017-12-11 13:30:44 +0800561static void
562wma_cdp_vdev_detach(ol_txrx_soc_handle soc,
563 tp_wma_handle wma_handle,
564 uint8_t vdev_id)
565{
566 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
567
568 cdp_vdev_detach(soc,
569 iface->handle, NULL, NULL);
570 iface->handle = NULL;
571 iface->is_vdev_valid = false;
572}
573
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530574static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800575 struct del_sta_self_params *del_sta_self_req_param,
576 uint8_t generate_rsp)
577{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530578 QDF_STATUS status = QDF_STATUS_SUCCESS;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800579 uint8_t vdev_id = del_sta_self_req_param->session_id;
580 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
581 struct wma_target_req *msg = NULL;
Leo Chang96464902016-10-28 11:10:54 -0700582 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800583
Nishank Aggarwala13b61d2016-12-01 12:53:58 +0530584 if (!soc) {
585 WMA_LOGE("%s:SOC context is NULL", __func__);
586 status = QDF_STATUS_E_FAILURE;
587 goto out;
588 }
589
Min Liu22202b72018-02-12 14:01:24 +0800590 QDF_BUG(qdf_atomic_read(&iface->fw_peer_count) == 0);
Min Liua9df1ff2018-02-09 02:44:13 +0800591
Govind Singhd76a5b02016-03-08 15:12:14 +0530592 status = wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id);
593 if (QDF_IS_STATUS_ERROR(status)) {
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800594 WMA_LOGE("Unable to remove an interface");
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800595 goto out;
596 }
597
Min Liu22202b72018-02-12 14:01:24 +0800598 qdf_event_destroy(&iface->fw_peer_delete_completion);
Min Liua9df1ff2018-02-09 02:44:13 +0800599
Jeff Johnsonadba3962017-09-18 08:12:35 -0700600 WMA_LOGD("vdev_id:%hu vdev_hdl:%pK", vdev_id, iface->handle);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800601 if (!generate_rsp) {
602 WMA_LOGE("Call txrx detach w/o callback for vdev %d", vdev_id);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800603 goto out;
604 }
605
606 iface->del_staself_req = del_sta_self_req_param;
607 msg = wma_fill_vdev_req(wma_handle, vdev_id, WMA_DEL_STA_SELF_REQ,
608 WMA_TARGET_REQ_TYPE_VDEV_DEL, iface, 6000);
609 if (!msg) {
610 WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d",
611 __func__, vdev_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530612 status = QDF_STATUS_E_NOMEM;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800613 goto out;
614 }
615
616 /* Acquire wake lock only when you expect a response from firmware */
Sourav Mohapatra89c85d12017-12-01 09:17:54 +0530617 if (wmi_service_enabled(wma_handle->wmi_handle,
618 wmi_service_sync_delete_cmds)) {
Dustin Brownec2c92e2017-07-26 11:13:49 -0700619 wma_acquire_wakelock(&wma_handle->wmi_cmd_rsp_wake_lock,
620 WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800621 }
622 WMA_LOGD("Call txrx detach with callback for vdev %d", vdev_id);
Jingxiang Gedf9292a2017-12-11 13:30:44 +0800623 wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800624
625 /*
626 * send the response immediately if WMI_SERVICE_SYNC_DELETE_CMDS
627 * service is not supported by firmware
628 */
Sourav Mohapatra89c85d12017-12-01 09:17:54 +0530629 if (!wmi_service_enabled(wma_handle->wmi_handle,
630 wmi_service_sync_delete_cmds))
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800631 wma_vdev_detach_callback(iface);
632 return status;
633out:
Jingxiang Gedf9292a2017-12-11 13:30:44 +0800634 WMA_LOGE("Call txrx detach callback for vdev %d, generate_rsp %u",
635 vdev_id, generate_rsp);
636 wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
637
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800638 if (iface->addBssStaContext)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530639 qdf_mem_free(iface->addBssStaContext);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800640 if (iface->staKeyParams)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530641 qdf_mem_free(iface->staKeyParams);
Dustin Brown35b61f62017-08-31 16:03:32 -0700642
643 wma_vdev_deinit(iface);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530644 qdf_mem_zero(iface, sizeof(*iface));
Dustin Brown35b61f62017-08-31 16:03:32 -0700645 wma_vdev_init(iface);
646
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800647 del_sta_self_req_param->status = status;
Abhishek Singhc614ec42017-04-25 16:17:34 +0530648 if (generate_rsp)
649 wma_send_del_sta_self_resp(del_sta_self_req_param);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800650 return status;
651}
Jiachao Wu2c42c222018-01-15 18:13:19 +0800652
653/**
Jiachao Wu641760e2018-01-21 12:11:31 +0800654 * wma_peer_remove_for_vdev_callback() - remove peer for vdev when SSR
655 * @handle: wma handle
656 * @bssid: mac address
657 * @vdev_id: vdev id
658 * @peer: peer ptr
659 *
660 * Wapper wma_remove_peer for callback, this function will remove peer
661 * without waiting for peer unmap event.
662 * Return: none
663 */
664static void wma_peer_remove_for_vdev_callback(void *handle, uint8_t *bssid,
665 uint8_t vdev_id, void *peer)
666{
667 wma_remove_peer(handle, bssid, vdev_id, peer, true);
668}
669
670/**
Jiachao Wu2c42c222018-01-15 18:13:19 +0800671 * wma_force_vdev_cleanup() - Cleanup vdev resource when SSR
672 * @wma_handle: WMA handle
673 * @vdev_id: vdev ID
674 *
675 * Return: none
676 */
677static void wma_force_vdev_cleanup(tp_wma_handle wma_handle, uint8_t vdev_id)
678{
679 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
680 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
Jiachao Wu641760e2018-01-21 12:11:31 +0800681 struct cdp_pdev *pdev;
682 struct cdp_vdev *vdev;
Jiachao Wu2c42c222018-01-15 18:13:19 +0800683
684 WMA_LOGE("SSR: force cleanup vdev(%d) resouce", vdev_id);
685 iface->vdev_active = false;
Jiachao Wu641760e2018-01-21 12:11:31 +0800686
687 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
688 if (!pdev) {
689 WMA_LOGE("%s: Failed to get pdev", __func__);
690 goto VDEV_DETACH;
691 }
692
693 vdev = cdp_get_vdev_from_vdev_id(soc, pdev, vdev_id);
694 if (!vdev) {
695 WMA_LOGE("%s: Failed to get vdev (%d)", __func__, vdev_id);
696 goto VDEV_DETACH;
697 }
698
699 /* force remove all peer for vdev */
700 cdp_peer_remove_for_vdev_no_lock(soc, vdev,
701 wma_peer_remove_for_vdev_callback,
702 wma_handle);
703
Min Liu46ef0bf2018-04-17 16:25:48 +0800704 qdf_atomic_init(&iface->fw_peer_count);
705 qdf_event_destroy(&iface->fw_peer_delete_completion);
706
Jiachao Wu641760e2018-01-21 12:11:31 +0800707VDEV_DETACH:
Jiachao Wu2c42c222018-01-15 18:13:19 +0800708 wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
709}
710
Min Liu22202b72018-02-12 14:01:24 +0800711#define WMA_WAIT_PEER_DELETE_COMPLETION_TIMEOUT (WMA_VDEV_STOP_REQUEST_TIMEOUT+ 1000)
712
713/**
714 * wma_vdev_wait_for_peer_delete_completion(): wait for all peers of the vdev
Wu Gao6fff9932018-03-23 15:16:51 +0800715 * to be deleted except vdev type is P2P device.
Min Liu22202b72018-02-12 14:01:24 +0800716 * @wma_handle: wma handle
717 * @vdev_id: vdev id
718 *
719 * Return: None
720 */
721void wma_vdev_wait_for_peer_delete_completion(tp_wma_handle wma_handle,
722 uint8_t vdev_id)
723{
724 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
725
Min Liu46ef0bf2018-04-17 16:25:48 +0800726 /* Do NOT wait when SSR is in progress
727 * since all WMI commands will be ignored and not sent to FW
728 */
729 if (cds_is_driver_recovering()) {
730 WMA_LOGD("%s: SSR is in progress", __func__);
731 return;
732 }
733
734 if (!iface || !iface->vdev_active) {
735 WMA_LOGE("%s: iface of vdev-%d is not available",
736 __func__, vdev_id);
Min Liu22202b72018-02-12 14:01:24 +0800737 return;
738 }
739
Wu Gao6fff9932018-03-23 15:16:51 +0800740 /* For P2P Device, firstly it will delete the last peer in
741 * wma vdev detach, so not wait before deliver
742 * WMA_DEL_STA_SELF_REQ. Secondly, no throughput case run on
743 * P2P device, and no need to take care the case which no
744 * vdev stop response from FW.
745 */
Sandeep Puligilladb6de352018-03-30 17:08:56 -0700746 if (((iface->type == WMI_VDEV_TYPE_AP) &&
747 (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) ||
748 (cds_is_fw_down())) {
749 WMA_LOGD("%s: type %d P2P devices or firmware is down, do not wait",
750 __func__, iface->type);
Wu Gao6fff9932018-03-23 15:16:51 +0800751 return;
752 }
753
Min Liu22202b72018-02-12 14:01:24 +0800754 qdf_wait_for_event_completion(&iface->fw_peer_delete_completion,
755 WMA_WAIT_PEER_DELETE_COMPLETION_TIMEOUT);
756}
757
Dustin Brown04823992018-03-29 13:27:01 -0700758static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype)
759{
760 switch (vdev_type) {
761 case WMI_VDEV_TYPE_AP:
762 return vdev_subtype == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE;
763
764 case WMI_VDEV_TYPE_MONITOR:
765 case WMI_VDEV_TYPE_NDI:
766 case WMI_VDEV_TYPE_OCB:
767 return true;
768
769 default:
770 return false;
771 }
772}
773
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774/**
775 * wma_vdev_detach() - send vdev delete command to fw
776 * @wma_handle: wma handle
777 * @pdel_sta_self_req_param: del sta params
778 * @generateRsp: generate Response flag
779 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530780 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530782QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800783 struct del_sta_self_params *pdel_sta_self_req_param,
784 uint8_t generateRsp)
785{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530786 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 uint8_t vdev_id = pdel_sta_self_req_param->session_id;
788 struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
Kiran Kumar Lokere35577652017-07-14 02:06:56 -0700789 struct wma_target_req *req_msg;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790
Jiachao Wu2c42c222018-01-15 18:13:19 +0800791 if (!iface->handle) {
792 WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed",
793 vdev_id);
794 goto send_rsp;
795 }
796
797 /*
798 * In SSR case, there is no need to destroy vdev in firmware since
799 * it has already asserted.
800 */
801 if (cds_is_driver_recovering()) {
802 wma_force_vdev_cleanup(wma_handle, vdev_id);
803 goto send_rsp;
804 }
805
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +0530806 if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) {
Kiran Kumar Lokere35577652017-07-14 02:06:56 -0700807 req_msg = wma_find_vdev_req(wma_handle, vdev_id,
Kiran Kumar Lokere20804162017-07-17 16:09:04 -0700808 WMA_TARGET_REQ_TYPE_VDEV_STOP, false);
Kiran Kumar Lokere35577652017-07-14 02:06:56 -0700809 if (!req_msg)
810 goto send_fail_rsp;
811 if (req_msg->msg_type != WMA_DELETE_BSS_REQ)
812 goto send_fail_rsp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800813 WMA_LOGA("BSS is not yet stopped. Defering vdev(vdev id %x) deletion",
814 vdev_id);
815 iface->del_staself_req = pdel_sta_self_req_param;
Abhishek Singh0d74f9e2017-09-26 14:02:42 +0530816 iface->is_del_sta_defered = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 return status;
818 }
Abhishek Singh0d74f9e2017-09-26 14:02:42 +0530819 iface->is_del_sta_defered = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820
Dustin Brown04823992018-03-29 13:27:01 -0700821 if (wma_vdev_uses_self_peer(iface->type, iface->sub_type)) {
Krunal Soni1b5debd2018-02-27 15:34:30 -0800822 status = wma_self_peer_remove(wma_handle,
823 pdel_sta_self_req_param, generateRsp);
824 if ((status != QDF_STATUS_SUCCESS) && generateRsp) {
825 WMA_LOGE("can't remove selfpeer, send rsp session: %d",
826 vdev_id);
Krunal Soni40c5e442018-02-28 11:40:15 -0800827 if (!cds_is_driver_unloading()) {
828 WMA_LOGE("Trigger recovery for session: %d",
829 vdev_id);
830 goto send_fail_rsp;
831 } else {
832 WMA_LOGE("driver unload, free mem vdev_id: %d",
833 vdev_id);
834 goto send_rsp;
835 }
836 } else if (status != QDF_STATUS_SUCCESS) {
Krunal Soni1b5debd2018-02-27 15:34:30 -0800837 WMA_LOGE("can't remove selfpeer, free msg session: %d",
838 vdev_id);
839 qdf_mem_free(pdel_sta_self_req_param);
840 pdel_sta_self_req_param = NULL;
841 return status;
842 }
Sourav Mohapatra89c85d12017-12-01 09:17:54 +0530843 if (!wmi_service_enabled(wma_handle->wmi_handle,
844 wmi_service_sync_delete_cmds))
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800845 status = wma_handle_vdev_detach(wma_handle,
846 pdel_sta_self_req_param, generateRsp);
Dustin Brown04823992018-03-29 13:27:01 -0700847 } else {
Sandeep Puligilla19ddda22016-01-05 12:18:02 -0800848 status = wma_handle_vdev_detach(wma_handle,
849 pdel_sta_self_req_param, generateRsp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800850 }
851
Arif Hussain380cfc72017-10-31 13:12:04 -0700852 if (QDF_IS_STATUS_SUCCESS(status))
853 iface->vdev_active = false;
854
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800855 return status;
Kiran Kumar Lokere35577652017-07-14 02:06:56 -0700856
857send_fail_rsp:
Himanshu Agarwalfc4dab92017-12-28 21:46:29 +0530858 if (!cds_is_driver_recovering()) {
859 if (cds_is_self_recovery_enabled()) {
860 WMA_LOGE("rcvd del_self_sta without del_bss, trigger recovery, vdev_id %d",
861 vdev_id);
862 cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
863 } else {
864 WMA_LOGE("rcvd del_self_sta without del_bss, BUG_ON(), vdev_id %d",
865 vdev_id);
866 QDF_BUG(0);
867 }
868 }
Jiachao Wu2c42c222018-01-15 18:13:19 +0800869 status = QDF_STATUS_E_FAILURE;
Himanshu Agarwalfc4dab92017-12-28 21:46:29 +0530870
Jiachao Wu2c42c222018-01-15 18:13:19 +0800871send_rsp:
872 if (generateRsp) {
873 pdel_sta_self_req_param->status = status;
874 wma_send_del_sta_self_resp(pdel_sta_self_req_param);
875 } else {
876 qdf_mem_free(pdel_sta_self_req_param);
877 pdel_sta_self_req_param = NULL;
878 }
Kiran Kumar Lokere35577652017-07-14 02:06:56 -0700879 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880}
881
882/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 * wma_vdev_start_rsp() - send vdev start response to upper layer
884 * @wma: wma handle
885 * @add_bss: add bss params
886 * @resp_event: response params
887 *
888 * Return: none
889 */
890static void wma_vdev_start_rsp(tp_wma_handle wma,
891 tpAddBssParams add_bss,
892 wmi_vdev_start_response_event_fixed_param *
893 resp_event)
894{
895 struct beacon_info *bcn;
Padma, Santhosh Kumar88104612017-04-10 18:49:12 +0530896 struct cdp_pdev *pdev;
897 void *peer = NULL;
898 uint8_t peer_id;
899 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900
901#ifdef QCA_IBSS_SUPPORT
902 WMA_LOGD("%s: vdev start response received for %s mode", __func__,
903 add_bss->operMode ==
904 BSS_OPERATIONAL_MODE_IBSS ? "IBSS" : "non-IBSS");
905#endif /* QCA_IBSS_SUPPORT */
906
907 if (resp_event->status) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530908 add_bss->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 goto send_fail_resp;
910 }
911
912 if ((add_bss->operMode == BSS_OPERATIONAL_MODE_AP)
913#ifdef QCA_IBSS_SUPPORT
914 || (add_bss->operMode == BSS_OPERATIONAL_MODE_IBSS)
915#endif /* QCA_IBSS_SUPPORT */
916 ) {
917 wma->interfaces[resp_event->vdev_id].beacon =
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530918 qdf_mem_malloc(sizeof(struct beacon_info));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919
920 bcn = wma->interfaces[resp_event->vdev_id].beacon;
921 if (!bcn) {
922 WMA_LOGE("%s: Failed alloc memory for beacon struct",
923 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530924 add_bss->status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 goto send_fail_resp;
926 }
Nirav Shahcbc6d722016-03-01 16:24:53 +0530927 bcn->buf = qdf_nbuf_alloc(NULL, WMA_BCN_BUF_MAX_SIZE, 0,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800928 sizeof(uint32_t), 0);
929 if (!bcn->buf) {
930 WMA_LOGE("%s: No memory allocated for beacon buffer",
931 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530932 qdf_mem_free(bcn);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530933 add_bss->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800934 goto send_fail_resp;
935 }
936 bcn->seq_no = MIN_SW_SEQ;
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530937 qdf_spinlock_create(&bcn->lock);
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +0530938 qdf_atomic_set(&wma->interfaces[resp_event->vdev_id].bss_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939 WMA_BSS_STATUS_STARTED);
940 WMA_LOGD("%s: AP mode (type %d subtype %d) BSS is started",
941 __func__, wma->interfaces[resp_event->vdev_id].type,
942 wma->interfaces[resp_event->vdev_id].sub_type);
943
Jeff Johnsonadba3962017-09-18 08:12:35 -0700944 WMA_LOGD("%s: Allocated beacon struct %pK, template memory %pK",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800945 __func__, bcn, bcn->buf);
946 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530947 add_bss->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800948 add_bss->bssIdx = resp_event->vdev_id;
949 add_bss->chainMask = resp_event->chain_mask;
950 if ((2 != resp_event->cfgd_rx_streams) ||
951 (2 != resp_event->cfgd_tx_streams)) {
952 add_bss->nss = 1;
953 }
954 add_bss->smpsMode = host_map_smps_mode(resp_event->smps_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800955send_fail_resp:
Padma, Santhosh Kumar88104612017-04-10 18:49:12 +0530956 if (add_bss->status != QDF_STATUS_SUCCESS) {
957 WMA_LOGE("%s: ADD BSS failure %d", __func__, add_bss->status);
958
959 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
960 if (NULL == pdev)
961 WMA_LOGE("%s: Failed to get pdev", __func__);
962
963 if (pdev)
964 peer = cdp_peer_find_by_addr(soc, pdev,
965 add_bss->bssId, &peer_id);
966 if (!peer)
967 WMA_LOGE("%s Failed to find peer %pM", __func__,
968 add_bss->bssId);
969
970 if (peer)
971 wma_remove_peer(wma, add_bss->bssId,
972 resp_event->vdev_id, peer, false);
973 }
974
Abhishek Singh34c15642017-05-08 16:13:02 +0530975 /* Send vdev stop if vdev start was success */
976 if ((add_bss->status != QDF_STATUS_SUCCESS) &&
977 !resp_event->status)
978 if (wma_send_vdev_stop_to_fw(wma, resp_event->vdev_id))
979 WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__);
980
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800981 WMA_LOGD("%s: Sending add bss rsp to umac(vdev %d status %d)",
982 __func__, resp_event->vdev_id, add_bss->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +0530983 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800984}
985
986#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
987/**
988 * wma_find_mcc_ap() - finds if device is operating AP in MCC mode or not
989 * @wma: wma handle.
990 * @vdev_id: vdev ID of device for which MCC has to be checked
991 * @add: flag indicating if current device is added or deleted
992 *
993 * This function parses through all the interfaces in wma and finds if
994 * any of those devces are in MCC mode with AP. If such a vdev is found
995 * involved AP vdevs are sent WDA_UPDATE_Q2Q_IE_IND msg to update their
996 * beacon template to include Q2Q IE.
997 *
998 * Return: none
999 */
Tang Yingying523322d2017-01-17 23:28:43 +08001000static void wma_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id, bool add)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001{
1002 uint8_t i;
1003 uint16_t prev_ch_freq = 0;
1004 bool is_ap = false;
1005 bool result = false;
1006 uint8_t *ap_vdev_ids = NULL;
1007 uint8_t num_ch = 0;
1008
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301009 ap_vdev_ids = qdf_mem_malloc(wma->max_bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010 if (!ap_vdev_ids)
1011 return;
1012
1013 for (i = 0; i < wma->max_bssid; i++) {
1014 ap_vdev_ids[i] = -1;
1015 if (add == false && i == vdev_id)
1016 continue;
1017
Mukul Sharmaf9047232017-03-02 16:58:56 +05301018 if (wma_is_vdev_up(vdev_id) || (i == vdev_id && add)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001019 if (wma->interfaces[i].type == WMI_VDEV_TYPE_AP) {
1020 is_ap = true;
1021 ap_vdev_ids[i] = i;
1022 }
1023
1024 if (wma->interfaces[i].mhz != prev_ch_freq) {
1025 num_ch++;
1026 prev_ch_freq = wma->interfaces[i].mhz;
1027 }
1028 }
1029 }
1030
1031 if (is_ap && (num_ch > 1))
1032 result = true;
1033 else
1034 result = false;
1035
1036 wma_send_msg(wma, WMA_UPDATE_Q2Q_IE_IND, (void *)ap_vdev_ids, result);
1037}
1038#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1039
1040/**
1041 * wma_vdev_start_resp_handler() - vdev start response handler
1042 * @handle: wma handle
1043 * @cmd_param_info: event buffer
1044 * @len: buffer length
1045 *
1046 * Return: 0 for success or error code
1047 */
1048int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
1049 uint32_t len)
1050{
1051 tp_wma_handle wma = (tp_wma_handle) handle;
1052 WMI_VDEV_START_RESP_EVENTID_param_tlvs *param_buf;
1053 wmi_vdev_start_response_event_fixed_param *resp_event;
1054 struct wma_target_req *req_msg;
1055 struct wma_txrx_node *iface;
Govind Singhd76a5b02016-03-08 15:12:14 +05301056 struct vdev_up_params param = {0};
1057 QDF_STATUS status;
Deepak Dhamdhered8455ce2016-11-02 13:11:55 -07001058 int err;
Naveen Rawatf8792bd2017-11-12 21:38:05 -08001059 wmi_host_channel_width chanwidth;
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301060 target_resource_config *wlan_res_cfg;
1061 struct wlan_objmgr_psoc *psoc = wma->psoc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001062#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Anurag Chouhan6d760662016-02-20 16:05:43 +05301063 tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301064#endif
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001065
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301066 if (!psoc) {
1067 WMA_LOGE("%s: psoc is NULL", __func__);
1068 return -EINVAL;
1069 }
1070
1071#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001072 if (NULL == mac_ctx) {
1073 WMA_LOGE("%s: Failed to get mac_ctx", __func__);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07001074 policy_mgr_set_do_hw_mode_change_flag(
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301075 psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001076 return -EINVAL;
1077 }
1078#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1079
1080 WMA_LOGD("%s: Enter", __func__);
Dustin Brown3e619822017-03-17 10:41:56 -07001081
Sourav Mohapatracf632572018-04-02 11:01:35 +05301082 wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301083 if (!wlan_res_cfg) {
1084 WMA_LOGE("%s: Wlan resource config is NULL", __func__);
1085 return -EINVAL;
1086 }
1087
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001088 param_buf = (WMI_VDEV_START_RESP_EVENTID_param_tlvs *) cmd_param_info;
1089 if (!param_buf) {
1090 WMA_LOGE("Invalid start response event buffer");
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07001091 policy_mgr_set_do_hw_mode_change_flag(
1092 wma->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001093 return -EINVAL;
1094 }
1095
1096 resp_event = param_buf->fixed_param;
1097 if (!resp_event) {
1098 WMA_LOGE("Invalid start response event buffer");
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07001099 policy_mgr_set_do_hw_mode_change_flag(
1100 wma->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001101 return -EINVAL;
1102 }
1103
Himanshu Agarwaldfca3d82017-10-06 12:40:27 +05301104 if (resp_event->vdev_id >= wma->max_bssid) {
1105 WMA_LOGE("Invalid vdev id received from firmware");
1106 return -EINVAL;
1107 }
1108
bings1f98e9f2018-01-24 16:13:41 +08001109 if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id))
1110 tgt_dfs_radar_enable(wma->pdev, 0, 0);
1111
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301112 if (resp_event->status == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001113 wma->interfaces[resp_event->vdev_id].tx_streams =
1114 resp_event->cfgd_tx_streams;
1115 wma->interfaces[resp_event->vdev_id].rx_streams =
1116 resp_event->cfgd_rx_streams;
1117 wma->interfaces[resp_event->vdev_id].chain_mask =
1118 resp_event->chain_mask;
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301119 if (wlan_res_cfg->use_pdev_id) {
Govind Singhefc5ccd2016-04-25 11:11:55 +05301120 if (resp_event->pdev_id == WMI_PDEV_ID_SOC) {
1121 WMA_LOGE("%s: soc level id received for mac id",
1122 __func__);
1123 QDF_BUG(0);
1124 return -EINVAL;
1125 }
1126 wma->interfaces[resp_event->vdev_id].mac_id =
1127 WMA_PDEV_TO_MAC_MAP(resp_event->pdev_id);
1128 } else {
1129 wma->interfaces[resp_event->vdev_id].mac_id =
1130 resp_event->mac_id;
1131 }
1132
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07001133 WMA_LOGD("%s: vdev:%d tx ss=%d rx ss=%d chain mask=%d mac=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001134 __func__,
1135 resp_event->vdev_id,
1136 wma->interfaces[resp_event->vdev_id].tx_streams,
1137 wma->interfaces[resp_event->vdev_id].rx_streams,
1138 wma->interfaces[resp_event->vdev_id].chain_mask,
1139 wma->interfaces[resp_event->vdev_id].mac_id);
1140 }
1141
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05301142 iface = &wma->interfaces[resp_event->vdev_id];
1143
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07001144 req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,
Kiran Kumar Lokere20804162017-07-17 16:09:04 -07001145 WMA_TARGET_REQ_TYPE_VDEV_START,
1146 true);
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07001147
1148 if (!req_msg) {
1149 WMA_LOGE("%s: Failed to lookup request message for vdev %d",
1150 __func__, resp_event->vdev_id);
1151 policy_mgr_set_do_hw_mode_change_flag(wma->psoc, false);
1152 return -EINVAL;
1153 }
1154
Naveen Rawatf2bd42d2017-06-29 14:51:43 -07001155 if ((resp_event->vdev_id < wma->max_bssid) &&
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001156 (qdf_atomic_read(
1157 &wma->interfaces[resp_event->vdev_id].vdev_restart_params.hidden_ssid_restart_in_progress))
Pragaspathi Thilagarajb9c46742018-04-13 18:53:50 +05301158 && (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) == true)
1159 && (req_msg->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART)) {
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07001160 tpHalHiddenSsidVdevRestart hidden_ssid_restart =
1161 (tpHalHiddenSsidVdevRestart)req_msg->user_data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001162 WMA_LOGE("%s: vdev restart event recevied for hidden ssid set using IOCTL",
1163 __func__);
1164
Govind Singhd76a5b02016-03-08 15:12:14 +05301165 param.vdev_id = resp_event->vdev_id;
1166 param.assoc_id = 0;
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05301167 qdf_atomic_set(&wma->interfaces[resp_event->vdev_id].
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001168 vdev_restart_params.
1169 hidden_ssid_restart_in_progress, 0);
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07001170
1171 wma_send_msg(wma, WMA_HIDDEN_SSID_RESTART_RSP,
1172 (void *)hidden_ssid_restart, 0);
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05301173 /*
1174 * Unpause TX queue in SAP case while configuring hidden ssid
1175 * enable or disable, else the data path is paused forever
1176 * causing data packets(starting from DHCP offer) to get stuck
1177 */
Leo Chang96464902016-10-28 11:10:54 -07001178 cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
1179 iface->handle,
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05301180 OL_TXQ_PAUSE_REASON_VDEV_STOP);
Mukul Sharma6411bb82017-03-01 15:57:07 +05301181 wma_vdev_clear_pause_bit(resp_event->vdev_id, PAUSE_TYPE_HOST);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001182 }
1183
Anurag Chouhan210db072016-02-22 18:42:15 +05301184 qdf_mc_timer_stop(&req_msg->event_timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001185
1186#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301187 if (resp_event->status == QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188 && mac_ctx->sap.sap_channel_avoidance)
1189 wma_find_mcc_ap(wma, resp_event->vdev_id, true);
1190#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1191
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192 if (req_msg->msg_type == WMA_CHNL_SWITCH_REQ) {
1193 tpSwitchChannelParams params =
1194 (tpSwitchChannelParams) req_msg->user_data;
Krunal Sonia5388a22018-02-12 19:47:44 -08001195
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001196 if (!params) {
1197 WMA_LOGE("%s: channel switch params is NULL for vdev %d",
1198 __func__, resp_event->vdev_id);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07001199 policy_mgr_set_do_hw_mode_change_flag(
1200 wma->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 return -EINVAL;
1202 }
1203
1204 WMA_LOGD("%s: Send channel switch resp vdev %d status %d",
1205 __func__, resp_event->vdev_id, resp_event->status);
1206 params->chainMask = resp_event->chain_mask;
1207 if ((2 != resp_event->cfgd_rx_streams) ||
1208 (2 != resp_event->cfgd_tx_streams)) {
1209 params->nss = 1;
1210 }
1211 params->smpsMode = host_map_smps_mode(resp_event->smps_mode);
1212 params->status = resp_event->status;
Agrawal Ashish7dd7c592016-02-22 14:25:11 +05301213 if (wma->interfaces[resp_event->vdev_id].is_channel_switch) {
1214 wma->interfaces[resp_event->vdev_id].is_channel_switch =
1215 false;
1216 }
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07001217 if (((resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT) &&
Krunal Sonia5388a22018-02-12 19:47:44 -08001218 ((iface->type == WMI_VDEV_TYPE_STA) ||
1219 (iface->type == WMI_VDEV_TYPE_MONITOR))) ||
Agrawal Ashish7dd7c592016-02-22 14:25:11 +05301220 ((resp_event->resp_type == WMI_VDEV_START_RESP_EVENT) &&
1221 (iface->type == WMI_VDEV_TYPE_MONITOR))) {
Naveen Rawatd24c1162018-03-07 15:59:31 -08001222 /* for CSA case firmware expects phymode before ch_wd */
1223 err = wma_set_peer_param(wma, iface->bssid,
1224 WMI_PEER_PHYMODE, iface->chanmode,
1225 resp_event->vdev_id);
1226 WMA_LOGD("%s:vdev_id %d chanmode %d status %d",
1227 __func__, resp_event->vdev_id,
1228 iface->chanmode, err);
1229
Naveen Rawatf8792bd2017-11-12 21:38:05 -08001230 chanwidth =
1231 wmi_get_ch_width_from_phy_mode(wma->wmi_handle,
1232 iface->chanmode);
Deepak Dhamdhered8455ce2016-11-02 13:11:55 -07001233 err = wma_set_peer_param(wma, iface->bssid,
1234 WMI_PEER_CHWIDTH, chanwidth,
1235 resp_event->vdev_id);
Deepak Dhamdhered8455ce2016-11-02 13:11:55 -07001236 WMA_LOGD("%s:vdev_id %d chanwidth %d status %d",
1237 __func__, resp_event->vdev_id,
1238 chanwidth, err);
1239
Govind Singhd76a5b02016-03-08 15:12:14 +05301240 param.vdev_id = resp_event->vdev_id;
1241 param.assoc_id = iface->aid;
Dustin Brownec2c92e2017-07-26 11:13:49 -07001242 status = wma_send_vdev_up_to_fw(wma, &param,
1243 iface->bssid);
Govind Singhd76a5b02016-03-08 15:12:14 +05301244 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001245 WMA_LOGE("%s:vdev_up failed vdev_id %d",
1246 __func__, resp_event->vdev_id);
Mukul Sharmaf9047232017-03-02 16:58:56 +05301247 wma_vdev_set_mlme_state(wma,
1248 resp_event->vdev_id, WLAN_VDEV_S_STOP);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07001249 policy_mgr_set_do_hw_mode_change_flag(
1250 wma->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001251 } else {
Mukul Sharmaf9047232017-03-02 16:58:56 +05301252 wma_vdev_set_mlme_state(wma,
1253 resp_event->vdev_id, WLAN_VDEV_S_RUN);
Kiran Kumar Lokeref9dc7912017-06-28 18:10:58 -07001254 if (iface->beacon_filter_enabled)
1255 wma_add_beacon_filter(wma,
1256 &iface->beacon_filter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257 }
1258 }
1259
Abhishek Singh2d775fd2017-08-18 10:51:33 +05301260 wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
1261 (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 } else if (req_msg->msg_type == WMA_ADD_BSS_REQ) {
1263 tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001264
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301265 qdf_mem_copy(iface->bssid, bssParams->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 IEEE80211_ADDR_LEN);
1267 wma_vdev_start_rsp(wma, bssParams, resp_event);
1268 } else if (req_msg->msg_type == WMA_OCB_SET_CONFIG_CMD) {
Govind Singhd76a5b02016-03-08 15:12:14 +05301269 param.vdev_id = resp_event->vdev_id;
1270 param.assoc_id = iface->aid;
Dustin Brownec2c92e2017-07-26 11:13:49 -07001271 if (wma_send_vdev_up_to_fw(wma, &param, iface->bssid) !=
1272 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 WMA_LOGE(FL("failed to send vdev up"));
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07001274 policy_mgr_set_do_hw_mode_change_flag(
1275 wma->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 return -EEXIST;
1277 }
Mukul Sharmaf9047232017-03-02 16:58:56 +05301278 wma_vdev_set_mlme_state(wma, resp_event->vdev_id,
1279 WLAN_VDEV_S_RUN);
Zhang Qian47e22ce2018-01-04 15:38:38 +08001280 ucfg_ocb_config_channel(wma->pdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001281 }
1282
1283 if ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP) &&
Mukul Sharmaf9047232017-03-02 16:58:56 +05301284 wma_is_vdev_up(resp_event->vdev_id))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285 wma_set_sap_keepalive(wma, resp_event->vdev_id);
1286
Anurag Chouhan210db072016-02-22 18:42:15 +05301287 qdf_mc_timer_destroy(&req_msg->event_timeout);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301288 qdf_mem_free(req_msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001289
1290 return 0;
1291}
1292
Yeshwanth Sriram Guntukad5aae7f2017-11-27 14:33:51 +05301293bool wma_is_vdev_valid(uint32_t vdev_id)
Rajeev Kumard9a43cf2017-07-19 14:55:42 -07001294{
1295 tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1296
Arif Hussain380cfc72017-10-31 13:12:04 -07001297 if (!wma_handle) {
1298 WMA_LOGD("%s: vdev_id: %d, null wma_handle", __func__, vdev_id);
Rajeev Kumard9a43cf2017-07-19 14:55:42 -07001299 return false;
Arif Hussain380cfc72017-10-31 13:12:04 -07001300 }
Rajeev Kumard9a43cf2017-07-19 14:55:42 -07001301
Vignesh Viswanathan9fa8fef2017-12-12 14:45:38 +05301302 /* No of interface are allocated based on max_bssid value */
1303 if (vdev_id >= wma_handle->max_bssid) {
1304 WMA_LOGD("%s: vdev_id: %d is invalid, max_bssid: %d",
1305 __func__, vdev_id, wma_handle->max_bssid);
1306 return false;
1307 }
1308
Arif Hussain380cfc72017-10-31 13:12:04 -07001309 WMA_LOGD("%s: vdev_id: %d, vdev_active: %d, is_vdev_valid %d",
1310 __func__, vdev_id, wma_handle->interfaces[vdev_id].vdev_active,
1311 wma_handle->interfaces[vdev_id].is_vdev_valid);
1312
1313 return wma_handle->interfaces[vdev_id].vdev_active ||
1314 wma_handle->interfaces[vdev_id].is_vdev_valid;
Rajeev Kumard9a43cf2017-07-19 14:55:42 -07001315}
1316
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001317/**
Govind Singhd76a5b02016-03-08 15:12:14 +05301318 * wma_vdev_set_param() - set per vdev params in fw
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001319 * @wmi_handle: wmi handle
1320 * @if_if: vdev id
1321 * @param_id: parameter id
1322 * @param_value: parameter value
1323 *
Govind Singhd76a5b02016-03-08 15:12:14 +05301324 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 */
Govind Singhd76a5b02016-03-08 15:12:14 +05301326QDF_STATUS
1327wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 uint32_t param_id, uint32_t param_value)
1329{
Govind Singhd76a5b02016-03-08 15:12:14 +05301330 struct vdev_set_params param = {0};
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001331
Rajeev Kumard9a43cf2017-07-19 14:55:42 -07001332 if (!wma_is_vdev_valid(if_id)) {
1333 WMA_LOGE(FL("vdev_id: %d is not active reject the req: param id %d val %d"),
1334 if_id, param_id, param_value);
Rajeev Kumard9a43cf2017-07-19 14:55:42 -07001335 return QDF_STATUS_E_INVAL;
1336 }
1337
Govind Singhd76a5b02016-03-08 15:12:14 +05301338 param.if_id = if_id;
1339 param.param_id = param_id;
1340 param.param_value = param_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001341
Govind Singhd76a5b02016-03-08 15:12:14 +05301342 return wmi_unified_vdev_set_param_send(wmi_handle, &param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001343}
1344
1345/**
1346 * wma_set_peer_authorized_cb() - set peer authorized callback function
1347 * @wma_Ctx: wma handle
1348 * @auth_cb: peer authorized callback
1349 *
1350 * Return: none
1351 */
1352void wma_set_peer_authorized_cb(void *wma_ctx, wma_peer_authorized_fp auth_cb)
1353{
1354 tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001355
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356 wma_handle->peer_authorized_cb = auth_cb;
1357}
1358
1359/**
1360 * wma_set_peer_param() - set peer parameter in fw
1361 * @wma_ctx: wma handle
1362 * @peer_addr: peer mac address
1363 * @param_id: parameter id
1364 * @param_value: parameter value
1365 * @vdev_id: vdev id
1366 *
Govind Singhd76a5b02016-03-08 15:12:14 +05301367 * Return: QDF_STATUS_SUCCESS for success or error code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001368 */
Govind Singhd76a5b02016-03-08 15:12:14 +05301369QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
1370 uint32_t param_id, uint32_t param_value,
1371 uint32_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372{
1373 tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx;
Govind Singhd76a5b02016-03-08 15:12:14 +05301374 struct peer_set_params param = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001375 int err;
1376
Govind Singhd76a5b02016-03-08 15:12:14 +05301377 param.vdev_id = vdev_id;
1378 param.param_value = param_value;
1379 param.param_id = param_id;
1380
1381 err = wmi_set_peer_param_send(wma_handle->wmi_handle, peer_addr,
1382 &param);
1383
1384 return err;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001385}
1386
1387/**
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07001388 * wma_remove_peer() - remove peer information from host driver and fw
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001389 * @wma: wma handle
1390 * @bssid: mac address
1391 * @vdev_id: vdev id
1392 * @peer: peer ptr
1393 * @roam_synch_in_progress: roam in progress flag
1394 *
1395 * Return: none
1396 */
1397void wma_remove_peer(tp_wma_handle wma, uint8_t *bssid,
Leo Chang96464902016-10-28 11:10:54 -07001398 uint8_t vdev_id, void *peer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001399 bool roam_synch_in_progress)
1400{
1401#define PEER_ALL_TID_BITMASK 0xffffffff
1402 uint32_t peer_tid_bitmap = PEER_ALL_TID_BITMASK;
1403 uint8_t *peer_addr = bssid;
Govind Singhd76a5b02016-03-08 15:12:14 +05301404 struct peer_flush_params param = {0};
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001405 uint8_t *peer_mac_addr;
Leo Chang96464902016-10-28 11:10:54 -07001406 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Naveen Rawatf4ada152017-09-05 14:56:12 -07001407 QDF_STATUS qdf_status;
Lin Bai973e6922018-01-08 17:59:19 +08001408 uint32_t bitmap = 1 << CDP_PEER_DELETE_NO_SPECIAL;
Govind Singhd76a5b02016-03-08 15:12:14 +05301409
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001410 if (!wma->interfaces[vdev_id].peer_count) {
1411 WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d",
1412 __func__, bssid, vdev_id,
1413 wma->interfaces[vdev_id].peer_count);
1414 return;
1415 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001416
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05301417 if (!soc) {
1418 WMA_LOGE("%s:SOC context is NULL", __func__);
1419 return;
1420 }
1421
Leo Chang96464902016-10-28 11:10:54 -07001422 peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001423 if (peer_mac_addr == NULL) {
1424 WMA_LOGE("%s: peer mac addr is NULL, Can't remove peer with peer_addr %pM vdevid %d peer_count %d",
1425 __func__, bssid, vdev_id,
1426 wma->interfaces[vdev_id].peer_count);
1427 return;
1428 }
1429
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001430 if (roam_synch_in_progress)
jge6435f4f2017-01-09 11:35:45 +08001431 goto peer_detach;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001432 /* Flush all TIDs except MGMT TID for this peer in Target */
1433 peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID);
Govind Singhd76a5b02016-03-08 15:12:14 +05301434 param.peer_tid_bitmap = peer_tid_bitmap;
1435 param.vdev_id = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 wmi_unified_peer_flush_tids_send(wma->wmi_handle, bssid,
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07001437 &param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001438
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001439 if (wma_is_vdev_in_ibss_mode(wma, vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 WMA_LOGD("%s: bssid %pM peer->mac_addr %pM", __func__,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001441 bssid, peer_mac_addr);
1442 peer_addr = peer_mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001444
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001445 /* peer->ref_cnt is not visible in WMA */
1446 wlan_roam_debug_log(vdev_id, DEBUG_PEER_DELETE_SEND,
1447 DEBUG_INVALID_PEER_ID, peer_addr, peer,
1448 0, 0);
Naveen Rawatf4ada152017-09-05 14:56:12 -07001449 qdf_status = wmi_unified_peer_delete_send(wma->wmi_handle, peer_addr,
1450 vdev_id);
1451 if (QDF_IS_STATUS_ERROR(qdf_status)) {
1452 WMA_LOGE("%s Peer delete could not be sent to firmware %d",
1453 __func__, qdf_status);
Lin Bai973e6922018-01-08 17:59:19 +08001454 /* Clear default bit and set to NOT_START_UNMAP */
1455 bitmap = 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER;
Min Liua9df1ff2018-02-09 02:44:13 +08001456 } else {
1457 qdf_atomic_dec(&wma->interfaces[vdev_id].fw_peer_count);
Min Liua9df1ff2018-02-09 02:44:13 +08001458 WMA_LOGD("%s: vdev-%d fw_peer_count %d", __func__, vdev_id,
1459 qdf_atomic_read(&wma->interfaces[vdev_id].fw_peer_count));
Min Liu22202b72018-02-12 14:01:24 +08001460 if (qdf_atomic_read(&wma->interfaces[vdev_id].fw_peer_count) == 0)
1461 qdf_event_set(&wma->interfaces[vdev_id].fw_peer_delete_completion);
Naveen Rawatf4ada152017-09-05 14:56:12 -07001462 }
jge6435f4f2017-01-09 11:35:45 +08001463
1464peer_detach:
Jeff Johnsonadba3962017-09-18 08:12:35 -07001465 WMA_LOGE("%s: Remove peer %pK with peer_addr %pM vdevid %d peer_count %d",
Deepak Dhamdhere137b54e2017-01-24 01:05:43 -08001466 __func__, peer, bssid, vdev_id,
1467 wma->interfaces[vdev_id].peer_count);
1468
jge6435f4f2017-01-09 11:35:45 +08001469 if (peer) {
1470 if (roam_synch_in_progress)
1471 cdp_peer_detach_force_delete(soc, peer);
1472 else
Naveen Rawatf4ada152017-09-05 14:56:12 -07001473 cdp_peer_delete(soc, peer, bitmap);
jge6435f4f2017-01-09 11:35:45 +08001474 }
1475
1476 wma->interfaces[vdev_id].peer_count--;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001477#undef PEER_ALL_TID_BITMASK
1478}
1479
1480/**
Abhishek Singh32517ed2017-05-29 14:25:14 +05301481 * wma_find_duplicate_peer_on_other_vdev() - Find if same peer exist
1482 * on other vdevs
1483 * @wma: wma handle
1484 * @pdev: txrx pdev ptr
1485 * @vdev_id: vdev id of vdev on which the peer
1486 * needs to be added
1487 * @peer_mac: peer mac addr which needs to be added
1488 *
1489 * Check if peer with same MAC is present on vdev other then
1490 * the provided vdev_id
1491 *
1492 * Return: true if same peer is present on vdev other then vdev_id
1493 * else return false
1494 */
1495static bool wma_find_duplicate_peer_on_other_vdev(tp_wma_handle wma,
1496 struct cdp_pdev *pdev, uint8_t vdev_id, uint8_t *peer_mac)
1497{
1498 int i;
1499 uint8_t peer_id;
1500 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1501
1502 for (i = 0; i < wma->max_bssid; i++) {
1503 /* Need to check vdevs other than the vdev_id */
1504 if (vdev_id == i ||
1505 !wma->interfaces[i].handle)
1506 continue;
1507 if (cdp_peer_find_by_addr_and_vdev(soc, pdev,
1508 wma->interfaces[i].handle, peer_mac, &peer_id)) {
1509 WMA_LOGE("%s :Duplicate peer %pM (peer id %d) already exist on vdev %d",
1510 __func__, peer_mac, peer_id, i);
1511 return true;
1512 }
1513 }
1514 return false;
1515}
1516
1517/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518 * wma_create_peer() - send peer create command to fw
1519 * @wma: wma handle
1520 * @pdev: txrx pdev ptr
1521 * @vdev: txrx vdev ptr
1522 * @peer_addr: peer mac addr
1523 * @peer_type: peer type
1524 * @vdev_id: vdev id
1525 * @roam_synch_in_progress: roam in progress
1526 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301527 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001529QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
1530 struct cdp_vdev *vdev,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531 u8 peer_addr[IEEE80211_ADDR_LEN],
1532 uint32_t peer_type, uint8_t vdev_id,
1533 bool roam_synch_in_progress)
1534{
Leo Chang96464902016-10-28 11:10:54 -07001535 void *peer = NULL;
Govind Singhd76a5b02016-03-08 15:12:14 +05301536 struct peer_create_params param = {0};
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001537 uint8_t *mac_addr_raw;
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301538 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC);
1539 struct wlan_objmgr_psoc *psoc = wma->psoc;
1540 target_resource_config *wlan_res_cfg;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301542 if (!psoc) {
1543 WMA_LOGE("%s: psoc is NULL", __func__);
1544 return QDF_STATUS_E_INVAL;
1545 }
1546
Sourav Mohapatracf632572018-04-02 11:01:35 +05301547 wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301548 if (!wlan_res_cfg) {
1549 WMA_LOGE("%s: psoc target res cfg is null", __func__);
1550 return QDF_STATUS_E_INVAL;
1551 }
Abhishek Singh32517ed2017-05-29 14:25:14 +05301552
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001553 if (++wma->interfaces[vdev_id].peer_count >
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301554 wlan_res_cfg->num_peers) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07001555 WMA_LOGE("%s, the peer count exceeds the limit %d", __func__,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001556 wma->interfaces[vdev_id].peer_count - 1);
1557 goto err;
1558 }
Deepak Dhamdherec47cfe82016-08-22 01:00:13 -07001559
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301560 if (!dp_soc) {
1561 WMA_LOGE("%s:DP SOC context is NULL", __func__);
Nishank Aggarwala13b61d2016-12-01 12:53:58 +05301562 goto err;
1563 }
1564
Abhishek Singh32517ed2017-05-29 14:25:14 +05301565 /*
1566 * Check if peer with same MAC exist on other Vdev, If so avoid
1567 * adding this peer, as it will cause FW to crash.
1568 */
1569 if (wma_find_duplicate_peer_on_other_vdev(wma, pdev,
1570 vdev_id, peer_addr))
1571 goto err;
1572
Dhanashri Atre272fd232016-11-10 16:20:46 -08001573 /* The peer object should be created before sending the WMI peer
1574 * create command to firmware. This is to prevent a race condition
1575 * where the HTT peer map event is received before the peer object
1576 * is created in the data path
1577 */
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301578 peer = cdp_peer_create(dp_soc, vdev, peer_addr);
Dhanashri Atre272fd232016-11-10 16:20:46 -08001579 if (!peer) {
1580 WMA_LOGE("%s : Unable to attach peer %pM", __func__, peer_addr);
1581 goto err;
1582 }
1583
Deepak Dhamdheref74d6f82016-09-16 02:47:01 -07001584 if (roam_synch_in_progress) {
Jeff Johnsonadba3962017-09-18 08:12:35 -07001585 WMA_LOGI("%s: LFR3: Created peer %pK with peer_addr %pM vdev_id %d, peer_count - %d",
Mohit Khanna3aee1312016-07-28 19:07:05 -07001586 __func__, peer, peer_addr, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 wma->interfaces[vdev_id].peer_count);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301588 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589 }
Govind Singhd76a5b02016-03-08 15:12:14 +05301590 param.peer_addr = peer_addr;
1591 param.peer_type = peer_type;
1592 param.vdev_id = vdev_id;
1593 if (wmi_unified_peer_create_send(wma->wmi_handle,
1594 &param) != QDF_STATUS_SUCCESS) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07001595 WMA_LOGE("%s : Unable to create peer in Target", __func__);
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301596 cdp_peer_delete(dp_soc, peer,
Lin Bai973e6922018-01-08 17:59:19 +08001597 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001598 goto err;
Min Liua9df1ff2018-02-09 02:44:13 +08001599 } else {
1600 qdf_atomic_inc(&wma->interfaces[vdev_id].fw_peer_count);
1601 WMA_LOGD("%s: vdev-%d fw_peer_count %d", __func__, vdev_id,
1602 qdf_atomic_read(&wma->interfaces[vdev_id].fw_peer_count));
Min Liu22202b72018-02-12 14:01:24 +08001603 qdf_event_reset(&wma->interfaces[vdev_id].fw_peer_delete_completion);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604 }
Dhanashri Atre272fd232016-11-10 16:20:46 -08001605
Jeff Johnsonadba3962017-09-18 08:12:35 -07001606 WMA_LOGD("%s: Created peer %pK with peer_addr %pM vdev_id %d, peer_count - %d",
Leo Chang96464902016-10-28 11:10:54 -07001607 __func__, peer, peer_addr, vdev_id,
Mohit Khanna3aee1312016-07-28 19:07:05 -07001608 wma->interfaces[vdev_id].peer_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609
Deepak Dhamdheref918d422017-07-06 12:56:29 -07001610 wlan_roam_debug_log(vdev_id, DEBUG_PEER_CREATE_SEND,
1611 DEBUG_INVALID_PEER_ID, peer_addr, peer, 0, 0);
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301612 cdp_peer_setup(dp_soc, vdev, peer);
Dhanashri Atre272fd232016-11-10 16:20:46 -08001613
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07001614 WMA_LOGD("%s: Initialized peer with peer_addr %pM vdev_id %d",
Dhanashri Atre272fd232016-11-10 16:20:46 -08001615 __func__, peer_addr, vdev_id);
1616
Arunk Khandavallicfde2712018-01-25 11:27:42 +05301617 mac_addr_raw = cdp_get_vdev_mac_addr(dp_soc, vdev);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001618 if (mac_addr_raw == NULL) {
1619 WMA_LOGE("%s: peer mac addr is NULL", __func__);
1620 return QDF_STATUS_E_FAULT;
1621 }
1622
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623 /* for each remote ibss peer, clear its keys */
1624 if (wma_is_vdev_in_ibss_mode(wma, vdev_id) &&
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001625 qdf_mem_cmp(peer_addr, mac_addr_raw, IEEE80211_ADDR_LEN)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626 tSetStaKeyParams key_info;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001627
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628 WMA_LOGD("%s: remote ibss peer %pM key clearing\n", __func__,
1629 peer_addr);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301630 qdf_mem_set(&key_info, sizeof(key_info), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631 key_info.smesessionId = vdev_id;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301632 qdf_mem_copy(key_info.peer_macaddr.bytes, peer_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633 IEEE80211_ADDR_LEN);
1634 key_info.sendRsp = false;
1635
1636 wma_set_stakey(wma, &key_info);
1637 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301639 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640err:
1641 wma->interfaces[vdev_id].peer_count--;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301642 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643}
1644
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645/**
1646 * wma_hidden_ssid_vdev_restart_on_vdev_stop() - restart vdev to set hidden ssid
1647 * @wma_handle: wma handle
1648 * @sessionId: session id
1649 *
1650 * Return: none
1651 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07001652static void wma_hidden_ssid_vdev_restart_on_vdev_stop(tp_wma_handle wma_handle,
1653 uint8_t sessionId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001654{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 struct wma_txrx_node *intr = wma_handle->interfaces;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301656 struct hidden_ssid_vdev_restart_params params;
1657 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301659 params.session_id = sessionId;
1660 params.ssid_len = intr[sessionId].vdev_restart_params.ssid.ssid_len;
1661 qdf_mem_copy(params.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 intr[sessionId].vdev_restart_params.ssid.ssid,
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301663 params.ssid_len);
1664 params.flags = intr[sessionId].vdev_restart_params.flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 if (intr[sessionId].vdev_restart_params.ssidHidden)
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301666 params.flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667 else
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301668 params.flags &= (0xFFFFFFFE);
1669 params.requestor_id = intr[sessionId].vdev_restart_params.requestor_id;
1670 params.disable_hw_ack =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001671 intr[sessionId].vdev_restart_params.disable_hw_ack;
1672
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301673 params.mhz = intr[sessionId].vdev_restart_params.chan.mhz;
1674 params.band_center_freq1 =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001675 intr[sessionId].vdev_restart_params.chan.band_center_freq1;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301676 params.band_center_freq2 =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677 intr[sessionId].vdev_restart_params.chan.band_center_freq2;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301678 params.info = intr[sessionId].vdev_restart_params.chan.info;
1679 params.reg_info_1 = intr[sessionId].vdev_restart_params.chan.reg_info_1;
1680 params.reg_info_2 = intr[sessionId].vdev_restart_params.chan.reg_info_2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001681
Siddarth Poddar17dc4712016-03-09 16:30:27 +05301682 status = wmi_unified_hidden_ssid_vdev_restart_send(
1683 wma_handle->wmi_handle, &params);
1684 if (status == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685 WMA_LOGE("%s: Failed to send vdev restart command", __func__);
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05301686 qdf_atomic_set(&intr[sessionId].vdev_restart_params.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001687 hidden_ssid_restart_in_progress, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 }
1689}
1690
1691/**
Liangwei Dong748cb5d2016-09-29 00:56:40 -04001692 * wma_cleanup_target_req_param() - free param memory of target request
1693 * @tgt_req: target request params
1694 *
1695 * Return: none
1696 */
1697static void wma_cleanup_target_req_param(struct wma_target_req *tgt_req)
1698{
1699 if (tgt_req->msg_type == WMA_CHNL_SWITCH_REQ ||
1700 tgt_req->msg_type == WMA_DELETE_BSS_REQ ||
1701 tgt_req->msg_type == WMA_ADD_BSS_REQ) {
1702 qdf_mem_free(tgt_req->user_data);
1703 tgt_req->user_data = NULL;
1704 }
Krishna Kumaar Natarajanfc8c3632017-05-24 17:09:40 -07001705
1706 if (tgt_req->msg_type == WMA_SET_LINK_STATE && tgt_req->user_data) {
1707 tpLinkStateParams params =
1708 (tpLinkStateParams) tgt_req->user_data;
1709 qdf_mem_free(params->callbackArg);
1710 qdf_mem_free(tgt_req->user_data);
1711 tgt_req->user_data = NULL;
1712 }
Liangwei Dong748cb5d2016-09-29 00:56:40 -04001713}
1714
1715/**
Krishna Kumaar Natarajanf24bfc82017-02-07 11:54:05 -08001716 * wma_remove_bss_peer() - remove BSS peer
1717 * @wma: pointer to WMA handle
1718 * @pdev: pointer to PDEV
1719 * @req_msg: pointer to WMA target Request
1720 * @vdev_id: vdev id on which delete BSS request was received
1721 * @params: pointer to Delete BSS params
1722 *
1723 * This function is called on receiving vdev stop response from FW or
1724 * vdev stop response timeout. In case of IBSS/NDI, use vdev's self MAC
1725 * for removing the peer. In case of STA/SAP use bssid passed as part of
1726 * delete STA parameter.
1727 *
1728 * Return: 0 on success, ERROR code on failure
1729 */
1730static int wma_remove_bss_peer(tp_wma_handle wma, void *pdev,
1731 struct wma_target_req *req_msg, uint32_t vdev_id,
1732 tpDeleteBssParams params)
1733{
1734 void *peer, *vdev;
1735 uint8_t peer_id;
1736 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1737 uint8_t *mac_addr = NULL;
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301738 struct wma_target_req *del_req;
Krishna Kumaar Natarajanf24bfc82017-02-07 11:54:05 -08001739
1740 vdev = cdp_get_vdev_from_vdev_id(soc, pdev, vdev_id);
1741 if (!vdev) {
1742 WMA_LOGE(FL("vdev is NULL for vdev_id = %d"), vdev_id);
1743 wma_cleanup_target_req_param(req_msg);
1744 return -EINVAL;
1745 }
1746
1747 if (wma_is_vdev_in_ibss_mode(wma, vdev_id) ||
1748 WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, vdev_id)) {
1749 mac_addr = cdp_get_vdev_mac_addr(soc, vdev);
1750 if (!mac_addr) {
1751 WMA_LOGE(FL("mac_addr is NULL for vdev_id = %d"),
1752 vdev_id);
1753 wma_cleanup_target_req_param(req_msg);
1754 return -EINVAL;
1755 }
1756 } else {
1757 mac_addr = params->bssid;
1758 }
1759
1760 peer = cdp_peer_find_by_addr(soc, pdev, mac_addr, &peer_id);
1761 if (!peer) {
1762 WMA_LOGE(FL("peer NULL for vdev_id = %d"), vdev_id);
1763 wma_cleanup_target_req_param(req_msg);
1764 return -EINVAL;
1765 }
1766
1767 wma_remove_peer(wma, mac_addr, vdev_id, peer, false);
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05301768 if (wmi_service_enabled(
1769 wma->wmi_handle,
1770 wmi_service_sync_delete_cmds)) {
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301771 WMA_LOGD(FL("Wait for the peer delete. vdev_id %d"),
1772 req_msg->vdev_id);
1773 del_req = wma_fill_hold_req(wma,
1774 req_msg->vdev_id,
1775 WMA_DELETE_STA_REQ,
1776 WMA_DELETE_PEER_RSP,
1777 params,
1778 WMA_DELETE_STA_TIMEOUT);
1779 if (!del_req) {
1780 WMA_LOGE(FL("Failed to allocate request. vdev_id %d"),
1781 req_msg->vdev_id);
1782 params->status = QDF_STATUS_E_NOMEM;
1783 return -EINVAL;
1784 }
1785 }
Krishna Kumaar Natarajanf24bfc82017-02-07 11:54:05 -08001786 return 0;
1787}
1788
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05301789/*
1790 * get_fw_active_bpf_mode() - convert HDD BPF mode to FW configurable BPF
1791 * mode
1792 * @mode: BPF mode maintained in HDD
1793 *
1794 * Return: FW configurable BP mode
1795 */
1796static enum wmi_host_active_bpf_mode
1797get_fw_active_bpf_mode(enum active_bpf_mode mode)
1798{
1799 switch (mode) {
1800 case ACTIVE_BPF_DISABLED:
1801 return WMI_HOST_ACTIVE_BPF_DISABLED;
1802 case ACTIVE_BPF_ENABLED:
1803 return WMI_HOST_ACTIVE_BPF_ENABLED;
1804 case ACTIVE_BPF_ADAPTIVE:
1805 return WMI_HOST_ACTIVE_BPF_ADAPTIVE;
1806 default:
1807 WMA_LOGE("Invalid Active BPF Mode %d; Using 'disabled'", mode);
1808 return WMI_HOST_ACTIVE_BPF_DISABLED;
1809 }
1810}
1811
Krishna Kumaar Natarajanf24bfc82017-02-07 11:54:05 -08001812/**
Dustin Brown13995f02017-01-12 15:38:42 -08001813 * wma_config_active_bpf_mode() - Config active BPF mode in FW
1814 * @wma: the WMA handle
1815 * @vdev_id: the Id of the vdev for which the configuration should be applied
1816 *
1817 * Return: QDF status
1818 */
1819static QDF_STATUS wma_config_active_bpf_mode(t_wma_handle *wma, uint8_t vdev_id)
1820{
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05301821 enum wmi_host_active_bpf_mode uc_mode, mcbc_mode;
Dustin Brown13995f02017-01-12 15:38:42 -08001822
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05301823 uc_mode = get_fw_active_bpf_mode(wma->active_uc_bpf_mode);
1824 mcbc_mode = get_fw_active_bpf_mode(wma->active_mc_bc_bpf_mode);
Dustin Brown13995f02017-01-12 15:38:42 -08001825
Hanumanth Reddy Pothulae87621b2017-04-12 20:53:35 +05301826 WMA_LOGD("Configuring Active BPF Mode UC:%d MC/BC:%d for vdev %u",
1827 uc_mode, mcbc_mode, vdev_id);
Dustin Brown13995f02017-01-12 15:38:42 -08001828
1829 return wmi_unified_set_active_bpf_mode_cmd(wma->wmi_handle, vdev_id,
1830 uc_mode, mcbc_mode);
1831}
1832
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301833#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1834/**
1835 * wma_check_and_find_mcc_ap() - finds if device is operating AP
1836 * in MCC mode or not
1837 * @wma: wma handle.
1838 * @vdev_id: vdev ID of device for which MCC has to be checked
1839 *
1840 * This function internally calls wma_find_mcc_ap finds if
1841 * device is operating AP in MCC mode or not
1842 *
1843 * Return: none
1844 */
1845static void
1846wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
1847{
1848 tpAniSirGlobal mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1849
1850 if (NULL == mac_ctx) {
1851 WMA_LOGE("%s: Failed to get mac_ctx", __func__);
1852 return;
1853 }
1854 if (mac_ctx->sap.sap_channel_avoidance)
1855 wma_find_mcc_ap(wma, vdev_id, false);
1856}
1857#else
1858static inline void
1859wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
1860{}
1861#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1862
1863/**
1864 * wma_send_del_bss_response() - send del bss resp to upper layer
1865 * @wma: wma handle.
1866 * @vdev_id: vdev ID of device for which MCC has to be checked
1867 *
1868 * This function sends del bss resp to upper layer
1869 *
1870 * Return: none
1871 */
1872static void
1873wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req,
1874 uint8_t vdev_id)
1875{
1876 struct wma_txrx_node *iface;
1877 struct beacon_info *bcn;
1878 tpDeleteBssParams params;
1879 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
1880
1881 if (!req) {
1882 WMA_LOGE("%s req is NULL", __func__);
1883 return;
1884 }
1885
1886 iface = &wma->interfaces[vdev_id];
1887 if (!iface->handle) {
1888 WMA_LOGE("%s vdev id %d is already deleted",
1889 __func__, vdev_id);
1890 if (req->user_data)
1891 qdf_mem_free(req->user_data);
1892 req->user_data = NULL;
1893 return;
1894 }
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301895
Dustin Brownec2c92e2017-07-26 11:13:49 -07001896 params = (tpDeleteBssParams)req->user_data;
1897 if (wma_send_vdev_down_to_fw(wma, vdev_id) != QDF_STATUS_SUCCESS) {
1898 WMA_LOGE("Failed to send vdev down cmd: vdev %d", vdev_id);
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301899 } else {
Dustin Brownec2c92e2017-07-26 11:13:49 -07001900 wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_STOP);
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301901 wma_check_and_find_mcc_ap(wma, vdev_id);
1902 }
1903
1904 cdp_fc_vdev_flush(soc, iface->handle);
1905 WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
1906 __func__, vdev_id);
1907 cdp_fc_vdev_unpause(soc, iface->handle,
1908 OL_TXQ_PAUSE_REASON_VDEV_STOP);
1909 wma_vdev_clear_pause_bit(vdev_id, PAUSE_TYPE_HOST);
1910 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
1911 WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
1912 __func__, iface->type, iface->sub_type);
1913
1914 bcn = wma->interfaces[vdev_id].beacon;
1915 if (bcn) {
Jeff Johnsonadba3962017-09-18 08:12:35 -07001916 WMA_LOGD("%s: Freeing beacon struct %pK, template memory %pK",
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301917 __func__, bcn, bcn->buf);
1918 if (bcn->dma_mapped)
1919 qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf,
1920 QDF_DMA_TO_DEVICE);
1921 qdf_nbuf_free(bcn->buf);
1922 qdf_mem_free(bcn);
1923 wma->interfaces[vdev_id].beacon = NULL;
1924 }
1925
1926 /* Timeout status means its WMA generated DEL BSS REQ when ADD
1927 * BSS REQ was timed out to stop the VDEV in this case no need
1928 * to send response to UMAC
1929 */
1930 if (params->status == QDF_STATUS_FW_MSG_TIMEDOUT) {
1931 qdf_mem_free(req->user_data);
1932 req->user_data = NULL;
1933 WMA_LOGE("%s: DEL BSS from ADD BSS timeout do not send resp to UMAC (vdev id %x)",
1934 __func__, vdev_id);
1935 } else {
1936 params->status = QDF_STATUS_SUCCESS;
Abhishek Singh2d775fd2017-08-18 10:51:33 +05301937 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
1938 (void *)params, 0);
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301939 }
1940
Abhishek Singh0d74f9e2017-09-26 14:02:42 +05301941 if (iface->del_staself_req && iface->is_del_sta_defered) {
1942 iface->is_del_sta_defered = false;
Abhishek Singhe8be9a62017-05-30 12:13:29 +05301943 WMA_LOGA("scheduling defered deletion (vdev id %x)",
1944 vdev_id);
1945 wma_vdev_detach(wma, iface->del_staself_req, 1);
1946 }
1947}
1948
1949
Dustin Brown13995f02017-01-12 15:38:42 -08001950/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001951 * wma_vdev_stop_resp_handler() - vdev stop response handler
1952 * @handle: wma handle
1953 * @cmd_param_info: event buffer
1954 * @len: buffer length
1955 *
1956 * Return: 0 for success or error code
1957 */
1958int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
1959 u32 len)
1960{
1961 tp_wma_handle wma = (tp_wma_handle) handle;
1962 WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
1963 wmi_vdev_stopped_event_fixed_param *resp_event;
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07001964 struct wma_target_req *req_msg, *del_req, *new_req_msg;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08001965 struct cdp_pdev *pdev;
Sandeep Puligilla7da86332016-11-10 16:14:40 -08001966 void *peer;
1967 uint8_t peer_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001968 struct wma_txrx_node *iface;
1969 int32_t status = 0;
Leo Chang96464902016-10-28 11:10:54 -07001970 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Dustin Brownbf6d16b2017-03-03 11:41:05 -08001971
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07001972 WMA_LOGD("%s: Enter", __func__);
Dustin Brown3e619822017-03-17 10:41:56 -07001973
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974 param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info;
1975 if (!param_buf) {
1976 WMA_LOGE("Invalid event buffer");
1977 return -EINVAL;
1978 }
Dustin Brownec2c92e2017-07-26 11:13:49 -07001979
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001980 resp_event = param_buf->fixed_param;
Vignesh Viswanathan08ad8a02018-02-14 18:00:01 +05301981
1982 if (resp_event->vdev_id >= wma->max_bssid) {
1983 WMA_LOGE("%s: Invalid vdev_id %d from FW",
1984 __func__, resp_event->vdev_id);
1985 return -EINVAL;
1986 }
1987
Dustin Brownec2c92e2017-07-26 11:13:49 -07001988 iface = &wma->interfaces[resp_event->vdev_id];
Naveen Rawata600b2e2018-03-29 13:41:18 -07001989
1990 /* vdev in stopped state, no more waiting for key */
1991 iface->is_waiting_for_key = false;
1992
Dustin Brownec2c92e2017-07-26 11:13:49 -07001993 wma_release_wakelock(&iface->vdev_stop_wakelock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001994
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07001995 req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,
Kiran Kumar Lokere20804162017-07-17 16:09:04 -07001996 WMA_TARGET_REQ_TYPE_VDEV_STOP, true);
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07001997 if (!req_msg) {
1998 WMA_LOGE("%s: Failed to lookup vdev request for vdev id %d",
1999 __func__, resp_event->vdev_id);
2000 return -EINVAL;
2001 }
2002
Vignesh Viswanathan08ad8a02018-02-14 18:00:01 +05302003 if ((qdf_atomic_read
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002004 (&wma->interfaces[resp_event->vdev_id].vdev_restart_params.
2005 hidden_ssid_restart_in_progress))
2006 && ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP)
2007 && (wma->interfaces[resp_event->vdev_id].sub_type == 0))) {
2008 WMA_LOGE("%s: vdev stop event recevied for hidden ssid set using IOCTL ",
2009 __func__);
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05302010
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07002011 wma_vdev_set_mlme_state(wma,
2012 resp_event->vdev_id, WLAN_VDEV_S_STOP);
2013 new_req_msg = wma_fill_vdev_req(wma, resp_event->vdev_id,
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05302014 WMA_HIDDEN_SSID_VDEV_RESTART,
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07002015 WMA_TARGET_REQ_TYPE_VDEV_START,
2016 req_msg->user_data,
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05302017 WMA_VDEV_START_REQUEST_TIMEOUT);
Kiran Kumar Lokere5798bfa2017-04-27 20:49:39 -07002018 if (!new_req_msg) {
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05302019 WMA_LOGE("%s: Failed to fill vdev request, vdev_id %d",
2020 __func__, resp_event->vdev_id);
2021 return -EINVAL;
2022 }
2023
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002024 wma_hidden_ssid_vdev_restart_on_vdev_stop(wma,
2025 resp_event->vdev_id);
2026 }
2027
Anurag Chouhan6d760662016-02-20 16:05:43 +05302028 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002029 if (!pdev) {
2030 WMA_LOGE("%s: pdev is NULL", __func__);
2031 status = -EINVAL;
Liangwei Dong748cb5d2016-09-29 00:56:40 -04002032 wma_cleanup_target_req_param(req_msg);
Anurag Chouhan210db072016-02-22 18:42:15 +05302033 qdf_mc_timer_stop(&req_msg->event_timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002034 goto free_req_msg;
2035 }
2036
Anurag Chouhan210db072016-02-22 18:42:15 +05302037 qdf_mc_timer_stop(&req_msg->event_timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002038 if (req_msg->msg_type == WMA_DELETE_BSS_REQ) {
2039 tpDeleteBssParams params =
2040 (tpDeleteBssParams) req_msg->user_data;
Dustin Brownbf6d16b2017-03-03 11:41:05 -08002041
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002042 if (iface->handle == NULL) {
2043 WMA_LOGE("%s vdev id %d is already deleted",
2044 __func__, resp_event->vdev_id);
Liangwei Dong748cb5d2016-09-29 00:56:40 -04002045 wma_cleanup_target_req_param(req_msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046 status = -EINVAL;
2047 goto free_req_msg;
2048 }
Mukul Sharma8d2d9ec2016-09-08 13:05:35 +05302049
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +05302050 /* CCA is required only for sta interface */
2051 if (iface->type == WMI_VDEV_TYPE_STA)
2052 wma_get_cca_stats(wma, resp_event->vdev_id);
2053
Mukul Sharma8d2d9ec2016-09-08 13:05:35 +05302054 /* Clear arp and ns offload cache */
2055 qdf_mem_zero(&iface->ns_offload_req,
2056 sizeof(iface->ns_offload_req));
2057 qdf_mem_zero(&iface->arp_offload_req,
2058 sizeof(iface->arp_offload_req));
2059
Krishna Kumaar Natarajanf24bfc82017-02-07 11:54:05 -08002060 status = wma_remove_bss_peer(wma, pdev, req_msg,
2061 resp_event->vdev_id, params);
2062 if (status != 0)
2063 goto free_req_msg;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002064
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05302065 if (wmi_service_enabled(
2066 wma->wmi_handle,
2067 wmi_service_sync_delete_cmds))
Abhishek Singhe8be9a62017-05-30 12:13:29 +05302068 goto free_req_msg;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002069
Abhishek Singhe8be9a62017-05-30 12:13:29 +05302070 wma_send_del_bss_response(wma, req_msg, resp_event->vdev_id);
Sandeep Puligilla7da86332016-11-10 16:14:40 -08002071 } else if (req_msg->msg_type == WMA_SET_LINK_STATE) {
2072 tpLinkStateParams params =
2073 (tpLinkStateParams) req_msg->user_data;
2074
2075 peer = cdp_peer_find_by_addr(soc, pdev, params->bssid, &peer_id);
2076 if (peer) {
2077 WMA_LOGP(FL("Deleting peer %pM vdev id %d"),
2078 params->bssid, req_msg->vdev_id);
2079 wma_remove_peer(wma, params->bssid, req_msg->vdev_id,
2080 peer, false);
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05302081 if (wmi_service_enabled(wma->wmi_handle,
2082 wmi_service_sync_delete_cmds)) {
Sandeep Puligillabbee8172017-04-07 19:26:33 -07002083 WMA_LOGI(FL("Wait for the peer delete. vdev_id %d"),
2084 req_msg->vdev_id);
2085 del_req = wma_fill_hold_req(wma,
2086 req_msg->vdev_id,
2087 WMA_DELETE_STA_REQ,
2088 WMA_SET_LINK_PEER_RSP,
2089 params,
2090 WMA_DELETE_STA_TIMEOUT);
2091 if (!del_req) {
2092 WMA_LOGE(FL("Failed to allocate request. vdev_id %d"),
2093 req_msg->vdev_id);
2094 params->status = QDF_STATUS_E_NOMEM;
2095 } else {
2096 goto free_req_msg;
2097 }
2098 }
Sandeep Puligilla7da86332016-11-10 16:14:40 -08002099 }
Dustin Brownec2c92e2017-07-26 11:13:49 -07002100 if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
2101 QDF_STATUS_SUCCESS) {
Sandeep Puligilla7da86332016-11-10 16:14:40 -08002102 WMA_LOGE("Failed to send vdev down cmd: vdev %d",
2103 req_msg->vdev_id);
2104 }
2105 wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106 }
Krishna Kumaar Natarajanf24bfc82017-02-07 11:54:05 -08002107
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002108free_req_msg:
Anurag Chouhan210db072016-02-22 18:42:15 +05302109 qdf_mc_timer_destroy(&req_msg->event_timeout);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302110 qdf_mem_free(req_msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002111 return status;
2112}
2113
2114/**
2115 * wma_vdev_attach() - create vdev in fw
2116 * @wma_handle: wma handle
2117 * @self_sta_req: self sta request
2118 * @generateRsp: generate response
2119 *
2120 * This function creates vdev in target and
2121 * attach this vdev to txrx module. It also set
2122 * vdev related params to fw.
2123 *
2124 * Return: txrx vdev handle
2125 */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002126struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002127 struct add_sta_self_params *self_sta_req,
2128 uint8_t generateRsp)
2129{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002130 struct cdp_vdev *txrx_vdev_handle = NULL;
2131 struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002132 enum wlan_op_mode txrx_vdev_type;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302133 QDF_STATUS status = QDF_STATUS_SUCCESS;
Anurag Chouhan6d760662016-02-20 16:05:43 +05302134 struct sAniSirGlobal *mac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002135 uint32_t cfg_val;
2136 uint16_t val16;
Govind Singhd76a5b02016-03-08 15:12:14 +05302137 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138 tSirMacHTCapabilityInfo *phtCapInfo;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08002139 struct scheduler_msg sme_msg = { 0 };
Govind Singhd76a5b02016-03-08 15:12:14 +05302140 struct vdev_create_params params = { 0 };
Bhargav Shaha89d3b42016-04-20 13:04:56 +05302141 u_int8_t vdev_id;
Padma, Santhosh Kumara7119672016-08-16 16:05:14 +05302142 struct sir_set_tx_rx_aggregation_size tx_rx_aggregation_size;
Paul Zhang33fae272018-04-23 16:19:00 +08002143 struct sir_set_tx_aggr_sw_retry_threshold tx_aggr_sw_retry_threshold;
Leo Chang96464902016-10-28 11:10:54 -07002144 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002145
Varun Reddy Yeturu30c24b72017-07-31 14:25:54 -07002146 WMA_LOGD("mac %pM, vdev_id %hu, type %d, sub_type %d, nss 2g %d, 5g %d",
2147 self_sta_req->self_mac_addr, self_sta_req->session_id,
2148 self_sta_req->type, self_sta_req->sub_type,
2149 self_sta_req->nss_2g, self_sta_req->nss_5g);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 if (NULL == mac) {
2151 WMA_LOGE("%s: Failed to get mac", __func__);
2152 goto end;
2153 }
Arif Hussain380cfc72017-10-31 13:12:04 -07002154
2155 vdev_id = self_sta_req->session_id;
2156 if (wma_is_vdev_valid(vdev_id)) {
2157 WMA_LOGE("%s: vdev %d already active", __func__, vdev_id);
Varun Reddy Yeturu30c24b72017-07-31 14:25:54 -07002158 goto end;
2159 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160
Govind Singhd76a5b02016-03-08 15:12:14 +05302161 params.if_id = self_sta_req->session_id;
2162 params.type = self_sta_req->type;
2163 params.subtype = self_sta_req->sub_type;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07002164 params.nss_2g = self_sta_req->nss_2g;
2165 params.nss_5g = self_sta_req->nss_5g;
Govind Singhd76a5b02016-03-08 15:12:14 +05302166
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002167 /* Create a vdev in target */
Govind Singhd76a5b02016-03-08 15:12:14 +05302168 status = wmi_unified_vdev_create_send(wma_handle->wmi_handle,
2169 self_sta_req->self_mac_addr,
2170 &params);
2171 if (QDF_IS_STATUS_ERROR(status)) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07002172 WMA_LOGE("%s: Unable to add an interface for ath_dev",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002173 __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002174 goto end;
2175 }
2176
2177 txrx_vdev_type = wma_get_txrx_vdev_type(self_sta_req->type);
2178
2179 if (wlan_op_mode_unknown == txrx_vdev_type) {
2180 WMA_LOGE("Failed to get txrx vdev type");
Govind Singhd76a5b02016-03-08 15:12:14 +05302181 wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182 self_sta_req->session_id);
2183 goto end;
2184 }
2185
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002186 txrx_vdev_handle = cdp_vdev_attach(soc,
2187 txrx_pdev,
2188 self_sta_req->self_mac_addr,
2189 self_sta_req->session_id,
2190 txrx_vdev_type);
Mukul Sharma6411bb82017-03-01 15:57:07 +05302191 wma_vdev_update_pause_bitmap(self_sta_req->session_id, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002192
Jeff Johnsonadba3962017-09-18 08:12:35 -07002193 WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %pK", self_sta_req->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002194 txrx_vdev_handle);
2195
2196 if (NULL == txrx_vdev_handle) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07002197 WMA_LOGE("%s: cdp_vdev_attach failed", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302198 status = QDF_STATUS_E_FAILURE;
Govind Singhd76a5b02016-03-08 15:12:14 +05302199 wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 self_sta_req->session_id);
2201 goto end;
2202 }
Selvaraj, Sridhar171e2252016-06-22 22:33:26 +05302203 wma_handle->interfaces[self_sta_req->session_id].vdev_active = true;
2204
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002205 wma_handle->interfaces[self_sta_req->session_id].handle =
2206 txrx_vdev_handle;
2207
2208 wma_handle->interfaces[self_sta_req->session_id].ptrn_match_enable =
2209 wma_handle->ptrn_match_enable_all_vdev ? true : false;
2210
2211 if (wlan_cfg_get_int(mac, WNI_CFG_WOWLAN_DEAUTH_ENABLE, &cfg_val)
2212 != eSIR_SUCCESS)
2213 wma_handle->wow.deauth_enable = true;
2214 else
2215 wma_handle->wow.deauth_enable = cfg_val ? true : false;
2216
2217 if (wlan_cfg_get_int(mac, WNI_CFG_WOWLAN_DISASSOC_ENABLE, &cfg_val)
2218 != eSIR_SUCCESS)
2219 wma_handle->wow.disassoc_enable = true;
2220 else
2221 wma_handle->wow.disassoc_enable = cfg_val ? true : false;
2222
2223 if (wlan_cfg_get_int(mac, WNI_CFG_WOWLAN_MAX_MISSED_BEACON, &cfg_val)
2224 != eSIR_SUCCESS)
2225 wma_handle->wow.bmiss_enable = true;
2226 else
2227 wma_handle->wow.bmiss_enable = cfg_val ? true : false;
2228
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302229 qdf_mem_copy(wma_handle->interfaces[self_sta_req->session_id].addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002230 self_sta_req->self_mac_addr,
2231 sizeof(wma_handle->interfaces[self_sta_req->session_id].
2232 addr));
Padma, Santhosh Kumara7119672016-08-16 16:05:14 +05302233
2234 tx_rx_aggregation_size.tx_aggregation_size =
2235 self_sta_req->tx_aggregation_size;
2236 tx_rx_aggregation_size.rx_aggregation_size =
2237 self_sta_req->rx_aggregation_size;
2238 tx_rx_aggregation_size.vdev_id = self_sta_req->session_id;
2239
2240 status = wma_set_tx_rx_aggregation_size(&tx_rx_aggregation_size);
2241 if (status != QDF_STATUS_SUCCESS)
2242 WMA_LOGE("failed to set aggregation sizes(err=%d)", status);
2243
Paul Zhangee09f8e2018-04-23 16:11:32 +08002244 tx_rx_aggregation_size.tx_aggregation_size_be =
2245 self_sta_req->tx_aggregation_size_be;
2246 tx_rx_aggregation_size.tx_aggregation_size_bk =
2247 self_sta_req->tx_aggregation_size_bk;
2248 tx_rx_aggregation_size.tx_aggregation_size_vi =
2249 self_sta_req->tx_aggregation_size_vi;
2250 tx_rx_aggregation_size.tx_aggregation_size_vo =
2251 self_sta_req->tx_aggregation_size_vo;
2252
Paul Zhang33fae272018-04-23 16:19:00 +08002253 tx_aggr_sw_retry_threshold.tx_aggr_sw_retry_threshold_be =
2254 self_sta_req->tx_aggr_sw_retry_threshold_be;
2255 tx_aggr_sw_retry_threshold.tx_aggr_sw_retry_threshold_bk =
2256 self_sta_req->tx_aggr_sw_retry_threshold_bk;
2257 tx_aggr_sw_retry_threshold.tx_aggr_sw_retry_threshold_vi =
2258 self_sta_req->tx_aggr_sw_retry_threshold_vi;
2259 tx_aggr_sw_retry_threshold.tx_aggr_sw_retry_threshold_vo =
2260 self_sta_req->tx_aggr_sw_retry_threshold_vo;
2261 tx_aggr_sw_retry_threshold.vdev_id = self_sta_req->session_id;
2262
2263
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002264 switch (self_sta_req->type) {
2265 case WMI_VDEV_TYPE_STA:
Paul Zhangee09f8e2018-04-23 16:11:32 +08002266 status = wma_set_tx_rx_aggregation_size_per_ac(
2267 &tx_rx_aggregation_size);
2268 if (status != QDF_STATUS_SUCCESS)
2269 WMA_LOGE("failed to set aggr sizes per ac(err=%d)",
2270 status);
2271
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002272 if (wlan_cfg_get_int(mac, WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD,
2273 &cfg_val) != eSIR_SUCCESS) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002274 WMA_LOGE("Failed to get value for WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002275 cfg_val = DEFAULT_INFRA_STA_KEEP_ALIVE_PERIOD;
2276 }
2277
2278 wma_set_sta_keep_alive(wma_handle,
2279 self_sta_req->session_id,
2280 SIR_KEEP_ALIVE_NULL_PKT,
2281 cfg_val, NULL, NULL, NULL);
mukul sharma72c8b222015-09-04 17:02:01 +05302282
2283 /* offload STA SA query related params to fwr */
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05302284 if (wmi_service_enabled(wma_handle->wmi_handle,
2285 wmi_service_sta_pmf_offload)) {
mukul sharma72c8b222015-09-04 17:02:01 +05302286 wma_set_sta_sa_query_param(wma_handle,
2287 self_sta_req->session_id);
2288 }
Paul Zhang33fae272018-04-23 16:19:00 +08002289
2290 status = wma_set_sw_retry_threshold(
2291 &tx_aggr_sw_retry_threshold);
2292 if (status != QDF_STATUS_SUCCESS)
2293 WMA_LOGE("failed to set retry threshold(err=%d)",
2294 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002295 break;
2296 }
2297
2298 wma_handle->interfaces[self_sta_req->session_id].type =
2299 self_sta_req->type;
2300 wma_handle->interfaces[self_sta_req->session_id].sub_type =
2301 self_sta_req->sub_type;
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05302302 qdf_atomic_init(&wma_handle->interfaces
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002303 [self_sta_req->session_id].bss_status);
Min Liua9df1ff2018-02-09 02:44:13 +08002304 qdf_atomic_init(&wma_handle->interfaces
2305 [self_sta_req->session_id].fw_peer_count);
2306 status = qdf_event_create(&wma_handle->interfaces
Min Liu22202b72018-02-12 14:01:24 +08002307 [self_sta_req->session_id].fw_peer_delete_completion);
2308 if (status != QDF_STATUS_SUCCESS) {
2309 WMA_LOGE("%s: Failed to create fw_peer_delete_completion", __func__);
2310 goto end;
2311 }
2312 qdf_event_set(&wma_handle->interfaces[vdev_id].fw_peer_delete_completion);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002313
Dustin Brown04823992018-03-29 13:27:01 -07002314 if (wma_vdev_uses_self_peer(self_sta_req->type,
2315 self_sta_req->sub_type)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002316 status = wma_create_peer(wma_handle, txrx_pdev,
2317 txrx_vdev_handle,
2318 self_sta_req->self_mac_addr,
2319 WMI_PEER_TYPE_DEFAULT,
2320 self_sta_req->session_id, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302321 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002322 WMA_LOGE("%s: Failed to create peer", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302323 status = QDF_STATUS_E_FAILURE;
Govind Singhd76a5b02016-03-08 15:12:14 +05302324 wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002325 self_sta_req->session_id);
2326 }
2327 }
2328
Naveen Rawat2b6e3c92017-03-20 13:59:07 -07002329 WMA_LOGD("Setting WMI_VDEV_PARAM_DISCONNECT_TH: %d",
2330 self_sta_req->pkt_err_disconn_th);
2331 ret = wma_vdev_set_param(wma_handle->wmi_handle,
2332 self_sta_req->session_id,
2333 WMI_VDEV_PARAM_DISCONNECT_TH,
2334 self_sta_req->pkt_err_disconn_th);
2335 if (ret)
2336 WMA_LOGE("Failed to set WMI_VDEV_PARAM_DISCONNECT_TH");
2337
Bhargav Shaha89d3b42016-04-20 13:04:56 +05302338 wma_handle->interfaces[vdev_id].is_vdev_valid = true;
Govind Singhd76a5b02016-03-08 15:12:14 +05302339 ret = wma_vdev_set_param(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002340 self_sta_req->session_id,
2341 WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE,
2342 mac->roam.configParam.mcc_rts_cts_prot_enable);
Govind Singhd76a5b02016-03-08 15:12:14 +05302343 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002344 WMA_LOGE("Failed to set WMI VDEV MCC_RTSCTS_PROTECTION_ENABLE");
2345
Govind Singhd76a5b02016-03-08 15:12:14 +05302346 ret = wma_vdev_set_param(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002347 self_sta_req->session_id,
2348 WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE,
2349 mac->roam.configParam.mcc_bcast_prob_resp_enable);
Govind Singhd76a5b02016-03-08 15:12:14 +05302350 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002351 WMA_LOGE("Failed to set WMI VDEV MCC_BROADCAST_PROBE_ENABLE");
2352
2353 if (wlan_cfg_get_int(mac, WNI_CFG_RTS_THRESHOLD,
2354 &cfg_val) == eSIR_SUCCESS) {
Govind Singhd76a5b02016-03-08 15:12:14 +05302355 ret = wma_vdev_set_param(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002356 self_sta_req->session_id,
2357 WMI_VDEV_PARAM_RTS_THRESHOLD,
2358 cfg_val);
Govind Singhd76a5b02016-03-08 15:12:14 +05302359 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002360 WMA_LOGE("Failed to set WMI_VDEV_PARAM_RTS_THRESHOLD");
2361 } else {
2362 WMA_LOGE("Failed to get value for WNI_CFG_RTS_THRESHOLD, leaving unchanged");
2363 }
2364
2365 if (wlan_cfg_get_int(mac, WNI_CFG_FRAGMENTATION_THRESHOLD,
2366 &cfg_val) == eSIR_SUCCESS) {
Govind Singhd76a5b02016-03-08 15:12:14 +05302367 ret = wma_vdev_set_param(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002368 self_sta_req->session_id,
2369 WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
2370 cfg_val);
Govind Singhd76a5b02016-03-08 15:12:14 +05302371 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 WMA_LOGE("Failed to set WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD");
2373 } else {
2374 WMA_LOGE("Failed to get value for WNI_CFG_FRAGMENTATION_THRESHOLD, leaving unchanged");
2375 }
2376
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002377 if (wlan_cfg_get_int(mac, WNI_CFG_HT_CAP_INFO, &cfg_val) ==
2378 eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002379 val16 = (uint16_t) cfg_val;
2380 phtCapInfo = (tSirMacHTCapabilityInfo *) &cfg_val;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002381
Govind Singhd76a5b02016-03-08 15:12:14 +05302382 ret = wma_vdev_set_param(wma_handle->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002383 self_sta_req->session_id,
2384 WMI_VDEV_PARAM_TX_STBC,
2385 phtCapInfo->txSTBC);
Govind Singhd76a5b02016-03-08 15:12:14 +05302386 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002387 WMA_LOGE("Failed to set WMI_VDEV_PARAM_TX_STBC");
2388 } else {
2389 WMA_LOGE("Failed to get value of HT_CAP, TX STBC unchanged");
2390 }
Hong Shib90718f2017-02-20 00:57:22 +08002391
2392 wma_set_vdev_mgmt_rate(wma_handle, self_sta_req->session_id);
2393
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002394 /* Initialize roaming offload state */
2395 if ((self_sta_req->type == WMI_VDEV_TYPE_STA) &&
2396 (self_sta_req->sub_type == 0)) {
2397 wma_handle->roam_offload_enabled = true;
Govind Singhd76a5b02016-03-08 15:12:14 +05302398 ret = wma_vdev_set_param(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002399 self_sta_req->session_id,
2400 WMI_VDEV_PARAM_ROAM_FW_OFFLOAD,
2401 (WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG |
2402 WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG));
Govind Singhd76a5b02016-03-08 15:12:14 +05302403 if (QDF_IS_STATUS_ERROR(ret))
2404 WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD");
Selvaraj, Sridhar4f684bb2017-01-19 15:59:23 +05302405
2406 /* Pass down enable/disable bcast probe rsp to FW */
2407 ret = wma_vdev_set_param(
2408 wma_handle->wmi_handle,
2409 self_sta_req->session_id,
2410 WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
2411 self_sta_req->enable_bcast_probe_rsp);
2412 if (QDF_IS_STATUS_ERROR(ret))
2413 WMA_LOGE("Failed to set WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE");
2414
Selvaraj, Sridhar97ce6582017-01-20 17:06:34 +05302415 /* Pass down the FILS max channel guard time to FW */
2416 ret = wma_vdev_set_param(
2417 wma_handle->wmi_handle,
2418 self_sta_req->session_id,
2419 WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
2420 self_sta_req->fils_max_chan_guard_time);
2421 if (QDF_IS_STATUS_ERROR(ret))
2422 WMA_LOGE("Failed to set WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME");
Sridhar Selvaraj87309212017-06-28 17:41:50 +05302423
2424 /* Pass down the Probe Request tx delay(in ms) to FW */
2425 ret = wma_vdev_set_param(
2426 wma_handle->wmi_handle,
2427 self_sta_req->session_id,
2428 WMI_VDEV_PARAM_PROBE_DELAY,
2429 PROBE_REQ_TX_DELAY);
2430 if (QDF_IS_STATUS_ERROR(ret))
2431 WMA_LOGE("Failed to set WMI_VDEV_PARAM_PROBE_DELAY");
2432
2433 /* Pass down the probe request tx time gap(in ms) to FW */
2434 ret = wma_vdev_set_param(
2435 wma_handle->wmi_handle,
2436 self_sta_req->session_id,
2437 WMI_VDEV_PARAM_REPEAT_PROBE_TIME,
2438 PROBE_REQ_TX_TIME_GAP);
2439 if (QDF_IS_STATUS_ERROR(ret))
2440 WMA_LOGE("Failed to set WMI_VDEV_PARAM_REPEAT_PROBE_TIME");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002441 }
2442
Yeshwanth Sriram Guntuka2ba6fe92017-10-04 14:40:45 +05302443 if ((self_sta_req->type == WMI_VDEV_TYPE_STA ||
2444 self_sta_req->type == WMI_VDEV_TYPE_AP) &&
2445 self_sta_req->sub_type == 0) {
2446 ret = wma_vdev_set_param(wma_handle->wmi_handle,
2447 self_sta_req->session_id,
2448 WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES,
2449 self_sta_req->oce_feature_bitmap);
2450 if (QDF_IS_STATUS_ERROR(ret))
2451 WMA_LOGE("Failed to set WMI_VDEV_PARAM_ENABLE_DISABLE_OCE_FEATURES");
2452 }
2453
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002454 /* Initialize BMISS parameters */
2455 if ((self_sta_req->type == WMI_VDEV_TYPE_STA) &&
2456 (self_sta_req->sub_type == 0))
2457 wma_roam_scan_bmiss_cnt(wma_handle,
2458 mac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt,
2459 mac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt,
2460 self_sta_req->session_id);
2461
2462 if (wlan_cfg_get_int(mac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
2463 &cfg_val) == eSIR_SUCCESS) {
2464 WMA_LOGD("%s: setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d",
2465 __func__, cfg_val);
2466 ret = wma_set_enable_disable_mcc_adaptive_scheduler(cfg_val);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302467 if (ret != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 WMA_LOGE("Failed to set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED");
2469 }
2470 } else {
2471 WMA_LOGE("Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, leaving unchanged");
2472 }
Dustin Brown13995f02017-01-12 15:38:42 -08002473
2474 if (self_sta_req->type == WMI_VDEV_TYPE_STA) {
2475 status = wma_config_active_bpf_mode(wma_handle,
2476 self_sta_req->session_id);
2477 if (QDF_IS_STATUS_ERROR(status))
2478 WMA_LOGE("Failed to configure active BPF mode");
2479 }
2480
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002481end:
2482 self_sta_req->status = status;
2483
2484#ifdef QCA_IBSS_SUPPORT
2485 if (generateRsp)
2486#endif
2487 {
2488 sme_msg.type = eWNI_SME_ADD_STA_SELF_RSP;
2489 sme_msg.bodyptr = self_sta_req;
2490 sme_msg.bodyval = 0;
2491
Rajeev Kumarb60abe42017-01-21 15:39:31 -08002492 status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302493 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002494 WMA_LOGE("Failed to post eWNI_SME_ADD_STA_SELF_RSP");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302495 qdf_mem_free(self_sta_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002496 }
2497 }
2498 return txrx_vdev_handle;
2499}
2500
Jiachao Wu712d4fd2017-08-23 16:52:34 +08002501uint32_t wma_get_bcn_rate_code(uint16_t rate)
2502{
2503 /* rate in multiples of 100 Kbps */
2504 switch (rate) {
2505 case WMA_BEACON_TX_RATE_1_M:
2506 return WMI_BCN_TX_RATE_CODE_1_M;
2507 case WMA_BEACON_TX_RATE_2_M:
2508 return WMI_BCN_TX_RATE_CODE_2_M;
2509 case WMA_BEACON_TX_RATE_5_5_M:
2510 return WMI_BCN_TX_RATE_CODE_5_5_M;
2511 case WMA_BEACON_TX_RATE_11_M:
2512 return WMI_BCN_TX_RATE_CODE_11M;
2513 case WMA_BEACON_TX_RATE_6_M:
2514 return WMI_BCN_TX_RATE_CODE_6_M;
2515 case WMA_BEACON_TX_RATE_9_M:
2516 return WMI_BCN_TX_RATE_CODE_9_M;
2517 case WMA_BEACON_TX_RATE_12_M:
2518 return WMI_BCN_TX_RATE_CODE_12_M;
2519 case WMA_BEACON_TX_RATE_18_M:
2520 return WMI_BCN_TX_RATE_CODE_18_M;
2521 case WMA_BEACON_TX_RATE_24_M:
2522 return WMI_BCN_TX_RATE_CODE_24_M;
2523 case WMA_BEACON_TX_RATE_36_M:
2524 return WMI_BCN_TX_RATE_CODE_36_M;
2525 case WMA_BEACON_TX_RATE_48_M:
2526 return WMI_BCN_TX_RATE_CODE_48_M;
2527 case WMA_BEACON_TX_RATE_54_M:
2528 return WMI_BCN_TX_RATE_CODE_54_M;
2529 default:
2530 return WMI_BCN_TX_RATE_CODE_1_M;
2531 }
2532}
2533
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002535 * wma_vdev_start() - send vdev start request to fw
2536 * @wma: wma handle
2537 * @req: vdev start params
2538 * @isRestart: isRestart flag
2539 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302540 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002541 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302542QDF_STATUS wma_vdev_start(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002543 struct wma_vdev_start_req *req, bool isRestart)
2544{
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302545 struct vdev_start_params params = { 0 };
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002546 wmi_vdev_start_request_cmd_fixed_param *cmd;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547 struct wma_txrx_node *intr = wma->interfaces;
2548 tpAniSirGlobal mac_ctx = NULL;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302549 uint32_t temp_ssid_len = 0;
2550 uint32_t temp_flags = 0;
2551 uint32_t temp_chan_info = 0;
2552 uint32_t temp_reg_info_1 = 0;
2553 uint32_t temp_reg_info_2 = 0;
Kiran Kumar Lokere02b9aa42016-05-26 14:54:49 -07002554 uint16_t bw_val;
Himanshu Agarwalfc4dab92017-12-28 21:46:29 +05302555 struct wma_txrx_node *iface = &wma->interfaces[req->vdev_id];
2556 struct wma_target_req *req_msg;
Kabilan Kannan43d051f2018-01-04 17:54:34 -08002557 uint32_t chan_mode;
Kiran Kumar Lokere05a0658a2018-02-01 21:34:27 -08002558 enum phy_ch_width ch_width;
Manjunathappa Prakashae749482018-03-06 14:23:03 -08002559 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002560
Anurag Chouhan6d760662016-02-20 16:05:43 +05302561 mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002562 if (mac_ctx == NULL) {
2563 WMA_LOGE("%s: vdev start failed as mac_ctx is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302564 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002565 }
2566
Naveen Rawatb4ea70f2018-03-23 17:10:01 -07002567 if (req->chan == 0) {
2568 WMA_LOGE("%s: invalid channel: %d", __func__, req->chan);
2569 QDF_ASSERT(0);
2570 return QDF_STATUS_E_INVAL;
2571 }
2572
Kiran Kumar Lokere05a0658a2018-02-01 21:34:27 -08002573 params.band_center_freq1 = cds_chan_to_freq(req->chan);
2574 ch_width = req->chan_width;
2575 bw_val = wlan_reg_get_bw_value(req->chan_width);
2576 if (20 < bw_val) {
2577 if (req->ch_center_freq_seg0) {
2578 params.band_center_freq1 =
2579 cds_chan_to_freq(req->ch_center_freq_seg0);
2580 } else {
2581 WMA_LOGE("%s: invalid cntr_freq for bw %d, drop to 20",
2582 __func__, bw_val);
2583 params.band_center_freq1 = cds_chan_to_freq(req->chan);
2584 ch_width = CH_WIDTH_20MHZ;
2585 bw_val = 20;
2586 }
2587 }
2588 if (80 < bw_val) {
2589 if (req->ch_center_freq_seg1) {
2590 params.band_center_freq2 =
2591 cds_chan_to_freq(req->ch_center_freq_seg1);
2592 } else {
2593 WMA_LOGE("%s: invalid cntr_freq for bw %d, drop to 80",
2594 __func__, bw_val);
2595 params.band_center_freq2 = 0;
2596 ch_width = CH_WIDTH_80MHZ;
2597 }
2598 } else {
2599 params.band_center_freq2 = 0;
2600 }
2601 chan_mode = wma_chan_phy_mode(req->chan, ch_width,
2602 req->dot11_mode);
Kabilan Kannan43d051f2018-01-04 17:54:34 -08002603
2604 if (chan_mode == MODE_UNKNOWN) {
2605 WMA_LOGE("%s: invalid phy mode!", __func__);
2606 return QDF_STATUS_E_FAILURE;
2607 }
2608
Kiran Kumar Lokere05a0658a2018-02-01 21:34:27 -08002609 if (!params.band_center_freq1) {
2610 WMA_LOGE("%s: invalid center freq1", __func__);
2611 return QDF_STATUS_E_FAILURE;
2612 }
2613
2614 if (((ch_width == CH_WIDTH_160MHZ) || (ch_width == CH_WIDTH_80P80MHZ))
2615 && !params.band_center_freq2) {
2616 WMA_LOGE("%s: invalid center freq2 for 160MHz", __func__);
2617 return QDF_STATUS_E_FAILURE;
2618 }
2619 /* Fill channel info */
2620 params.chan_freq = cds_chan_to_freq(req->chan);
2621 params.chan_mode = chan_mode;
2622
Himanshu Agarwalfc4dab92017-12-28 21:46:29 +05302623 if (!isRestart &&
2624 qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) {
2625 req_msg = wma_find_vdev_req(wma, req->vdev_id,
2626 WMA_TARGET_REQ_TYPE_VDEV_STOP,
2627 false);
2628 if (!req_msg || req_msg->msg_type != WMA_DELETE_BSS_REQ) {
2629 if (!cds_is_driver_recovering()) {
2630 if (cds_is_self_recovery_enabled()) {
2631 WMA_LOGE("BSS is in started state before vdev start, trigger recovery");
2632 cds_trigger_recovery(
2633 QDF_REASON_UNSPECIFIED);
2634 } else {
2635 WMA_LOGE("BSS is in started state before vdev start, BUG_ON()");
2636 QDF_BUG(0);
2637 }
2638 }
2639 }
2640 }
2641
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002642 WMA_LOGD("%s: Enter isRestart=%d vdev=%d", __func__, isRestart,
2643 req->vdev_id);
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302644 params.vdev_id = req->vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002645
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302646 intr[params.vdev_id].chanmode = params.chan_mode;
2647 intr[params.vdev_id].ht_capable = req->ht_capable;
2648 intr[params.vdev_id].vht_capable = req->vht_capable;
2649 intr[params.vdev_id].config.gtx_info.gtxRTMask[0] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002650 CFG_TGT_DEFAULT_GTX_HT_MASK;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302651 intr[params.vdev_id].config.gtx_info.gtxRTMask[1] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652 CFG_TGT_DEFAULT_GTX_VHT_MASK;
Rajeev Kumar Sirasanagandlaaf474742016-09-06 17:54:50 +05302653
2654 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TGT_GTX_USR_CFG,
2655 &intr[params.vdev_id].config.gtx_info.gtxUsrcfg) != eSIR_SUCCESS) {
2656 intr[params.vdev_id].config.gtx_info.gtxUsrcfg =
2657 WNI_CFG_TGT_GTX_USR_CFG_STADEF;
2658 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_WARN,
2659 "Failed to get WNI_CFG_TGT_GTX_USR_CFG");
2660 }
2661
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302662 intr[params.vdev_id].config.gtx_info.gtxPERThreshold =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002663 CFG_TGT_DEFAULT_GTX_PER_THRESHOLD;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302664 intr[params.vdev_id].config.gtx_info.gtxPERMargin =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002665 CFG_TGT_DEFAULT_GTX_PER_MARGIN;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302666 intr[params.vdev_id].config.gtx_info.gtxTPCstep =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667 CFG_TGT_DEFAULT_GTX_TPC_STEP;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302668 intr[params.vdev_id].config.gtx_info.gtxTPCMin =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 CFG_TGT_DEFAULT_GTX_TPC_MIN;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302670 intr[params.vdev_id].config.gtx_info.gtxBWMask =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002671 CFG_TGT_DEFAULT_GTX_BW_MASK;
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302672 intr[params.vdev_id].mhz = params.chan_freq;
Kiran Kumar Lokere05a0658a2018-02-01 21:34:27 -08002673 intr[params.vdev_id].chan_width = ch_width;
Yeshwanth Sriram Guntukaa3f8d572018-03-14 11:10:23 +05302674 intr[params.vdev_id].channel = req->chan;
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08002675 wma_copy_txrxnode_he_ops(&intr[params.vdev_id], req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002676
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302677 temp_chan_info &= 0xffffffc0;
2678 temp_chan_info |= params.chan_mode;
2679
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680 /* Set half or quarter rate WMI flags */
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302681 params.is_half_rate = req->is_half_rate;
2682 params.is_quarter_rate = req->is_quarter_rate;
2683
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002684 if (req->is_half_rate)
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302685 temp_chan_info |= (1 << WMI_CHAN_FLAG_HALF_RATE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002686 else if (req->is_quarter_rate)
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302687 temp_chan_info |= (1 << WMI_CHAN_FLAG_QUARTER_RATE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002688
2689 /*
2690 * If the channel has DFS set, flip on radar reporting.
2691 *
2692 * It may be that this should only be done for IBSS/hostap operation
2693 * as this flag may be interpreted (at some point in the future)
2694 * by the firmware as "oh, and please do radar DETECTION."
2695 *
2696 * If that is ever the case we would insert the decision whether to
2697 * enable the firmware flag here.
2698 */
2699
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302700 params.is_dfs = req->is_dfs;
2701 params.is_restart = isRestart;
Arif Hussain671a1902017-03-17 09:08:32 -07002702 params.cac_duration_ms = req->cac_duration_ms;
2703 params.regdomain = req->dfs_regdomain;
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002704 if ((QDF_GLOBAL_MONITOR_MODE != cds_get_conparam()) && req->is_dfs) {
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302705 temp_chan_info |= (1 << WMI_CHAN_FLAG_DFS);
2706 params.dis_hw_ack = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002707
2708 /*
Arif Hussaincd151632017-02-11 16:57:19 -08002709 * If channel is DFS and operating in AP mode,
2710 * set the WMI_CHAN_FLAG_DFS flag.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002711 */
Arif Hussaincd151632017-02-11 16:57:19 -08002712 if (wma_is_vdev_in_ap_mode(wma, params.vdev_id) == true)
2713 params.flag_dfs = WMI_CHAN_FLAG_DFS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002714 }
2715
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302716 params.beacon_intval = req->beacon_intval;
2717 params.dtim_period = req->dtim_period;
Jiachao Wu712d4fd2017-08-23 16:52:34 +08002718
2719 if (req->beacon_tx_rate) {
2720 WMA_LOGD("%s: beacon tx rate [%hu * 100 Kbps]",
2721 __func__, req->beacon_tx_rate);
2722 temp_flags |= WMI_UNIFIED_VDEV_START_BCN_TX_RATE_PRESENT;
2723 /*
2724 * beacon_tx_rate is in multiples of 100 Kbps.
2725 * Convert the data rate to hw rate code.
2726 */
2727 params.bcn_tx_rate_code =
2728 wma_get_bcn_rate_code(req->beacon_tx_rate);
2729 }
2730
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002731 /* FIXME: Find out min, max and regulatory power levels */
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302732 params.max_txpow = req->max_txpow;
2733 temp_reg_info_1 &= 0xff00ffff;
2734 temp_reg_info_1 |= ((req->max_txpow&0xff) << 16);
2735
2736 temp_reg_info_2 &= 0xffff00ff;
2737 temp_reg_info_2 |= ((req->max_txpow&0xff)<<8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002738
2739 /* TODO: Handle regulatory class, max antenna */
2740 if (!isRestart) {
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302741 params.beacon_intval = req->beacon_intval;
2742 params.dtim_period = req->dtim_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743
2744 /* Copy the SSID */
2745 if (req->ssid.length) {
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302746 params.ssid.length = req->ssid.length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747 if (req->ssid.length < sizeof(cmd->ssid.ssid))
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302748 temp_ssid_len = req->ssid.length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002749 else
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302750 temp_ssid_len = sizeof(cmd->ssid.ssid);
2751 qdf_mem_copy(params.ssid.mac_ssid, req->ssid.ssId,
2752 temp_ssid_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002753 }
2754
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302755 params.pmf_enabled = req->pmf_enabled;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002756 if (req->pmf_enabled)
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302757 temp_flags |= WMI_UNIFIED_VDEV_START_PMF_ENABLED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002758 }
2759
gaurank kathpalia1b42e8d2017-12-15 15:44:06 +05302760 params.hidden_ssid = req->hidden_ssid;
2761 if (req->hidden_ssid)
2762 temp_flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
2763
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302764 params.num_noa_descriptors = 0;
2765 params.preferred_rx_streams = req->preferred_rx_streams;
2766 params.preferred_tx_streams = req->preferred_tx_streams;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002767
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08002768 wma_copy_vdev_start_he_ops(&params, req);
2769
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002770 /* Store vdev params in SAP mode which can be used in vdev restart */
2771 if (intr[req->vdev_id].type == WMI_VDEV_TYPE_AP &&
2772 intr[req->vdev_id].sub_type == 0) {
2773 intr[req->vdev_id].vdev_restart_params.vdev_id = req->vdev_id;
2774 intr[req->vdev_id].vdev_restart_params.ssid.ssid_len =
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302775 temp_ssid_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302776 qdf_mem_copy(intr[req->vdev_id].vdev_restart_params.ssid.ssid,
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302777 params.ssid.mac_ssid, temp_ssid_len);
2778 intr[req->vdev_id].vdev_restart_params.flags = temp_flags;
2779 intr[req->vdev_id].vdev_restart_params.requestor_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 intr[req->vdev_id].vdev_restart_params.disable_hw_ack =
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302781 params.dis_hw_ack;
2782 intr[req->vdev_id].vdev_restart_params.chan.mhz =
2783 params.chan_freq;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002784 intr[req->vdev_id].vdev_restart_params.chan.band_center_freq1 =
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302785 params.band_center_freq1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002786 intr[req->vdev_id].vdev_restart_params.chan.band_center_freq2 =
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302787 params.band_center_freq2;
2788 intr[req->vdev_id].vdev_restart_params.chan.info =
2789 temp_chan_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002790 intr[req->vdev_id].vdev_restart_params.chan.reg_info_1 =
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302791 temp_reg_info_1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002792 intr[req->vdev_id].vdev_restart_params.chan.reg_info_2 =
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302793 temp_reg_info_2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002794 }
2795
2796 if (isRestart) {
2797 /*
2798 * Marking the VDEV UP STATUS to false
2799 * since, VDEV RESTART will do a VDEV DOWN
2800 * in the firmware.
2801 */
Mukul Sharmaf9047232017-03-02 16:58:56 +05302802 wma_vdev_set_mlme_state(wma, params.vdev_id, WLAN_VDEV_S_STOP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002803 } else {
2804 WMA_LOGD("%s, vdev_id: %d, unpausing tx_ll_queue at VDEV_START",
Siddarth Poddar17dc4712016-03-09 16:30:27 +05302805 __func__, params.vdev_id);
Leo Chang96464902016-10-28 11:10:54 -07002806 cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002807 wma->interfaces[params.vdev_id].handle,
2808 0xffffffff);
Manjunathappa Prakashae749482018-03-06 14:23:03 -08002809 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
2810 cds_get_context(QDF_MODULE_ID_TXRX),
2811 params.vdev_id);
2812 /*
2813 * For Adrastea flow control v2 is based on FW MAP events,
2814 * so this above callback is not implemented.
2815 * Hence this is not actual failure. Dont return failure
2816 */
2817 if ((status != QDF_STATUS_SUCCESS) &&
2818 (status != QDF_STATUS_E_INVAL)) {
2819 WMA_LOGE("%s: vdev_id: %d, failed to create flow pool status %d",
2820 __func__, params.vdev_id, status);
2821 return status;
2822 }
Mukul Sharma6411bb82017-03-01 15:57:07 +05302823 wma_vdev_update_pause_bitmap(params.vdev_id, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002824 }
2825
Dustin Brownd5f12942017-03-10 11:06:25 -08002826 return wma_send_vdev_start_to_fw(wma, &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002827}
2828
2829/**
2830 * wma_peer_assoc_conf_handler() - peer assoc conf handler
2831 * @handle: wma handle
2832 * @cmd_param_info: event buffer
2833 * @len: buffer length
2834 *
2835 * Return: 0 for success or error code
2836 */
2837int wma_peer_assoc_conf_handler(void *handle, uint8_t *cmd_param_info,
2838 uint32_t len)
2839{
2840 tp_wma_handle wma = (tp_wma_handle) handle;
2841 WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *param_buf;
2842 wmi_peer_assoc_conf_event_fixed_param *event;
2843 struct wma_target_req *req_msg;
2844 uint8_t macaddr[IEEE80211_ADDR_LEN];
2845 int status = 0;
2846
2847 WMA_LOGD(FL("Enter"));
2848 param_buf = (WMI_PEER_ASSOC_CONF_EVENTID_param_tlvs *) cmd_param_info;
2849 if (!param_buf) {
2850 WMA_LOGE("Invalid peer assoc conf event buffer");
2851 return -EINVAL;
2852 }
2853
2854 event = param_buf->fixed_param;
2855 if (!event) {
2856 WMA_LOGE("Invalid peer assoc conf event buffer");
2857 return -EINVAL;
2858 }
2859
2860 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
2861 WMA_LOGD(FL("peer assoc conf for vdev:%d mac=%pM"),
2862 event->vdev_id, macaddr);
2863
2864 req_msg = wma_find_req(wma, event->vdev_id,
2865 WMA_PEER_ASSOC_CNF_START);
2866
2867 if (!req_msg) {
2868 WMA_LOGE(FL("Failed to lookup request message for vdev %d"),
2869 event->vdev_id);
2870 return -EINVAL;
2871 }
2872
Anurag Chouhan210db072016-02-22 18:42:15 +05302873 qdf_mc_timer_stop(&req_msg->event_timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002874
2875 if (req_msg->msg_type == WMA_ADD_STA_REQ) {
2876 tpAddStaParams params = (tpAddStaParams)req_msg->user_data;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002877
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002878 if (!params) {
2879 WMA_LOGE(FL("add STA params is NULL for vdev %d"),
2880 event->vdev_id);
2881 status = -EINVAL;
2882 goto free_req_msg;
2883 }
2884
2885 /* peer assoc conf event means the cmd succeeds */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302886 params->status = QDF_STATUS_SUCCESS;
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08002887 WMA_LOGD(FL("Send ADD_STA_RSP: statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002888 params->staType, params->smesessionId,
2889 params->assocId, params->bssId, params->staIdx,
2890 params->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05302891 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
2892 (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002893 } else if (req_msg->msg_type == WMA_ADD_BSS_REQ) {
2894 tpAddBssParams params = (tpAddBssParams) req_msg->user_data;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002895
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896 if (!params) {
2897 WMA_LOGE(FL("add BSS params is NULL for vdev %d"),
2898 event->vdev_id);
2899 status = -EINVAL;
2900 goto free_req_msg;
2901 }
2902
2903 /* peer assoc conf event means the cmd succeeds */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302904 params->status = QDF_STATUS_SUCCESS;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002905 WMA_LOGD(FL("Send ADD BSS RSP: opermode: %d update_bss: %d nw_type: %d bssid: %pM staIdx %d status %d"),
2906 params->operMode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907 params->updateBss, params->nwType, params->bssId,
2908 params->staContext.staIdx, params->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05302909 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
2910 (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911 } else {
2912 WMA_LOGE(FL("Unhandled request message type: %d"),
2913 req_msg->msg_type);
2914 }
2915
2916free_req_msg:
Anurag Chouhan210db072016-02-22 18:42:15 +05302917 qdf_mc_timer_destroy(&req_msg->event_timeout);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302918 qdf_mem_free(req_msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002919
2920 return status;
2921}
2922
2923/**
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08002924 * wma_vdev_delete_handler() - vdev delete response handler
2925 * @handle: wma handle
2926 * @cmd_param_info: event buffer
2927 * @len: buffer length
2928 *
2929 * Return: 0 for success or error code
2930 */
2931int wma_vdev_delete_handler(void *handle, uint8_t *cmd_param_info,
2932 uint32_t len)
2933{
2934 tp_wma_handle wma = (tp_wma_handle) handle;
2935 WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *param_buf;
2936 wmi_vdev_delete_cmd_fixed_param *event;
2937 struct wma_target_req *req_msg;
2938 int status = 0;
2939
2940 param_buf = (WMI_VDEV_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info;
2941 if (!param_buf) {
2942 WMA_LOGE("Invalid vdev delete event buffer");
2943 return -EINVAL;
2944 }
2945
2946 event = (wmi_vdev_delete_cmd_fixed_param *)param_buf->fixed_param;
2947 if (!event) {
2948 WMA_LOGE("Invalid vdev delete event buffer");
2949 return -EINVAL;
2950 }
2951
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07002952 WMA_LOGD("%s Vdev delete resp vdev id %d", __func__, event->vdev_id);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08002953 req_msg = wma_find_vdev_req(wma, event->vdev_id,
Kiran Kumar Lokere20804162017-07-17 16:09:04 -07002954 WMA_TARGET_REQ_TYPE_VDEV_DEL, true);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08002955 if (!req_msg) {
2956 WMA_LOGD(FL("Vdev delete resp is not handled! vdev id %d"),
2957 event->vdev_id);
2958 return -EINVAL;
2959 }
Abhishek Singh1d1d3e32018-03-01 17:30:48 +05302960 qdf_mc_timer_stop(&req_msg->event_timeout);
2961 qdf_mc_timer_destroy(&req_msg->event_timeout);
Dustin Brownec2c92e2017-07-26 11:13:49 -07002962
2963 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
2964
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08002965 /* Send response to upper layers */
2966 wma_vdev_detach_callback(req_msg->user_data);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302967 qdf_mem_free(req_msg);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08002968
2969 return status;
2970}
2971
2972/**
2973 * wma_peer_delete_handler() - peer delete response handler
2974 * @handle: wma handle
2975 * @cmd_param_info: event buffer
2976 * @len: buffer length
2977 *
2978 * Return: 0 for success or error code
2979 */
2980int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
2981 uint32_t len)
2982{
2983 tp_wma_handle wma = (tp_wma_handle) handle;
2984 WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *param_buf;
2985 wmi_peer_delete_cmd_fixed_param *event;
2986 struct wma_target_req *req_msg;
2987 tDeleteStaParams *del_sta;
2988 uint8_t macaddr[IEEE80211_ADDR_LEN];
2989 int status = 0;
2990
2991 param_buf = (WMI_PEER_DELETE_RESP_EVENTID_param_tlvs *)cmd_param_info;
2992 if (!param_buf) {
2993 WMA_LOGE("Invalid vdev delete event buffer");
2994 return -EINVAL;
2995 }
2996
2997 event = (wmi_peer_delete_cmd_fixed_param *)param_buf->fixed_param;
2998 if (!event) {
2999 WMA_LOGE("Invalid vdev delete event buffer");
3000 return -EINVAL;
3001 }
3002
3003 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->peer_macaddr, macaddr);
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003004 WMA_LOGD(FL("Peer Delete Response, vdev %d Peer %pM"),
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003005 event->vdev_id, macaddr);
Deepak Dhamdheref918d422017-07-06 12:56:29 -07003006 wlan_roam_debug_log(event->vdev_id, DEBUG_PEER_DELETE_RESP,
3007 DEBUG_INVALID_PEER_ID, macaddr, NULL, 0, 0);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003008 req_msg = wma_find_remove_req_msgtype(wma, event->vdev_id,
3009 WMA_DELETE_STA_REQ);
3010 if (!req_msg) {
3011 WMA_LOGD("Peer Delete response is not handled");
3012 return -EINVAL;
3013 }
3014
Dustin Brownec2c92e2017-07-26 11:13:49 -07003015 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
3016
3017 /* Cleanup timeout handler */
Anurag Chouhan210db072016-02-22 18:42:15 +05303018 qdf_mc_timer_stop(&req_msg->event_timeout);
3019 qdf_mc_timer_destroy(&req_msg->event_timeout);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003020
3021 if (req_msg->type == WMA_DELETE_STA_RSP_START) {
3022 del_sta = req_msg->user_data;
3023 if (del_sta->respReqd) {
3024 WMA_LOGD(FL("Sending peer del rsp to umac"));
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303025 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303026 (void *)del_sta, QDF_STATUS_SUCCESS);
yeshwanth sriram guntuka945b6212017-03-07 15:56:45 +05303027 } else {
3028 qdf_mem_free(del_sta);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003029 }
3030 } else if (req_msg->type == WMA_DEL_P2P_SELF_STA_RSP_START) {
3031 struct del_sta_self_rsp_params *data;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003032
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003033 data = (struct del_sta_self_rsp_params *)req_msg->user_data;
3034 WMA_LOGD(FL("Calling vdev detach handler"));
3035 wma_handle_vdev_detach(wma, data->self_sta_param,
3036 data->generate_rsp);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303037 qdf_mem_free(data);
Sandeep Puligillabbee8172017-04-07 19:26:33 -07003038 } else if (req_msg->type == WMA_SET_LINK_PEER_RSP) {
3039 tpLinkStateParams params =
3040 (tpLinkStateParams) req_msg->user_data;
Dustin Brownec2c92e2017-07-26 11:13:49 -07003041 if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
3042 QDF_STATUS_SUCCESS) {
Sandeep Puligillabbee8172017-04-07 19:26:33 -07003043 WMA_LOGE("Failed to send vdev down cmd: vdev %d",
3044 req_msg->vdev_id);
3045 }
3046 wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
Abhishek Singhe8be9a62017-05-30 12:13:29 +05303047 } else if (req_msg->type == WMA_DELETE_PEER_RSP) {
3048 wma_send_del_bss_response(wma, req_msg, req_msg->vdev_id);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003049 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303050 qdf_mem_free(req_msg);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003051 return status;
3052}
3053
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303054static void wma_trigger_recovery_assert_on_fw_timeout(
3055 uint16_t wma_msg)
3056{
3057 if (cds_is_self_recovery_enabled()) {
3058 WMA_LOGE("%s timed out, triggering recovery",
3059 mac_trace_get_wma_msg_string(wma_msg));
3060 cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
3061 } else {
3062 WMA_LOGE("%s timed out, BUG_ON()",
3063 mac_trace_get_wma_msg_string(wma_msg));
3064 QDF_BUG(0);
3065 }
3066}
3067
Manikandan Mohanb089ed62017-02-13 11:38:14 -08003068static inline bool wma_crash_on_fw_timeout(bool crash_enabled)
3069{
3070 /* Discard FW timeouts and dont crash during SSR */
3071 if (cds_is_driver_recovering())
3072 return false;
3073
Sandeep Puligilla5ac6bd22017-10-17 12:33:56 -07003074 /* Firmware is down send failure response */
3075 if (cds_is_fw_down())
Nachiket Kukade8003d252017-03-30 15:55:58 +05303076 return false;
3077
Kapil Gupta8c336652017-05-30 16:54:13 +05303078 if (cds_is_driver_unloading())
3079 return false;
3080
Manikandan Mohanb089ed62017-02-13 11:38:14 -08003081 return crash_enabled;
3082}
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003083
3084/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003085 * wma_hold_req_timer() - wma hold request timeout function
3086 * @data: target request params
3087 *
3088 * Return: none
3089 */
3090void wma_hold_req_timer(void *data)
3091{
3092 tp_wma_handle wma;
3093 struct wma_target_req *tgt_req = (struct wma_target_req *)data;
3094 struct wma_target_req *msg;
3095
Anurag Chouhan6d760662016-02-20 16:05:43 +05303096 wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003097 if (NULL == wma) {
3098 WMA_LOGE(FL("Failed to get wma"));
Naveen Rawat0eb3dd02017-04-03 20:18:30 -07003099 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003100 }
3101
3102 WMA_LOGA(FL("request %d is timed out for vdev_id - %d"),
3103 tgt_req->msg_type, tgt_req->vdev_id);
3104 msg = wma_find_req(wma, tgt_req->vdev_id, tgt_req->type);
3105
3106 if (!msg) {
3107 WMA_LOGE(FL("Failed to lookup request message - %d"),
3108 tgt_req->msg_type);
Naveen Rawat0eb3dd02017-04-03 20:18:30 -07003109 /*
3110 * if find request failed, then firmware rsp should have
3111 * consumed the buffer. Do not free.
3112 */
3113 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003114 }
3115
3116 if (tgt_req->msg_type == WMA_ADD_STA_REQ) {
3117 tpAddStaParams params = (tpAddStaParams) tgt_req->user_data;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003118
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303119 params->status = QDF_STATUS_E_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003120 WMA_LOGA(FL("WMA_ADD_STA_REQ timed out"));
3121 WMA_LOGD(FL("Sending add sta rsp to umac (mac:%pM, status:%d)"),
3122 params->staMac, params->status);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303123 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
3124 wma_trigger_recovery_assert_on_fw_timeout(
3125 WMA_ADD_STA_REQ);
3126 } else {
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303127 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
3128 (void *)params, 0);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303129 }
Krishna Kumaar Natarajanf1d6dee2016-02-11 16:40:43 -08003130 } else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) {
3131 tpAddBssParams params = (tpAddBssParams) tgt_req->user_data;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003132
Krishna Kumaar Natarajanf1d6dee2016-02-11 16:40:43 -08003133 params->status = QDF_STATUS_E_TIMEOUT;
3134 WMA_LOGA(FL("WMA_ADD_BSS_REQ timed out"));
3135 WMA_LOGD(FL("Sending add bss rsp to umac (mac:%pM, status:%d)"),
3136 params->selfMacAddr, params->status);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303137 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
3138 wma_trigger_recovery_assert_on_fw_timeout(
3139 WMA_ADD_BSS_REQ);
3140 } else {
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303141 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
3142 (void *)params, 0);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303143 }
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003144 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3145 (tgt_req->type == WMA_DELETE_STA_RSP_START)) {
3146 tpDeleteStaParams params =
3147 (tpDeleteStaParams) tgt_req->user_data;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303148 params->status = QDF_STATUS_E_TIMEOUT;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003149 WMA_LOGE(FL("WMA_DEL_STA_REQ timed out"));
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003150 WMA_LOGE(FL("Sending del sta rsp to umac (mac:%pM, status:%d)"),
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003151 params->staMac, params->status);
Sandeep Puligillaafa52892016-10-26 19:03:16 -07003152
Manikandan Mohanb089ed62017-02-13 11:38:14 -08003153 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303154 wma_trigger_recovery_assert_on_fw_timeout(
3155 WMA_DELETE_STA_REQ);
Sandeep Puligillaafa52892016-10-26 19:03:16 -07003156 } else {
3157 /*
3158 * Assert in development build only.
3159 * Send response in production builds.
3160 */
3161 QDF_ASSERT(0);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303162 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
Sandeep Puligillaafa52892016-10-26 19:03:16 -07003163 (void *)params, 0);
3164 }
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003165 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3166 (tgt_req->type == WMA_DEL_P2P_SELF_STA_RSP_START)) {
Abhishek Singhc614ec42017-04-25 16:17:34 +05303167 struct del_sta_self_rsp_params *del_sta;
Srinivas Girigowda4d65ebe2017-10-13 21:41:42 -07003168
Abhishek Singhc614ec42017-04-25 16:17:34 +05303169 del_sta = (struct del_sta_self_rsp_params *)tgt_req->user_data;
3170 del_sta->self_sta_param->status = QDF_STATUS_E_TIMEOUT;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003171 WMA_LOGA(FL("wma delete sta p2p request timed out"));
Abhishek Singhc614ec42017-04-25 16:17:34 +05303172
3173 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash)) {
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303174 wma_trigger_recovery_assert_on_fw_timeout(
3175 WMA_DELETE_STA_REQ);
Abhishek Singhc614ec42017-04-25 16:17:34 +05303176 } else {
3177 if (del_sta->generate_rsp)
3178 wma_send_del_sta_self_resp(
3179 del_sta->self_sta_param);
3180 }
3181 qdf_mem_free(tgt_req->user_data);
Sandeep Puligillabbee8172017-04-07 19:26:33 -07003182 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3183 (tgt_req->type == WMA_SET_LINK_PEER_RSP)) {
Abhishek Singhc614ec42017-04-25 16:17:34 +05303184 tpLinkStateParams params =
3185 (tpLinkStateParams) tgt_req->user_data;
3186
3187 params->status = false;
Sandeep Puligillabbee8172017-04-07 19:26:33 -07003188 WMA_LOGA(FL("wma delete peer for set link timed out"));
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303189 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
3190 wma_trigger_recovery_assert_on_fw_timeout(
3191 WMA_DELETE_STA_REQ);
3192 } else {
Abhishek Singhc614ec42017-04-25 16:17:34 +05303193 wma_send_msg(wma, WMA_SET_LINK_STATE_RSP,
3194 params, 0);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303195 }
Abhishek Singhe8be9a62017-05-30 12:13:29 +05303196 } else if ((tgt_req->msg_type == WMA_DELETE_STA_REQ) &&
3197 (tgt_req->type == WMA_DELETE_PEER_RSP)) {
Abhishek Singhc614ec42017-04-25 16:17:34 +05303198 tpDeleteBssParams params =
3199 (tpDeleteBssParams) tgt_req->user_data;
3200
3201 params->status = QDF_STATUS_E_TIMEOUT;
3202 WMA_LOGE(FL("wma delete peer for del bss req timed out"));
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303203 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
3204 wma_trigger_recovery_assert_on_fw_timeout(
3205 WMA_DELETE_STA_REQ);
3206 } else {
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303207 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
3208 params, 0);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303209 }
Tushnim Bhattacharyya86294892017-10-25 16:29:11 -07003210 } else if ((tgt_req->msg_type == SIR_HAL_PDEV_SET_HW_MODE) &&
3211 (tgt_req->type == WMA_PDEV_SET_HW_MODE_RESP)) {
3212 struct sir_set_hw_mode_resp *params =
3213 qdf_mem_malloc(sizeof(*params));
3214
3215 WMA_LOGE(FL("set hw mode req timed out"));
3216
3217 if (!params)
3218 WMA_LOGE("%s: Memory allocation failed", __func__);
3219 else {
3220 params->status = SET_HW_MODE_STATUS_ECANCELED;
3221 params->cfgd_hw_mode_index = 0;
3222 params->num_vdev_mac_entries = 0;
3223
3224 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true)
3225 QDF_BUG(0);
3226 else
3227 wma_send_msg_high_priority(wma,
3228 SIR_HAL_PDEV_SET_HW_MODE_RESP, params, 0);
3229 }
Krishna Kumaar Natarajanf1d6dee2016-02-11 16:40:43 -08003230 } else {
3231 WMA_LOGE(FL("Unhandled timeout for msg_type:%d and type:%d"),
3232 tgt_req->msg_type, tgt_req->type);
3233 QDF_BUG(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003234 }
Abhishek Singh07b97852017-08-01 11:10:07 +05303235 qdf_mc_timer_destroy(&tgt_req->event_timeout);
Abhishek Singhc614ec42017-04-25 16:17:34 +05303236 qdf_mem_free(tgt_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003237}
3238
3239/**
3240 * wma_fill_hold_req() - fill wma request
3241 * @wma: wma handle
3242 * @msg_type: message type
3243 * @type: request type
3244 * @params: request params
3245 * @timeout: timeout value
3246 *
3247 * Return: wma_target_req ptr
3248 */
3249struct wma_target_req *wma_fill_hold_req(tp_wma_handle wma,
3250 uint8_t vdev_id,
3251 uint32_t msg_type, uint8_t type,
3252 void *params, uint32_t timeout)
3253{
3254 struct wma_target_req *req;
Anurag Chouhanffb21542016-02-17 14:33:03 +05303255 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003256
Himanshu Agarwal51d818c2018-04-19 18:16:46 +05303257 if (!cds_is_target_ready()) {
3258 WMA_LOGE("target not ready, drop the request");
3259 return NULL;
3260 }
3261
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303262 req = qdf_mem_malloc(sizeof(*req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003263 if (!req) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003264 WMA_LOGE(FL("Failed to allocate memory for msg %d vdev %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003265 msg_type, vdev_id);
3266 return NULL;
3267 }
3268
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003269 WMA_LOGD(FL("vdev_id %d msg %d type %d"), vdev_id, msg_type, type);
Abhishek Singhc614ec42017-04-25 16:17:34 +05303270 qdf_spin_lock_bh(&wma->wma_hold_req_q_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003271 req->vdev_id = vdev_id;
3272 req->msg_type = msg_type;
3273 req->type = type;
3274 req->user_data = params;
Anurag Chouhanffb21542016-02-17 14:33:03 +05303275 status = qdf_list_insert_back(&wma->wma_hold_req_queue, &req->node);
3276 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303277 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278 WMA_LOGE(FL("Failed add request in queue"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303279 qdf_mem_free(req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003280 return NULL;
3281 }
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303282 qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
Abhishek Singhc614ec42017-04-25 16:17:34 +05303283 qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW,
3284 wma_hold_req_timer, req);
3285 qdf_mc_timer_start(&req->event_timeout, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003286 return req;
3287}
3288
3289/**
3290 * wma_remove_req() - remove request
3291 * @wma: wma handle
3292 * @vdev_id: vdev id
3293 * @type: type
3294 *
3295 * Return: none
3296 */
3297void wma_remove_req(tp_wma_handle wma, uint8_t vdev_id,
3298 uint8_t type)
3299{
3300 struct wma_target_req *req_msg;
3301
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003302 WMA_LOGD(FL("Remove req for vdev: %d type: %d"), vdev_id, type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003303 req_msg = wma_find_req(wma, vdev_id, type);
3304 if (!req_msg) {
3305 WMA_LOGE(FL("target req not found for vdev: %d type: %d"),
3306 vdev_id, type);
3307 return;
3308 }
3309
Anurag Chouhan210db072016-02-22 18:42:15 +05303310 qdf_mc_timer_stop(&req_msg->event_timeout);
3311 qdf_mc_timer_destroy(&req_msg->event_timeout);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303312 qdf_mem_free(req_msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003313}
3314
3315/**
3316 * wma_vdev_resp_timer() - wma response timeout function
3317 * @data: target request params
3318 *
3319 * Return: none
3320 */
3321void wma_vdev_resp_timer(void *data)
3322{
3323 tp_wma_handle wma;
3324 struct wma_target_req *tgt_req = (struct wma_target_req *)data;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003325 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003326 struct wma_target_req *msg;
Sandeep Puligilla7da86332016-11-10 16:14:40 -08003327 uint8_t peer_id;
Abhishek Singhc614ec42017-04-25 16:17:34 +05303328 int status;
Sandeep Puligilla7da86332016-11-10 16:14:40 -08003329 void *peer;
Leo Chang96464902016-10-28 11:10:54 -07003330 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003331#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Wu Gao30f65eb2017-08-09 19:56:10 +08003332 tpAniSirGlobal mac_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003333#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
3334
Anurag Chouhan6d760662016-02-20 16:05:43 +05303335 wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003336
3337 if (NULL == wma) {
3338 WMA_LOGE("%s: Failed to get wma", __func__);
Liangwei Dong748cb5d2016-09-29 00:56:40 -04003339 wma_cleanup_target_req_param(tgt_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003340 goto free_tgt_req;
3341 }
3342
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003343 WMA_LOGA("%s: request %d is timed out for vdev_id - %d", __func__,
3344 tgt_req->msg_type, tgt_req->vdev_id);
Kiran Kumar Lokere20804162017-07-17 16:09:04 -07003345 msg = wma_find_vdev_req(wma, tgt_req->vdev_id, tgt_req->type, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003346
3347 if (!msg) {
3348 WMA_LOGE("%s: Failed to lookup request message - %d",
3349 __func__, tgt_req->msg_type);
Houston Hoffmanb4558eb2017-05-18 15:07:51 -07003350 return;
3351 }
3352
3353 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
3354
3355 if (NULL == pdev) {
3356 WMA_LOGE("%s: Failed to get pdev", __func__);
Liangwei Dong748cb5d2016-09-29 00:56:40 -04003357 wma_cleanup_target_req_param(tgt_req);
Houston Hoffmanb4558eb2017-05-18 15:07:51 -07003358 qdf_mc_timer_stop(&tgt_req->event_timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003359 goto free_tgt_req;
3360 }
3361
Wu Gao30f65eb2017-08-09 19:56:10 +08003362#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
3363 mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
3364 if (!mac_ctx) {
3365 WMA_LOGE("%s: Failed to get mac_ctx", __func__);
3366 wma_cleanup_target_req_param(tgt_req);
3367 goto free_tgt_req;
3368 }
3369#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
3370
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003371 if (tgt_req->msg_type == WMA_CHNL_SWITCH_REQ) {
3372 tpSwitchChannelParams params =
3373 (tpSwitchChannelParams) tgt_req->user_data;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303374 params->status = QDF_STATUS_E_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003375 WMA_LOGA("%s: WMA_SWITCH_CHANNEL_REQ timedout", __func__);
Sandeep Puligillaafa52892016-10-26 19:03:16 -07003376
Nachiket Kukade8003d252017-03-30 15:55:58 +05303377 /*
3378 * Trigger host crash if the flag is set or if the timeout
3379 * is not due to fw down
3380 */
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303381 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
3382 wma_trigger_recovery_assert_on_fw_timeout(
3383 WMA_CHNL_SWITCH_REQ);
3384 } else {
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303385 wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
Sandeep Puligillaafa52892016-10-26 19:03:16 -07003386 (void *)params, 0);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303387 }
Agrawal Ashish7dd7c592016-02-22 14:25:11 +05303388 if (wma->interfaces[tgt_req->vdev_id].is_channel_switch) {
3389 wma->interfaces[tgt_req->vdev_id].is_channel_switch =
3390 false;
3391 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003392 } else if (tgt_req->msg_type == WMA_DELETE_BSS_REQ) {
3393 tpDeleteBssParams params =
3394 (tpDeleteBssParams) tgt_req->user_data;
3395 struct beacon_info *bcn;
3396 struct wma_txrx_node *iface;
3397
Naveen Rawatf2bd42d2017-06-29 14:51:43 -07003398 if (tgt_req->vdev_id >= wma->max_bssid) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003399 WMA_LOGE("%s: Invalid vdev_id %d", __func__,
3400 tgt_req->vdev_id);
Liangwei Dong748cb5d2016-09-29 00:56:40 -04003401 wma_cleanup_target_req_param(tgt_req);
Anurag Chouhan210db072016-02-22 18:42:15 +05303402 qdf_mc_timer_stop(&tgt_req->event_timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003403 goto free_tgt_req;
3404 }
3405
3406 iface = &wma->interfaces[tgt_req->vdev_id];
3407 if (iface->handle == NULL) {
3408 WMA_LOGE("%s vdev id %d is already deleted",
3409 __func__, tgt_req->vdev_id);
Liangwei Dong748cb5d2016-09-29 00:56:40 -04003410 wma_cleanup_target_req_param(tgt_req);
Anurag Chouhan210db072016-02-22 18:42:15 +05303411 qdf_mc_timer_stop(&tgt_req->event_timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003412 goto free_tgt_req;
3413 }
Nachiket Kukade8003d252017-03-30 15:55:58 +05303414 /*
3415 * Trigger host crash if the flag is set or if the timeout
3416 * is not due to fw down
3417 */
Manikandan Mohanb089ed62017-02-13 11:38:14 -08003418 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303419 wma_trigger_recovery_assert_on_fw_timeout(
3420 WMA_DELETE_BSS_REQ);
Prakash Dhavali0b792742016-12-02 17:56:36 -08003421 return;
3422 }
3423
Krishna Kumaar Natarajanf24bfc82017-02-07 11:54:05 -08003424 status = wma_remove_bss_peer(wma, pdev, tgt_req,
3425 tgt_req->vdev_id, params);
3426 if (status != 0)
3427 goto free_tgt_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003428
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303429 if (wmi_service_enabled(
3430 wma->wmi_handle,
3431 wmi_service_sync_delete_cmds))
Abhishek Singhe8be9a62017-05-30 12:13:29 +05303432 goto free_tgt_req;
3433
Dustin Brownec2c92e2017-07-26 11:13:49 -07003434 if (wma_send_vdev_down_to_fw(wma, tgt_req->vdev_id) !=
3435 QDF_STATUS_SUCCESS) {
Sandeep Puligilla58c84ef2016-08-21 16:20:33 -07003436 WMA_LOGE("Failed to send vdev down cmd: vdev %d",
3437 tgt_req->vdev_id);
3438 } else {
Mukul Sharmaf9047232017-03-02 16:58:56 +05303439 wma_vdev_set_mlme_state(wma, tgt_req->vdev_id,
3440 WLAN_VDEV_S_STOP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003441#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Sandeep Puligilla58c84ef2016-08-21 16:20:33 -07003442 if (mac_ctx->sap.sap_channel_avoidance)
3443 wma_find_mcc_ap(wma, tgt_req->vdev_id, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003444#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
3445 }
Leo Chang96464902016-10-28 11:10:54 -07003446 cdp_fc_vdev_flush(soc, iface->handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003447 WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for WDA_DELETE_BSS_REQ timeout",
3448 __func__, tgt_req->vdev_id);
Leo Chang96464902016-10-28 11:10:54 -07003449 cdp_fc_vdev_unpause(soc, iface->handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003450 OL_TXQ_PAUSE_REASON_VDEV_STOP);
Mukul Sharma6411bb82017-03-01 15:57:07 +05303451 wma_vdev_clear_pause_bit(tgt_req->vdev_id, PAUSE_TYPE_HOST);
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05303452 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003453 WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
3454 __func__, iface->type, iface->sub_type);
3455
3456 bcn = wma->interfaces[tgt_req->vdev_id].beacon;
3457
3458 if (bcn) {
Jeff Johnsonadba3962017-09-18 08:12:35 -07003459 WMA_LOGD("%s: Freeing beacon struct %pK, template memory %pK",
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003460 __func__, bcn, bcn->buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003461 if (bcn->dma_mapped)
Leo Chang96464902016-10-28 11:10:54 -07003462 qdf_nbuf_unmap_single(wma->qdf_dev, bcn->buf,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303463 QDF_DMA_TO_DEVICE);
Nirav Shahcbc6d722016-03-01 16:24:53 +05303464 qdf_nbuf_free(bcn->buf);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303465 qdf_mem_free(bcn);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003466 wma->interfaces[tgt_req->vdev_id].beacon = NULL;
3467 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303468 params->status = QDF_STATUS_E_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003469 WMA_LOGA("%s: WMA_DELETE_BSS_REQ timedout", __func__);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303470 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
3471 (void *)params, 0);
Abhishek Singh0d74f9e2017-09-26 14:02:42 +05303472 if (iface->del_staself_req && iface->is_del_sta_defered) {
3473 iface->is_del_sta_defered = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003474 WMA_LOGA("scheduling defered deletion(vdev id %x)",
3475 tgt_req->vdev_id);
3476 wma_vdev_detach(wma, iface->del_staself_req, 1);
3477 }
3478 } else if (tgt_req->msg_type == WMA_DEL_STA_SELF_REQ) {
3479 struct wma_txrx_node *iface =
3480 (struct wma_txrx_node *)tgt_req->user_data;
3481 struct del_sta_self_params *params =
3482 (struct del_sta_self_params *) iface->del_staself_req;
3483
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303484 if (wmi_service_enabled(wma->wmi_handle,
3485 wmi_service_sync_delete_cmds)) {
Dustin Brownec2c92e2017-07-26 11:13:49 -07003486 wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003487 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303488 params->status = QDF_STATUS_E_TIMEOUT;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08003489
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003490 WMA_LOGA("%s: WMA_DEL_STA_SELF_REQ timedout", __func__);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303491 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
3492 wma_trigger_recovery_assert_on_fw_timeout(
3493 WMA_DEL_STA_SELF_REQ);
3494 } else {
Abhishek Singhc614ec42017-04-25 16:17:34 +05303495 wma_send_del_sta_self_resp(iface->del_staself_req);
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303496 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003497 if (iface->addBssStaContext)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303498 qdf_mem_free(iface->addBssStaContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003499 if (iface->staKeyParams)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303500 qdf_mem_free(iface->staKeyParams);
Dustin Brown35b61f62017-08-31 16:03:32 -07003501
3502 wma_vdev_deinit(iface);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303503 qdf_mem_zero(iface, sizeof(*iface));
Dustin Brown35b61f62017-08-31 16:03:32 -07003504 wma_vdev_init(iface);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003505 } else if (tgt_req->msg_type == WMA_ADD_BSS_REQ) {
3506 tpAddBssParams params = (tpAddBssParams) tgt_req->user_data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003507
Krishna Kumaar Natarajan06edf7c2016-11-17 12:21:59 -08003508 params->status = QDF_STATUS_E_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003509 WMA_LOGA("%s: WMA_ADD_BSS_REQ timedout", __func__);
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003510 WMA_LOGD("%s: bssid %pM vdev_id %d", __func__, params->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003511 tgt_req->vdev_id);
Manikandan Mohanb089ed62017-02-13 11:38:14 -08003512 if (wma_crash_on_fw_timeout(wma->fw_timeout_crash) == true) {
Himanshu Agarwal1230ee02018-05-04 00:31:12 +05303513 wma_trigger_recovery_assert_on_fw_timeout(
3514 WMA_ADD_BSS_REQ);
Sandeep Puligillaafa52892016-10-26 19:03:16 -07003515 } else {
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303516 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
3517 (void *)params, 0);
Sandeep Puligillaafa52892016-10-26 19:03:16 -07003518 QDF_ASSERT(0);
3519 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003520 goto free_tgt_req;
Sandeep Puligilla88de6fb2016-09-23 17:08:44 -07003521
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003522 } else if (tgt_req->msg_type == WMA_OCB_SET_CONFIG_CMD) {
3523 struct wma_txrx_node *iface;
3524
3525 WMA_LOGE(FL("Failed to send OCB set config cmd"));
3526 iface = &wma->interfaces[tgt_req->vdev_id];
Mukul Sharmaf9047232017-03-02 16:58:56 +05303527 wma_vdev_set_mlme_state(wma, tgt_req->vdev_id,
3528 WLAN_VDEV_S_STOP);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303529 wma_ocb_set_config_resp(wma, QDF_STATUS_E_TIMEOUT);
Selvaraj, Sridhara0083c42016-06-22 22:15:43 +05303530 } else if (tgt_req->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART) {
3531 WMA_LOGE("Hidden ssid vdev restart Timed Out; vdev_id: %d, type = %d",
3532 tgt_req->vdev_id, tgt_req->type);
Sandeep Puligilla7da86332016-11-10 16:14:40 -08003533 } else if (tgt_req->msg_type == WMA_SET_LINK_STATE) {
3534 tpLinkStateParams params =
3535 (tpLinkStateParams) tgt_req->user_data;
3536
3537 peer = cdp_peer_find_by_addr(soc, pdev, params->bssid, &peer_id);
3538 if (peer) {
3539 WMA_LOGP(FL("Deleting peer %pM vdev id %d"),
3540 params->bssid, tgt_req->vdev_id);
3541 wma_remove_peer(wma, params->bssid, tgt_req->vdev_id,
3542 peer, false);
3543 }
Dustin Brownec2c92e2017-07-26 11:13:49 -07003544 if (wma_send_vdev_down_to_fw(wma, tgt_req->vdev_id) !=
3545 QDF_STATUS_SUCCESS) {
Sandeep Puligilla7da86332016-11-10 16:14:40 -08003546 WMA_LOGE("Failed to send vdev down cmd: vdev %d",
3547 tgt_req->vdev_id);
3548 }
3549 params->status = QDF_STATUS_E_TIMEOUT;
3550 WMA_LOGA("%s: WMA_SET_LINK_STATE timedout vdev %d", __func__,
3551 tgt_req->vdev_id);
3552 wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003553 }
3554free_tgt_req:
Anurag Chouhan210db072016-02-22 18:42:15 +05303555 qdf_mc_timer_destroy(&tgt_req->event_timeout);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303556 qdf_mem_free(tgt_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003557}
3558
3559/**
3560 * wma_fill_vdev_req() - fill vdev request
3561 * @wma: wma handle
3562 * @msg_type: message type
3563 * @type: request type
3564 * @params: request params
3565 * @timeout: timeout value
3566 *
3567 * Return: wma_target_req ptr
3568 */
3569struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma,
3570 uint8_t vdev_id,
3571 uint32_t msg_type, uint8_t type,
3572 void *params, uint32_t timeout)
3573{
3574 struct wma_target_req *req;
Anurag Chouhanffb21542016-02-17 14:33:03 +05303575 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003576
Himanshu Agarwal51d818c2018-04-19 18:16:46 +05303577 if (!cds_is_target_ready()) {
3578 WMA_LOGE("target not ready, drop the request");
3579 return NULL;
3580 }
3581
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303582 req = qdf_mem_malloc(sizeof(*req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003583 if (!req) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003584 WMA_LOGE("%s: Failed to allocate memory for msg %d vdev %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003585 __func__, msg_type, vdev_id);
3586 return NULL;
3587 }
3588
3589 WMA_LOGD("%s: vdev_id %d msg %d", __func__, vdev_id, msg_type);
Abhishek Singhc614ec42017-04-25 16:17:34 +05303590 qdf_spin_lock_bh(&wma->vdev_respq_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003591 req->vdev_id = vdev_id;
3592 req->msg_type = msg_type;
3593 req->type = type;
3594 req->user_data = params;
Anurag Chouhanffb21542016-02-17 14:33:03 +05303595 status = qdf_list_insert_back(&wma->vdev_resp_queue, &req->node);
3596 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303597 qdf_spin_unlock_bh(&wma->vdev_respq_lock);
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -07003598 WMA_LOGE(FL("Failed add request in queue for vdev_id %d type %d"),
3599 vdev_id, type);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303600 qdf_mem_free(req);
Krishna Kumaar Natarajana5c53bd2015-10-27 11:48:27 -07003601 return NULL;
3602 }
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303603 qdf_spin_unlock_bh(&wma->vdev_respq_lock);
Abhishek Singhc614ec42017-04-25 16:17:34 +05303604 qdf_mc_timer_init(&req->event_timeout, QDF_TIMER_TYPE_SW,
3605 wma_vdev_resp_timer, req);
3606 qdf_mc_timer_start(&req->event_timeout, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003607 return req;
3608}
3609
3610/**
3611 * wma_remove_vdev_req() - remove vdev request
3612 * @wma: wma handle
3613 * @vdev_id: vdev id
3614 * @type: type
3615 *
3616 * Return: none
3617 */
3618void wma_remove_vdev_req(tp_wma_handle wma, uint8_t vdev_id,
3619 uint8_t type)
3620{
3621 struct wma_target_req *req_msg;
3622
Kiran Kumar Lokere20804162017-07-17 16:09:04 -07003623 req_msg = wma_find_vdev_req(wma, vdev_id, type, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003624 if (!req_msg)
3625 return;
3626
Anurag Chouhan210db072016-02-22 18:42:15 +05303627 qdf_mc_timer_stop(&req_msg->event_timeout);
3628 qdf_mc_timer_destroy(&req_msg->event_timeout);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303629 qdf_mem_free(req_msg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003630}
3631
3632/**
3633 * wma_vdev_set_bss_params() - BSS set params functions
3634 * @wma: wma handle
3635 * @vdev_id: vdev id
3636 * @beaconInterval: beacon interval
3637 * @dtimPeriod: DTIM period
3638 * @shortSlotTimeSupported: short slot time
3639 * @llbCoexist: llbCoexist
3640 * @maxTxPower: max tx power
3641 *
3642 * Return: none
3643 */
3644static void
3645wma_vdev_set_bss_params(tp_wma_handle wma, int vdev_id,
3646 tSirMacBeaconInterval beaconInterval,
3647 uint8_t dtimPeriod, uint8_t shortSlotTimeSupported,
Amar Singhala297bfa2015-10-15 15:07:29 -07003648 uint8_t llbCoexist, int8_t maxTxPower)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003649{
Govind Singhd76a5b02016-03-08 15:12:14 +05303650 QDF_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003651 uint32_t slot_time;
3652 struct wma_txrx_node *intr = wma->interfaces;
3653
3654 /* Beacon Interval setting */
Govind Singhd76a5b02016-03-08 15:12:14 +05303655 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003656 WMI_VDEV_PARAM_BEACON_INTERVAL,
3657 beaconInterval);
3658
Govind Singhd76a5b02016-03-08 15:12:14 +05303659 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003660 WMA_LOGE("failed to set WMI_VDEV_PARAM_BEACON_INTERVAL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003661 ret = wmi_unified_vdev_set_gtx_cfg_send(wma->wmi_handle, vdev_id,
3662 &intr[vdev_id].config.gtx_info);
Govind Singhd76a5b02016-03-08 15:12:14 +05303663 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003664 WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD");
Govind Singhd76a5b02016-03-08 15:12:14 +05303665 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003666 WMI_VDEV_PARAM_DTIM_PERIOD,
3667 dtimPeriod);
Kiran Kumar Lokere6d3a30d2018-01-15 18:18:29 -08003668 intr[vdev_id].dtimPeriod = dtimPeriod;
Govind Singhd76a5b02016-03-08 15:12:14 +05303669 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003670 WMA_LOGE("failed to set WMI_VDEV_PARAM_DTIM_PERIOD");
3671
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003672 if (!maxTxPower)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003673 WMA_LOGW("Setting Tx power limit to 0");
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003674 WMA_LOGD("Set maxTx pwr [WMI_VDEV_PARAM_TX_PWRLIMIT] to %d",
Padma, Santhosh Kumar29df3622016-08-16 19:15:16 +05303675 maxTxPower);
Govind Singhd76a5b02016-03-08 15:12:14 +05303676 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003677 WMI_VDEV_PARAM_TX_PWRLIMIT,
3678 maxTxPower);
Govind Singhd76a5b02016-03-08 15:12:14 +05303679 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003680 WMA_LOGE("failed to set WMI_VDEV_PARAM_TX_PWRLIMIT");
3681 else
3682 intr[vdev_id].max_tx_power = maxTxPower;
3683
3684 /* Slot time */
3685 if (shortSlotTimeSupported)
3686 slot_time = WMI_VDEV_SLOT_TIME_SHORT;
3687 else
3688 slot_time = WMI_VDEV_SLOT_TIME_LONG;
3689
Govind Singhd76a5b02016-03-08 15:12:14 +05303690 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003691 WMI_VDEV_PARAM_SLOT_TIME,
3692 slot_time);
Govind Singhd76a5b02016-03-08 15:12:14 +05303693 if (QDF_IS_STATUS_ERROR(ret))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003694 WMA_LOGE("failed to set WMI_VDEV_PARAM_SLOT_TIME");
3695
3696 /* Initialize protection mode in case of coexistence */
3697 wma_update_protection_mode(wma, vdev_id, llbCoexist);
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08003698
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003699}
3700
Abhishek Singhcfb44482017-03-10 12:42:37 +05303701#ifdef WLAN_FEATURE_11W
3702static void wma_set_mgmt_frame_protection(tp_wma_handle wma)
3703{
3704 struct pdev_params param = {0};
3705 QDF_STATUS ret;
3706
3707 /*
3708 * when 802.11w PMF is enabled for hw encr/decr
3709 * use hw MFP Qos bits 0x10
3710 */
3711 param.param_id = WMI_PDEV_PARAM_PMF_QOS;
3712 param.param_value = true;
3713 ret = wmi_unified_pdev_param_send(wma->wmi_handle,
3714 &param, WMA_WILDCARD_PDEV_ID);
3715 if (QDF_IS_STATUS_ERROR(ret)) {
3716 WMA_LOGE("%s: Failed to set QOS MFP/PMF (%d)",
3717 __func__, ret);
3718 } else {
3719 WMA_LOGD("%s: QOS MFP/PMF set", __func__);
3720 }
3721}
3722#else
3723static inline void wma_set_mgmt_frame_protection(tp_wma_handle wma)
3724{
3725}
3726#endif /* WLAN_FEATURE_11W */
3727
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003728/**
3729 * wma_add_bss_ap_mode() - process add bss request in ap mode
3730 * @wma: wma handle
3731 * @add_bss: add bss parameters
3732 *
3733 * Return: none
3734 */
3735static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss)
3736{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003737 struct cdp_pdev *pdev;
3738 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003739 struct wma_vdev_start_req req;
Leo Chang96464902016-10-28 11:10:54 -07003740 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741 struct wma_target_req *msg;
3742 uint8_t vdev_id, peer_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303743 QDF_STATUS status;
Amar Singhala297bfa2015-10-15 15:07:29 -07003744 int8_t maxTxPower;
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003745 struct policy_mgr_hw_mode_params hw_mode = {0};
Leo Chang96464902016-10-28 11:10:54 -07003746 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003747
Anurag Chouhan6d760662016-02-20 16:05:43 +05303748 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003749
3750 if (NULL == pdev) {
3751 WMA_LOGE("%s: Failed to get pdev", __func__);
3752 goto send_fail_resp;
3753 }
3754
3755 vdev = wma_find_vdev_by_addr(wma, add_bss->bssId, &vdev_id);
3756 if (!vdev) {
Peng Xu66162de2016-02-11 17:01:20 -08003757 WMA_LOGE("%s: Failed to get vdev handle:"MAC_ADDRESS_STR,
3758 __func__, MAC_ADDR_ARRAY(add_bss->bssId));
3759
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003760 goto send_fail_resp;
3761 }
3762 if (SAP_WPS_DISABLED == add_bss->wps_state)
Mukul Sharma00058692017-01-28 19:04:32 +05303763 pmo_ucfg_disable_wakeup_event(wma->psoc, vdev_id,
3764 (1 << WOW_PROBE_REQ_WPS_IE_EVENT));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003765 wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss);
3766 status = wma_create_peer(wma, pdev, vdev, add_bss->bssId,
3767 WMI_PEER_TYPE_DEFAULT, vdev_id, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303768 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003769 WMA_LOGE("%s: Failed to create peer", __func__);
3770 goto send_fail_resp;
3771 }
3772
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003773 peer = cdp_peer_find_by_addr(soc, pdev,
3774 add_bss->bssId, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003775 if (!peer) {
3776 WMA_LOGE("%s Failed to find peer %pM", __func__,
3777 add_bss->bssId);
3778 goto send_fail_resp;
3779 }
3780 msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
3781 WMA_TARGET_REQ_TYPE_VDEV_START, add_bss,
3782 WMA_VDEV_START_REQUEST_TIMEOUT);
3783 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003784 WMA_LOGE("%s Failed to allocate vdev request vdev_id %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003785 __func__, vdev_id);
3786 goto peer_cleanup;
3787 }
3788
Leo Chang96464902016-10-28 11:10:54 -07003789 add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003790
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303791 qdf_mem_zero(&req, sizeof(req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003792 req.vdev_id = vdev_id;
3793 req.chan = add_bss->currentOperChannel;
3794 req.chan_width = add_bss->ch_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07003795
3796 if (add_bss->ch_width == CH_WIDTH_10MHZ)
3797 req.is_half_rate = 1;
3798 else if (add_bss->ch_width == CH_WIDTH_5MHZ)
3799 req.is_quarter_rate = 1;
3800
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003801 req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
3802 req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
3803 req.vht_capable = add_bss->vhtCapable;
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08003804 wma_update_vdev_he_ops(&req, add_bss);
3805
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003806 req.max_txpow = add_bss->maxTxPower;
3807 maxTxPower = add_bss->maxTxPower;
Abhishek Singhcfb44482017-03-10 12:42:37 +05303808
3809 if (add_bss->rmfEnabled)
3810 wma_set_mgmt_frame_protection(wma);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003811
Krishna Kumaar Natarajanc1ebd992016-11-29 16:20:32 -08003812 req.dot11_mode = add_bss->dot11_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003813 req.beacon_intval = add_bss->beaconInterval;
3814 req.dtim_period = add_bss->dtimPeriod;
Jiachao Wu712d4fd2017-08-23 16:52:34 +08003815 req.beacon_tx_rate = add_bss->beacon_tx_rate;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003816 req.hidden_ssid = add_bss->bHiddenSSIDEn;
3817 req.is_dfs = add_bss->bSpectrumMgtEnabled;
3818 req.oper_mode = BSS_OPERATIONAL_MODE_AP;
3819 req.ssid.length = add_bss->ssId.length;
Arif Hussain671a1902017-03-17 09:08:32 -07003820 req.cac_duration_ms = add_bss->cac_duration_ms;
3821 req.dfs_regdomain = add_bss->dfs_regdomain;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003822 if (req.ssid.length > 0)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303823 qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003824 add_bss->ssId.length);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003825 status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303826 if (!QDF_IS_STATUS_SUCCESS(status))
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003827 WMA_LOGE("policy_mgr_get_current_hw_mode failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003828
Paul Zhang42dade02017-05-12 19:20:37 +08003829 if (add_bss->nss == 2) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003830 req.preferred_rx_streams = 2;
3831 req.preferred_tx_streams = 2;
3832 } else {
3833 req.preferred_rx_streams = 1;
3834 req.preferred_tx_streams = 1;
3835 }
3836
3837 status = wma_vdev_start(wma, &req, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303838 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003839 wma_remove_vdev_req(wma, vdev_id,
3840 WMA_TARGET_REQ_TYPE_VDEV_START);
3841 goto peer_cleanup;
3842 }
3843
3844 wma_vdev_set_bss_params(wma, vdev_id,
3845 add_bss->beaconInterval, add_bss->dtimPeriod,
3846 add_bss->shortSlotTimeSupported,
3847 add_bss->llbCoexist, maxTxPower);
3848
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08003849 wma_vdev_set_he_bss_params(wma, vdev_id, &req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003850 return;
3851
3852peer_cleanup:
3853 wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, false);
3854send_fail_resp:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303855 add_bss->status = QDF_STATUS_E_FAILURE;
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303856 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003857}
3858
3859#ifdef QCA_IBSS_SUPPORT
3860/**
3861 * wma_add_bss_ibss_mode() - process add bss request in IBSS mode
3862 * @wma: wma handle
3863 * @add_bss: add bss parameters
3864 *
3865 * Return: none
3866 */
3867static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
3868{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003869 struct cdp_pdev *pdev;
3870 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871 struct wma_vdev_start_req req;
Leo Chang96464902016-10-28 11:10:54 -07003872 void *peer = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873 struct wma_target_req *msg;
3874 uint8_t vdev_id, peer_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303875 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003876 tSetBssKeyParams key_info;
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003877 struct policy_mgr_hw_mode_params hw_mode = {0};
Leo Chang96464902016-10-28 11:10:54 -07003878 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003879
Krunal Soni2c68f232015-10-26 20:52:51 -07003880 vdev = wma_find_vdev_by_addr(wma, add_bss->selfMacAddr, &vdev_id);
3881 if (!vdev) {
3882 WMA_LOGE("%s: vdev not found for vdev id %d.",
3883 __func__, vdev_id);
3884 goto send_fail_resp;
3885 }
3886 WMA_LOGD("%s: add_bss->sessionId = %d", __func__, vdev_id);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303887 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003888
3889 if (NULL == pdev) {
3890 WMA_LOGE("%s: Failed to get pdev", __func__);
3891 goto send_fail_resp;
3892 }
3893 wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss);
3894
Krunal Soni8c37e322016-02-03 16:08:37 -08003895 /* create ibss bss peer */
3896 status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr,
3897 WMI_PEER_TYPE_DEFAULT, vdev_id,
3898 false);
3899 if (status != QDF_STATUS_SUCCESS) {
3900 WMA_LOGE("%s: Failed to create peer", __func__);
3901 goto send_fail_resp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003902 }
Krunal Soni8c37e322016-02-03 16:08:37 -08003903 WMA_LOGA("IBSS BSS peer created with mac %pM",
3904 add_bss->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003906 peer = cdp_peer_find_by_addr(soc, pdev,
3907 add_bss->selfMacAddr, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003908 if (!peer) {
3909 WMA_LOGE("%s Failed to find peer %pM", __func__,
3910 add_bss->selfMacAddr);
3911 goto send_fail_resp;
3912 }
3913
3914 /* clear leftover ibss keys on bss peer */
3915
3916 WMA_LOGD("%s: ibss bss key clearing", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303917 qdf_mem_set(&key_info, sizeof(key_info), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003918 key_info.smesessionId = vdev_id;
3919 key_info.numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303920 qdf_mem_copy(&wma->ibsskey_info, &key_info, sizeof(tSetBssKeyParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003921
3922 /* start ibss vdev */
3923
3924 add_bss->operMode = BSS_OPERATIONAL_MODE_IBSS;
3925
3926 msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
3927 WMA_TARGET_REQ_TYPE_VDEV_START, add_bss,
3928 WMA_VDEV_START_REQUEST_TIMEOUT);
3929 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07003930 WMA_LOGE("%s Failed to allocate vdev request vdev_id %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003931 __func__, vdev_id);
3932 goto peer_cleanup;
3933 }
3934 WMA_LOGD("%s: vdev start request for IBSS enqueued", __func__);
3935
Leo Chang96464902016-10-28 11:10:54 -07003936 add_bss->staContext.staIdx = cdp_peer_get_local_peer_id(soc, peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003937
3938 /*
3939 * If IBSS Power Save is supported by firmware
3940 * set the IBSS power save params to firmware.
3941 */
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05303942 if (wmi_service_enabled(wma->wmi_handle,
3943 wmi_service_ibss_pwrsave)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003944 status = wma_set_ibss_pwrsave_params(wma, vdev_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303945 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003946 WMA_LOGE("%s: Failed to Set IBSS Power Save Params to firmware",
3947 __func__);
3948 goto peer_cleanup;
3949 }
3950 }
3951
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303952 qdf_mem_zero(&req, sizeof(req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003953 req.vdev_id = vdev_id;
3954 req.chan = add_bss->currentOperChannel;
3955 req.chan_width = add_bss->ch_width;
3956 req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
3957 req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
3958 req.vht_capable = add_bss->vhtCapable;
3959#if defined WLAN_FEATURE_VOWIF
3960 req.max_txpow = add_bss->maxTxPower;
3961#else
3962 req.max_txpow = 0;
3963#endif /* WLAN_FEATURE_VOWIF */
3964 req.beacon_intval = add_bss->beaconInterval;
3965 req.dtim_period = add_bss->dtimPeriod;
3966 req.hidden_ssid = add_bss->bHiddenSSIDEn;
3967 req.is_dfs = add_bss->bSpectrumMgtEnabled;
3968 req.oper_mode = BSS_OPERATIONAL_MODE_IBSS;
3969 req.ssid.length = add_bss->ssId.length;
3970 if (req.ssid.length > 0)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303971 qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003972 add_bss->ssId.length);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003973 status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303974 if (!QDF_IS_STATUS_SUCCESS(status))
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003975 WMA_LOGE("policy_mgr_get_current_hw_mode failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003976
Paul Zhang42dade02017-05-12 19:20:37 +08003977 if (add_bss->nss == 2) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003978 req.preferred_rx_streams = 2;
3979 req.preferred_tx_streams = 2;
3980 } else {
3981 req.preferred_rx_streams = 1;
3982 req.preferred_tx_streams = 1;
3983 }
3984
3985 WMA_LOGD("%s: chan %d chan_width %d", __func__, req.chan,
3986 req.chan_width);
3987 WMA_LOGD("%s: ssid = %s", __func__, req.ssid.ssId);
3988
3989 status = wma_vdev_start(wma, &req, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303990 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003991 wma_remove_vdev_req(wma, vdev_id,
3992 WMA_TARGET_REQ_TYPE_VDEV_START);
3993 goto peer_cleanup;
3994 }
3995 WMA_LOGD("%s: vdev start request for IBSS sent to target", __func__);
3996
3997 /* Initialize protection mode to no protection */
Govind Singhd76a5b02016-03-08 15:12:14 +05303998 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
3999 WMI_VDEV_PARAM_PROTECTION_MODE,
4000 IEEE80211_PROT_NONE);
4001 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004002 WMA_LOGE("Failed to initialize protection mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004003
4004 return;
4005
4006peer_cleanup:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004007 if (peer)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004008 wma_remove_peer(wma, add_bss->bssId, vdev_id, peer, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004009send_fail_resp:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304010 add_bss->status = QDF_STATUS_E_FAILURE;
Abhishek Singh2d775fd2017-08-18 10:51:33 +05304011 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004012}
4013#endif /* QCA_IBSS_SUPPORT */
4014
4015/**
4016 * wma_add_bss_sta_mode() - process add bss request in sta mode
4017 * @wma: wma handle
4018 * @add_bss: add bss parameters
4019 *
4020 * Return: none
4021 */
4022static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
4023{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004024 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004025 struct wma_vdev_start_req req;
4026 struct wma_target_req *msg;
Leo Chang96464902016-10-28 11:10:54 -07004027 uint8_t vdev_id = 0, peer_id;
Amar Singhal4c3fbb42018-01-02 13:20:28 -08004028 void *peer = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304029 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004030 struct wma_txrx_node *iface;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004031 int pps_val = 0;
4032 bool roam_synch_in_progress = false;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304033 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07004034 struct policy_mgr_hw_mode_params hw_mode = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004035 bool peer_assoc_sent = false;
Leo Chang96464902016-10-28 11:10:54 -07004036 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004037
4038 if (NULL == pMac) {
4039 WMA_LOGE("%s: Unable to get PE context", __func__);
4040 goto send_fail_resp;
4041 }
4042
Anurag Chouhan6d760662016-02-20 16:05:43 +05304043 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004044
4045 if (NULL == pdev) {
4046 WMA_LOGE("%s Failed to get pdev", __func__);
4047 goto send_fail_resp;
4048 }
4049
Leo Chang96464902016-10-28 11:10:54 -07004050 vdev_id = add_bss->staContext.smesessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004051 iface = &wma->interfaces[vdev_id];
4052
4053 wma_set_bss_rate_flags(iface, add_bss);
4054 if (add_bss->operMode) {
4055 /* Save parameters later needed by WMA_ADD_STA_REQ */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004056 if (iface->addBssStaContext)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304057 qdf_mem_free(iface->addBssStaContext);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304058 iface->addBssStaContext = qdf_mem_malloc(sizeof(tAddStaParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004059 if (!iface->addBssStaContext) {
4060 WMA_LOGE("%s Failed to allocat memory", __func__);
4061 goto send_fail_resp;
4062 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304063 qdf_mem_copy(iface->addBssStaContext, &add_bss->staContext,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004064 sizeof(tAddStaParams));
4065
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066 if (iface->staKeyParams) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304067 qdf_mem_free(iface->staKeyParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004068 iface->staKeyParams = NULL;
4069 }
4070 if (add_bss->extSetStaKeyParamValid) {
4071 iface->staKeyParams =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304072 qdf_mem_malloc(sizeof(tSetStaKeyParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004073 if (!iface->staKeyParams) {
4074 WMA_LOGE("%s Failed to allocat memory",
4075 __func__);
4076 goto send_fail_resp;
4077 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304078 qdf_mem_copy(iface->staKeyParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004079 &add_bss->extSetStaKeyParam,
4080 sizeof(tSetStaKeyParams));
4081 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082 /* Save parameters later needed by WMA_ADD_STA_REQ */
4083 iface->rmfEnabled = add_bss->rmfEnabled;
4084 iface->beaconInterval = add_bss->beaconInterval;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004085 iface->llbCoexist = add_bss->llbCoexist;
4086 iface->shortSlotTimeSupported = add_bss->shortSlotTimeSupported;
4087 iface->nwType = add_bss->nwType;
4088 if (add_bss->nonRoamReassoc) {
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004089 peer = cdp_peer_find_by_addr(soc,
4090 pdev, add_bss->bssId,
4091 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004092 if (peer) {
4093 add_bss->staContext.staIdx =
Leo Chang96464902016-10-28 11:10:54 -07004094 cdp_peer_get_local_peer_id(soc, peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004095 goto send_bss_resp;
4096 }
4097 }
4098 if (add_bss->reassocReq) {
4099#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004100 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004101#endif
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004102 /* Called in preassoc state. BSSID peer is already
4103 * added by set_linkstate
4104 */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004105 peer = cdp_peer_find_by_addr(soc,
4106 pdev,
4107 add_bss->bssId,
4108 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004109 if (!peer) {
4110 WMA_LOGE("%s Failed to find peer %pM", __func__,
4111 add_bss->bssId);
4112 goto send_fail_resp;
4113 }
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004114 if (wma_is_roam_synch_in_progress(wma, vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004115 add_bss->staContext.staIdx =
Leo Chang96464902016-10-28 11:10:54 -07004116 cdp_peer_get_local_peer_id(soc, peer);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004117 WMA_LOGD("LFR3:%s: bssid %pM staIdx %d",
4118 __func__, add_bss->bssId,
4119 add_bss->staContext.staIdx);
4120 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004121 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004122 msg = wma_fill_vdev_req(wma, vdev_id, WMA_ADD_BSS_REQ,
4123 WMA_TARGET_REQ_TYPE_VDEV_START,
4124 add_bss,
4125 WMA_VDEV_START_REQUEST_TIMEOUT);
4126 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004127 WMA_LOGE("%s Failed to allocate vdev request vdev_id %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004128 __func__, vdev_id);
4129 goto peer_cleanup;
4130 }
4131
4132 add_bss->staContext.staIdx =
Leo Chang96464902016-10-28 11:10:54 -07004133 cdp_peer_get_local_peer_id(soc, peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004134
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304135 qdf_mem_zero(&req, sizeof(req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004136 req.vdev_id = vdev_id;
4137 req.chan = add_bss->currentOperChannel;
4138 req.chan_width = add_bss->ch_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07004139
4140 if (add_bss->ch_width == CH_WIDTH_10MHZ)
4141 req.is_half_rate = 1;
4142 else if (add_bss->ch_width == CH_WIDTH_5MHZ)
4143 req.is_quarter_rate = 1;
4144
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004145 req.ch_center_freq_seg0 = add_bss->ch_center_freq_seg0;
4146 req.ch_center_freq_seg1 = add_bss->ch_center_freq_seg1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004147 req.max_txpow = add_bss->maxTxPower;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004148 req.beacon_intval = add_bss->beaconInterval;
4149 req.dtim_period = add_bss->dtimPeriod;
4150 req.hidden_ssid = add_bss->bHiddenSSIDEn;
4151 req.is_dfs = add_bss->bSpectrumMgtEnabled;
4152 req.ssid.length = add_bss->ssId.length;
4153 req.oper_mode = BSS_OPERATIONAL_MODE_STA;
4154 if (req.ssid.length > 0)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304155 qdf_mem_copy(req.ssid.ssId, add_bss->ssId.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004156 add_bss->ssId.length);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07004157 status = policy_mgr_get_current_hw_mode(wma->psoc,
4158 &hw_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304159 if (!QDF_IS_STATUS_SUCCESS(status))
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07004160 WMA_LOGE("policy_mgr_get_current_hw_mode failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004161
Paul Zhang42dade02017-05-12 19:20:37 +08004162 if (add_bss->nss == 2) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004163 req.preferred_rx_streams = 2;
4164 req.preferred_tx_streams = 2;
4165 } else {
4166 req.preferred_rx_streams = 1;
4167 req.preferred_tx_streams = 1;
4168 }
4169
4170 status = wma_vdev_start(wma, &req, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304171 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004172 wma_remove_vdev_req(wma, vdev_id,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004173 WMA_TARGET_REQ_TYPE_VDEV_START);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004174 goto peer_cleanup;
4175 }
4176#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
4177 vdev = wma_find_vdev_by_id(wma, vdev_id);
4178 if (!vdev) {
4179 WMA_LOGE("%s Invalid txrx vdev", __func__);
4180 goto peer_cleanup;
4181 }
Leo Chang96464902016-10-28 11:10:54 -07004182 cdp_fc_vdev_pause(soc, vdev,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004183 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184#endif
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004185 /* ADD_BSS_RESP will be deferred to completion of
4186 * VDEV_START
4187 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004188 return;
4189 }
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004190 if (!add_bss->updateBss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004191 goto send_bss_resp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004192 /* Update peer state */
4193 if (add_bss->staContext.encryptType == eSIR_ED_NONE) {
4194 WMA_LOGD("%s: Update peer(%pM) state into auth",
4195 __func__, add_bss->bssId);
Leo Chang96464902016-10-28 11:10:54 -07004196 cdp_peer_state_update(soc, pdev, add_bss->bssId,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08004197 OL_TXRX_PEER_STATE_AUTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004198 } else {
4199#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004200 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004201#endif
4202 WMA_LOGD("%s: Update peer(%pM) state into conn",
4203 __func__, add_bss->bssId);
Leo Chang96464902016-10-28 11:10:54 -07004204 cdp_peer_state_update(soc, pdev, add_bss->bssId,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08004205 OL_TXRX_PEER_STATE_CONN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004206#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Leo Chang96464902016-10-28 11:10:54 -07004207 peer = cdp_peer_find_by_addr(soc, pdev, add_bss->bssId,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004208 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004209 if (!peer) {
4210 WMA_LOGE("%s:%d Failed to find peer %pM",
4211 __func__, __LINE__, add_bss->bssId);
4212 goto send_fail_resp;
4213 }
4214
4215 vdev = wma_find_vdev_by_id(wma, vdev_id);
4216 if (!vdev) {
4217 WMA_LOGE("%s Invalid txrx vdev", __func__);
4218 goto peer_cleanup;
4219 }
Leo Chang96464902016-10-28 11:10:54 -07004220 cdp_fc_vdev_pause(soc, vdev,
4221 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004222#endif
4223 }
4224
4225 wmi_unified_send_txbf(wma, &add_bss->staContext);
4226
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004227 pps_val = ((pMac->enable5gEBT << 31) & 0xffff0000) |
4228 (PKT_PWR_SAVE_5G_EBT & 0xffff);
Govind Singhd76a5b02016-03-08 15:12:14 +05304229 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004230 WMI_VDEV_PARAM_PACKET_POWERSAVE,
4231 pps_val);
Govind Singhd76a5b02016-03-08 15:12:14 +05304232 if (QDF_IS_STATUS_ERROR(status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004233 WMA_LOGE("Failed to send wmi packet power save cmd");
4234 else
Govind Singhd76a5b02016-03-08 15:12:14 +05304235 WMA_LOGD("Sent PKT_PWR_SAVE_5G_EBT cmd to target, val = %x, status = %d",
4236 pps_val, status);
Govind Singhb30d4c02016-03-24 11:01:23 +05304237 wma_send_peer_assoc(wma, add_bss->nwType,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004238 &add_bss->staContext);
Naveen Rawatd7734142017-10-27 10:02:40 -07004239 /* we just had peer assoc, so install key will be done later */
Naveen Rawata600b2e2018-03-29 13:41:18 -07004240
4241 if (add_bss->staContext.encryptType != eSIR_ED_NONE)
4242 iface->is_waiting_for_key = true;
4243
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004244 peer_assoc_sent = true;
Abhishek Singhcfb44482017-03-10 12:42:37 +05304245
4246 if (add_bss->rmfEnabled)
4247 wma_set_mgmt_frame_protection(wma);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004248
4249 wma_vdev_set_bss_params(wma, add_bss->staContext.smesessionId,
4250 add_bss->beaconInterval,
4251 add_bss->dtimPeriod,
4252 add_bss->shortSlotTimeSupported,
4253 add_bss->llbCoexist,
4254 add_bss->maxTxPower);
4255
4256 /*
4257 * Store the bssid in interface table, bssid will
4258 * be used during group key setting sta mode.
4259 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304260 qdf_mem_copy(iface->bssid, add_bss->bssId, IEEE80211_ADDR_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004261
4262 }
4263send_bss_resp:
Manikandan Mohan39accff2017-05-02 16:09:00 -07004264
4265 wma_vdev_set_he_config(wma, vdev_id, add_bss);
Sreelakshmi Konamki0d17c6a2017-06-08 12:58:54 +05304266 if (NULL == cdp_peer_find_by_addr(soc, pdev, add_bss->bssId,
4267 &add_bss->staContext.staIdx))
4268 add_bss->status = QDF_STATUS_E_FAILURE;
4269 else
4270 add_bss->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004271 add_bss->bssIdx = add_bss->staContext.smesessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304272 qdf_mem_copy(add_bss->staContext.staMac, add_bss->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004273 sizeof(add_bss->staContext.staMac));
4274
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304275 if (!wmi_service_enabled(wma->wmi_handle,
4276 wmi_service_peer_assoc_conf)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277 WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
4278 goto send_final_rsp;
4279 }
4280
4281 /* In case of reassoc, peer assoc cmd will not be sent */
4282 if (!peer_assoc_sent)
4283 goto send_final_rsp;
4284
4285 msg = wma_fill_hold_req(wma, vdev_id, WMA_ADD_BSS_REQ,
4286 WMA_PEER_ASSOC_CNF_START, add_bss,
4287 WMA_PEER_ASSOC_TIMEOUT);
4288 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004289 WMA_LOGE(FL("Failed to allocate request for vdev_id %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004290 vdev_id);
4291 wma_remove_req(wma, vdev_id, WMA_PEER_ASSOC_CNF_START);
4292 goto peer_cleanup;
4293 }
4294 return;
4295
4296send_final_rsp:
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004297 WMA_LOGD("%s: opermode %d update_bss %d nw_type %d bssid %pM staIdx %d status %d",
4298 __func__, add_bss->operMode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004299 add_bss->updateBss, add_bss->nwType, add_bss->bssId,
4300 add_bss->staContext.staIdx, add_bss->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05304301 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004302 return;
4303
4304peer_cleanup:
Amar Singhal4c3fbb42018-01-02 13:20:28 -08004305 if (peer)
4306 wma_remove_peer(wma, add_bss->bssId, vdev_id, peer,
4307 roam_synch_in_progress);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004308send_fail_resp:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304309 add_bss->status = QDF_STATUS_E_FAILURE;
Sandeep Puligilla2ff3ebe2016-08-31 23:55:07 -07004310 if (!wma_is_roam_synch_in_progress(wma, vdev_id))
Abhishek Singh2d775fd2017-08-18 10:51:33 +05304311 wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP,
4312 (void *)add_bss, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004313}
4314
4315/**
4316 * wma_add_bss() - Add BSS request to fw as per opmode
4317 * @wma: wma handle
4318 * @params: add bss params
4319 *
4320 * Return: none
4321 */
4322void wma_add_bss(tp_wma_handle wma, tpAddBssParams params)
4323{
4324 WMA_LOGD("%s: add_bss_param.halPersona = %d",
4325 __func__, params->halPersona);
4326
4327 switch (params->halPersona) {
4328
Anurag Chouhan6d760662016-02-20 16:05:43 +05304329 case QDF_SAP_MODE:
4330 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004331 wma_add_bss_ap_mode(wma, params);
4332 break;
4333
4334#ifdef QCA_IBSS_SUPPORT
Anurag Chouhan6d760662016-02-20 16:05:43 +05304335 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004336 wma_add_bss_ibss_mode(wma, params);
4337 break;
4338#endif
4339
Deepak Dhamdheree2dd5442016-05-27 15:05:51 -07004340 case QDF_NDI_MODE:
4341 wma_add_bss_ndi_mode(wma, params);
4342 break;
4343
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004344 default:
4345 wma_add_bss_sta_mode(wma, params);
4346 break;
4347 }
4348}
4349
4350/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004351 * wma_add_sta_req_ap_mode() - process add sta request in ap mode
4352 * @wma: wma handle
4353 * @add_sta: add sta params
4354 *
4355 * Return: none
4356 */
4357static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
4358{
Dhanashri Atreb08959a2016-03-01 17:28:03 -08004359 enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004360 struct cdp_pdev *pdev;
4361 struct cdp_vdev *vdev;
Leo Chang96464902016-10-28 11:10:54 -07004362 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004363 uint8_t peer_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304364 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004365 int32_t ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004366 struct wma_txrx_node *iface = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004367 struct wma_target_req *msg;
4368 bool peer_assoc_cnf = false;
Leo Chang96464902016-10-28 11:10:54 -07004369 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
lifeng13a89d72017-05-10 14:49:29 +08004370 uint32_t mcs_limit, i, j;
4371 uint8_t *rate_pos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004372
Anurag Chouhan6d760662016-02-20 16:05:43 +05304373 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004374
4375 if (NULL == pdev) {
4376 WMA_LOGE("%s: Failed to find pdev", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304377 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004378 goto send_rsp;
4379 }
4380 /* UMAC sends WMA_ADD_STA_REQ msg twice to WMA when the station
4381 * associates. First WMA_ADD_STA_REQ will have staType as
4382 * STA_ENTRY_PEER and second posting will have STA_ENTRY_SELF.
4383 * Peer creation is done in first WMA_ADD_STA_REQ and second
4384 * WMA_ADD_STA_REQ which has STA_ENTRY_SELF is ignored and
4385 * send fake response with success to UMAC. Otherwise UMAC
4386 * will get blocked.
4387 */
4388 if (add_sta->staType != STA_ENTRY_PEER) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304389 add_sta->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004390 goto send_rsp;
4391 }
4392
4393 vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId);
4394 if (!vdev) {
4395 WMA_LOGE("%s: Failed to find vdev", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304396 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004397 goto send_rsp;
4398 }
4399
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004400 iface = &wma->interfaces[add_sta->smesessionId];
Leo Chang96464902016-10-28 11:10:54 -07004401 peer = cdp_peer_find_by_addr_and_vdev(soc, pdev, vdev,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004402 add_sta->staMac, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004403 if (peer) {
4404 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4405 peer, false);
4406 WMA_LOGE("%s: Peer already exists, Deleted peer with peer_addr %pM",
4407 __func__, add_sta->staMac);
4408 }
Liangwei Dong7d845112016-09-27 22:24:21 -04004409 /* The code above only checks the peer existence on its own vdev.
4410 * Need to check whether the peer exists on other vDevs because firmware
4411 * can't create the peer if the peer with same MAC address already
4412 * exists on the pDev. As this peer belongs to other vDevs, just return
4413 * here.
4414 */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004415 peer = cdp_peer_find_by_addr(soc, pdev,
4416 add_sta->staMac, &peer_id);
Liangwei Dong7d845112016-09-27 22:24:21 -04004417 if (peer) {
Jeff Johnsonadba3962017-09-18 08:12:35 -07004418 WMA_LOGE("%s: My vdev:%pK, but Peer exists on other vdev with peer_addr %pM and peer_id %d",
Leo Chang96464902016-10-28 11:10:54 -07004419 __func__, vdev, add_sta->staMac, peer_id);
Liangwei Dong7d845112016-09-27 22:24:21 -04004420 add_sta->status = QDF_STATUS_E_FAILURE;
4421 goto send_rsp;
4422 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004423
4424 status = wma_create_peer(wma, pdev, vdev, add_sta->staMac,
4425 WMI_PEER_TYPE_DEFAULT, add_sta->smesessionId,
4426 false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304427 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004428 WMA_LOGE("%s: Failed to create peer for %pM",
4429 __func__, add_sta->staMac);
4430 add_sta->status = status;
4431 goto send_rsp;
4432 }
4433
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004434 peer = cdp_peer_find_by_addr_and_vdev(soc, pdev,
4435 vdev,
4436 add_sta->staMac, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004437 if (!peer) {
4438 WMA_LOGE("%s: Failed to find peer handle using peer mac %pM",
4439 __func__, add_sta->staMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304440 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004441 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4442 peer, false);
4443 goto send_rsp;
4444 }
4445
4446 wmi_unified_send_txbf(wma, add_sta);
4447
lifeng13a89d72017-05-10 14:49:29 +08004448 /*
4449 * Get MCS limit from ini configure, and map it to rate parameters
4450 * This will limit HT rate upper bound. CFG_CTRL_MASK is used to
4451 * check whether ini config is enabled and CFG_DATA_MASK to get the
4452 * MCS value.
4453 */
4454#define CFG_CTRL_MASK 0xFF00
4455#define CFG_DATA_MASK 0x00FF
4456
4457 if (wlan_cfg_get_int(wma->mac_context, WNI_CFG_SAP_MAX_MCS_DATA,
4458 &mcs_limit) != eSIR_SUCCESS) {
4459 mcs_limit = WNI_CFG_SAP_MAX_MCS_DATA_STADEF;
4460 }
4461
4462 if (mcs_limit & CFG_CTRL_MASK) {
4463 WMA_LOGD("%s: set mcs_limit %x", __func__, mcs_limit);
4464
4465 mcs_limit &= CFG_DATA_MASK;
4466 rate_pos = (u_int8_t *)add_sta->supportedRates.supportedMCSSet;
4467 for (i = 0, j = 0; i < MAX_SUPPORTED_RATES;) {
4468 if (j < mcs_limit / 8) {
4469 rate_pos[j] = 0xff;
4470 j++;
4471 i += 8;
4472 } else if (j < mcs_limit / 8 + 1) {
4473 if (i <= mcs_limit)
4474 rate_pos[i / 8] |= 1 << (i % 8);
4475 else
4476 rate_pos[i / 8] &= ~(1 << (i % 8));
4477 i++;
4478
4479 if (i >= (j + 1) * 8)
4480 j++;
4481 } else {
4482 rate_pos[j++] = 0;
4483 i += 8;
4484 }
4485 }
4486 }
4487
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304488 if (wmi_service_enabled(wma->wmi_handle,
4489 wmi_service_peer_assoc_conf)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004490 peer_assoc_cnf = true;
4491 msg = wma_fill_hold_req(wma, add_sta->smesessionId,
4492 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
4493 add_sta, WMA_PEER_ASSOC_TIMEOUT);
4494 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004495 WMA_LOGE(FL("Failed to alloc request for vdev_id %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004496 add_sta->smesessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304497 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004498 wma_remove_req(wma, add_sta->smesessionId,
4499 WMA_PEER_ASSOC_CNF_START);
4500 wma_remove_peer(wma, add_sta->staMac,
4501 add_sta->smesessionId, peer, false);
4502 peer_assoc_cnf = false;
4503 goto send_rsp;
4504 }
4505 } else {
4506 WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
4507 }
4508
Govind Singhb30d4c02016-03-24 11:01:23 +05304509 ret = wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004510 if (ret) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304511 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004512 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
4513 peer, false);
4514 goto send_rsp;
4515 }
4516#ifdef QCA_IBSS_SUPPORT
4517 /*
4518 * In IBSS mode send the peer
4519 * Atim Window length if IBSS
4520 * power save is enabled by the
4521 * firmware.
4522 */
4523 if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId) &&
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304524 wmi_service_enabled(wma->wmi_handle,
4525 wmi_service_ibss_pwrsave)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004526 /*
4527 * If ATIM Window is present in the peer
4528 * beacon then send it to firmware else
4529 * configure Zero ATIM Window length to
4530 * firmware.
4531 */
4532 if (add_sta->atimIePresent) {
4533 wma_set_peer_param(wma, add_sta->staMac,
4534 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH,
4535 add_sta->peerAtimWindowLength,
4536 add_sta->smesessionId);
4537 } else {
4538 wma_set_peer_param(wma, add_sta->staMac,
4539 WMI_PEER_IBSS_ATIM_WINDOW_LENGTH,
4540 0, add_sta->smesessionId);
4541 }
4542 }
4543#endif
4544
Abhishek Singhd7bc9132017-05-17 13:59:04 +05304545 iface->rmfEnabled = add_sta->rmfEnabled;
Abhishek Singhcfb44482017-03-10 12:42:37 +05304546 if (add_sta->rmfEnabled)
4547 wma_set_mgmt_frame_protection(wma);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004548
4549 if (add_sta->uAPSD) {
Govind Singhd76a5b02016-03-08 15:12:14 +05304550 status = wma_set_ap_peer_uapsd(wma, add_sta->smesessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004551 add_sta->staMac,
4552 add_sta->uAPSD, add_sta->maxSPLen);
Govind Singhd76a5b02016-03-08 15:12:14 +05304553 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004554 WMA_LOGE("Failed to set peer uapsd param for %pM",
4555 add_sta->staMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304556 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004557 wma_remove_peer(wma, add_sta->staMac,
4558 add_sta->smesessionId, peer, false);
4559 goto send_rsp;
4560 }
4561 }
4562
4563 WMA_LOGD("%s: Moving peer %pM to state %d",
4564 __func__, add_sta->staMac, state);
Leo Chang96464902016-10-28 11:10:54 -07004565 cdp_peer_state_update(soc, pdev, add_sta->staMac, state);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004566
Leo Chang96464902016-10-28 11:10:54 -07004567 add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05304568 add_sta->nss = iface->nss;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304569 add_sta->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004570send_rsp:
4571 /* Do not send add stat resp when peer assoc cnf is enabled */
4572 if (peer_assoc_cnf) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004573 WMA_LOGD(FL("WMI_SERVICE_PEER_ASSOC_CONF is enabled"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004574 return;
4575 }
4576
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004577 WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004578 add_sta->staType, add_sta->smesessionId,
4579 add_sta->assocId, add_sta->bssId, add_sta->staIdx,
4580 add_sta->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05304581 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004582}
4583
4584#ifdef FEATURE_WLAN_TDLS
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304585
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004586/**
4587 * wma_add_tdls_sta() - process add sta request in TDLS mode
4588 * @wma: wma handle
4589 * @add_sta: add sta params
4590 *
4591 * Return: none
4592 */
4593static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta)
4594{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004595 struct cdp_pdev *pdev;
4596 struct cdp_vdev *vdev;
Leo Chang96464902016-10-28 11:10:54 -07004597 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004598 uint8_t peer_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304599 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004600 int32_t ret;
4601 tTdlsPeerStateParams *peerStateParams;
4602 struct wma_target_req *msg;
4603 bool peer_assoc_cnf = false;
Leo Chang96464902016-10-28 11:10:54 -07004604 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004605
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004606 WMA_LOGD("%s: staType: %d, staIdx: %d, updateSta: %d, bssId: %pM, staMac: %pM",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004607 __func__, add_sta->staType, add_sta->staIdx,
4608 add_sta->updateSta, add_sta->bssId, add_sta->staMac);
4609
Anurag Chouhan6d760662016-02-20 16:05:43 +05304610 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004611
4612 if (NULL == pdev) {
4613 WMA_LOGE("%s: Failed to find pdev", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304614 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004615 goto send_rsp;
4616 }
4617
4618 vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId);
4619 if (!vdev) {
4620 WMA_LOGE("%s: Failed to find vdev", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304621 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004622 goto send_rsp;
4623 }
4624
Nitesh Shah622d3122017-06-05 17:04:06 +05304625 if (wma_is_roam_synch_in_progress(wma, add_sta->smesessionId)) {
4626 WMA_LOGE("%s: roaming in progress, reject add sta!", __func__);
4627 add_sta->status = QDF_STATUS_E_PERM;
4628 goto send_rsp;
4629 }
4630
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004631 if (0 == add_sta->updateSta) {
4632 /* its a add sta request * */
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304633
Leo Chang96464902016-10-28 11:10:54 -07004634 cdp_peer_copy_mac_addr_raw(soc, vdev, add_sta->bssId);
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304635
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004636 WMA_LOGD("%s: addSta, calling wma_create_peer for %pM, vdev_id %hu",
4637 __func__, add_sta->staMac, add_sta->smesessionId);
4638
4639 status = wma_create_peer(wma, pdev, vdev, add_sta->staMac,
4640 WMI_PEER_TYPE_TDLS,
4641 add_sta->smesessionId, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304642 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004643 WMA_LOGE("%s: Failed to create peer for %pM",
4644 __func__, add_sta->staMac);
4645 add_sta->status = status;
4646 goto send_rsp;
4647 }
4648
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004649 peer = cdp_peer_find_by_addr(soc, pdev,
4650 add_sta->staMac,
4651 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004652 if (!peer) {
4653 WMA_LOGE("%s: addSta, failed to find peer handle for mac %pM",
4654 __func__, add_sta->staMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304655 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004656 wma_remove_peer(wma, add_sta->staMac,
4657 add_sta->smesessionId, peer, false);
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304658
Leo Chang96464902016-10-28 11:10:54 -07004659 cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004660 goto send_rsp;
4661 }
4662
Leo Chang96464902016-10-28 11:10:54 -07004663 add_sta->staIdx = cdp_peer_get_local_peer_id(soc, peer);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004664 WMA_LOGD("%s: addSta, after calling cdp_local_peer_id, staIdx: %d, staMac: %pM",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004665 __func__, add_sta->staIdx, add_sta->staMac);
4666
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304667 peerStateParams = qdf_mem_malloc(sizeof(tTdlsPeerStateParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004668 if (!peerStateParams) {
4669 WMA_LOGE
4670 ("%s: Failed to allocate memory for peerStateParams for %pM",
4671 __func__, add_sta->staMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304672 add_sta->status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004673 goto send_rsp;
4674 }
4675
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004676 peerStateParams->peerState = WMI_TDLS_PEER_STATE_PEERING;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004677 peerStateParams->vdevId = add_sta->smesessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304678 qdf_mem_copy(&peerStateParams->peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004679 &add_sta->staMac, sizeof(tSirMacAddr));
4680 wma_update_tdls_peer_state(wma, peerStateParams);
4681 } else {
4682 /* its a change sta request * */
4683 peer =
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004684 cdp_peer_find_by_addr(soc, pdev,
4685 add_sta->staMac,
4686 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004687 if (!peer) {
4688 WMA_LOGE("%s: changeSta,failed to find peer handle for mac %pM",
4689 __func__, add_sta->staMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304690 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004691 wma_remove_peer(wma, add_sta->staMac,
4692 add_sta->smesessionId, peer, false);
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304693
Leo Chang96464902016-10-28 11:10:54 -07004694 cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id);
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304695
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004696 goto send_rsp;
4697 }
4698
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304699 if (wmi_service_enabled(wma->wmi_handle,
4700 wmi_service_peer_assoc_conf)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004701 WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF is enabled"));
4702 peer_assoc_cnf = true;
4703 msg = wma_fill_hold_req(wma, add_sta->smesessionId,
4704 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
4705 add_sta, WMA_PEER_ASSOC_TIMEOUT);
4706 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004707 WMA_LOGE(FL("Failed to alloc request for vdev_id %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004708 add_sta->smesessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304709 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004710 wma_remove_req(wma, add_sta->smesessionId,
4711 WMA_PEER_ASSOC_CNF_START);
4712 wma_remove_peer(wma, add_sta->staMac,
4713 add_sta->smesessionId, peer, false);
4714 peer_assoc_cnf = false;
4715 goto send_rsp;
4716 }
4717 } else {
4718 WMA_LOGE(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
4719 }
4720
Govind Singhb30d4c02016-03-24 11:01:23 +05304721 WMA_LOGD("%s: changeSta, calling wma_send_peer_assoc",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004722 __func__);
4723
4724 ret =
Govind Singhb30d4c02016-03-24 11:01:23 +05304725 wma_send_peer_assoc(wma, add_sta->nwType, add_sta);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004726 if (ret) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304727 add_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004728 wma_remove_peer(wma, add_sta->staMac,
4729 add_sta->smesessionId, peer, false);
Leo Chang96464902016-10-28 11:10:54 -07004730 cdp_peer_add_last_real_peer(soc, pdev, vdev, &peer_id);
Poddar, Siddarth5a91f5b2016-04-28 12:24:10 +05304731
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004732 goto send_rsp;
4733 }
4734 }
4735
4736send_rsp:
4737 /* Do not send add stat resp when peer assoc cnf is enabled */
4738 if (peer_assoc_cnf)
4739 return;
4740
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004741 WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004742 add_sta->staType, add_sta->smesessionId,
4743 add_sta->assocId, add_sta->bssId, add_sta->staIdx,
4744 add_sta->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05304745 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004746}
4747#endif
4748
4749/**
Arif Hussain05fb4872018-01-03 16:02:55 -08004750 * wma_send_bss_color_change_enable() - send bss color chnage enable cmd.
4751 * @wma: wma handle
4752 * @params: add sta params
4753 *
4754 * Send bss color change command to firmware, to enable firmware to update
4755 * internally if any change in bss color in advertised by associated AP.
4756 *
4757 * Return: none
4758 */
4759#ifdef WLAN_FEATURE_11AX
4760static void wma_send_bss_color_change_enable(tp_wma_handle wma,
4761 tpAddStaParams params)
4762{
4763 QDF_STATUS status;
4764 uint32_t vdev_id = params->smesessionId;
4765
4766 if (!params->he_capable) {
4767 WMA_LOGD("%s: he_capable is not set for vdev_id:%d",
4768 __func__, vdev_id);
4769 return;
4770 }
4771
4772 status = wmi_unified_send_bss_color_change_enable_cmd(wma->wmi_handle,
4773 vdev_id,
4774 true);
4775 if (QDF_IS_STATUS_ERROR(status)) {
4776 WMA_LOGE("Failed to enable bss color change offload, vdev:%d",
4777 vdev_id);
4778 }
4779
4780 return;
4781}
4782#else
4783static void wma_send_bss_color_change_enable(tp_wma_handle wma,
4784 tpAddStaParams params)
4785{
4786}
4787#endif
4788
4789/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004790 * wma_add_sta_req_sta_mode() - process add sta request in sta mode
4791 * @wma: wma handle
Arif Hussain05fb4872018-01-03 16:02:55 -08004792 * @params: add sta params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004793 *
4794 * Return: none
4795 */
4796static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
4797{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004798 struct cdp_pdev *pdev;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304799 QDF_STATUS status = QDF_STATUS_SUCCESS;
Leo Chang96464902016-10-28 11:10:54 -07004800 void *peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004801 struct wma_txrx_node *iface;
Amar Singhala297bfa2015-10-15 15:07:29 -07004802 int8_t maxTxPower;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004803 int ret = 0;
4804 struct wma_target_req *msg;
4805 bool peer_assoc_cnf = false;
Govind Singhd76a5b02016-03-08 15:12:14 +05304806 struct vdev_up_params param = {0};
Archana Ramachandran20d2e232016-02-11 16:58:40 -08004807 int smps_param;
Leo Chang96464902016-10-28 11:10:54 -07004808 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004809
4810#ifdef FEATURE_WLAN_TDLS
4811 if (STA_ENTRY_TDLS_PEER == params->staType) {
4812 wma_add_tdls_sta(wma, params);
4813 return;
4814 }
4815#endif
4816
Anurag Chouhan6d760662016-02-20 16:05:43 +05304817 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004818
4819 if (NULL == pdev) {
4820 WMA_LOGE("%s: Unable to get pdev", __func__);
4821 goto out;
4822 }
4823
4824 iface = &wma->interfaces[params->smesessionId];
4825 if (params->staType != STA_ENTRY_SELF) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004826 WMA_LOGE("%s: unsupported station type %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004827 __func__, params->staType);
4828 goto out;
4829 }
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004830 peer = cdp_peer_find_by_addr(soc,
4831 pdev,
4832 params->bssId, &params->staIdx);
Sandeep Puligilla2ff3ebe2016-08-31 23:55:07 -07004833 if (peer == NULL) {
4834 WMA_LOGE("%s: Peer is not present vdev id %d for %pM", __func__,
4835 params->smesessionId, params->bssId);
4836 status = QDF_STATUS_E_FAILURE;
4837 goto out;
4838 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004839 if (params->nonRoamReassoc) {
Leo Chang96464902016-10-28 11:10:54 -07004840 cdp_peer_state_update(soc, pdev, params->bssId,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08004841 OL_TXRX_PEER_STATE_AUTH);
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05304842 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004843 iface->aid = params->assocId;
4844 goto out;
4845 }
4846
Mukul Sharmaf9047232017-03-02 16:58:56 +05304847 if (wma_is_vdev_up(params->smesessionId)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004848 WMA_LOGE("%s: vdev id %d is already UP for %pM", __func__,
4849 params->smesessionId, params->bssId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304850 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004851 goto out;
4852 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004853
4854 if (peer != NULL &&
Leo Chang96464902016-10-28 11:10:54 -07004855 (cdp_peer_state_get(soc, peer) == OL_TXRX_PEER_STATE_DISC)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004856 /*
4857 * This is the case for reassociation.
4858 * peer state update and peer_assoc is required since it
4859 * was not done by WMA_ADD_BSS_REQ.
4860 */
4861
4862 /* Update peer state */
4863 if (params->encryptType == eSIR_ED_NONE) {
4864 WMA_LOGD("%s: Update peer(%pM) state into auth",
4865 __func__, params->bssId);
Leo Chang96464902016-10-28 11:10:54 -07004866 cdp_peer_state_update(soc, pdev, params->bssId,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08004867 OL_TXRX_PEER_STATE_AUTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004868 } else {
4869 WMA_LOGD("%s: Update peer(%pM) state into conn",
4870 __func__, params->bssId);
Leo Chang96464902016-10-28 11:10:54 -07004871 cdp_peer_state_update(soc, pdev, params->bssId,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08004872 OL_TXRX_PEER_STATE_CONN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004873 }
4874
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004875 if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004876 /* iface->nss = params->nss; */
4877 /*In LFR2.0, the following operations are performed as
Govind Singhb30d4c02016-03-24 11:01:23 +05304878 * part of wma_send_peer_assoc. As we are
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004879 * skipping this operation, we are just executing the
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004880 * following which are useful for LFR3.0
4881 */
Leo Chang96464902016-10-28 11:10:54 -07004882 cdp_peer_state_update(soc, pdev, params->bssId,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08004883 OL_TXRX_PEER_STATE_AUTH);
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05304884 qdf_atomic_set(&iface->bss_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004885 WMA_BSS_STATUS_STARTED);
4886 iface->aid = params->assocId;
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004887 WMA_LOGD("LFR3:statype %d vdev %d aid %d bssid %pM",
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08004888 params->staType, params->smesessionId,
4889 params->assocId, params->bssId);
4890 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004891 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004892 wmi_unified_send_txbf(wma, params);
4893
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304894 if (wmi_service_enabled(wma->wmi_handle,
4895 wmi_service_peer_assoc_conf)) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004896 WMA_LOGD(FL("WMI_SERVICE_PEER_ASSOC_CONF is enabled"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004897 peer_assoc_cnf = true;
4898 msg = wma_fill_hold_req(wma, params->smesessionId,
4899 WMA_ADD_STA_REQ, WMA_PEER_ASSOC_CNF_START,
4900 params, WMA_PEER_ASSOC_TIMEOUT);
4901 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004902 WMA_LOGD(FL("Failed to alloc request for vdev_id %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004903 params->smesessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304904 params->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004905 wma_remove_req(wma, params->smesessionId,
4906 WMA_PEER_ASSOC_CNF_START);
4907 wma_remove_peer(wma, params->staMac,
4908 params->smesessionId, peer, false);
4909 peer_assoc_cnf = false;
4910 goto out;
4911 }
4912 } else {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004913 WMA_LOGD(FL("WMI_SERVICE_PEER_ASSOC_CONF not enabled"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004914 }
4915
Govind Singhb30d4c02016-03-24 11:01:23 +05304916 ret = wma_send_peer_assoc(wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004917 iface->nwType,
4918 (tAddStaParams *) iface->addBssStaContext);
4919 if (ret) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304920 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004921 wma_remove_peer(wma, params->bssId,
4922 params->smesessionId, peer, false);
4923 goto out;
4924 }
Abhishek Singhcfb44482017-03-10 12:42:37 +05304925
4926 if (params->rmfEnabled)
4927 wma_set_mgmt_frame_protection(wma);
4928
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004929 /*
4930 * Set the PTK in 11r mode because we already have it.
4931 */
4932 if (iface->staKeyParams) {
4933 wma_set_stakey(wma,
4934 (tpSetStaKeyParams) iface->staKeyParams);
4935 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004936 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004937 maxTxPower = params->maxTxPower;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004938 wma_vdev_set_bss_params(wma, params->smesessionId,
4939 iface->beaconInterval, iface->dtimPeriod,
4940 iface->shortSlotTimeSupported,
4941 iface->llbCoexist, maxTxPower);
4942
4943 params->csaOffloadEnable = 0;
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304944 if (wmi_service_enabled(wma->wmi_handle,
4945 wmi_service_csa_offload)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004946 params->csaOffloadEnable = 1;
Govind Singhd76a5b02016-03-08 15:12:14 +05304947 if (wma_unified_csa_offload_enable(wma, params->smesessionId) <
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004948 0) {
4949 WMA_LOGE("Unable to enable CSA offload for vdev_id:%d",
4950 params->smesessionId);
4951 }
4952 }
4953
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05304954 if (wmi_service_enabled(wma->wmi_handle,
4955 wmi_service_filter_ipsec_natkeepalive)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004956 if (wmi_unified_nat_keepalive_enable(wma, params->smesessionId)
4957 < 0) {
4958 WMA_LOGE("Unable to enable NAT keepalive for vdev_id:%d",
4959 params->smesessionId);
4960 }
4961 }
4962
Govind Singhd76a5b02016-03-08 15:12:14 +05304963 param.vdev_id = params->smesessionId;
4964 param.assoc_id = params->assocId;
Dustin Brownec2c92e2017-07-26 11:13:49 -07004965 if (wma_send_vdev_up_to_fw(wma, &param, params->bssId) !=
4966 QDF_STATUS_SUCCESS) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07004967 WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004968 __func__, params->smesessionId, params->bssId);
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07004969 policy_mgr_set_do_hw_mode_change_flag(
4970 wma->psoc, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304971 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004972 } else {
Hong Shib90718f2017-02-20 00:57:22 +08004973 wma_set_vdev_mgmt_rate(wma, params->smesessionId);
Mukul Sharmaf9047232017-03-02 16:58:56 +05304974 wma_vdev_set_mlme_state(wma, params->smesessionId,
4975 WLAN_VDEV_S_RUN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004976 }
4977
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05304978 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004979 WMA_LOGD("%s: STA mode (type %d subtype %d) BSS is started",
4980 __func__, iface->type, iface->sub_type);
4981 /* Sta is now associated, configure various params */
4982
Archana Ramachandran20d2e232016-02-11 16:58:40 -08004983 /* Send SMPS force command to FW to send the required
4984 * action frame only when SM power save is enbaled in
Archana Ramachandranfec24812016-02-16 16:31:56 -08004985 * from INI. In case dynamic antenna selection, the
4986 * action frames are sent by the chain mask manager
Archana Ramachandran20d2e232016-02-11 16:58:40 -08004987 * In addition to the action frames, The SM power save is
4988 * published in the assoc request HT SMPS IE for both cases.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004989 */
Archana Ramachandranfec24812016-02-16 16:31:56 -08004990 if ((params->enableHtSmps) && (params->send_smps_action)) {
Archana Ramachandran20d2e232016-02-11 16:58:40 -08004991 smps_param = wma_smps_mode_to_force_mode_param(
4992 params->htSmpsconfig);
4993 if (smps_param >= 0) {
Archana Ramachandranfec24812016-02-16 16:31:56 -08004994 WMA_LOGD("%s: Send SMPS force mode: %d",
Archana Ramachandran20d2e232016-02-11 16:58:40 -08004995 __func__, params->htSmpsconfig);
4996 wma_set_mimops(wma, params->smesessionId,
4997 smps_param);
4998 }
4999 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005000
Arif Hussain05fb4872018-01-03 16:02:55 -08005001 wma_send_bss_color_change_enable(wma, params);
5002
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005003 /* Partial AID match power save, enable when SU bformee */
5004 if (params->enableVhtpAid && params->vhtTxBFCapable)
5005 wma_set_ppsconfig(params->smesessionId,
5006 WMA_VHT_PPS_PAID_MATCH, 1);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005007
5008 /* Enable AMPDU power save, if htCapable/vhtCapable */
5009 if (params->enableAmpduPs && (params->htCapable || params->vhtCapable))
5010 wma_set_ppsconfig(params->smesessionId,
5011 WMA_VHT_PPS_DELIM_CRC_FAIL, 1);
Krunal Soni1fd496d2018-02-02 01:25:19 -08005012 if (WMI_SERVICE_EXT_IS_ENABLED(wma->wmi_service_bitmap,
5013 wma->wmi_service_ext_bitmap,
5014 WMI_SERVICE_LISTEN_INTERVAL_OFFLOAD_SUPPORT)) {
5015 WMA_LOGD("%s: listen interval offload enabled, setting params",
5016 __func__);
5017 status = wma_vdev_set_param(wma->wmi_handle,
5018 params->smesessionId,
5019 WMI_VDEV_PARAM_MAX_LI_OF_MODDTIM,
5020 wma->staMaxLIModDtim);
5021 if (status != QDF_STATUS_SUCCESS) {
5022 WMA_LOGE(FL("can't set MAX_LI for session: %d"),
5023 params->smesessionId);
5024 }
5025 status = wma_vdev_set_param(wma->wmi_handle,
5026 params->smesessionId,
5027 WMI_VDEV_PARAM_DYNDTIM_CNT,
5028 wma->staDynamicDtim);
5029 if (status != QDF_STATUS_SUCCESS) {
5030 WMA_LOGE(FL("can't set DYNDTIM_CNT for session: %d"),
5031 params->smesessionId);
5032 }
5033 status = wma_vdev_set_param(wma->wmi_handle,
5034 params->smesessionId,
5035 WMI_VDEV_PARAM_MODDTIM_CNT,
5036 wma->staModDtim);
5037 if (status != QDF_STATUS_SUCCESS) {
5038 WMA_LOGE(FL("can't set DTIM_CNT for session: %d"),
5039 params->smesessionId);
5040 }
5041
5042 } else {
5043 WMA_LOGD("%s: listen interval offload is not set",
5044 __func__);
5045 }
5046
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005047 iface->aid = params->assocId;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05305048 params->nss = iface->nss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005049out:
5050 /* Do not send add stat resp when peer assoc cnf is enabled */
5051 if (peer_assoc_cnf)
5052 return;
5053
5054 params->status = status;
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07005055 WMA_LOGD(FL("statype %d vdev_id %d aid %d bssid %pM staIdx %d status %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005056 params->staType, params->smesessionId,
5057 params->assocId, params->bssId, params->staIdx,
5058 params->status);
Sandeep Puligilla2ff3ebe2016-08-31 23:55:07 -07005059 /* Don't send a response during roam sync operation */
5060 if (!wma_is_roam_synch_in_progress(wma, params->smesessionId))
Abhishek Singh2d775fd2017-08-18 10:51:33 +05305061 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP,
5062 (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005063}
5064
5065/**
5066 * wma_delete_sta_req_ap_mode() - proces delete sta request from UMAC in AP mode
5067 * @wma: wma handle
5068 * @del_sta: delete sta params
5069 *
5070 * Return: none
5071 */
5072static void wma_delete_sta_req_ap_mode(tp_wma_handle wma,
5073 tpDeleteStaParams del_sta)
5074{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005075 struct cdp_pdev *pdev;
Leo Chang96464902016-10-28 11:10:54 -07005076 void *peer;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08005077 struct wma_target_req *msg;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005078 uint8_t *peer_mac_addr;
Leo Chang96464902016-10-28 11:10:54 -07005079 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005080
Anurag Chouhan6d760662016-02-20 16:05:43 +05305081 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005082
5083 if (NULL == pdev) {
5084 WMA_LOGE("%s: Failed to get pdev", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305085 del_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005086 goto send_del_rsp;
5087 }
5088
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005089 peer = cdp_peer_find_by_local_id(soc,
5090 pdev, del_sta->staIdx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005091 if (!peer) {
5092 WMA_LOGE("%s: Failed to get peer handle using peer id %d",
5093 __func__, del_sta->staIdx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305094 del_sta->status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005095 goto send_del_rsp;
5096 }
Leo Chang96464902016-10-28 11:10:54 -07005097 peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005098
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005099 wma_remove_peer(wma, peer_mac_addr, del_sta->smesessionId, peer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005100 false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305101 del_sta->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005102
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05305103 if (wmi_service_enabled(wma->wmi_handle,
5104 wmi_service_sync_delete_cmds)) {
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08005105 msg = wma_fill_hold_req(wma, del_sta->smesessionId,
5106 WMA_DELETE_STA_REQ,
5107 WMA_DELETE_STA_RSP_START, del_sta,
5108 WMA_DELETE_STA_TIMEOUT);
5109 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07005110 WMA_LOGE(FL("Failed to allocate request. vdev_id %d"),
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08005111 del_sta->smesessionId);
5112 wma_remove_req(wma, del_sta->smesessionId,
5113 WMA_DELETE_STA_RSP_START);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305114 del_sta->status = QDF_STATUS_E_NOMEM;
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08005115 goto send_del_rsp;
5116 }
Dustin Brownec2c92e2017-07-26 11:13:49 -07005117
5118 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
5119 WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
5120
Sandeep Puligilla19ddda22016-01-05 12:18:02 -08005121 return;
5122 }
5123
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005124send_del_rsp:
5125 if (del_sta->respReqd) {
5126 WMA_LOGD("%s: Sending del rsp to umac (status: %d)",
5127 __func__, del_sta->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05305128 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5129 (void *)del_sta, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005130 }
5131}
5132
5133#ifdef FEATURE_WLAN_TDLS
5134/**
5135 * wma_del_tdls_sta() - proces delete sta request from UMAC in TDLS
5136 * @wma: wma handle
5137 * @del_sta: delete sta params
5138 *
5139 * Return: none
5140 */
5141static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
5142{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005143 tTdlsPeerStateParams *peerStateParams;
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305144 struct wma_target_req *msg;
5145 int status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005146
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305147 peerStateParams = qdf_mem_malloc(sizeof(tTdlsPeerStateParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005148 if (!peerStateParams) {
5149 WMA_LOGE("%s: Failed to allocate memory for peerStateParams for: %pM",
5150 __func__, del_sta->staMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305151 del_sta->status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005152 goto send_del_rsp;
5153 }
5154
Nitesh Shah622d3122017-06-05 17:04:06 +05305155 if (wma_is_roam_synch_in_progress(wma, del_sta->smesessionId)) {
5156 WMA_LOGE("%s: roaming in progress, reject del sta!", __func__);
5157 del_sta->status = QDF_STATUS_E_PERM;
5158 goto send_del_rsp;
5159 }
5160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005161 peerStateParams->peerState = WMA_TDLS_PEER_STATE_TEARDOWN;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005162 peerStateParams->vdevId = del_sta->smesessionId;
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305163 peerStateParams->resp_reqd = del_sta->respReqd;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305164 qdf_mem_copy(&peerStateParams->peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005165 &del_sta->staMac, sizeof(tSirMacAddr));
5166
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005167 WMA_LOGD("%s: sending tdls_peer_state for peer mac: %pM, peerState: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005168 __func__, peerStateParams->peerMacAddr,
5169 peerStateParams->peerState);
5170
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305171 status = wma_update_tdls_peer_state(wma, peerStateParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005172
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305173 if (status < 0) {
5174 WMA_LOGE("%s: wma_update_tdls_peer_state returned failure",
5175 __func__);
5176 goto send_del_rsp;
5177 }
5178
5179 if (del_sta->respReqd &&
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05305180 wmi_service_enabled(wma->wmi_handle,
5181 wmi_service_sync_delete_cmds)) {
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305182 del_sta->status = QDF_STATUS_SUCCESS;
5183 msg = wma_fill_hold_req(wma,
5184 del_sta->smesessionId,
5185 WMA_DELETE_STA_REQ,
5186 WMA_DELETE_STA_RSP_START, del_sta,
5187 WMA_DELETE_STA_TIMEOUT);
5188 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07005189 WMA_LOGE(FL("Failed to allocate vdev_id %d"),
Pragaspathi Thilagaraj78474342018-04-11 17:09:28 +05305190 del_sta->smesessionId);
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305191 wma_remove_req(wma,
Pragaspathi Thilagaraj78474342018-04-11 17:09:28 +05305192 del_sta->smesessionId,
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305193 WMA_DELETE_STA_RSP_START);
5194 del_sta->status = QDF_STATUS_E_NOMEM;
5195 goto send_del_rsp;
5196 }
Dustin Brownec2c92e2017-07-26 11:13:49 -07005197
5198 wma_acquire_wakelock(&wma->wmi_cmd_rsp_wake_lock,
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305199 WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
Padma, Santhosh Kumar4eb79082017-02-24 16:00:20 +05305200 }
5201
5202 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005203
5204send_del_rsp:
5205 if (del_sta->respReqd) {
5206 WMA_LOGD("%s: Sending del rsp to umac (status: %d)",
5207 __func__, del_sta->status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05305208 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5209 (void *)del_sta, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005210 }
5211}
5212#endif
5213
5214/**
5215 * wma_delete_sta_req_sta_mode() - proces delete sta request from UMAC
5216 * @wma: wma handle
5217 * @params: delete sta params
5218 *
5219 * Return: none
5220 */
5221static void wma_delete_sta_req_sta_mode(tp_wma_handle wma,
5222 tpDeleteStaParams params)
5223{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305224 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005225 struct wma_txrx_node *iface;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005226
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005227 iface = &wma->interfaces[params->smesessionId];
5228 iface->uapsd_cached_val = 0;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08005229 if (wma_is_roam_synch_in_progress(wma, params->smesessionId))
5230 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005231#ifdef FEATURE_WLAN_TDLS
5232 if (STA_ENTRY_TDLS_PEER == params->staType) {
5233 wma_del_tdls_sta(wma, params);
5234 return;
5235 }
5236#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005237 params->status = status;
5238 if (params->respReqd) {
5239 WMA_LOGD("%s: vdev_id %d status %d", __func__,
5240 params->smesessionId, status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05305241 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP,
5242 (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005243 }
5244}
5245
5246/**
5247 * wma_add_sta() - process add sta request as per opmode
5248 * @wma: wma handle
5249 * @add_Sta: add sta params
5250 *
5251 * Return: none
5252 */
5253void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta)
5254{
5255 uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
Arunk Khandavallia6305a32018-01-25 11:19:18 +05305256 void *htc_handle;
5257
Sourav Mohapatracf632572018-04-02 11:01:35 +05305258 htc_handle = lmac_get_htc_hdl(wma->psoc);
Arunk Khandavallia6305a32018-01-25 11:19:18 +05305259 if (!htc_handle) {
5260 WMA_LOGE(":%sHTC handle is NULL:%d", __func__, __LINE__);
5261 return;
5262 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005263
5264 WMA_LOGD("%s: add_sta->sessionId = %d.", __func__,
5265 add_sta->smesessionId);
5266 WMA_LOGD("%s: add_sta->bssId = %x:%x:%x:%x:%x:%x", __func__,
5267 add_sta->bssId[0], add_sta->bssId[1], add_sta->bssId[2],
5268 add_sta->bssId[3], add_sta->bssId[4], add_sta->bssId[5]);
5269
5270 if (wma_is_vdev_in_ap_mode(wma, add_sta->smesessionId))
5271 oper_mode = BSS_OPERATIONAL_MODE_AP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005272 else if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId))
5273 oper_mode = BSS_OPERATIONAL_MODE_IBSS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005274
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07005275 if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, add_sta->smesessionId))
5276 oper_mode = BSS_OPERATIONAL_MODE_NDI;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005277 switch (oper_mode) {
5278 case BSS_OPERATIONAL_MODE_STA:
5279 wma_add_sta_req_sta_mode(wma, add_sta);
5280 break;
5281
Houston Hoffman79b4af22015-10-06 12:01:08 -07005282 /* IBSS should share the same code as AP mode */
5283 case BSS_OPERATIONAL_MODE_IBSS:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005284 case BSS_OPERATIONAL_MODE_AP:
Arunk Khandavallia6305a32018-01-25 11:19:18 +05305285 htc_vote_link_up(htc_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005286 wma_add_sta_req_ap_mode(wma, add_sta);
5287 break;
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07005288 case BSS_OPERATIONAL_MODE_NDI:
5289 wma_add_sta_ndi_mode(wma, add_sta);
5290 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005291 }
5292
5293#ifdef QCA_IBSS_SUPPORT
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005294 /* adjust heart beat thresold timer value for detecting ibss peer
5295 * departure
5296 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005297 if (oper_mode == BSS_OPERATIONAL_MODE_IBSS)
5298 wma_adjust_ibss_heart_beat_timer(wma, add_sta->smesessionId, 1);
5299#endif
5300
5301}
5302
5303/**
5304 * wma_delete_sta() - process del sta request as per opmode
5305 * @wma: wma handle
5306 * @del_sta: delete sta params
5307 *
5308 * Return: none
5309 */
5310void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
5311{
5312 uint8_t oper_mode = BSS_OPERATIONAL_MODE_STA;
5313 uint8_t smesession_id = del_sta->smesessionId;
5314 bool rsp_requested = del_sta->respReqd;
Arunk Khandavallia6305a32018-01-25 11:19:18 +05305315 void *htc_handle;
5316
Sourav Mohapatracf632572018-04-02 11:01:35 +05305317 htc_handle = lmac_get_htc_hdl(wma->psoc);
Arunk Khandavallia6305a32018-01-25 11:19:18 +05305318 if (!htc_handle) {
5319 WMA_LOGE(":%sHTC handle is NULL:%d", __func__, __LINE__);
5320 return;
5321 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005322
5323 if (wma_is_vdev_in_ap_mode(wma, smesession_id))
5324 oper_mode = BSS_OPERATIONAL_MODE_AP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005325 if (wma_is_vdev_in_ibss_mode(wma, smesession_id)) {
5326 oper_mode = BSS_OPERATIONAL_MODE_IBSS;
5327 WMA_LOGD("%s: to delete sta for IBSS mode", __func__);
5328 }
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07005329 if (del_sta->staType == STA_ENTRY_NDI_PEER)
5330 oper_mode = BSS_OPERATIONAL_MODE_NDI;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005331
Padma, Santhosh Kumarcd35f532016-12-27 12:07:39 +05305332 WMA_LOGD(FL("oper_mode %d"), oper_mode);
5333
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005334 switch (oper_mode) {
5335 case BSS_OPERATIONAL_MODE_STA:
5336 wma_delete_sta_req_sta_mode(wma, del_sta);
Varun Reddy Yeturu33894272017-10-27 15:37:31 -07005337 if (wma_is_roam_synch_in_progress(wma, smesession_id)) {
5338 WMA_LOGD(FL("LFR3: Del STA on vdev_id %d"),
5339 del_sta->smesessionId);
5340 qdf_mem_free(del_sta);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08005341 return;
Varun Reddy Yeturu33894272017-10-27 15:37:31 -07005342 }
Krishna Kumaar Natarajan70133f02016-02-03 14:35:48 -08005343 if (!rsp_requested) {
5344 WMA_LOGD(FL("vdev_id %d status %d"),
5345 del_sta->smesessionId, del_sta->status);
5346 qdf_mem_free(del_sta);
5347 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005348 break;
5349
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005350 case BSS_OPERATIONAL_MODE_IBSS: /* IBSS shares AP code */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005351 case BSS_OPERATIONAL_MODE_AP:
Arunk Khandavallia6305a32018-01-25 11:19:18 +05305352 htc_vote_link_down(htc_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005353 wma_delete_sta_req_ap_mode(wma, del_sta);
Krishna Kumaar Natarajan70133f02016-02-03 14:35:48 -08005354 /* free the memory here only if sync feature is not enabled */
5355 if (!rsp_requested &&
Sourav Mohapatra89c85d12017-12-01 09:17:54 +05305356 !wmi_service_enabled(wma->wmi_handle,
5357 wmi_service_sync_delete_cmds)) {
Krishna Kumaar Natarajan70133f02016-02-03 14:35:48 -08005358 WMA_LOGD(FL("vdev_id %d status %d"),
5359 del_sta->smesessionId, del_sta->status);
5360 qdf_mem_free(del_sta);
Krunal Sonie50ff452017-10-11 18:23:55 -07005361 } else if (!rsp_requested &&
5362 (del_sta->status != QDF_STATUS_SUCCESS)) {
5363 WMA_LOGD(FL("Release del_sta mem vdev_id %d status %d"),
5364 del_sta->smesessionId, del_sta->status);
5365 qdf_mem_free(del_sta);
Krishna Kumaar Natarajan70133f02016-02-03 14:35:48 -08005366 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005367 break;
Deepak Dhamdherea6d2f4c2016-06-04 00:24:52 -07005368 case BSS_OPERATIONAL_MODE_NDI:
5369 wma_delete_sta_req_ndi_mode(wma, del_sta);
5370 break;
Varun Reddy Yeturu33894272017-10-27 15:37:31 -07005371 default:
5372 WMA_LOGE(FL("Incorrect oper mode %d"), oper_mode);
5373 qdf_mem_free(del_sta);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005374 }
5375
5376#ifdef QCA_IBSS_SUPPORT
5377 /* adjust heart beat thresold timer value for
5378 * detecting ibss peer departure
5379 */
5380 if (oper_mode == BSS_OPERATIONAL_MODE_IBSS)
5381 wma_adjust_ibss_heart_beat_timer(wma, smesession_id, -1);
5382#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005383}
5384
5385/**
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005386 * wma_delete_bss_ho_fail() - process delete bss request for handoff failure
5387 * @wma: wma handle
5388 * @params: del bss parameters
5389 *
5390 * Delete BSS in case of ROAM_HO_FAIL processing is handled separately in
5391 * this routine. It needs to be done without sending any commands to firmware
5392 * because firmware has already stopped and deleted peer and vdev is down.
5393 * Relevent logic is aggregated from other routines. It changes the host
5394 * data structures without sending VDEV_STOP, PEER_FLUSH_TIDS, PEER_DELETE
5395 * and VDEV_DOWN commands to firmware.
5396 *
5397 * Return: none
5398 */
5399void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params)
5400{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005401 struct cdp_pdev *pdev;
Leo Chang96464902016-10-28 11:10:54 -07005402 void *peer = NULL;
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005403 QDF_STATUS status = QDF_STATUS_SUCCESS;
5404 uint8_t peer_id;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005405 struct cdp_vdev *txrx_vdev = NULL;
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005406 struct wma_txrx_node *iface;
Leo Chang96464902016-10-28 11:10:54 -07005407 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005408
5409 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
5410
5411 if (NULL == pdev) {
5412 WMA_LOGE("%s:Unable to get TXRX context", __func__);
5413 goto fail_del_bss_ho_fail;
5414 }
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005415
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005416 peer = cdp_peer_find_by_addr(soc,
5417 pdev,
5418 params->bssid, &peer_id);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005419 if (!peer) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07005420 WMA_LOGE("%s: Failed to find peer %pM", __func__,
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005421 params->bssid);
5422 status = QDF_STATUS_E_FAILURE;
5423 goto fail_del_bss_ho_fail;
5424 }
5425
5426 iface = &wma->interfaces[params->smesessionId];
5427 if (!iface || !iface->handle) {
5428 WMA_LOGE("%s vdev id %d is already deleted",
5429 __func__, params->smesessionId);
5430 goto fail_del_bss_ho_fail;
5431 }
5432 qdf_mem_zero(iface->bssid, IEEE80211_ADDR_LEN);
5433
5434 txrx_vdev = wma_find_vdev_by_id(wma, params->smesessionId);
5435 if (!txrx_vdev) {
5436 WMA_LOGE("%s:Invalid vdev handle", __func__);
5437 status = QDF_STATUS_E_FAILURE;
5438 goto fail_del_bss_ho_fail;
5439 }
5440
5441 /* Free the allocated stats response buffer for the the session */
5442 if (iface->stats_rsp) {
5443 qdf_mem_free(iface->stats_rsp);
5444 iface->stats_rsp = NULL;
5445 }
5446
5447 if (iface->psnr_req) {
5448 qdf_mem_free(iface->psnr_req);
5449 iface->psnr_req = NULL;
5450 }
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05305451
5452 if (iface->rcpi_req) {
5453 struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
5454
5455 iface->rcpi_req = NULL;
5456 qdf_mem_free(rcpi_req);
5457 }
5458
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005459 qdf_mem_zero(&iface->ns_offload_req,
5460 sizeof(iface->ns_offload_req));
5461 qdf_mem_zero(&iface->arp_offload_req,
5462 sizeof(iface->arp_offload_req));
5463
5464 WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
5465 __func__, params->smesessionId);
Leo Chang96464902016-10-28 11:10:54 -07005466 cdp_fc_vdev_pause(soc, iface->handle,
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005467 OL_TXQ_PAUSE_REASON_VDEV_STOP);
Mukul Sharma6411bb82017-03-01 15:57:07 +05305468 wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005469
Leo Chang96464902016-10-28 11:10:54 -07005470 cdp_fc_vdev_flush(soc, iface->handle);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005471 WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
5472 __func__, params->smesessionId);
Leo Chang96464902016-10-28 11:10:54 -07005473 cdp_fc_vdev_unpause(soc, iface->handle,
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005474 OL_TXQ_PAUSE_REASON_VDEV_STOP);
Mukul Sharma6411bb82017-03-01 15:57:07 +05305475 wma_vdev_clear_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005476 qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
5477 WMA_LOGD("%s: (type %d subtype %d) BSS is stopped",
5478 __func__, iface->type, iface->sub_type);
Mukul Sharmaf9047232017-03-02 16:58:56 +05305479 wma_vdev_set_mlme_state(wma, params->smesessionId, WLAN_VDEV_S_STOP);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005480 params->status = QDF_STATUS_SUCCESS;
5481 if (!iface->peer_count) {
5482 WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d",
5483 __func__, params->bssid, params->smesessionId,
5484 iface->peer_count);
5485 goto fail_del_bss_ho_fail;
5486 }
5487
5488 if (peer)
Lin Bai973e6922018-01-08 17:59:19 +08005489 cdp_peer_delete(soc, peer, 1 << CDP_PEER_DELETE_NO_SPECIAL);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005490 iface->peer_count--;
Jeff Johnsonadba3962017-09-18 08:12:35 -07005491 WMA_LOGI("%s: Removed peer %pK with peer_addr %pM vdevid %d peer_count %d",
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005492 __func__, peer, params->bssid, params->smesessionId,
5493 iface->peer_count);
5494fail_del_bss_ho_fail:
5495 params->status = status;
Abhishek Singh2d775fd2017-08-18 10:51:33 +05305496 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_HO_FAIL_RSP,
5497 (void *)params, 0);
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005498}
5499
Sandeep Puligillaf22263c2017-08-28 13:15:15 -07005500/**
5501 * wma_wait_tx_complete() - Wait till tx packets are drained
5502 * @wma: wma handle
5503 * @session_id: vdev id
5504 *
5505 * Return: none
5506 */
5507static void wma_wait_tx_complete(tp_wma_handle wma,
5508 uint32_t session_id)
5509{
5510 struct cdp_pdev *pdev;
5511 uint8_t max_wait_iterations = 0;
5512 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
5513
5514 if (!wma->interfaces[session_id].is_vdev_valid) {
5515 WMA_LOGE("%s: Vdev is not valid: %d",
5516 __func__, session_id);
5517 return;
5518 }
5519
5520 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Varun Reddy Yeturu81d0b372017-09-19 14:41:19 -07005521 if (pdev == NULL) {
5522 WMA_LOGE("%s: pdev is not valid: %d",
5523 __func__, session_id);
5524 return;
5525 }
Sandeep Puligillaf22263c2017-08-28 13:15:15 -07005526 max_wait_iterations =
5527 wma->interfaces[session_id].delay_before_vdev_stop /
5528 WMA_TX_Q_RECHECK_TIMER_WAIT;
5529
5530 while (cdp_get_tx_pending(soc, pdev) && max_wait_iterations) {
5531 WMA_LOGW(FL("Waiting for outstanding packet to drain."));
Nachiket Kukade0396b732017-11-14 16:35:16 +05305532 qdf_wait_for_event_completion(&wma->tx_queue_empty_event,
Sandeep Puligillaf22263c2017-08-28 13:15:15 -07005533 WMA_TX_Q_RECHECK_TIMER_WAIT);
5534 max_wait_iterations--;
5535 }
5536}
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005537/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005538 * wma_delete_bss() - process delete bss request from upper layer
5539 * @wma: wma handle
5540 * @params: del bss parameters
5541 *
5542 * Return: none
5543 */
5544void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
5545{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005546 struct cdp_pdev *pdev;
Leo Chang96464902016-10-28 11:10:54 -07005547 void *peer = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005548 struct wma_target_req *msg;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305549 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005550 uint8_t peer_id;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005551 struct cdp_vdev *txrx_vdev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005552 bool roam_synch_in_progress = false;
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005553 struct wma_txrx_node *iface;
Leo Chang96464902016-10-28 11:10:54 -07005554 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005555
Anurag Chouhan6d760662016-02-20 16:05:43 +05305556 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005557
5558 if (NULL == pdev) {
5559 WMA_LOGE("%s:Unable to get TXRX context", __func__);
5560 goto out;
5561 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005562 if (wma_is_vdev_in_ibss_mode(wma, params->smesessionId))
5563 /* in rome ibss case, self mac is used to create the bss peer */
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005564 peer = cdp_peer_find_by_addr(soc,
5565 pdev,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005566 wma->interfaces[params->smesessionId].addr,
5567 &peer_id);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005568 else if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces,
5569 params->smesessionId))
5570 /* In ndi case, self mac is used to create the self peer */
Leo Chang96464902016-10-28 11:10:54 -07005571 peer = cdp_peer_find_by_addr(soc, pdev,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005572 wma->interfaces[params->smesessionId].addr,
5573 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005574 else
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005575 peer = cdp_peer_find_by_addr(soc, pdev,
5576 params->bssid,
5577 &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005578
5579 if (!peer) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07005580 WMA_LOGE("%s: Failed to find peer %pM", __func__,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005581 params->bssid);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305582 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005583 goto out;
5584 }
5585
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305586 qdf_mem_zero(wma->interfaces[params->smesessionId].bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005587 IEEE80211_ADDR_LEN);
5588
5589 txrx_vdev = wma_find_vdev_by_id(wma, params->smesessionId);
5590 if (!txrx_vdev) {
5591 WMA_LOGE("%s:Invalid vdev handle", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305592 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005593 goto out;
5594 }
5595
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005596 iface = &wma->interfaces[params->smesessionId];
5597 if (!iface || !iface->handle) {
5598 WMA_LOGE("%s vdev id %d is already deleted",
5599 __func__, params->smesessionId);
5600 goto out;
5601 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005602 /*Free the allocated stats response buffer for the the session */
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005603 if (iface->stats_rsp) {
5604 qdf_mem_free(iface->stats_rsp);
5605 iface->stats_rsp = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005606 }
5607
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005608 if (iface->psnr_req) {
5609 qdf_mem_free(iface->psnr_req);
5610 iface->psnr_req = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005611 }
5612
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05305613 if (iface->rcpi_req) {
5614 struct sme_rcpi_req *rcpi_req = iface->rcpi_req;
5615
5616 iface->rcpi_req = NULL;
5617 qdf_mem_free(rcpi_req);
5618 }
5619
Leo Chang96464902016-10-28 11:10:54 -07005620 if (wlan_op_mode_ibss == cdp_get_opmode(soc, txrx_vdev))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005621 wma->ibss_started = 0;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005622
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08005623 if (wma_is_roam_synch_in_progress(wma, params->smesessionId)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005624 roam_synch_in_progress = true;
5625 WMA_LOGD("LFR3:%s: Setting vdev_up to FALSE for session %d",
5626 __func__, params->smesessionId);
Mukul Sharmaf9047232017-03-02 16:58:56 +05305627 wma_vdev_set_mlme_state(wma, params->smesessionId,
5628 WLAN_VDEV_S_STOP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005629 goto detach_peer;
5630 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005631 msg = wma_fill_vdev_req(wma, params->smesessionId, WMA_DELETE_BSS_REQ,
5632 WMA_TARGET_REQ_TYPE_VDEV_STOP, params,
5633 WMA_VDEV_STOP_REQUEST_TIMEOUT);
5634 if (!msg) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07005635 WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005636 __func__, params->smesessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305637 status = QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005638 goto detach_peer;
5639 }
5640
5641 WMA_LOGW(FL("Outstanding msdu packets: %d"),
Leo Chang96464902016-10-28 11:10:54 -07005642 cdp_get_tx_pending(soc, pdev));
Sandeep Puligillaf22263c2017-08-28 13:15:15 -07005643 wma_wait_tx_complete(wma, params->smesessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005644
Leo Chang96464902016-10-28 11:10:54 -07005645 if (cdp_get_tx_pending(soc, pdev)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005646 WMA_LOGW(FL("Outstanding msdu packets before VDEV_STOP : %d"),
Leo Chang96464902016-10-28 11:10:54 -07005647 cdp_get_tx_pending(soc, pdev));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005648 }
5649
5650 WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
5651 __func__, params->smesessionId);
Mukul Sharma6411bb82017-03-01 15:57:07 +05305652 wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005653 cdp_fc_vdev_pause(soc,
5654 wma->interfaces[params->smesessionId].handle,
5655 OL_TXQ_PAUSE_REASON_VDEV_STOP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005656
Manjunathappa Prakashae749482018-03-06 14:23:03 -08005657 /* smesessionId is not equal to vdev_id with which pool is created */
5658 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
5659 cds_get_context(QDF_MODULE_ID_TXRX),
5660 params->smesessionId);
5661
Dustin Brownbf6d16b2017-03-03 11:41:05 -08005662 if (wma_send_vdev_stop_to_fw(wma, params->smesessionId)) {
Srinivas Girigowdada0e8482017-03-19 23:15:45 -07005663 WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005664 wma_remove_vdev_req(wma, params->smesessionId,
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005665 WMA_TARGET_REQ_TYPE_VDEV_STOP);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305666 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005667 goto detach_peer;
Deepak Dhamdhere2dae1bd2016-10-27 10:58:29 -07005668 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005669 WMA_LOGD("%s: bssid %pM vdev_id %d",
5670 __func__, params->bssid, params->smesessionId);
5671 return;
5672detach_peer:
5673 wma_remove_peer(wma, params->bssid, params->smesessionId, peer,
5674 roam_synch_in_progress);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08005675 if (wma_is_roam_synch_in_progress(wma, params->smesessionId))
5676 return;
5677
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005678out:
5679 params->status = status;
Abhishek Singh2d775fd2017-08-18 10:51:33 +05305680 wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP, (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005681}
5682
5683/**
5684 * wma_find_ibss_vdev() - This function finds vdev_id based on input type
5685 * @wma: wma handle
5686 * @type: vdev type
5687 *
5688 * Return: vdev id
5689 */
5690int32_t wma_find_vdev_by_type(tp_wma_handle wma, int32_t type)
5691{
5692 int32_t vdev_id = 0;
5693 struct wma_txrx_node *intf = wma->interfaces;
5694
5695 for (vdev_id = 0; vdev_id < wma->max_bssid; vdev_id++) {
5696 if (NULL != intf) {
5697 if (intf[vdev_id].type == type)
5698 return vdev_id;
5699 }
5700 }
5701
5702 return -EFAULT;
5703}
5704
5705/**
5706 * wma_set_vdev_intrabss_fwd() - set intra_fwd value to wni_in.
5707 * @wma_handle: wma handle
5708 * @pdis_intra_fwd: Pointer to DisableIntraBssFwd struct
5709 *
5710 * Return: none
5711 */
5712void wma_set_vdev_intrabss_fwd(tp_wma_handle wma_handle,
5713 tpDisableIntraBssFwd pdis_intra_fwd)
5714{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005715 struct cdp_vdev *txrx_vdev;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005716
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005717 WMA_LOGD("%s:intra_fwd:vdev(%d) intrabss_dis=%s",
5718 __func__, pdis_intra_fwd->sessionId,
5719 (pdis_intra_fwd->disableintrabssfwd ? "true" : "false"));
5720
5721 txrx_vdev = wma_handle->interfaces[pdis_intra_fwd->sessionId].handle;
Leo Chang96464902016-10-28 11:10:54 -07005722 cdp_cfg_vdev_rx_set_intrabss_fwd(cds_get_context(QDF_MODULE_ID_SOC),
5723 txrx_vdev,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005724 pdis_intra_fwd->disableintrabssfwd);
5725}
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07005726
5727void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev)
5728{
5729 tp_wma_handle wma = (tp_wma_handle)wma_ctx;
5730 QDF_STATUS status;
5731
5732 status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_WMA_ID);
5733 if (QDF_STATUS_SUCCESS != status) {
5734 wma->pdev = NULL;
5735 return;
5736 }
5737
5738 wma->pdev = pdev;
5739}
5740
lifeng7c607dd2017-02-21 21:16:49 +08005741/**
5742 * wma_vdev_reset_beacon_interval_timer() - reset beacon interval back
5743 * to its original value after the channel switch.
5744 *
5745 * @data: data
5746 *
5747 * Return: void
5748 */
5749static void wma_vdev_reset_beacon_interval_timer(void *data)
5750{
5751 tp_wma_handle wma;
5752 struct wma_beacon_interval_reset_req *req =
5753 (struct wma_beacon_interval_reset_req *)data;
5754 uint16_t beacon_interval = req->interval;
5755 uint8_t vdev_id = req->vdev_id;
5756
5757 wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
5758 if (NULL == wma) {
5759 WMA_LOGE("%s: Failed to get wma", __func__);
5760 goto end;
5761 }
5762
5763 /* Change the beacon interval back to its original value */
5764 WMA_LOGE("%s: Change beacon interval back to %d",
5765 __func__, beacon_interval);
5766 wma_update_beacon_interval(wma, vdev_id, beacon_interval);
5767
5768end:
5769 qdf_timer_stop(&req->event_timeout);
5770 qdf_timer_free(&req->event_timeout);
5771 qdf_mem_free(req);
5772}
5773
5774int wma_fill_beacon_interval_reset_req(tp_wma_handle wma, uint8_t vdev_id,
5775 uint16_t beacon_interval, uint32_t timeout)
5776{
5777 struct wma_beacon_interval_reset_req *req;
5778
5779 req = qdf_mem_malloc(sizeof(*req));
5780 if (!req) {
5781 WMA_LOGE("%s: Failed to allocate memory for beacon_interval_reset_req vdev %d",
5782 __func__, vdev_id);
5783 return -ENOMEM;
5784 }
5785
5786 WMA_LOGD("%s: vdev_id %d ", __func__, vdev_id);
5787 req->vdev_id = vdev_id;
5788 req->interval = beacon_interval;
5789 qdf_timer_init(NULL, &req->event_timeout,
5790 wma_vdev_reset_beacon_interval_timer, req, QDF_TIMER_TYPE_SW);
5791 qdf_timer_start(&req->event_timeout, timeout);
5792
5793 return 0;
5794}
Paul Zhang99fe8842017-12-08 14:43:46 +08005795
5796QDF_STATUS wma_set_wlm_latency_level(void *wma_ptr,
5797 struct wlm_latency_level_param *latency_params)
5798{
5799 QDF_STATUS ret;
5800 tp_wma_handle wma = (tp_wma_handle)wma_ptr;
5801
5802 WMA_LOGD("%s: set latency level %d, flags flag 0x%x",
5803 __func__, latency_params->wlm_latency_level,
5804 latency_params->wlm_latency_flags);
5805
5806 ret = wmi_unified_wlm_latency_level_cmd(wma->wmi_handle,
5807 latency_params);
5808 if (QDF_IS_STATUS_ERROR(ret))
5809 WMA_LOGW("Failed to set latency level");
5810
5811 return ret;
5812}