blob: 3fb2c0da78992eda8812cc217ed90a7063caccb0 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyya5015e982017-01-11 13:30:57 -08002 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wma_scan_roam.c
30 * This file contains functions related to scan and
31 * roaming functionality.
32 */
33
34/* Header files */
35
36#include "wma.h"
37#include "wma_api.h"
38#include "cds_api.h"
39#include "wmi_unified_api.h"
40#include "wlan_qct_sys.h"
41#include "wni_api.h"
42#include "ani_global.h"
43#include "wmi_unified.h"
44#include "wni_cfg.h"
45#include "cfg_api.h"
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -070046#include <cdp_txrx_peer_ops.h>
47#include <cdp_txrx_cfg.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048
Nirav Shahcbc6d722016-03-01 16:24:53 +053049#include "qdf_nbuf.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053050#include "qdf_types.h"
Anurag Chouhan600c3a02016-03-01 10:33:54 +053051#include "qdf_mem.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080052
53#include "wma_types.h"
54#include "lim_api.h"
55#include "lim_session_utils.h"
56
57#include "cds_utils.h"
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -070058#include "wlan_policy_mgr_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059
60#if !defined(REMOVE_PKT_LOG)
61#include "pktlog_ac.h"
62#endif /* REMOVE_PKT_LOG */
63
64#include "dbglog_host.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065#include "csr_api.h"
66#include "ol_fw.h"
67
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068#include "wma_internal.h"
Leo Chang96464902016-10-28 11:10:54 -070069#include "wlan_tgt_def_config.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070070#include "wlan_reg_services_api.h"
71
Leo Chang96464902016-10-28 11:10:54 -070072/* This is temporary, should be removed */
73#include "ol_htt_api.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080074#include <cdp_txrx_handle.h>
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -080075#include "wma_he.h"
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -080076#include <wlan_scan_public_structs.h>
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -070077#include <wlan_scan_ucfg_api.h>
Ravi Joshi3750de92017-06-01 13:26:09 -070078#include "wma_nan_datapath.h"
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -070079
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080#define WMA_MCC_MIRACAST_REST_TIME 400
81#define WMA_SCAN_ID_MASK 0x0fff
82
83#ifdef FEATURE_WLAN_EXTSCAN
84/**
85 * enum extscan_report_events_type - extscan report events type
86 * @EXTSCAN_REPORT_EVENTS_BUFFER_FULL: report only when scan history is % full
87 * @EXTSCAN_REPORT_EVENTS_EACH_SCAN: report a scan completion event after scan
88 * @EXTSCAN_REPORT_EVENTS_FULL_RESULTS: forward scan results
89 * (beacons/probe responses + IEs)
90 * in real time to HAL, in addition to completion events.
91 * Note: To keep backward compatibility,
92 * fire completion events regardless of REPORT_EVENTS_EACH_SCAN.
93 * @EXTSCAN_REPORT_EVENTS_NO_BATCH: controls batching,
94 * 0 => batching, 1 => no batching
Mukul Sharmafa937be2016-08-12 18:13:36 +053095 * @EXTSCAN_REPORT_EVENTS_CONTEXT_HUB: forward results to context hub
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -070096 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097enum extscan_report_events_type {
98 EXTSCAN_REPORT_EVENTS_BUFFER_FULL = 0x00,
99 EXTSCAN_REPORT_EVENTS_EACH_SCAN = 0x01,
100 EXTSCAN_REPORT_EVENTS_FULL_RESULTS = 0x02,
101 EXTSCAN_REPORT_EVENTS_NO_BATCH = 0x04,
Mukul Sharmafa937be2016-08-12 18:13:36 +0530102 EXTSCAN_REPORT_EVENTS_CONTEXT_HUB = 0x08,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800103};
104
105#define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION (5 * 1000) /* in msec */
Sridhar Selvaraj22943572017-07-26 15:06:40 +0530106
107/*
108 * Maximum number of entires that could be present in the
109 * WMI_EXTSCAN_HOTLIST_MATCH_EVENT buffer from the firmware
110 */
111#define WMA_EXTSCAN_MAX_HOTLIST_ENTRIES 10
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800112#endif
113
114/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 * wma_is_mcc_24G() - check that if device is in 2.4GHz MCC
116 * @handle: wma handle
117 *
118 * Return: true/false
119 */
120static bool wma_is_mcc_24G(WMA_HANDLE handle)
121{
122 tp_wma_handle wma_handle = (tp_wma_handle) handle;
123 int32_t prev_chan = 0;
124 int32_t i;
125
126 if (NULL == wma_handle) {
127 WMA_LOGE("%s: wma_handle is NULL", __func__);
128 return false;
129 }
130 for (i = 0; i < wma_handle->max_bssid; i++) {
131 if (wma_handle->interfaces[i].handle &&
Mukul Sharmaf9047232017-03-02 16:58:56 +0530132 wma_is_vdev_up(i)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800133 if ((prev_chan != 0 &&
134 prev_chan != wma_handle->interfaces[i].mhz) &&
135 (wma_handle->interfaces[i].mhz <=
136 CDS_CHAN_14_FREQ))
137 return true;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700138 prev_chan = wma_handle->interfaces[i].mhz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800139 }
140 }
141 return false;
142}
143
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700144static inline int wma_get_burst_duration(int max_ch_time, int miracast_value)
145{
146 int burst_duration = 0;
147
148 if (miracast_value) {
149 /* When miracast is running, burst
150 * duration needs to be minimum to avoid
151 * any stutter or glitch in miracast
152 * during station scan
153 */
154 if (max_ch_time <= WMA_GO_MIN_ACTIVE_SCAN_BURST_DURATION)
155 burst_duration = max_ch_time;
156 else
157 burst_duration = WMA_GO_MIN_ACTIVE_SCAN_BURST_DURATION;
158 } else {
159 /* If miracast is not running, accommodate max
160 * stations to make the scans faster
161 */
162 burst_duration = WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS *
163 max_ch_time;
164 if (burst_duration > WMA_GO_MAX_ACTIVE_SCAN_BURST_DURATION) {
165 uint8_t channels = WMA_P2P_SCAN_MAX_BURST_DURATION /
166 max_ch_time;
167
168 if (channels)
169 burst_duration = channels * max_ch_time;
170 else
171 burst_duration =
172 WMA_GO_MAX_ACTIVE_SCAN_BURST_DURATION;
173 }
174 }
175 return burst_duration;
176}
177
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800178/**
179 * wma_get_buf_start_scan_cmd() - Fill start scan command
180 * @wma_handle: wma handle
181 * @scan_req: scan request
Govind Singh498bf2a2016-03-08 15:44:17 +0530182 * @cmd: wmi buffer to be filled in
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800183 *
184 * Fill individual elements of wmi_start_scan_req and TLV for
185 * channel list, bssid, ssid etc.
186 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530187 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530189QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800190 tSirScanOffloadReq *scan_req,
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800191 struct scan_req_params *cmd)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800192{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530193 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800194 uint32_t dwell_time;
195 uint8_t SSID_num;
196 int i;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530197 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198
199 if (!pMac) {
200 WMA_LOGP("%s: pMac is NULL!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530201 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202 }
203
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800204 cmd->vdev_id = scan_req->sessionId;
205 /*
206 * host cycles through the lower 12 bits for scan id generation
207 * and prefix 0xA000 to scan id
208 */
209 if (scan_req->scan_id < WMA_HOST_SCAN_REQID_PREFIX) {
210 WMA_LOGE("Received scan_id 0x%x is wrong",
211 cmd->scan_id);
212 scan_req->scan_id = scan_req->scan_id & WMA_SCAN_ID_MASK;
213 /* Appending the 0xA000 to scan Id*/
214 cmd->scan_id = scan_req->scan_id | WMA_HOST_SCAN_REQID_PREFIX;
215 } else {
216 cmd->scan_id = scan_req->scan_id;
217 }
218 cmd->scan_priority = WMI_SCAN_PRIORITY_LOW;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700219 cmd->scan_req_id = scan_req->scan_requestor_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220
Abhishek Singh5a331712016-08-08 18:10:20 +0530221 if (PREAUTH_REQUESTOR_ID == cmd->scan_req_id)
222 cmd->scan_priority = WMI_SCAN_PRIORITY_VERY_HIGH;
223
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224 /* Set the scan events which the driver is intereseted to receive */
225 /* TODO: handle all the other flags also */
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800226 cmd->scan_events = WMI_SCAN_EVENT_STARTED |
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227 WMI_SCAN_EVENT_START_FAILED |
228 WMI_SCAN_EVENT_FOREIGN_CHANNEL |
229 WMI_SCAN_EVENT_COMPLETED |
230 WMI_SCAN_EVENT_DEQUEUED |
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700231 WMI_SCAN_EVENT_PREEMPTED |
232 WMI_SCAN_EVENT_RESTARTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800233
234 cmd->dwell_time_active = scan_req->maxChannelTime;
235
236 if (scan_req->scanType == eSIR_ACTIVE_SCAN) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700237 /* In Active scan case, the firmware has to do passive scan on
238 * DFS channels So the passive scan duration should be updated
239 * properly so that the duration will be sufficient enough to
240 * receive the beacon from AP
241 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242 if (wlan_cfg_get_int(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
243 &dwell_time) != eSIR_SUCCESS) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700244 WMA_LOGE("Failed to get passive max channel value using default value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800245 dwell_time = WMA_DWELL_TIME_PASSIVE_DEFAULT;
246 }
247 cmd->dwell_time_passive = dwell_time;
248 } else
249 cmd->dwell_time_passive = scan_req->maxChannelTime;
250
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251 /* Ensure correct number of probes are sent on active channel */
252 cmd->repeat_probe_time =
253 cmd->dwell_time_active / WMA_SCAN_NPROBES_DEFAULT;
254
Agrawal Ashish17bb3902016-05-05 13:29:40 +0530255 /* CSR sends min_rest_Time, max_rest_time and idle_time
256 * for staying on home channel to continue data traffic.
257 * Rome fw has facility to monitor the traffic
258 * and move to next channel. Stay on the channel for min_rest_time
259 * and then leave if there is no traffic.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800260 */
Agrawal Ashish17bb3902016-05-05 13:29:40 +0530261 cmd->min_rest_time = scan_req->min_rest_time;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262 cmd->max_rest_time = scan_req->restTime;
263
264 /* Check for traffic at idle_time interval after min_rest_time.
265 * Default value is 25 ms to allow full use of max_rest_time
266 * when voice packets are running at 20 ms interval.
267 */
Agrawal Ashish17bb3902016-05-05 13:29:40 +0530268 cmd->idle_time = scan_req->idle_time;
269
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800270
271 /* Large timeout value for full scan cycle, 30 seconds */
272 cmd->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
273
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +0530274 /* add DS param IE in probe req frame */
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800275 cmd->scan_f_add_ds_ie_in_probe = true;
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +0530276
Kapil Gupta4f0c0c12017-02-07 15:21:15 +0530277 /* set flag to get chan stats */
278 if (pMac->snr_monitor_enabled)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800279 cmd->scan_f_chan_stat_evnt = true;
Kapil Gupta4f0c0c12017-02-07 15:21:15 +0530280
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800281 /* do not add OFDM rates in 11B mode */
282 if (scan_req->dot11mode != WNI_CFG_DOT11_MODE_11B)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800283 cmd->scan_f_ofdm_rates = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800284 else
285 WMA_LOGD("OFDM_RATES not included in 11B mode");
286
Tushnim Bhattacharyya5015e982017-01-11 13:30:57 -0800287 if (scan_req->p2pScanType)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800288 cmd->adaptive_dwell_time_mode = WMI_DWELL_MODE_STATIC;
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +0530289
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290 /* Do not combine multiple channels in a single burst. Come back
291 * to home channel for data traffic after every foreign channel.
292 * By default, prefer throughput performance over scan cycle time.
293 */
294 cmd->burst_duration = 0;
295
296 if (!scan_req->p2pScanType) {
297 WMA_LOGD("Normal Scan request");
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800298 cmd->scan_f_cck_rates = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800299 if (!scan_req->numSsid)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800300 cmd->scan_f_bcast_probe = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800301 if (scan_req->scanType == eSIR_PASSIVE_SCAN)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800302 cmd->scan_f_passive = true;
303 cmd->scan_f_add_tpc_ie_in_probe = true;
304 cmd->scan_f_filter_prb_req = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305
gaoleze5108942017-03-31 16:56:42 +0800306 if (pMac->sap.acs_with_more_param) {
307 /* add chan stat info report tag */
308 if (pMac->sme.currDeviceMode == QDF_SAP_MODE) {
309 cmd->scan_f_chan_stat_evnt = true;
310 WMA_LOGD("set ACS ctrl BIT");
311 }
312 }
313
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800314 /*
315 * Decide burst_duration and dwell_time_active based on
316 * what type of devices are active.
317 */
318 do {
319 if (wma_is_sap_active(wma_handle) &&
320 wma_is_p2p_go_active(wma_handle) &&
321 wma_is_sta_active(wma_handle)) {
322 if (scan_req->maxChannelTime <=
323 WMA_3PORT_CONC_SCAN_MAX_BURST_DURATION)
324 cmd->burst_duration =
325 scan_req->maxChannelTime;
326 else
327 cmd->burst_duration =
328 WMA_3PORT_CONC_SCAN_MAX_BURST_DURATION;
329 break;
330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331 if (wma_handle->miracast_value &&
332 wma_is_mcc_24G(wma_handle)) {
333 cmd->max_rest_time =
334 pMac->f_sta_miracast_mcc_rest_time_val;
335 }
336 if (wma_is_p2p_go_active(wma_handle)) {
337 /* Background scan while GO is sending beacons.
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700338 * Every off-channel transition has overhead of
339 * 2 beacon intervals for NOA. Maximize number
340 * of channels in every transition by using
341 * burst scan.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800342 */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700343 cmd->burst_duration =
344 wma_get_burst_duration(
345 scan_req->maxChannelTime,
346 wma_handle->miracast_value);
347
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800348 break;
349 }
350 if (wma_is_sta_active(wma_handle) ||
351 wma_is_p2p_cli_active(wma_handle)) {
Paul Zhangd2315472017-02-22 10:02:50 +0800352 if (scan_req->burst_scan_duration)
353 cmd->burst_duration =
354 scan_req->burst_scan_duration;
355 else
356 /* Typical background scan.
357 * Disable burst scan for now.
358 */
359 cmd->burst_duration = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800360 break;
361 }
Ravi Joshi3750de92017-06-01 13:26:09 -0700362 if (wma_is_ndi_active(wma_handle)) {
363 cmd->burst_duration = wma_get_burst_duration(
364 scan_req->maxChannelTime,
365 wma_handle->miracast_value);
366 WMA_LOGD("NDI Active, Burst duration: %x",
367 cmd->burst_duration);
368 break;
369 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800370 } while (0);
371
372 } else {
373 WMA_LOGD("P2P Scan");
374 switch (scan_req->p2pScanType) {
375 case P2P_SCAN_TYPE_LISTEN:
376 WMA_LOGD("P2P_SCAN_TYPE_LISTEN");
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800377 cmd->scan_f_passive = true;
378 cmd->scan_events |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 WMI_SCAN_EVENT_FOREIGN_CHANNEL;
380 cmd->repeat_probe_time = 0;
Nishank Aggarwalf3f22842017-03-08 11:49:20 +0530381 cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800382 break;
383 case P2P_SCAN_TYPE_SEARCH:
384 WMA_LOGD("P2P_SCAN_TYPE_SEARCH");
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800385 cmd->scan_f_filter_prb_req = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800386 /* Default P2P burst duration of 120 ms will cover
387 * 3 channels with default max dwell time 40 ms.
388 * Cap limit will be set by
389 * WMA_P2P_SCAN_MAX_BURST_DURATION. Burst duration
390 * should be such that no channel is scanned less
391 * than the dwell time in normal scenarios.
392 */
393 if (scan_req->channelList.numChannels ==
394 P2P_SOCIAL_CHANNELS
395 && (!(wma_handle->miracast_value)))
396 cmd->repeat_probe_time =
397 scan_req->maxChannelTime / 5;
398 else
399 cmd->repeat_probe_time =
400 scan_req->maxChannelTime / 3;
401
402 cmd->burst_duration =
403 WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS *
404 scan_req->maxChannelTime;
405 if (cmd->burst_duration >
406 WMA_P2P_SCAN_MAX_BURST_DURATION) {
407 uint8_t channels =
408 WMA_P2P_SCAN_MAX_BURST_DURATION /
409 scan_req->maxChannelTime;
410 if (channels)
411 cmd->burst_duration =
412 channels * scan_req->maxChannelTime;
413 else
414 cmd->burst_duration =
415 WMA_P2P_SCAN_MAX_BURST_DURATION;
416 }
Nishank Aggarwalf3f22842017-03-08 11:49:20 +0530417 cmd->scan_priority = WMI_SCAN_PRIORITY_MEDIUM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800418 break;
419 default:
420 WMA_LOGE("Invalid scan type");
421 goto error;
422 }
423 }
424
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530425 if (wma_is_sap_active(wma_handle)) {
426 /* P2P/STA scan while SoftAP is sending beacons.
427 * Max duration of CTS2self is 32 ms, which limits the
Krunal Soni499d3642016-09-26 16:46:03 -0700428 * dwell time. If DBS is supported and if SAP is on 2G channel
429 * then keep passive dwell time default.
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530430 */
431 cmd->dwell_time_active =
432 QDF_MIN(scan_req->maxChannelTime,
433 (WMA_CTS_DURATION_MS_MAX -
434 WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME));
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -0700435 if (!policy_mgr_is_hw_dbs_capable(wma_handle->psoc) ||
436 (policy_mgr_is_hw_dbs_capable(wma_handle->psoc) &&
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700437 WLAN_REG_IS_5GHZ_CH(
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -0700438 policy_mgr_get_channel(wma_handle->psoc,
439 PM_SAP_MODE, NULL)))) {
Krunal Soni499d3642016-09-26 16:46:03 -0700440 cmd->dwell_time_passive = cmd->dwell_time_active;
441 }
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530442 cmd->burst_duration = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700443 if (wlan_reg_is_dfs_ch(wma_handle->pdev,
444 policy_mgr_get_channel(wma_handle->psoc,
445 PM_SAP_MODE, NULL)))
Nitesh Shah77442572017-03-09 17:06:34 +0530446 cmd->burst_duration =
447 WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS *
448 scan_req->maxChannelTime;
449 WMA_LOGI("SAP: burst_duration: %d", cmd->burst_duration);
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530450 }
451
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 cmd->n_probes = (cmd->repeat_probe_time > 0) ?
453 cmd->dwell_time_active / cmd->repeat_probe_time : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 if (scan_req->channelList.numChannels) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 cmd->num_chan = scan_req->channelList.numChannels;
456 for (i = 0; i < scan_req->channelList.numChannels; ++i) {
Govind Singh498bf2a2016-03-08 15:44:17 +0530457 cmd->chan_list[i] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800458 cds_chan_to_freq(scan_req->channelList.
459 channelNumber[i]);
460 }
461 }
Govind Singh498bf2a2016-03-08 15:44:17 +0530462
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 if (scan_req->numSsid > SIR_SCAN_MAX_NUM_SSID) {
464 WMA_LOGE("Invalid value for numSsid");
465 goto error;
466 }
Govind Singh498bf2a2016-03-08 15:44:17 +0530467
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800468 cmd->num_ssids = scan_req->numSsid;
Govind Singh498bf2a2016-03-08 15:44:17 +0530469
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470 if (scan_req->numSsid) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800471 for (i = 0; i < scan_req->numSsid; ++i) {
Govind Singh498bf2a2016-03-08 15:44:17 +0530472 cmd->ssid[i].length = scan_req->ssId[i].length;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800473 qdf_mem_copy(cmd->ssid[i].ssid,
Govind Singh498bf2a2016-03-08 15:44:17 +0530474 scan_req->ssId[i].ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800475 scan_req->ssId[i].length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800476 }
477 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800478
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479 if (!scan_req->p2pScanType) {
480 if (wma_is_sap_active(wma_handle)) {
481 SSID_num = cmd->num_ssids * cmd->num_bssid;
482 cmd->repeat_probe_time = probe_time_dwell_time_map[
Anurag Chouhan6d760662016-02-20 16:05:43 +0530483 QDF_MIN(SSID_num,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 WMA_DWELL_TIME_PROBE_TIME_MAP_SIZE
485 - 1)].probe_time;
Liangwei Dong271f92f2016-09-28 06:05:08 -0400486 cmd->n_probes = (cmd->repeat_probe_time > 0) ?
487 cmd->dwell_time_active/
488 cmd->repeat_probe_time : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489 }
490 }
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800491 WMA_LOGD("Scan Type 0x%x, Active dwell time %u, Passive dwell time %u",
Liangwei Dong271f92f2016-09-28 06:05:08 -0400492 scan_req->scanType, cmd->dwell_time_active,
493 cmd->dwell_time_passive);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800494 WMA_LOGD("Scan repeat_probe_time %u n_probes %u num_ssids %u num_bssid %u",
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700495 cmd->repeat_probe_time, cmd->n_probes, cmd->num_ssids,
Liangwei Dong271f92f2016-09-28 06:05:08 -0400496 cmd->num_bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800497
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800498 cmd->num_bssid = 1;
499 qdf_mem_copy(cmd->bssid_list, scan_req->bssId.bytes, QDF_MAC_ADDR_SIZE);
500 cmd->extraie.len = scan_req->uIEFieldLen;
501 cmd->extraie.ptr = (uint8_t *) scan_req +
502 (scan_req->uIEFieldOffset);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530503 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800504
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800505error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530506 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800507}
508
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800509/**
510 * wma_start_scan() - start scan command
511 * @wma_handle: wma handle
512 * @scan_req: scan request params
513 * @msg_type: message time
514 *
515 * Send start scan command to fw.
516 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530517 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530519QDF_STATUS wma_start_scan(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 tSirScanOffloadReq *scan_req, uint16_t msg_type)
521{
522 uint32_t vdev_id, scan_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530523 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800524 struct scan_req_params cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800525 tSirScanOffloadEvent *scan_event;
526
Naveen Rawatf2bd42d2017-06-29 14:51:43 -0700527 if (scan_req->sessionId >= wma_handle->max_bssid) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528 WMA_LOGE("%s: Invalid vdev_id %d, msg_type : 0x%x", __func__,
529 scan_req->sessionId, msg_type);
Govind Singh498bf2a2016-03-08 15:44:17 +0530530 goto error1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800531 }
532
533 /* Sanity check to find whether vdev id active or not */
534 if (msg_type != WMA_START_SCAN_OFFLOAD_REQ &&
535 !wma_handle->interfaces[scan_req->sessionId].handle) {
536 WMA_LOGA("vdev id [%d] is not active", scan_req->sessionId);
Govind Singh498bf2a2016-03-08 15:44:17 +0530537 goto error1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800538 }
539
540 /* Fill individual elements of wmi_start_scan_req and
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700541 * TLV for channel list, bssid, ssid etc ...
542 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530543 qdf_status = wma_get_buf_start_scan_cmd(wma_handle, scan_req,
Govind Singh498bf2a2016-03-08 15:44:17 +0530544 &cmd);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530545 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546 WMA_LOGE("Failed to get buffer for start scan cmd");
Govind Singh498bf2a2016-03-08 15:44:17 +0530547 goto error1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548 }
549
Archana Ramachandran31b5b652016-09-21 15:37:58 -0700550 WMA_LOGI("scan_id 0x%x, vdev_id %d, p2pScanType %d, msg_type 0x%x",
Govind Singh498bf2a2016-03-08 15:44:17 +0530551 cmd.scan_id, cmd.vdev_id, scan_req->p2pScanType, msg_type);
Kapil Gupta139c3302016-09-22 16:48:12 +0530552
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 /*
554 * Cache vdev_id and scan_id because cmd is freed after calling
555 * wmi_unified_cmd_send cmd. WMI internally frees cmd buffer after
556 * getting TX complete from CE
557 */
Govind Singh498bf2a2016-03-08 15:44:17 +0530558 vdev_id = cmd.vdev_id;
559 scan_id = cmd.scan_id;
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800560 WMA_LOGD("ActiveDwell %d, PassiveDwell %d, ScanFlags 0x%x NumChan %d",
Govind Singh498bf2a2016-03-08 15:44:17 +0530561 cmd.dwell_time_active, cmd.dwell_time_passive,
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800562 cmd.scan_flags, cmd.num_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800563
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564 /* Call the wmi api to request the scan */
Govind Singh498bf2a2016-03-08 15:44:17 +0530565 qdf_status = wmi_unified_scan_start_cmd_send(wma_handle->wmi_handle,
566 &cmd);
567 if (QDF_IS_STATUS_ERROR(qdf_status)) {
568 WMA_LOGE("wmi_unified_cmd_send returned Error %d", qdf_status);
Dustin Brownc86d5362017-07-07 13:08:51 -0700569 goto error1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 }
571
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800572 WMA_LOGD("WMA --> WMI_START_SCAN_CMDID");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800573
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530574 return QDF_STATUS_SUCCESS;
Govind Singh498bf2a2016-03-08 15:44:17 +0530575
576error1:
577 if (NULL != cmd.chan_list)
578 qdf_mem_free(cmd.chan_list);
579
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800580 /* Send completion event for only for start scan request */
581 if (msg_type == WMA_START_SCAN_OFFLOAD_REQ) {
582 scan_event =
583 (tSirScanOffloadEvent *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530584 qdf_mem_malloc(sizeof(tSirScanOffloadEvent));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800585 if (!scan_event) {
586 WMA_LOGP("%s: Failed to allocate memory for scan rsp",
587 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530588 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 }
590 memset(scan_event, 0x00, sizeof(*scan_event));
591 scan_event->event = WMI_SCAN_EVENT_COMPLETED;
592 scan_event->reasonCode = eSIR_SME_SCAN_FAILED;
593 scan_event->sessionId = scan_req->sessionId;
594 scan_event->p2pScanType = scan_req->p2pScanType;
595 scan_event->scanId = scan_req->scan_id;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700596 scan_event->requestor = scan_req->scan_requestor_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597 wma_send_msg(wma_handle, WMA_RX_SCAN_EVENT, (void *)scan_event,
598 0);
599 }
Govind Singh498bf2a2016-03-08 15:44:17 +0530600
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530601 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602}
603
604/**
605 * wma_stop_scan() - stop scan command
606 * @wma_handle: wma handle
607 * @abort_scan_req: abort scan params
608 *
609 * Send stop scan command to fw.
610 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530611 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800612 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530613QDF_STATUS wma_stop_scan(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614 tAbortScanParams *abort_scan_req)
615{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530616 QDF_STATUS qdf_status;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800617 struct scan_cancel_param scan_param = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618
Govind Singh498bf2a2016-03-08 15:44:17 +0530619 scan_param.vdev_id = abort_scan_req->SessionId;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800620 scan_param.requester = abort_scan_req->scan_requestor_id;
Govind Singh498bf2a2016-03-08 15:44:17 +0530621 scan_param.scan_id = abort_scan_req->scan_id;
622 /* stop the scan with the corresponding scan_id */
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800623 scan_param.req_type = WLAN_SCAN_CANCEL_SINGLE;
Govind Singh498bf2a2016-03-08 15:44:17 +0530624 qdf_status = wmi_unified_scan_stop_cmd_send(wma_handle->wmi_handle,
625 &scan_param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626 /* Call the wmi api to request the scan */
Govind Singh498bf2a2016-03-08 15:44:17 +0530627 if (QDF_IS_STATUS_ERROR(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628 WMA_LOGE("wmi_unified_cmd_send WMI_STOP_SCAN_CMDID returned Error %d",
Govind Singh498bf2a2016-03-08 15:44:17 +0530629 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 goto error;
631 }
Archana Ramachandran31b5b652016-09-21 15:37:58 -0700632 WMA_LOGI("scan_id 0x%x, scan_requestor_id 0x%x, vdev_id %d",
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700633 abort_scan_req->scan_id,
634 abort_scan_req->scan_requestor_id,
635 abort_scan_req->SessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636 WMA_LOGI("WMA --> WMI_STOP_SCAN_CMDID");
637
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530638 return QDF_STATUS_SUCCESS;
Govind Singh498bf2a2016-03-08 15:44:17 +0530639
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800640error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530641 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800642}
643
644/**
645 * wma_update_channel_list() - update channel list
646 * @handle: wma handle
647 * @chan_list: channel list
648 *
649 * Function is used to update the support channel list in fw.
650 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530651 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800652 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530653QDF_STATUS wma_update_channel_list(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800654 tSirUpdateChanList *chan_list)
655{
656 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530657 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Govind Singhbc64c9e2016-02-25 17:42:38 +0530658 int i;
659 struct scan_chan_list_params scan_ch_param = {0};
Himanshu Agarwalb56ad2e2016-07-19 15:43:09 +0530660 wmi_channel_param *tchan_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661
Govind Singhbc64c9e2016-02-25 17:42:38 +0530662 scan_ch_param.chan_info = qdf_mem_malloc(sizeof(wmi_channel) *
663 chan_list->numChan);
664 if (NULL == scan_ch_param.chan_info) {
665 WMA_LOGE("%s: Failed to allocate channel info", __func__);
666 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667 }
Govind Singhbc64c9e2016-02-25 17:42:38 +0530668 qdf_mem_zero(scan_ch_param.chan_info, sizeof(wmi_channel) *
669 chan_list->numChan);
670 WMA_LOGD("no of channels = %d", chan_list->numChan);
671 tchan_info = scan_ch_param.chan_info;
672 scan_ch_param.num_scan_chans = chan_list->numChan;
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +0530673 wma_handle->saved_chan.num_channels = chan_list->numChan;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700674 WMA_LOGD("ht %d, vht %d, vht_24 %d", chan_list->ht_en,
675 chan_list->vht_en, chan_list->vht_24_en);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676
677 for (i = 0; i < chan_list->numChan; ++i) {
Govind Singhbc64c9e2016-02-25 17:42:38 +0530678 tchan_info->mhz =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800679 cds_chan_to_freq(chan_list->chanParam[i].chanId);
Govind Singhbc64c9e2016-02-25 17:42:38 +0530680 tchan_info->band_center_freq1 =
681 tchan_info->mhz;
682 tchan_info->band_center_freq2 = 0;
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +0530683 wma_handle->saved_chan.channel_list[i] =
684 chan_list->chanParam[i].chanId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685
Amar Singhal4b7b78b2016-08-23 15:49:41 -0700686 WMA_LOGD("chan[%d] = freq:%u chan:%d DFS:%d tx power:%d",
687 i, tchan_info->mhz,
688 chan_list->chanParam[i].chanId,
689 chan_list->chanParam[i].dfsSet,
690 chan_list->chanParam[i].pwr);
691
692 if (chan_list->chanParam[i].dfsSet)
693 WMI_SET_CHANNEL_FLAG(tchan_info,
694 WMI_CHAN_FLAG_PASSIVE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700696 if (tchan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) {
Govind Singhbc64c9e2016-02-25 17:42:38 +0530697 WMI_SET_CHANNEL_MODE(tchan_info, MODE_11G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700698 if (chan_list->vht_en && chan_list->vht_24_en)
699 WMI_SET_CHANNEL_FLAG(tchan_info,
700 WMI_CHAN_FLAG_ALLOW_VHT);
701 } else {
Govind Singhbc64c9e2016-02-25 17:42:38 +0530702 WMI_SET_CHANNEL_MODE(tchan_info, MODE_11A);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700703 if (chan_list->vht_en)
704 WMI_SET_CHANNEL_FLAG(tchan_info,
705 WMI_CHAN_FLAG_ALLOW_VHT);
706 }
707
708 if (chan_list->ht_en)
709 WMI_SET_CHANNEL_FLAG(tchan_info,
710 WMI_CHAN_FLAG_ALLOW_HT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800711
712 if (chan_list->chanParam[i].half_rate)
Govind Singhbc64c9e2016-02-25 17:42:38 +0530713 WMI_SET_CHANNEL_FLAG(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800714 WMI_CHAN_FLAG_HALF_RATE);
715 else if (chan_list->chanParam[i].quarter_rate)
Govind Singhbc64c9e2016-02-25 17:42:38 +0530716 WMI_SET_CHANNEL_FLAG(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 WMI_CHAN_FLAG_QUARTER_RATE);
718
Govind Singhbc64c9e2016-02-25 17:42:38 +0530719 WMI_SET_CHANNEL_MAX_TX_POWER(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800720 chan_list->chanParam[i].pwr);
721
Govind Singhbc64c9e2016-02-25 17:42:38 +0530722 WMI_SET_CHANNEL_REG_POWER(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800723 chan_list->chanParam[i].pwr);
Govind Singhbc64c9e2016-02-25 17:42:38 +0530724 tchan_info++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725 }
726
Govind Singhbc64c9e2016-02-25 17:42:38 +0530727 qdf_status = wmi_unified_scan_chan_list_cmd_send(wma_handle->wmi_handle,
728 &scan_ch_param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700730 if (QDF_IS_STATUS_ERROR(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 WMA_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
Govind Singhbc64c9e2016-02-25 17:42:38 +0530732
733 qdf_mem_free(scan_ch_param.chan_info);
734
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530735 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800736}
737
Varun Reddy Yeturu061d4d62017-07-20 09:39:32 -0700738QDF_STATUS wma_roam_scan_mawc_params(tp_wma_handle wma_handle,
739 tSirRoamOffloadScanReq *roam_req)
740{
741 struct wmi_mawc_roam_params *params;
742 QDF_STATUS status;
743
744 if (!roam_req) {
745 WMA_LOGE("No MAWC parameters to send");
746 return QDF_STATUS_E_INVAL;
747 }
748 params = qdf_mem_malloc(sizeof(*params));
749 if (!params) {
750 WMA_LOGE("No memory allocated for MAWC roam params");
751 return QDF_STATUS_E_NOMEM;
752 }
753 params->vdev_id = roam_req->sessionId;
754 params->enable = roam_req->mawc_roam_params.mawc_enabled &&
755 roam_req->mawc_roam_params.mawc_roam_enabled;
756 params->traffic_load_threshold =
757 roam_req->mawc_roam_params.mawc_roam_traffic_threshold;
758 params->best_ap_rssi_threshold =
759 roam_req->mawc_roam_params.mawc_roam_ap_rssi_threshold -
760 WMA_NOISE_FLOOR_DBM_DEFAULT;
761 params->rssi_stationary_high_adjust =
762 roam_req->mawc_roam_params.mawc_roam_rssi_high_adjust;
763 params->rssi_stationary_low_adjust =
764 roam_req->mawc_roam_params.mawc_roam_rssi_low_adjust;
765 status = wmi_unified_roam_mawc_params_cmd(
766 wma_handle->wmi_handle, params);
767 qdf_mem_free(params);
768
769 return status;
770}
771
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800772/**
773 * wma_roam_scan_offload_mode() - send roam scan mode request to fw
774 * @wma_handle: wma handle
775 * @scan_cmd_fp: start scan command ptr
776 * @roam_req: roam request param
777 * @mode: mode
778 * @vdev_id: vdev id
779 *
780 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
781 * of WMI_ROAM_SCAN_MODE.
782 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530783 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530785QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 wmi_start_scan_cmd_fixed_param *
787 scan_cmd_fp,
788 tSirRoamOffloadScanReq *roam_req,
789 uint32_t mode, uint32_t vdev_id)
790{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530791 QDF_STATUS status = QDF_STATUS_SUCCESS;
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530792 struct roam_offload_scan_params *params =
793 qdf_mem_malloc(sizeof(*params));
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530794
Arif Hussaincf6b9602016-10-25 14:46:53 -0700795 if (!params) {
796 WMA_LOGE("%s: Failed to allocate scan params", __func__);
797 return QDF_STATUS_E_NOMEM;
798 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Arif Hussaincf6b9602016-10-25 14:46:53 -0700800 params->auth_mode = WMI_AUTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 if (roam_req)
Arif Hussaincf6b9602016-10-25 14:46:53 -0700802 params->auth_mode = e_csr_auth_type_to_rsn_authmode
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 (roam_req->ConnectedNetwork.authentication,
804 roam_req->ConnectedNetwork.encryption);
Arif Hussaincf6b9602016-10-25 14:46:53 -0700805 WMA_LOGD("%s : auth mode = %d", __func__, params->auth_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530807
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530808 params->is_roam_req_valid = 0;
809 params->mode = mode;
810 params->vdev_id = vdev_id;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530811 if (roam_req) {
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530812 params->is_roam_req_valid = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800813#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530814 params->roam_offload_enabled = roam_req->RoamOffloadEnabled;
815 params->prefer_5ghz = roam_req->Prefer5GHz;
816 params->roam_rssi_cat_gap = roam_req->RoamRssiCatGap;
817 params->select_5ghz_margin = roam_req->Select5GHzMargin;
818 params->reassoc_failure_timeout =
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530819 roam_req->ReassocFailureTimeout;
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530820 params->rokh_id_length = roam_req->R0KH_ID_Length;
821 qdf_mem_copy(params->rokh_id, roam_req->R0KH_ID,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530822 WMI_ROAM_R0KH_ID_MAX_LEN);
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530823 qdf_mem_copy(params->krk, roam_req->KRK, WMI_KRK_KEY_LEN);
824 qdf_mem_copy(params->btk, roam_req->BTK, WMI_BTK_KEY_LEN);
825 qdf_mem_copy(params->psk_pmk, roam_req->PSK_PMK,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530826 WMI_ROAM_SCAN_PSK_SIZE);
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530827 params->pmk_len = roam_req->pmk_len;
828 params->roam_key_mgmt_offload_enabled =
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530829 roam_req->RoamKeyMgmtOffloadEnabled;
830 wma_roam_scan_fill_self_caps(wma_handle,
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530831 &params->roam_offload_params, roam_req);
Deepak Dhamdhere828f1892017-02-09 11:51:19 -0800832 params->fw_okc = roam_req->pmkid_modes.fw_okc;
833 params->fw_pmksa_cache = roam_req->pmkid_modes.fw_pmksa_cache;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530834#endif
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530835 params->is_ese_assoc = roam_req->IsESEAssoc;
836 params->mdid.mdie_present = roam_req->MDID.mdiePresent;
837 params->mdid.mobility_domain = roam_req->MDID.mobilityDomain;
838 params->assoc_ie_length = roam_req->assoc_ie.length;
839 qdf_mem_copy(params->assoc_ie, roam_req->assoc_ie.addIEdata,
840 roam_req->assoc_ie.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841 }
842
Varun Reddy Yeturu69d44b22017-08-15 14:29:32 -0700843 WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d, roam_scan_mode: %d"),
Naveen Rawat08340742016-11-17 14:54:39 -0800844 params->roam_offload_params.qos_caps,
Varun Reddy Yeturu69d44b22017-08-15 14:29:32 -0700845 params->roam_offload_params.qos_enabled,
846 params->mode);
Naveen Rawat08340742016-11-17 14:54:39 -0800847
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530848 status = wmi_unified_roam_scan_offload_mode_cmd(wma_handle->wmi_handle,
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530849 scan_cmd_fp, params);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530850 if (QDF_IS_STATUS_ERROR(status))
851 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800853 WMA_LOGD("%s: WMA --> WMI_ROAM_SCAN_MODE", __func__);
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530854 qdf_mem_free(params);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530855 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800856}
857
858/**
859 * wma_roam_scan_offload_rssi_threshold() - set scan offload rssi threashold
860 * @wma_handle: wma handle
861 * @roam_req: Roaming request buffer
862 *
863 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
864 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530865 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530867QDF_STATUS wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868 tSirRoamOffloadScanReq *roam_req)
869{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530870 struct roam_offload_scan_rssi_params params = {0};
871 QDF_STATUS status = QDF_STATUS_SUCCESS;
872 int rssi_thresh, rssi_thresh_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873 struct roam_ext_params *roam_params;
874 int32_t good_rssi_threshold;
875 uint32_t hirssi_scan_max_count;
876 uint32_t hirssi_scan_delta;
877 int32_t hirssi_upper_bound;
878
879 /* Send rssi threshold */
880 roam_params = &roam_req->roam_params;
881 rssi_thresh = roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT;
882 rssi_thresh_diff = roam_req->OpportunisticScanThresholdDiff;
883 hirssi_scan_max_count = roam_req->hi_rssi_scan_max_count;
884 hirssi_scan_delta = roam_req->hi_rssi_scan_rssi_delta;
885 hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub -
886 WMA_NOISE_FLOOR_DBM_DEFAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 /* fill in threshold values */
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530889 params.session_id = roam_req->sessionId;
890 params.rssi_thresh = rssi_thresh & 0x000000ff;
891 params.rssi_thresh_diff = rssi_thresh_diff & 0x000000ff;
892 params.hi_rssi_scan_max_count = hirssi_scan_max_count;
893 params.hi_rssi_scan_rssi_delta = hirssi_scan_delta;
894 params.hi_rssi_scan_rssi_ub = hirssi_upper_bound & 0x00000ff;
895 params.raise_rssi_thresh_5g = roam_params->raise_rssi_thresh_5g;
Gupta, Kapilc68ad462016-02-01 19:17:23 +0530896 params.dense_rssi_thresh_offset =
897 roam_params->dense_rssi_thresh_offset;
898 params.dense_min_aps_cnt = roam_params->dense_min_aps_cnt;
899 params.traffic_threshold =
900 roam_params->traffic_threshold;
Kapil Gupta0a2477b2016-08-23 18:00:34 +0530901 params.initial_dense_status = roam_params->initial_dense_status;
Varun Reddy Yeturufaad37e2017-07-26 10:54:13 -0700902 params.bg_scan_bad_rssi_thresh = roam_params->bg_scan_bad_rssi_thresh -
903 WMA_NOISE_FLOOR_DBM_DEFAULT;
904 params.bg_scan_client_bitmap = roam_params->bg_scan_client_bitmap;
Vignesh Viswanathanc018e982017-09-07 18:49:19 +0530905 params.roam_bad_rssi_thresh_offset_2g =
906 roam_params->roam_bad_rssi_thresh_offset_2g;
907 if (params.roam_bad_rssi_thresh_offset_2g)
908 params.flags |= WMI_ROAM_BG_SCAN_FLAGS_2G_TO_5G_ONLY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800910 /*
911 * The current Noise floor in firmware is -96dBm. Penalty/Boost
912 * threshold is applied on a weaker signal to make it even more weaker.
913 * So, there is a chance that the user may configure a very low
914 * Penalty/Boost threshold beyond the noise floor. If that is the case,
915 * then suppress the penalty/boost threshold to the noise floor.
916 */
917 if (roam_params->raise_rssi_thresh_5g < WMA_NOISE_FLOOR_DBM_DEFAULT)
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530918 params.penalty_threshold_5g = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919 else
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530920 params.boost_threshold_5g =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800921 (roam_params->raise_rssi_thresh_5g -
922 WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
923 if (roam_params->drop_rssi_thresh_5g < WMA_NOISE_FLOOR_DBM_DEFAULT)
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530924 params.penalty_threshold_5g = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 else
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530926 params.penalty_threshold_5g =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 (roam_params->drop_rssi_thresh_5g -
928 WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530929 params.raise_factor_5g = roam_params->raise_factor_5g;
930 params.drop_factor_5g = roam_params->drop_factor_5g;
931 params.max_raise_rssi_5g = roam_params->max_raise_rssi_5g;
932 params.max_drop_rssi_5g = roam_params->max_drop_rssi_5g;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800933
934 if (roam_params->good_rssi_roam)
935 good_rssi_threshold = WMA_NOISE_FLOOR_DBM_DEFAULT;
936 else
937 good_rssi_threshold = 0;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530938 params.good_rssi_threshold =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939 (good_rssi_threshold - WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
940
941 WMA_LOGD("WMA --> good_rssi_threshold=%d",
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530942 params.good_rssi_threshold);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800943
Varun Reddy Yeturu21953a22016-05-17 15:16:44 -0700944 if (roam_req->early_stop_scan_enable) {
945 params.roam_earlystop_thres_min =
946 roam_req->early_stop_scan_min_threshold -
947 WMA_NOISE_FLOOR_DBM_DEFAULT;
948 params.roam_earlystop_thres_max =
949 roam_req->early_stop_scan_max_threshold -
950 WMA_NOISE_FLOOR_DBM_DEFAULT;
951 } else {
952 params.roam_earlystop_thres_min = 0;
953 params.roam_earlystop_thres_max = 0;
954 }
Varun Reddy Yeturu168134f2017-06-26 13:46:05 -0700955 params.rssi_thresh_offset_5g =
956 roam_req->rssi_thresh_offset_5g;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530957
Varun Reddy Yeturu05186292015-09-28 17:12:33 -0700958 WMA_LOGD("early_stop_thresholds en=%d, min=%d, max=%d",
959 roam_req->early_stop_scan_enable,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530960 params.roam_earlystop_thres_min,
961 params.roam_earlystop_thres_max);
Varun Reddy Yeturu168134f2017-06-26 13:46:05 -0700962 WMA_LOGD("rssi_thresh_offset_5g = %d", params.rssi_thresh_offset_5g);
Varun Reddy Yeturu05186292015-09-28 17:12:33 -0700963
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530964 status = wmi_unified_roam_scan_offload_rssi_thresh_cmd(
965 wma_handle->wmi_handle, &params);
Varun Reddy Yeturufaad37e2017-07-26 10:54:13 -0700966 if (QDF_IS_STATUS_ERROR(status)) {
967 WMA_LOGE("roam_scan_offload_rssi_thresh_cmd failed %d", status);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530968 return status;
Varun Reddy Yeturufaad37e2017-07-26 10:54:13 -0700969 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800970
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800971 WMA_LOGD(FL("roam_scan_rssi_thresh=%d, roam_rssi_thresh_diff=%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800972 rssi_thresh, rssi_thresh_diff);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800973 WMA_LOGD(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800974 FL("hirssi_scan max_count=%d, delta=%d, hirssi_upper_bound=%d"),
975 hirssi_scan_max_count, hirssi_scan_delta, hirssi_upper_bound);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800976 WMA_LOGD(
Kapil Gupta0a2477b2016-08-23 18:00:34 +0530977 FL("dense_rssi_thresh_offset=%d, dense_min_aps_cnt=%d, traffic_threshold=%d initial_dense_status=%d"),
Gupta, Kapilc68ad462016-02-01 19:17:23 +0530978 roam_params->dense_rssi_thresh_offset,
979 roam_params->dense_min_aps_cnt,
Kapil Gupta0a2477b2016-08-23 18:00:34 +0530980 roam_params->traffic_threshold,
981 roam_params->initial_dense_status);
Vignesh Viswanathanc018e982017-09-07 18:49:19 +0530982 WMA_LOGD(FL("BG Scan Bad RSSI:%d, bitmap:0x%x Offset for 2G to 5G Roam:%d"),
Varun Reddy Yeturufaad37e2017-07-26 10:54:13 -0700983 roam_params->bg_scan_bad_rssi_thresh,
Vignesh Viswanathanc018e982017-09-07 18:49:19 +0530984 roam_params->bg_scan_client_bitmap,
985 roam_params->roam_bad_rssi_thresh_offset_2g);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530986 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987}
988
989/**
990 * wma_roam_scan_offload_scan_period() - set roam offload scan period
991 * @wma_handle: wma handle
992 * @scan_period: scan period
993 * @scan_age: scan age
994 * @vdev_id: vdev id
995 *
996 * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
997 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530998 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800999 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301000QDF_STATUS wma_roam_scan_offload_scan_period(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001 uint32_t scan_period,
1002 uint32_t scan_age,
1003 uint32_t vdev_id)
1004{
Govind Singh64b5e112016-03-08 11:53:50 +05301005 return wmi_unified_roam_scan_offload_scan_period(wma_handle->wmi_handle,
1006 scan_period, scan_age, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007}
1008
1009/**
1010 * wma_roam_scan_offload_rssi_change() - set roam offload RSSI change threshold
1011 * @wma_handle: wma handle
1012 * @rssi_change_thresh: RSSI Change threshold
1013 * @bcn_rssi_weight: beacon RSSI weight
1014 * @vdev_id: vdev id
1015 *
1016 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
1017 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301018 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001019 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301020QDF_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 uint32_t vdev_id,
1022 int32_t rssi_change_thresh,
1023 uint32_t bcn_rssi_weight,
1024 uint32_t hirssi_delay_btw_scans)
1025{
Govind Singh64b5e112016-03-08 11:53:50 +05301026 int status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001027
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001028 status = wmi_unified_roam_scan_offload_rssi_change_cmd(
1029 wma_handle->wmi_handle,
1030 vdev_id, rssi_change_thresh,
1031 bcn_rssi_weight, hirssi_delay_btw_scans);
Govind Singh64b5e112016-03-08 11:53:50 +05301032 if (status != EOK)
1033 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001034
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001035
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301036 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001037}
1038
1039/**
1040 * wma_roam_scan_offload_chan_list() - set roam offload channel list
1041 * @wma_handle: wma handle
1042 * @chan_count: channel count
1043 * @chan_list: channel list
1044 * @list_type: list type
1045 * @vdev_id: vdev id
1046 *
1047 * Set roam offload channel list.
1048 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301049 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001050 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301051QDF_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052 uint8_t chan_count,
1053 uint8_t *chan_list,
1054 uint8_t list_type, uint32_t vdev_id)
1055{
Govind Singh64b5e112016-03-08 11:53:50 +05301056 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057 int i;
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001058 uint32_t *chan_list_mhz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001059
1060 if (chan_count == 0) {
1061 WMA_LOGD("%s : invalid number of channels %d", __func__,
1062 chan_count);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301063 return QDF_STATUS_E_EMPTY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001064 }
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001065 chan_list_mhz = qdf_mem_malloc(chan_count * sizeof(*chan_list_mhz));
1066 if (chan_list_mhz == NULL) {
Naveen Rawat35804772016-06-27 15:40:28 -07001067 WMA_LOGE("%s : Memory allocation failed", __func__);
1068 return QDF_STATUS_E_NOMEM;
1069 }
1070
Govind Singh64b5e112016-03-08 11:53:50 +05301071 for (i = 0; ((i < chan_count) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001072 (i < SIR_ROAM_MAX_CHANNELS)); i++) {
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001073 chan_list_mhz[i] = cds_chan_to_freq(chan_list[i]);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08001074 WMA_LOGD("%d,", chan_list_mhz[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001075 }
1076
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001077 status = wmi_unified_roam_scan_offload_chan_list_cmd(
1078 wma_handle->wmi_handle,
1079 chan_count, chan_list_mhz,
1080 list_type, vdev_id);
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001081 qdf_mem_free(chan_list_mhz);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001082
Govind Singh64b5e112016-03-08 11:53:50 +05301083 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001084}
1085
1086/**
1087 * e_csr_auth_type_to_rsn_authmode() - map csr auth type to rsn authmode
1088 * @authtype: CSR authtype
1089 * @encr: CSR Encryption
1090 *
1091 * Map CSR's authentication type into RSN auth mode used by firmware
1092 *
1093 * Return: WMI RSN auth mode
1094 */
1095A_UINT32 e_csr_auth_type_to_rsn_authmode(eCsrAuthType authtype,
1096 eCsrEncryptionType encr)
1097{
1098 switch (authtype) {
1099 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
1100 return WMI_AUTH_OPEN;
1101 case eCSR_AUTH_TYPE_WPA:
1102 return WMI_AUTH_WPA;
1103 case eCSR_AUTH_TYPE_WPA_PSK:
1104 return WMI_AUTH_WPA_PSK;
1105 case eCSR_AUTH_TYPE_RSN:
1106 return WMI_AUTH_RSNA;
1107 case eCSR_AUTH_TYPE_RSN_PSK:
1108 return WMI_AUTH_RSNA_PSK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001109 case eCSR_AUTH_TYPE_FT_RSN:
1110 return WMI_AUTH_FT_RSNA;
1111 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1112 return WMI_AUTH_FT_RSNA_PSK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001113#ifdef FEATURE_WLAN_WAPI
1114 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1115 return WMI_AUTH_WAPI;
1116 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1117 return WMI_AUTH_WAPI_PSK;
1118#endif /* FEATURE_WLAN_WAPI */
1119#ifdef FEATURE_WLAN_ESE
1120 case eCSR_AUTH_TYPE_CCKM_WPA:
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001121 return WMI_AUTH_CCKM_WPA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001122 case eCSR_AUTH_TYPE_CCKM_RSN:
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001123 return WMI_AUTH_CCKM_RSNA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001124#endif /* FEATURE_WLAN_ESE */
1125#ifdef WLAN_FEATURE_11W
1126 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1127 return WMI_AUTH_RSNA_PSK_SHA256;
1128 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1129 return WMI_AUTH_RSNA_8021X_SHA256;
1130#endif /* WLAN_FEATURE_11W */
1131 case eCSR_AUTH_TYPE_NONE:
1132 case eCSR_AUTH_TYPE_AUTOSWITCH:
1133 /* In case of WEP and other keys, NONE means OPEN auth */
1134 if (encr == eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ||
1135 encr == eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ||
1136 encr == eCSR_ENCRYPT_TYPE_WEP40 ||
1137 encr == eCSR_ENCRYPT_TYPE_WEP104 ||
1138 encr == eCSR_ENCRYPT_TYPE_TKIP ||
Mukul Sharma05504ac2017-06-08 12:35:53 +05301139 encr == eCSR_ENCRYPT_TYPE_AES ||
1140 encr == eCSR_ENCRYPT_TYPE_AES_GCMP ||
1141 encr == eCSR_ENCRYPT_TYPE_AES_GCMP_256) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001142 return WMI_AUTH_OPEN;
1143 }
1144 return WMI_AUTH_NONE;
1145 default:
1146 return WMI_AUTH_NONE;
1147 }
1148}
1149
1150/**
1151 * e_csr_encryption_type_to_rsn_cipherset() - map csr enc type to ESN cipher
1152 * @encr: CSR Encryption
1153 *
1154 * Map CSR's encryption type into RSN cipher types used by firmware
1155 *
1156 * Return: WMI RSN cipher
1157 */
1158A_UINT32 e_csr_encryption_type_to_rsn_cipherset(eCsrEncryptionType encr)
1159{
1160
1161 switch (encr) {
1162 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
1163 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
1164 case eCSR_ENCRYPT_TYPE_WEP40:
1165 case eCSR_ENCRYPT_TYPE_WEP104:
1166 return WMI_CIPHER_WEP;
1167 case eCSR_ENCRYPT_TYPE_TKIP:
1168 return WMI_CIPHER_TKIP;
1169 case eCSR_ENCRYPT_TYPE_AES:
1170 return WMI_CIPHER_AES_CCM;
Mukul Sharma05504ac2017-06-08 12:35:53 +05301171 /* FWR will use key length to distinguish GCMP 128 or 256 */
1172 case eCSR_ENCRYPT_TYPE_AES_GCMP:
1173 case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
1174 return WMI_CIPHER_AES_GCM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001175#ifdef FEATURE_WLAN_WAPI
1176 case eCSR_ENCRYPT_TYPE_WPI:
1177 return WMI_CIPHER_WAPI;
1178#endif /* FEATURE_WLAN_WAPI */
1179 case eCSR_ENCRYPT_TYPE_ANY:
1180 return WMI_CIPHER_ANY;
1181 case eCSR_ENCRYPT_TYPE_NONE:
1182 default:
1183 return WMI_CIPHER_NONE;
1184 }
1185}
1186
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001187#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1188/**
1189 * wma_roam_scan_get_cckm_mode() - Get the CCKM auth mode
1190 * @roam_req: Roaming request buffer
1191 * @auth_mode: Auth mode to be converted
1192 *
1193 * Based on LFR2.0 or LFR3.0, return the proper auth type
1194 *
1195 * Return: if LFR2.0, then return WMI_AUTH_CCKM for backward compatibility
1196 * if LFR3.0 then return the appropriate auth type
1197 */
1198static uint32_t wma_roam_scan_get_cckm_mode(tSirRoamOffloadScanReq *roam_req,
1199 uint32_t auth_mode)
1200{
1201 if (roam_req->RoamOffloadEnabled)
1202 return auth_mode;
1203 else
1204 return WMI_AUTH_CCKM;
1205
1206}
1207#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001208/**
1209 * wma_roam_scan_fill_ap_profile() - fill ap_profile
1210 * @wma_handle: wma handle
1211 * @pMac: Mac ptr
1212 * @roam_req: roam offload scan request
1213 * @ap_profile_p: ap profile
1214 *
1215 * Fill ap_profile structure from configured parameters
1216 *
1217 * Return: none
1218 */
1219void wma_roam_scan_fill_ap_profile(tp_wma_handle wma_handle,
1220 tpAniSirGlobal pMac,
1221 tSirRoamOffloadScanReq *roam_req,
1222 wmi_ap_profile *ap_profile_p)
1223{
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001224 uint32_t rsn_authmode;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001225
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301226 qdf_mem_zero(ap_profile_p, sizeof(wmi_ap_profile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001227 if (roam_req == NULL) {
1228 ap_profile_p->ssid.ssid_len = 0;
1229 ap_profile_p->ssid.ssid[0] = 0;
1230 ap_profile_p->rsn_authmode = WMI_AUTH_NONE;
1231 ap_profile_p->rsn_ucastcipherset = WMI_CIPHER_NONE;
1232 ap_profile_p->rsn_mcastcipherset = WMI_CIPHER_NONE;
1233 ap_profile_p->rsn_mcastmgmtcipherset = WMI_CIPHER_NONE;
1234 ap_profile_p->rssi_threshold = WMA_ROAM_RSSI_DIFF_DEFAULT;
1235 } else {
1236 ap_profile_p->ssid.ssid_len =
1237 roam_req->ConnectedNetwork.ssId.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301238 qdf_mem_copy(ap_profile_p->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001239 roam_req->ConnectedNetwork.ssId.ssId,
1240 ap_profile_p->ssid.ssid_len);
1241 ap_profile_p->rsn_authmode =
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001242 e_csr_auth_type_to_rsn_authmode(
1243 roam_req->ConnectedNetwork.authentication,
1244 roam_req->ConnectedNetwork.encryption);
1245 rsn_authmode = ap_profile_p->rsn_authmode;
1246
1247 if ((rsn_authmode == WMI_AUTH_CCKM_WPA) ||
1248 (rsn_authmode == WMI_AUTH_CCKM_RSNA))
1249 ap_profile_p->rsn_authmode =
1250 wma_roam_scan_get_cckm_mode(
1251 roam_req, rsn_authmode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001252 ap_profile_p->rsn_ucastcipherset =
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001253 e_csr_encryption_type_to_rsn_cipherset(
1254 roam_req->ConnectedNetwork.encryption);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255 ap_profile_p->rsn_mcastcipherset =
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001256 e_csr_encryption_type_to_rsn_cipherset(
1257 roam_req->ConnectedNetwork.mcencryption);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001258 ap_profile_p->rsn_mcastmgmtcipherset =
1259 ap_profile_p->rsn_mcastcipherset;
1260 ap_profile_p->rssi_threshold = roam_req->RoamRssiDiff;
1261#ifdef WLAN_FEATURE_11W
1262 if (roam_req->ConnectedNetwork.mfp_enabled)
1263 ap_profile_p->flags |= WMI_AP_PROFILE_FLAG_PMF;
1264#endif
1265 }
1266}
1267
1268/**
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001269 * wma_process_set_pdev_ie_req() - process the pdev set IE req
1270 * @wma: Pointer to wma handle
1271 * @ie_params: Pointer to IE data.
1272 *
1273 * Sends the WMI req to set the IE to FW.
1274 *
1275 * Return: None
1276 */
1277void wma_process_set_pdev_ie_req(tp_wma_handle wma,
1278 struct set_ie_param *ie_params)
1279{
1280 if (ie_params->ie_type == DOT11_HT_IE)
1281 wma_process_set_pdev_ht_ie_req(wma, ie_params);
1282 if (ie_params->ie_type == DOT11_VHT_IE)
1283 wma_process_set_pdev_vht_ie_req(wma, ie_params);
1284
1285 qdf_mem_free(ie_params->ie_ptr);
1286}
1287
1288/**
1289 * wma_process_set_pdev_ht_ie_req() - sends HT IE data to FW
1290 * @wma: Pointer to wma handle
1291 * @ie_params: Pointer to IE data.
1292 * @nss: Nss values to prepare the HT IE.
1293 *
1294 * Sends the WMI req to set the HT IE to FW.
1295 *
1296 * Return: None
1297 */
1298void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
1299 struct set_ie_param *ie_params)
1300{
1301 int ret;
1302 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
1303 wmi_buf_t buf;
1304 uint16_t len;
1305 uint16_t ie_len_pad;
1306 uint8_t *buf_ptr;
1307
1308 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1309 ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_t));
1310 len += ie_len_pad;
1311
1312 buf = wmi_buf_alloc(wma->wmi_handle, len);
1313 if (!buf) {
1314 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1315 return;
1316 }
1317 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *) wmi_buf_data(buf);
1318 WMITLV_SET_HDR(&cmd->tlv_header,
1319 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
1320 WMITLV_GET_STRUCT_TLVLEN(
1321 wmi_pdev_set_ht_ie_cmd_fixed_param));
1322 cmd->reserved0 = 0;
1323 cmd->ie_len = ie_params->ie_len;
1324 cmd->tx_streams = ie_params->nss;
1325 cmd->rx_streams = ie_params->nss;
1326 WMA_LOGD("Setting pdev HT ie with Nss = %u",
1327 ie_params->nss);
1328 buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
1329 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
1330 if (ie_params->ie_len) {
1331 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
1332 (uint8_t *)ie_params->ie_ptr,
1333 ie_params->ie_len);
1334 }
1335 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
1336 WMI_PDEV_SET_HT_CAP_IE_CMDID);
1337 if (ret != EOK) {
1338 WMA_LOGE("Failed to send set param command ret = %d", ret);
1339 wmi_buf_free(buf);
1340 }
1341}
1342
1343/**
1344 * wma_process_set_pdev_vht_ie_req() - sends VHT IE data to FW
1345 * @wma: Pointer to wma handle
1346 * @ie_params: Pointer to IE data.
1347 * @nss: Nss values to prepare the VHT IE.
1348 *
1349 * Sends the WMI req to set the VHT IE to FW.
1350 *
1351 * Return: None
1352 */
1353void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
1354 struct set_ie_param *ie_params)
1355{
1356 int ret;
1357 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
1358 wmi_buf_t buf;
1359 uint16_t len;
1360 uint16_t ie_len_pad;
1361 uint8_t *buf_ptr;
1362
1363 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1364 ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_t));
1365 len += ie_len_pad;
1366
1367 buf = wmi_buf_alloc(wma->wmi_handle, len);
1368 if (!buf) {
1369 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1370 return;
1371 }
1372 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *) wmi_buf_data(buf);
1373 WMITLV_SET_HDR(&cmd->tlv_header,
1374 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
1375 WMITLV_GET_STRUCT_TLVLEN(
1376 wmi_pdev_set_vht_ie_cmd_fixed_param));
1377 cmd->reserved0 = 0;
1378 cmd->ie_len = ie_params->ie_len;
1379 cmd->tx_streams = ie_params->nss;
1380 cmd->rx_streams = ie_params->nss;
1381 WMA_LOGD("Setting pdev VHT ie with Nss = %u",
1382 ie_params->nss);
1383 buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
1384 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
1385 if (ie_params->ie_len) {
1386 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
1387 (uint8_t *)ie_params->ie_ptr,
1388 ie_params->ie_len);
1389 }
1390 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
1391 WMI_PDEV_SET_VHT_CAP_IE_CMDID);
1392 if (ret != EOK) {
1393 WMA_LOGE("Failed to send set param command ret = %d", ret);
1394 wmi_buf_free(buf);
1395 }
1396}
1397
1398/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001399 * wma_roam_scan_scan_params() - fill roam scan params
1400 * @wma_handle: wma handle
1401 * @pMac: Mac ptr
1402 * @scan_params: scan parameters
1403 * @roam_req: NULL if this routine is called before connect
1404 * It will be non-NULL if called after assoc.
1405 *
1406 * Fill scan_params structure from configured parameters
1407 *
1408 * Return: none
1409 */
1410void wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle,
1411 tpAniSirGlobal pMac,
1412 tSirRoamOffloadScanReq *roam_req,
1413 wmi_start_scan_cmd_fixed_param *
1414 scan_params)
1415{
1416 uint8_t channels_per_burst = 0;
1417 uint32_t val = 0;
1418
1419 if (NULL == pMac) {
1420 WMA_LOGE("%s: pMac is NULL", __func__);
1421 return;
1422 }
1423
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301424 qdf_mem_zero(scan_params, sizeof(wmi_start_scan_cmd_fixed_param));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425 scan_params->scan_ctrl_flags = WMI_SCAN_ADD_CCK_RATES |
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +05301426 WMI_SCAN_ADD_OFDM_RATES |
1427 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 if (roam_req != NULL) {
1429 /* Parameters updated after association is complete */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001430 WMA_LOGD("%s: NeighborScanChannelMinTime: %d NeighborScanChannelMaxTime: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431 __func__,
1432 roam_req->NeighborScanChannelMinTime,
1433 roam_req->NeighborScanChannelMaxTime);
Sridhar Selvaraj1b2330c2017-07-21 15:16:42 +05301434 WMA_LOGD("%s: NeighborScanTimerPeriod: %d "
1435 "neighbor_scan_min_timer_period %d "
1436 "HomeAwayTime: %d nProbes: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437 __func__,
1438 roam_req->NeighborScanTimerPeriod,
Sridhar Selvaraj1b2330c2017-07-21 15:16:42 +05301439 roam_req->neighbor_scan_min_timer_period,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 roam_req->HomeAwayTime, roam_req->nProbes);
1441
1442 /*
1443 * roam_req->NeighborScanChannelMaxTime = SCAN_CHANNEL_TIME
1444 * roam_req->HomeAwayTime = SCAN_HOME_AWAY_TIME
1445 * roam_req->NeighborScanTimerPeriod = SCAN_HOME_TIME
1446 *
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001447 * scan_params->dwell_time_active :time station stays on channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001448 * and sends probes;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001449 * scan_params->dwell_time_passive:time station stays on channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001450 * and listens probes;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001451 * scan_params->burst_duration :time station goes off channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452 * to scan;
1453 */
1454
1455 if (wlan_cfg_get_int
1456 (pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
1457 &val) != eSIR_SUCCESS) {
1458 /*
1459 * Could not get max channel value from CFG. Log error.
1460 */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001461 WMA_LOGE("could not retrieve passive max channel value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001462
1463 /* use a default value of 110ms */
1464 val = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
1465 }
1466
1467 scan_params->dwell_time_passive = val;
1468 /*
1469 * Here is the formula,
1470 * T(HomeAway) = N * T(dwell) + (N+1) * T(cs)
1471 * where N is number of channels scanned in single burst
1472 */
1473 scan_params->dwell_time_active =
1474 roam_req->NeighborScanChannelMaxTime;
1475 if (roam_req->HomeAwayTime <
1476 2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME) {
1477 /* clearly we can't follow home away time.
1478 * Make it a split scan.
1479 */
1480 scan_params->burst_duration = 0;
1481 } else {
1482 channels_per_burst =
1483 (roam_req->HomeAwayTime -
1484 WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME)
1485 / (scan_params->dwell_time_active +
1486 WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME);
1487
1488 if (channels_per_burst < 1) {
1489 /* dwell time and home away time conflicts */
1490 /* we will override dwell time */
1491 scan_params->dwell_time_active =
1492 roam_req->HomeAwayTime -
1493 2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME;
1494 scan_params->burst_duration =
1495 scan_params->dwell_time_active;
1496 } else {
1497 scan_params->burst_duration =
1498 channels_per_burst *
1499 scan_params->dwell_time_active;
1500 }
1501 }
1502 if (roam_req->allowDFSChannelRoam ==
1503 SIR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL
1504 && roam_req->HomeAwayTime > 0
1505 && roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) {
1506 /* Roaming on DFS channels is supported and it is not
1507 * app channel list. It is ok to override homeAwayTime
1508 * to accomodate DFS dwell time in burst
1509 * duration.
1510 */
1511 scan_params->burst_duration =
Anurag Chouhan6d760662016-02-20 16:05:43 +05301512 QDF_MAX(scan_params->burst_duration,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001513 scan_params->dwell_time_passive);
1514 }
Sridhar Selvaraj1b2330c2017-07-21 15:16:42 +05301515 scan_params->min_rest_time =
1516 roam_req->neighbor_scan_min_timer_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001517 scan_params->max_rest_time = roam_req->NeighborScanTimerPeriod;
1518 scan_params->repeat_probe_time = (roam_req->nProbes > 0) ?
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001519 QDF_MAX(scan_params->dwell_time_active /
1520 roam_req->nProbes, 1) : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 scan_params->probe_spacing_time = 0;
1522 scan_params->probe_delay = 0;
1523 /* 30 seconds for full scan cycle */
1524 scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
1525 scan_params->idle_time = scan_params->min_rest_time;
1526 scan_params->n_probes = roam_req->nProbes;
1527 if (roam_req->allowDFSChannelRoam ==
1528 SIR_ROAMING_DFS_CHANNEL_DISABLED) {
1529 scan_params->scan_ctrl_flags |= WMI_SCAN_BYPASS_DFS_CHN;
1530 } else {
1531 /* Roaming scan on DFS channel is allowed.
1532 * No need to change any flags for default
1533 * allowDFSChannelRoam = 1.
1534 * Special case where static channel list is given by\
1535 * application that contains DFS channels.
1536 * Assume that the application has knowledge of matching
1537 * APs being active and that probe request transmission
1538 * is permitted on those channel.
1539 * Force active scans on those channels.
1540 */
1541
1542 if (roam_req->allowDFSChannelRoam ==
1543 SIR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE &&
1544 roam_req->ChannelCacheType == CHANNEL_LIST_STATIC &&
1545 roam_req->ConnectedNetwork.ChannelCount > 0) {
1546 scan_params->scan_ctrl_flags |=
1547 WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
1548 }
1549 }
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05301550 WMI_SCAN_SET_DWELL_MODE(scan_params->scan_ctrl_flags,
1551 roam_req->roamscan_adaptive_dwell_mode);
1552
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001553 } else {
1554 /* roam_req = NULL during initial or pre-assoc invocation */
1555 scan_params->dwell_time_active =
1556 WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT;
1557 scan_params->dwell_time_passive =
1558 WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
1559 scan_params->min_rest_time = WMA_ROAM_MIN_REST_TIME_DEFAULT;
1560 scan_params->max_rest_time = WMA_ROAM_MAX_REST_TIME_DEFAULT;
1561 scan_params->repeat_probe_time = 0;
1562 scan_params->probe_spacing_time = 0;
1563 scan_params->probe_delay = 0;
1564 scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
1565 scan_params->idle_time = scan_params->min_rest_time;
1566 scan_params->burst_duration = 0;
1567 scan_params->n_probes = 0;
1568 }
1569
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001570 WMA_LOGD("%s: Rome roam scan parameters: dwell_time_active = %d, dwell_time_passive = %d",
1571 __func__, scan_params->dwell_time_active,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572 scan_params->dwell_time_passive);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001573 WMA_LOGD("%s: min_rest_time = %d, max_rest_time = %d, repeat_probe_time = %d n_probes = %d",
1574 __func__, scan_params->min_rest_time,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001575 scan_params->max_rest_time,
1576 scan_params->repeat_probe_time, scan_params->n_probes);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001577 WMA_LOGD("%s: max_scan_time = %d, idle_time = %d, burst_duration = %d, scan_ctrl_flags = 0x%x",
1578 __func__, scan_params->max_scan_time, scan_params->idle_time,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001579 scan_params->burst_duration, scan_params->scan_ctrl_flags);
1580}
1581
1582/**
1583 * wma_roam_scan_offload_ap_profile() - set roam ap profile in fw
1584 * @wma_handle: wma handle
1585 * @ap_profile_p: ap profile
1586 * @vdev_id: vdev id
1587 *
1588 * Send WMI_ROAM_AP_PROFILE to firmware
1589 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301590 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001591 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301592QDF_STATUS wma_roam_scan_offload_ap_profile(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001593 wmi_ap_profile *ap_profile_p,
1594 uint32_t vdev_id)
1595{
Govind Singh64b5e112016-03-08 11:53:50 +05301596 return wmi_unified_send_roam_scan_offload_ap_cmd(wma_handle->wmi_handle,
1597 ap_profile_p, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001598}
1599
1600/**
1601 * wma_roam_scan_filter() - Filter to be applied while roaming
1602 * @wma_handle: Global WMA Handle
1603 * @roam_req: Request which contains the filters
1604 *
1605 * There are filters such as whitelist, blacklist and preferred
1606 * list that need to be applied to the scan results to form the
1607 * probable candidates for roaming.
1608 *
1609 * Return: Return success upon succesfully passing the
1610 * parameters to the firmware, otherwise failure.
1611 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07001612static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle,
1613 tSirRoamOffloadScanReq *roam_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001614{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301615 int i;
1616 QDF_STATUS status = QDF_STATUS_SUCCESS;
Abhishek Singh2e1a11a2017-07-06 11:24:11 +05301617 uint32_t num_bssid_black_list = 0, num_ssid_white_list = 0,
Abhishek Singh4db8c152017-07-18 10:40:08 +05301618 num_bssid_preferred_list = 0, num_rssi_rejection_ap = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619 uint32_t op_bitmap = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 struct roam_ext_params *roam_params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301621 struct roam_scan_filter_params *params;
Selvaraj, Sridhar57ce4df2017-05-29 18:30:49 +05301622 struct lca_disallow_config_params *lca_config_params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301624 params = qdf_mem_malloc(sizeof(struct roam_scan_filter_params));
Naveen Rawat35804772016-06-27 15:40:28 -07001625 if (params == NULL) {
1626 WMA_LOGE("%s : Memory allocation failed", __func__);
1627 return QDF_STATUS_E_NOMEM;
1628 }
1629
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630 roam_params = &roam_req->roam_params;
Selvaraj, Sridhar57ce4df2017-05-29 18:30:49 +05301631 lca_config_params = &roam_req->lca_config_params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001632 if (roam_req->Command != ROAM_SCAN_OFFLOAD_STOP) {
1633 switch (roam_req->reason) {
1634 case REASON_ROAM_SET_BLACKLIST_BSSID:
1635 op_bitmap |= 0x1;
1636 num_bssid_black_list =
1637 roam_params->num_bssid_avoid_list;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638 break;
1639 case REASON_ROAM_SET_SSID_ALLOWED:
1640 op_bitmap |= 0x2;
1641 num_ssid_white_list =
1642 roam_params->num_ssid_allowed_list;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 break;
1644 case REASON_ROAM_SET_FAVORED_BSSID:
1645 op_bitmap |= 0x4;
1646 num_bssid_preferred_list =
1647 roam_params->num_bssid_favored;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648 break;
Selvaraj, Sridhar57ce4df2017-05-29 18:30:49 +05301649 case REASON_CTX_INIT:
1650 if (roam_req->Command == ROAM_SCAN_OFFLOAD_START) {
1651 params->lca_disallow_config_present = true;
Abhishek Singh4db8c152017-07-18 10:40:08 +05301652 op_bitmap |=
1653 ROAM_FILTER_OP_BITMAP_LCA_DISALLOW |
1654 ROAM_FILTER_OP_BITMAP_RSSI_REJECTION_OCE;
1655 num_rssi_rejection_ap =
1656 roam_params->num_rssi_rejection_ap;
Selvaraj, Sridhar57ce4df2017-05-29 18:30:49 +05301657 } else {
1658 WMA_LOGD("%s : Roam Filter need not be sent", __func__);
1659 qdf_mem_free(params);
1660 return QDF_STATUS_SUCCESS;
1661 }
1662 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001663 default:
1664 WMA_LOGD("%s : Roam Filter need not be sent", __func__);
Arif Hussaina915f492016-07-29 15:29:42 -07001665 qdf_mem_free(params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301666 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667 }
1668 } else {
1669 /* In case of STOP command, reset all the variables
1670 * except for blacklist BSSID which should be retained
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001671 * across connections.
1672 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673 op_bitmap = 0x2 | 0x4;
1674 num_ssid_white_list = roam_params->num_ssid_allowed_list;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001675 num_bssid_preferred_list = roam_params->num_bssid_favored;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001678 /* fill in fixed values */
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301679 params->session_id = roam_req->sessionId;
1680 params->op_bitmap = op_bitmap;
1681 params->num_bssid_black_list = num_bssid_black_list;
1682 params->num_ssid_white_list = num_ssid_white_list;
1683 params->num_bssid_preferred_list = num_bssid_preferred_list;
Abhishek Singh4db8c152017-07-18 10:40:08 +05301684 params->num_rssi_rejection_ap = num_rssi_rejection_ap;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301685 qdf_mem_copy(params->bssid_avoid_list, roam_params->bssid_avoid_list,
1686 MAX_BSSID_AVOID_LIST * sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001687
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 for (i = 0; i < num_ssid_white_list; i++) {
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301689 qdf_mem_copy(params->ssid_allowed_list[i].mac_ssid,
1690 roam_params->ssid_allowed_list[i].ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001691 roam_params->ssid_allowed_list[i].length);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301692 params->ssid_allowed_list[i].length =
1693 roam_params->ssid_allowed_list[i].length;
1694 WMA_LOGD("%s: SSID length=%d", __func__,
1695 params->ssid_allowed_list[i].length);
1696 qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
1697 (uint8_t *)params->ssid_allowed_list[i].mac_ssid,
1698 params->ssid_allowed_list[i].length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301700 qdf_mem_copy(params->bssid_favored, roam_params->bssid_favored,
1701 MAX_BSSID_FAVORED * sizeof(struct qdf_mac_addr));
1702 qdf_mem_copy(params->bssid_favored_factor,
1703 roam_params->bssid_favored_factor, MAX_BSSID_FAVORED);
Abhishek Singh4db8c152017-07-18 10:40:08 +05301704 qdf_mem_copy(params->rssi_rejection_ap,
1705 roam_params->rssi_rejection_ap,
1706 MAX_RSSI_AVOID_BSSID_LIST *
1707 sizeof(struct rssi_disallow_bssid));
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301708
Selvaraj, Sridhar57ce4df2017-05-29 18:30:49 +05301709 if (params->lca_disallow_config_present) {
1710 params->disallow_duration
1711 = lca_config_params->disallow_duration;
1712 params->rssi_channel_penalization
1713 = lca_config_params->rssi_channel_penalization;
1714 params->num_disallowed_aps
1715 = lca_config_params->num_disallowed_aps;
1716 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301717 status = wmi_unified_roam_scan_filter_cmd(wma_handle->wmi_handle,
1718 params);
1719
1720 qdf_mem_free(params);
1721 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001722}
1723
1724/**
1725 * wma_roam_scan_bmiss_cnt() - set bmiss count to fw
1726 * @wma_handle: wma handle
1727 * @first_bcnt: first bmiss count
1728 * @final_bcnt: final bmiss count
1729 * @vdev_id: vdev id
1730 *
1731 * set first & final biss count to fw.
1732 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301733 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301735QDF_STATUS wma_roam_scan_bmiss_cnt(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001736 A_INT32 first_bcnt,
1737 A_UINT32 final_bcnt, uint32_t vdev_id)
1738{
Govind Singhd76a5b02016-03-08 15:12:14 +05301739 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08001741 WMA_LOGD("%s: first_bcnt: %d, final_bcnt: %d", __func__, first_bcnt,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742 final_bcnt);
1743
Govind Singhd76a5b02016-03-08 15:12:14 +05301744 status = wma_vdev_set_param(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001745 vdev_id, WMI_VDEV_PARAM_BMISS_FIRST_BCNT,
1746 first_bcnt);
Govind Singhd76a5b02016-03-08 15:12:14 +05301747 if (QDF_IS_STATUS_ERROR(status)) {
1748 WMA_LOGE("wma_vdev_set_param WMI_VDEV_PARAM_BMISS_FIRST_BCNT returned Error %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 status);
Govind Singhd76a5b02016-03-08 15:12:14 +05301750 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751 }
1752
Govind Singhd76a5b02016-03-08 15:12:14 +05301753 status = wma_vdev_set_param(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001754 vdev_id, WMI_VDEV_PARAM_BMISS_FINAL_BCNT,
1755 final_bcnt);
Govind Singhd76a5b02016-03-08 15:12:14 +05301756 if (QDF_IS_STATUS_ERROR(status)) {
1757 WMA_LOGE("wma_vdev_set_param WMI_VDEV_PARAM_BMISS_FINAL_BCNT returned Error %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001758 status);
Govind Singhd76a5b02016-03-08 15:12:14 +05301759 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760 }
1761
Govind Singhd76a5b02016-03-08 15:12:14 +05301762 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001763}
1764
1765/**
1766 * wma_roam_scan_offload_command() - set roam offload command
1767 * @wma_handle: wma handle
1768 * @command: command
1769 * @vdev_id: vdev id
1770 *
1771 * This function set roam offload command to fw.
1772 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301773 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001774 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301775QDF_STATUS wma_roam_scan_offload_command(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776 uint32_t command, uint32_t vdev_id)
1777{
Govind Singh64b5e112016-03-08 11:53:50 +05301778 return wmi_unified_roam_scan_offload_cmd(wma_handle->wmi_handle,
1779 command, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001780}
1781
1782/**
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08001783 * wma_process_roaming_config() - process roam request
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001784 * @wma_handle: wma handle
1785 * @roam_req: roam request parameters
1786 *
1787 * Main routine to handle ROAM commands coming from CSR module.
1788 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301789 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001790 */
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08001791QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001792 tSirRoamOffloadScanReq *roam_req)
1793{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301794 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001795 wmi_start_scan_cmd_fixed_param scan_params;
1796 wmi_ap_profile ap_profile;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301797 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001798 uint32_t mode = 0;
1799 struct wma_txrx_node *intr = NULL;
1800
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001801 if (NULL == pMac) {
1802 WMA_LOGE("%s: pMac is NULL", __func__);
Selvaraj, Sridhar8fe6c672017-01-10 11:37:29 +05301803 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301804 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 }
1806
1807 if (!wma_handle->roam_offload_enabled) {
1808 /* roam scan offload is not enabled in firmware.
1809 * Cannot initialize it in the middle of connection.
1810 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301811 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301812 return QDF_STATUS_E_PERM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001813 }
Varun Reddy Yeturu061d4d62017-07-20 09:39:32 -07001814 WMA_LOGD("%s: RSO Command:%d, reason:%d",
1815 __func__, roam_req->Command, roam_req->reason);
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08001816 wma_handle->interfaces[roam_req->sessionId].roaming_in_progress = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817 switch (roam_req->Command) {
1818 case ROAM_SCAN_OFFLOAD_START:
1819 intr = &wma_handle->interfaces[roam_req->sessionId];
1820 intr->delay_before_vdev_stop = roam_req->delay_before_vdev_stop;
1821 /*
1822 * Scan/Roam threshold parameters are translated from fields of
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001823 * tSirRoamOffloadScanReq to WMITLV values sent to Rome firmware
1824 * some of these parameters are configurable in qcom_cfg.ini
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001825 */
1826
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001827 /* First param is positive rssi value to trigger rssi based scan
1828 * Opportunistic scan is started at 30dB > trigger rssi.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001829 */
1830 wma_handle->suitable_ap_hb_failure = false;
1831
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301832 qdf_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001833 roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301834 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835 break;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301836 qdf_status = wma_roam_scan_bmiss_cnt(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001837 roam_req->RoamBmissFirstBcnt,
1838 roam_req->RoamBmissFinalBcnt,
1839 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301840 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 break;
1842
1843 /* Opportunistic scan runs on a timer, value set by
1844 * EmptyRefreshScanPeriod. Age out the entries after 3 such
1845 * cycles.
1846 */
1847 if (roam_req->EmptyRefreshScanPeriod > 0) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301848 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001849 wma_roam_scan_offload_scan_period(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001850 roam_req->EmptyRefreshScanPeriod,
1851 roam_req->EmptyRefreshScanPeriod * 3,
1852 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301853 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001854 break;
1855
1856 mode = WMI_ROAM_SCAN_MODE_PERIODIC;
1857 /* Don't use rssi triggered roam scans if external app
1858 * is in control of channel list.
1859 */
1860 if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC)
1861 mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
1862
1863 } else {
1864 mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
1865 }
1866
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001867 /* Start new rssi triggered scan only if it changes by
1868 * RoamRssiDiff value. Beacon weight of 14 means average rssi
1869 * is taken over 14 previous samples + 2 times the current
1870 * beacon's rssi.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301872 qdf_status = wma_roam_scan_offload_rssi_change(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001873 roam_req->sessionId,
1874 roam_req->RoamRescanRssiDiff,
1875 roam_req->RoamBeaconRssiWeight,
1876 roam_req->hi_rssi_scan_delay);
1877
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301878 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001879 break;
1880
1881 wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req,
1882 &ap_profile);
1883
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301884 qdf_status = wma_roam_scan_offload_ap_profile(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001885 &ap_profile, roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301886 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887 break;
1888
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301889 qdf_status = wma_roam_scan_offload_chan_list(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001890 roam_req->ConnectedNetwork.ChannelCount,
1891 &roam_req->ConnectedNetwork.ChannelCache[0],
1892 roam_req->ChannelCacheType,
1893 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301894 if ((qdf_status != QDF_STATUS_SUCCESS) &&
1895 (qdf_status != QDF_STATUS_E_EMPTY))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001896 break;
1897
1898
1899 wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
1900 &scan_params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301901 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001902 wma_roam_scan_offload_mode(wma_handle, &scan_params,
1903 roam_req, mode,
1904 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301905 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001906 break;
Varun Reddy Yeturu061d4d62017-07-20 09:39:32 -07001907 qdf_status = wma_roam_scan_mawc_params(wma_handle, roam_req);
1908 if (qdf_status != QDF_STATUS_SUCCESS) {
1909 WMA_LOGE("Sending roaming MAWC params failed");
1910 break;
1911 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301912 qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
1913 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001914 WMA_LOGE("Sending start for roam scan filter failed");
1915 break;
1916 }
1917 break;
1918
1919 case ROAM_SCAN_OFFLOAD_STOP:
Varun Reddy Yeturu06488012017-05-25 11:44:10 -07001920 /*
1921 * If roam synch propagation is in progress and an user space
1922 * disconnect is requested, then there is no need to send the
1923 * RSO STOP to firmware, since the roaming is already complete.
1924 * If the RSO STOP is sent to firmware, then an HO_FAIL will be
1925 * generated and the expectation from firmware would be to
1926 * clean up the peer context on the host and not send down any
1927 * WMI PEER DELETE commands to firmware. But, if the user space
1928 * disconnect gets processed first, then there is a chance to
1929 * send down the PEER DELETE commands. Hence, if we do not
1930 * receive the HO_FAIL, and we complete the roam sync
1931 * propagation, then the host and firmware will be in sync with
1932 * respect to the peer and then the user space disconnect can
1933 * be handled gracefully in a normal way.
1934 *
1935 * Ensure to check the reason code since the RSO Stop might
1936 * come when roam sync failed as well and at that point it
1937 * should go through to the firmware and receive HO_FAIL
1938 * and clean up.
1939 */
1940 if (wma_is_roam_synch_in_progress(wma_handle,
1941 roam_req->sessionId) &&
1942 roam_req->reason ==
1943 REASON_ROAM_STOP_ALL) {
1944 WMA_LOGD("Dont send RSO stop during roam sync");
1945 break;
1946 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001947 wma_handle->suitable_ap_hb_failure = false;
1948 if (wma_handle->roam_offload_enabled) {
Abhishek Singh533c9da2017-05-04 10:23:34 +05301949 uint32_t mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001950
1951 wma_roam_scan_fill_scan_params(wma_handle, pMac,
1952 NULL, &scan_params);
Abhishek Singh533c9da2017-05-04 10:23:34 +05301953
1954 if (roam_req->reason == REASON_ROAM_STOP_ALL)
1955 mode = WMI_ROAM_SCAN_MODE_NONE;
1956 else
1957 mode = WMI_ROAM_SCAN_MODE_NONE |
1958 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301959 qdf_status = wma_roam_scan_offload_mode(wma_handle,
Abhishek Singh533c9da2017-05-04 10:23:34 +05301960 &scan_params, NULL, mode,
Selvaraj, Sridharecc81df2016-10-14 23:26:16 +05301961 roam_req->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001962 }
1963 /*
Varun Reddy Yeturu69d44b22017-08-15 14:29:32 -07001964 * After sending the roam scan mode because of a disconnect,
1965 * clear the scan bitmap client as well by sending
1966 * the following command
1967 */
1968 wma_roam_scan_offload_rssi_thresh(wma_handle, roam_req);
1969 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 * If the STOP command is due to a disconnect, then
1971 * send the filter command to clear all the filter
1972 * entries. If it is roaming scenario, then do not
1973 * send the cleared entries.
1974 */
1975 if (!roam_req->middle_of_roaming) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301976 qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
1977 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001978 WMA_LOGE("clear for roam scan filter failed");
1979 break;
1980 }
1981 }
1982
1983 if (roam_req->reason ==
1984 REASON_OS_REQUESTED_ROAMING_NOW) {
Rajeev Kumarcf7bd802017-04-18 11:11:42 -07001985 struct scheduler_msg cds_msg = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001986 tSirRoamOffloadScanRsp *scan_offload_rsp;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001987
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001988 scan_offload_rsp =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301989 qdf_mem_malloc(sizeof(*scan_offload_rsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990 if (!scan_offload_rsp) {
1991 WMA_LOGE("%s: Alloc failed for scan_offload_rsp",
1992 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301993 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301994 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001995 }
1996 cds_msg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP;
1997 scan_offload_rsp->sessionId = roam_req->sessionId;
1998 scan_offload_rsp->reason = roam_req->reason;
1999 cds_msg.bodyptr = scan_offload_rsp;
2000 /*
2001 * Since REASSOC request is processed in
2002 * Roam_Scan_Offload_Rsp post a dummy rsp msg back to
2003 * SME with proper reason code.
2004 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302005 if (QDF_STATUS_SUCCESS !=
Rajeev Kumarb60abe42017-01-21 15:39:31 -08002006 scheduler_post_msg(QDF_MODULE_ID_SME,
Rajeev Kumar156188e2017-01-21 17:23:52 -08002007 &cds_msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302008 qdf_mem_free(scan_offload_rsp);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302009 QDF_TRACE(QDF_MODULE_ID_WMA,
2010 QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 "%s: Failed to post Scan Offload Rsp to UMAC",
2012 __func__);
2013 }
2014 }
2015 break;
2016
2017 case ROAM_SCAN_OFFLOAD_ABORT_SCAN:
2018 /* If roam scan is running, stop that cycle.
2019 * It will continue automatically on next trigger.
2020 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302021 qdf_status = wma_roam_scan_offload_command(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002022 WMI_ROAM_SCAN_STOP_CMD,
2023 roam_req->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002024 break;
2025
2026 case ROAM_SCAN_OFFLOAD_RESTART:
2027 /* Rome offload engine does not stop after any scan.
2028 * If this command is sent because all preauth attempts failed
2029 * and WMI_ROAM_REASON_SUITABLE_AP event was received earlier,
2030 * now it is time to call it heartbeat failure.
2031 */
2032 if ((roam_req->reason == REASON_PREAUTH_FAILED_FOR_ALL)
2033 && wma_handle->suitable_ap_hb_failure) {
2034 WMA_LOGE("%s: Sending heartbeat failure after preauth failures",
2035 __func__);
2036 wma_beacon_miss_handler(wma_handle,
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05302037 roam_req->sessionId,
2038 wma_handle->suitable_ap_hb_failure_rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002039 wma_handle->suitable_ap_hb_failure = false;
2040 }
2041 break;
2042
2043 case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
2044 wma_handle->suitable_ap_hb_failure = false;
2045 wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
2046 &scan_params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302047 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002048 wma_roam_scan_offload_mode(wma_handle, &scan_params,
2049 roam_req,
2050 WMI_ROAM_SCAN_MODE_NONE,
2051 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302052 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002053 break;
2054
2055 if (roam_req->RoamScanOffloadEnabled == false)
2056 break;
2057
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302058 qdf_status = wma_roam_scan_bmiss_cnt(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002059 roam_req->RoamBmissFirstBcnt,
2060 roam_req->RoamBmissFinalBcnt,
2061 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302062 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002063 break;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302064 qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
2065 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 WMA_LOGE("Sending update for roam scan filter failed");
2067 break;
2068 }
2069
2070
2071 /*
2072 * Runtime (after association) changes to rssi thresholds and
2073 * other parameters.
2074 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302075 qdf_status = wma_roam_scan_offload_chan_list(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002076 roam_req->ConnectedNetwork.ChannelCount,
2077 &roam_req->ConnectedNetwork.ChannelCache[0],
2078 roam_req->ChannelCacheType,
2079 roam_req->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080 /*
2081 * Even though the channel list is empty, we can
2082 * still go ahead and start Roaming.
2083 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302084 if ((qdf_status != QDF_STATUS_SUCCESS) &&
2085 (qdf_status != QDF_STATUS_E_EMPTY))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086 break;
2087
2088
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302089 qdf_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090 roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302091 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002092 break;
2093
2094 if (roam_req->EmptyRefreshScanPeriod > 0) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002095 qdf_status = wma_roam_scan_offload_scan_period(
2096 wma_handle,
2097 roam_req->EmptyRefreshScanPeriod,
2098 roam_req->EmptyRefreshScanPeriod * 3,
2099 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302100 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002101 break;
2102
2103 mode = WMI_ROAM_SCAN_MODE_PERIODIC;
2104 /* Don't use rssi triggered roam scans if external app
2105 * is in control of channel list.
2106 */
2107 if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC)
2108 mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
2109
2110 } else {
2111 mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
2112 }
2113
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302114 qdf_status = wma_roam_scan_offload_rssi_change(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002115 roam_req->sessionId,
2116 roam_req->RoamRescanRssiDiff,
2117 roam_req->RoamBeaconRssiWeight,
2118 roam_req->hi_rssi_scan_delay);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302119 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002120 break;
2121
2122 wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req,
2123 &ap_profile);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002124 qdf_status = wma_roam_scan_offload_ap_profile(wma_handle,
2125 &ap_profile, roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302126 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002127 break;
2128
2129 wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
2130 &scan_params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302131 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002132 wma_roam_scan_offload_mode(wma_handle, &scan_params,
2133 roam_req, mode,
2134 roam_req->sessionId);
2135
2136 break;
2137
2138 default:
2139 break;
2140 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302141 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302142 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143}
2144
Kapil Gupta5cda2252016-12-29 18:44:26 +05302145void wma_update_per_roam_config(WMA_HANDLE handle,
2146 struct wmi_per_roam_config_req *req_buf)
2147{
2148 int status;
2149 tp_wma_handle wma_handle = (tp_wma_handle) handle;
2150
2151 if (!wma_handle || !wma_handle->wmi_handle) {
2152 WMA_LOGE("%s: WMA is closed, cannot send per roam config",
2153 __func__);
2154 return;
2155 }
2156
2157 status = wmi_unified_set_per_roam_config(wma_handle->wmi_handle,
2158 req_buf);
2159 if (status != EOK)
2160 WMA_LOGE("%s: failed to set per roam config to FW",
2161 __func__);
2162}
2163
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2165
2166/**
2167 * wma_process_roam_invoke() - send roam invoke command to fw.
2168 * @handle: wma handle
2169 * @roaminvoke: roam invoke command
2170 *
2171 * Send roam invoke command to fw for fastreassoc.
2172 *
2173 * Return: none
2174 */
2175void wma_process_roam_invoke(WMA_HANDLE handle,
2176 struct wma_roam_invoke_cmd *roaminvoke)
2177{
2178 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singh64b5e112016-03-08 11:53:50 +05302179 uint32_t ch_hz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180
2181 if (!wma_handle || !wma_handle->wmi_handle) {
2182 WMA_LOGE("%s: WMA is closed, can not send roam invoke",
2183 __func__);
Naveen Rawat664a7cb2017-01-19 17:58:14 -08002184 goto free_frame_buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185 }
Govind Singh64b5e112016-03-08 11:53:50 +05302186 ch_hz = (A_UINT32)cds_chan_to_freq(roaminvoke->channel);
2187 wmi_unified_roam_invoke_cmd(wma_handle->wmi_handle,
2188 (struct wmi_roam_invoke_cmd *)roaminvoke,
2189 ch_hz);
Naveen Rawat664a7cb2017-01-19 17:58:14 -08002190free_frame_buf:
2191 if (roaminvoke->frame_len) {
2192 qdf_mem_free(roaminvoke->frame_buf);
2193 roaminvoke->frame_buf = NULL;
2194 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002195}
2196
2197/**
2198 * wma_process_roam_synch_fail() -roam synch failure handle
2199 * @handle: wma handle
2200 * @synch_fail: roam synch fail parameters
2201 *
2202 * Return: none
2203 */
2204void wma_process_roam_synch_fail(WMA_HANDLE handle,
2205 struct roam_offload_synch_fail *synch_fail)
2206{
2207 tp_wma_handle wma_handle = (tp_wma_handle) handle;
2208 if (!wma_handle || !wma_handle->wmi_handle) {
2209 WMA_LOGE("%s: WMA is closed, can not clean-up roam synch",
2210 __func__);
2211 return;
2212 }
2213 /* Hand Off Failure could happen as an exception, when a roam synch
2214 * indication is posted to Host, but a roam synch complete is not
2215 * posted to the firmware.So, clear the roam synch in progress
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002216 * flag before disconnecting the session through this event.
2217 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002218 wma_handle->interfaces[synch_fail->session_id].roam_synch_in_progress =
2219 false;
2220}
2221
2222/**
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002223 * wma_fill_roam_synch_buffer() - Fill the the roam sync buffer
2224 * @wma: Global WMA Handle
2225 * @roam_synch_ind_ptr: Buffer to be filled
2226 * @param_buf: Source buffer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002227 *
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002228 * Firmware sends all the required information required for roam
2229 * synch propagation as TLV's and stored in param_buf. These
2230 * parameters are parsed and filled into the roam synch indication
2231 * buffer which will be used at different layers for propagation.
2232 *
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002233 * Return: Success or Failure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002234 */
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002235static int wma_fill_roam_synch_buffer(tp_wma_handle wma,
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002236 roam_offload_synch_ind *roam_synch_ind_ptr,
2237 WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002238{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002239 wmi_roam_synch_event_fixed_param *synch_event;
2240 uint8_t *bcn_probersp_ptr;
2241 uint8_t *reassoc_rsp_ptr;
2242 uint8_t *reassoc_req_ptr;
2243 wmi_channel *chan;
2244 wmi_key_material *key;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002245
2246 synch_event = param_buf->fixed_param;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002247 roam_synch_ind_ptr->roamedVdevId = synch_event->vdev_id;
2248 roam_synch_ind_ptr->authStatus = synch_event->auth_status;
2249 roam_synch_ind_ptr->roamReason = synch_event->roam_reason;
2250 roam_synch_ind_ptr->rssi = synch_event->rssi;
2251 roam_synch_ind_ptr->isBeacon = synch_event->is_beacon;
2252 WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid,
Srinivas Girigowda198b2032015-11-24 11:37:34 -08002253 roam_synch_ind_ptr->bssid.bytes);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002254 WMA_LOGI("%s: roamedVdevId %d authStatus %d roamReason %d rssi %d isBeacon %d",
2255 __func__, roam_synch_ind_ptr->roamedVdevId,
2256 roam_synch_ind_ptr->authStatus, roam_synch_ind_ptr->roamReason,
2257 roam_synch_ind_ptr->rssi, roam_synch_ind_ptr->isBeacon);
Padma, Santhosh Kumarcd35f532016-12-27 12:07:39 +05302258
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002259 if (!QDF_IS_STATUS_SUCCESS(
2260 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2261 roam_synch_ind_ptr, NULL, SIR_ROAMING_DEREGISTER_STA))) {
2262 WMA_LOGE("LFR3: CSR Roam synch cb failed");
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002263 return -EINVAL;
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002264 }
Naveen Rawat14298b92015-11-25 16:27:41 -08002265 /* Beacon/Probe Rsp data */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002266 roam_synch_ind_ptr->beaconProbeRespOffset =
2267 sizeof(roam_offload_synch_ind);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002268 bcn_probersp_ptr = (uint8_t *) roam_synch_ind_ptr +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002269 roam_synch_ind_ptr->beaconProbeRespOffset;
2270 roam_synch_ind_ptr->beaconProbeRespLength =
2271 synch_event->bcn_probe_rsp_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302272 qdf_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002273 roam_synch_ind_ptr->beaconProbeRespLength);
Naveen Rawat14298b92015-11-25 16:27:41 -08002274 /* ReAssoc Rsp data */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002275 roam_synch_ind_ptr->reassocRespOffset =
2276 sizeof(roam_offload_synch_ind) +
2277 roam_synch_ind_ptr->beaconProbeRespLength;
2278 roam_synch_ind_ptr->reassocRespLength = synch_event->reassoc_rsp_len;
2279 reassoc_rsp_ptr = (uint8_t *) roam_synch_ind_ptr +
2280 roam_synch_ind_ptr->reassocRespOffset;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302281 qdf_mem_copy(reassoc_rsp_ptr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002282 param_buf->reassoc_rsp_frame,
2283 roam_synch_ind_ptr->reassocRespLength);
Naveen Rawat14298b92015-11-25 16:27:41 -08002284
2285 /* ReAssoc Req data */
2286 roam_synch_ind_ptr->reassoc_req_offset =
2287 sizeof(roam_offload_synch_ind) +
2288 roam_synch_ind_ptr->beaconProbeRespLength +
2289 roam_synch_ind_ptr->reassocRespLength;
2290 roam_synch_ind_ptr->reassoc_req_length = synch_event->reassoc_req_len;
2291 reassoc_req_ptr = (uint8_t *) roam_synch_ind_ptr +
2292 roam_synch_ind_ptr->reassoc_req_offset;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302293 qdf_mem_copy(reassoc_req_ptr, param_buf->reassoc_req_frame,
Naveen Rawat14298b92015-11-25 16:27:41 -08002294 roam_synch_ind_ptr->reassoc_req_length);
2295
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002296 chan = (wmi_channel *) param_buf->chan;
2297 roam_synch_ind_ptr->chan_freq = chan->mhz;
2298 key = (wmi_key_material *) param_buf->key;
2299 if (key != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302300 qdf_mem_copy(roam_synch_ind_ptr->kck, key->kck,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002301 SIR_KCK_KEY_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302302 qdf_mem_copy(roam_synch_ind_ptr->kek, key->kek,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002303 SIR_KEK_KEY_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302304 qdf_mem_copy(roam_synch_ind_ptr->replay_ctr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002305 key->replay_counter, SIR_REPLAY_CTR_LEN);
Naveen Rawat14298b92015-11-25 16:27:41 -08002306 WMA_LOGD("%s: KCK dump", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302307 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002308 key->kck, SIR_KCK_KEY_LEN);
2309 WMA_LOGD("%s: KEK dump", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302310 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002311 key->kek, SIR_KEK_KEY_LEN);
2312 WMA_LOGD("%s: Key Replay Counter dump", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302313 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002314 key->replay_counter, SIR_REPLAY_CTR_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002315 }
Naveen Rawat8cc23b02016-07-14 12:22:56 -07002316 if (param_buf->hw_mode_transition_fixed_param)
2317 wma_process_pdev_hw_mode_trans_ind(wma,
2318 param_buf->hw_mode_transition_fixed_param,
2319 param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping,
2320 &roam_synch_ind_ptr->hw_mode_trans_ind);
2321 else
2322 WMA_LOGD(FL("hw_mode transition fixed param is NULL"));
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002323
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002324 return 0;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002325}
2326
2327/**
2328 * wma_roam_update_vdev() - Update the STA and BSS
2329 * @wma: Global WMA Handle
2330 * @roam_synch_ind_ptr: Information needed for roam sync propagation
2331 *
2332 * This function will perform all the vdev related operations with
2333 * respect to the self sta and the peer after roaming and completes
2334 * the roam synch propagation with respect to WMA layer.
2335 *
2336 * Return: None
2337 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002338static void wma_roam_update_vdev(tp_wma_handle wma,
2339 roam_offload_synch_ind *roam_synch_ind_ptr)
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002340{
2341 tDeleteBssParams *del_bss_params;
2342 tDeleteStaParams *del_sta_params;
2343 tLinkStateParams *set_link_params;
2344 tAddStaParams *add_sta_params;
2345 uint8_t vdev_id;
2346
Naveen Rawat746a90b2017-06-07 15:16:35 -07002347 vdev_id = roam_synch_ind_ptr->roamedVdevId;
2348 wma->interfaces[vdev_id].nss = roam_synch_ind_ptr->nss;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302349 del_bss_params = qdf_mem_malloc(sizeof(*del_bss_params));
2350 del_sta_params = qdf_mem_malloc(sizeof(*del_sta_params));
2351 set_link_params = qdf_mem_malloc(sizeof(*set_link_params));
2352 add_sta_params = qdf_mem_malloc(sizeof(*add_sta_params));
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002353 if (!del_bss_params || !del_sta_params ||
2354 !set_link_params || !add_sta_params) {
2355 WMA_LOGE("%s: failed to allocate memory", __func__);
2356 return;
2357 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302358 qdf_mem_zero(del_bss_params, sizeof(*del_bss_params));
2359 qdf_mem_zero(del_sta_params, sizeof(*del_sta_params));
2360 qdf_mem_zero(set_link_params, sizeof(*set_link_params));
2361 qdf_mem_zero(add_sta_params, sizeof(*add_sta_params));
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002362
2363 del_bss_params->smesessionId = vdev_id;
2364 del_sta_params->smesessionId = vdev_id;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302365 qdf_mem_copy(del_bss_params->bssid, wma->interfaces[vdev_id].bssid,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002366 IEEE80211_ADDR_LEN);
2367 set_link_params->state = eSIR_LINK_PREASSOC_STATE;
Varun Reddy Yeturu28925b42016-02-08 07:18:50 -08002368 qdf_mem_copy(set_link_params->selfMacAddr,
2369 roam_synch_ind_ptr->self_mac.bytes, IEEE80211_ADDR_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302370 qdf_mem_copy(set_link_params->bssid, roam_synch_ind_ptr->bssid.bytes,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002371 IEEE80211_ADDR_LEN);
2372 add_sta_params->staType = STA_ENTRY_SELF;
2373 add_sta_params->smesessionId = vdev_id;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302374 qdf_mem_copy(&add_sta_params->bssId, &roam_synch_ind_ptr->bssid.bytes,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002375 IEEE80211_ADDR_LEN);
2376 add_sta_params->staIdx = STA_INVALID_IDX;
2377 add_sta_params->assocId = roam_synch_ind_ptr->aid;
2378
2379 wma_delete_sta(wma, del_sta_params);
2380 wma_delete_bss(wma, del_bss_params);
2381 wma_set_linkstate(wma, set_link_params);
2382 wma_add_bss(wma, (tpAddBssParams)roam_synch_ind_ptr->add_bss_params);
2383 wma_add_sta(wma, add_sta_params);
Mukul Sharmaf9047232017-03-02 16:58:56 +05302384 wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_RUN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302385 qdf_mem_copy(wma->interfaces[vdev_id].bssid,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002386 roam_synch_ind_ptr->bssid.bytes, IEEE80211_ADDR_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302387 qdf_mem_free(del_bss_params);
2388 qdf_mem_free(del_sta_params);
2389 qdf_mem_free(set_link_params);
2390 qdf_mem_free(add_sta_params);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002391}
2392
2393/**
2394 * wma_roam_synch_event_handler() - roam synch event handler
2395 * @handle: wma handle
2396 * @event: event data
2397 * @len: length of data
2398 *
2399 * This function is roam synch event handler. It sends roam
2400 * indication for upper layer.
2401 *
2402 * Return: Success or Failure status
2403 */
2404int wma_roam_synch_event_handler(void *handle, uint8_t *event,
2405 uint32_t len)
2406{
2407 WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL;
2408 wmi_roam_synch_event_fixed_param *synch_event = NULL;
2409 tp_wma_handle wma = (tp_wma_handle) handle;
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002410 roam_offload_synch_ind *roam_synch_ind_ptr = NULL;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002411 tpSirBssDescription bss_desc_ptr = NULL;
2412 uint16_t ie_len = 0;
2413 int status = -EINVAL;
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002414 tSirRoamOffloadScanReq *roam_req;
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07002415 qdf_time_t roam_synch_received = qdf_get_system_timestamp();
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002416
2417 WMA_LOGD("LFR3:%s", __func__);
2418 if (!event) {
2419 WMA_LOGE("%s: event param null", __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002420 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002421 }
2422
2423 param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *) event;
2424 if (!param_buf) {
2425 WMA_LOGE("%s: received null buf from target", __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002426 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002427 }
2428
2429 synch_event = param_buf->fixed_param;
2430 if (!synch_event) {
2431 WMA_LOGE("%s: received null event data from target", __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002432 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002433 }
2434
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302435 DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07002436 synch_event->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
2437 QDF_PROTO_TYPE_EVENT, QDF_ROAM_SYNCH));
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302438
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002439 if (wma_is_roam_synch_in_progress(wma, synch_event->vdev_id)) {
2440 WMA_LOGE("%s: Ignoring RSI since one is already in progress",
2441 __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002442 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002443 }
Srinivas Girigowda6598eea2017-07-06 19:26:19 -07002444 WMA_LOGI("LFR3: Received WMA_ROAM_OFFLOAD_SYNCH_IND");
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002445
Varun Reddy Yeturu46ba20c2017-08-17 15:03:27 -07002446 /*
2447 * All below length fields are unsigned and hence positive numbers.
2448 * Maximum number during the addition would be (3 * MAX_LIMIT(UINT32) +
2449 * few fixed fields).
2450 */
2451 if (sizeof(*synch_event) + synch_event->bcn_probe_rsp_len +
2452 synch_event->reassoc_rsp_len +
2453 synch_event->reassoc_req_len +
2454 sizeof(wmi_channel) + sizeof(wmi_key_material) +
2455 sizeof(uint32_t) > WMI_SVC_MSG_MAX_SIZE) {
2456 WMA_LOGE("excess synch payload: LEN bcn:%d, req:%d, rsp:%d",
2457 synch_event->bcn_probe_rsp_len,
2458 synch_event->reassoc_req_len,
2459 synch_event->reassoc_rsp_len);
2460 goto cleanup_label;
2461 }
2462
Mukul Sharmae44d0542017-05-23 21:50:56 +05302463 cds_host_diag_log_work(&wma->roam_ho_wl,
2464 WMA_ROAM_HO_WAKE_LOCK_DURATION,
2465 WIFI_POWER_EVENT_WAKELOCK_WOW);
2466 qdf_wake_lock_timeout_acquire(&wma->roam_ho_wl,
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302467 WMA_ROAM_HO_WAKE_LOCK_DURATION);
2468
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002469 wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = true;
2470 len = sizeof(roam_offload_synch_ind) +
2471 synch_event->bcn_probe_rsp_len + synch_event->reassoc_rsp_len +
2472 synch_event->reassoc_req_len;
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302473 roam_synch_ind_ptr = (roam_offload_synch_ind *)qdf_mem_malloc(len);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002474 if (!roam_synch_ind_ptr) {
2475 WMA_LOGE("%s: failed to allocate memory for roam_synch_event",
2476 __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302477 QDF_ASSERT(roam_synch_ind_ptr != NULL);
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302478 status = -ENOMEM;
2479 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002480 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302481 qdf_mem_zero(roam_synch_ind_ptr, len);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002482 status = wma_fill_roam_synch_buffer(wma,
2483 roam_synch_ind_ptr, param_buf);
2484 if (status != 0)
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002485 goto cleanup_label;
Naveen Rawat8cc23b02016-07-14 12:22:56 -07002486 /* 24 byte MAC header and 12 byte to ssid IE */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002487 if (roam_synch_ind_ptr->beaconProbeRespLength >
2488 (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
2489 ie_len = roam_synch_ind_ptr->beaconProbeRespLength -
2490 (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
2491 } else {
2492 WMA_LOGE("LFR3: Invalid Beacon Length");
2493 goto cleanup_label;
2494 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302495 bss_desc_ptr = qdf_mem_malloc(sizeof(tSirBssDescription) + ie_len);
Kiran Kumar Lokereba3b4312016-04-29 16:40:20 -07002496 if (NULL == bss_desc_ptr) {
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002497 WMA_LOGE("LFR3: mem alloc failed!");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302498 QDF_ASSERT(bss_desc_ptr != NULL);
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302499 status = -ENOMEM;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002500 goto cleanup_label;
2501 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302502 qdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription) + ie_len);
Selvaraj, Sridhara6e3eba2017-03-14 19:52:39 +05302503 if (QDF_IS_STATUS_ERROR(wma->pe_roam_synch_cb(
2504 (tpAniSirGlobal)wma->mac_context,
2505 roam_synch_ind_ptr, bss_desc_ptr))) {
2506 WMA_LOGE("LFR3: PE roam synch cb failed");
2507 status = -EBUSY;
2508 goto cleanup_label;
2509 }
Naveen Rawat746a90b2017-06-07 15:16:35 -07002510
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002511 wma_roam_update_vdev(wma, roam_synch_ind_ptr);
2512 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07002513 roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_PROPAGATION);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002514 wma_process_roam_synch_complete(wma, synch_event->vdev_id);
Naveen Rawat8cc23b02016-07-14 12:22:56 -07002515
2516 /* update freq and channel width */
2517 wma->interfaces[synch_event->vdev_id].mhz =
2518 roam_synch_ind_ptr->chan_freq;
2519 if (roam_synch_ind_ptr->join_rsp)
2520 wma->interfaces[synch_event->vdev_id].chan_width =
2521 roam_synch_ind_ptr->join_rsp->vht_channel_width;
2522
2523 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2524 roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_COMPLETE);
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07002525 wma->interfaces[synch_event->vdev_id].roam_synch_delay =
2526 qdf_get_system_timestamp() - roam_synch_received;
2527 WMA_LOGD("LFR3: roam_synch_delay:%d",
2528 wma->interfaces[synch_event->vdev_id].roam_synch_delay);
Varun Reddy Yeturu04251862016-09-16 10:33:19 -07002529 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2530 roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_NAPI_OFF);
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302531
2532 status = 0;
2533
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002534cleanup_label:
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002535 if (status != 0) {
2536 if (roam_synch_ind_ptr)
2537 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2538 roam_synch_ind_ptr, NULL, SIR_ROAMING_ABORT);
2539 roam_req = qdf_mem_malloc(sizeof(tSirRoamOffloadScanReq));
Varun Reddy Yeturu06488012017-05-25 11:44:10 -07002540 if (roam_req && synch_event) {
Krunal Sonifea06802017-04-13 14:44:48 -07002541 roam_req->Command = ROAM_SCAN_OFFLOAD_STOP;
2542 roam_req->reason = REASON_ROAM_SYNCH_FAILED;
Varun Reddy Yeturu06488012017-05-25 11:44:10 -07002543 roam_req->sessionId = synch_event->vdev_id;
Krunal Sonifea06802017-04-13 14:44:48 -07002544 wma_process_roaming_config(wma, roam_req);
2545 }
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002546 }
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302547 if (roam_synch_ind_ptr && roam_synch_ind_ptr->join_rsp)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302548 qdf_mem_free(roam_synch_ind_ptr->join_rsp);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002549 if (roam_synch_ind_ptr)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302550 qdf_mem_free(roam_synch_ind_ptr);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002551 if (bss_desc_ptr)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302552 qdf_mem_free(bss_desc_ptr);
Krunal Sonifea06802017-04-13 14:44:48 -07002553 if (wma && synch_event)
2554 wma->interfaces[synch_event->vdev_id].roam_synch_in_progress =
2555 false;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002556
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302557 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558}
2559
2560/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002561 * wma_roam_scan_fill_self_caps() - fill capabilities
2562 * @wma_handle: wma handle
2563 * @roam_offload_params: offload parameters
2564 * @roam_req: roam request
2565 *
2566 * This function fills roam self capablities.
2567 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302568 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002569 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302570QDF_STATUS wma_roam_scan_fill_self_caps(tp_wma_handle wma_handle,
Himanshu Agarwalb56ad2e2016-07-19 15:43:09 +05302571 roam_offload_param *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002572 roam_offload_params,
2573 tSirRoamOffloadScanReq *roam_req)
2574{
2575 struct sAniSirGlobal *pMac = NULL;
2576 tSirMacCapabilityInfo selfCaps;
2577 uint32_t val = 0;
2578 uint32_t nCfgValue;
2579 uint16_t *pCfgValue16;
2580 uint8_t nCfgValue8, *pCfgValue8;
2581 tSirMacQosInfoStation macQosInfoSta;
2582 union {
2583 uint16_t nCfgValue16;
2584 tSirMacHTCapabilityInfo htCapInfo;
2585 tSirMacExtendedHTCapabilityInfo extHtCapInfo;
2586 } uHTCapabilityInfo;
2587
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302588 qdf_mem_set(&macQosInfoSta, sizeof(tSirMacQosInfoStation), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002589 /* Roaming is done only for INFRA STA type.
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002590 * So, ess will be one and ibss will be Zero
2591 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302592 pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002593 if (!pMac) {
2594 WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302595 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302596 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002597 }
2598
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002599 if (wlan_cfg_get_int(pMac, WNI_CFG_PRIVACY_ENABLED, &val) !=
2600 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302601 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002602 "Failed to get WNI_CFG_PRIVACY_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302603 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002604 }
2605 selfCaps.ess = 1;
2606 selfCaps.ibss = 0;
2607 if (val)
2608 selfCaps.privacy = 1;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002609 if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) !=
2610 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302611 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002612 "Failed to get WNI_CFG_SHORT_PREAMBLE");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302613 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614 }
2615 if (val)
2616 selfCaps.shortPreamble = 1;
2617
2618 selfCaps.pbcc = 0;
2619 selfCaps.channelAgility = 0;
2620 if (wlan_cfg_get_int(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
2621 &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302622 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002623 "Failed to get WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302624 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002625 }
2626 if (val)
2627 selfCaps.shortSlotTime = 1;
2628 if (wlan_cfg_get_int(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302629 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002630 "Failed to get WNI_CFG_11H_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302631 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002632 }
2633 if (val)
2634 selfCaps.spectrumMgt = 1;
2635 if (wlan_cfg_get_int(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302636 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002637 "Failed to get WNI_CFG_QOS_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302638 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002639 }
2640 if (val)
2641 selfCaps.qos = 1;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002642 if (wlan_cfg_get_int(pMac, WNI_CFG_APSD_ENABLED, &val) !=
2643 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302644 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002645 "Failed to get WNI_CFG_APSD_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302646 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002647 }
2648 if (val)
2649 selfCaps.apsd = 1;
Krishna Kumaar Natarajan4340c682015-11-03 12:09:00 -08002650
2651 selfCaps.rrm = pMac->rrm.rrmSmeContext.rrmConfig.rrm_enabled;
2652
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002653 if (wlan_cfg_get_int(pMac, WNI_CFG_BLOCK_ACK_ENABLED, &val) !=
2654 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302655 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002656 "Failed to get WNI_CFG_BLOCK_ACK_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302657 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002658 }
2659 selfCaps.delayedBA =
2660 (uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
2661 selfCaps.immediateBA =
2662 (uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
2663 pCfgValue16 = (uint16_t *) &selfCaps;
2664 roam_offload_params->capability = (*pCfgValue16) & 0xFFFF;
2665
2666 if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &nCfgValue) !=
2667 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302668 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 "Failed to get WNI_CFG_HT_CAP_INFO");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302670 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002671 }
2672 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2673 roam_offload_params->ht_caps_info =
2674 uHTCapabilityInfo.nCfgValue16 & 0xFFFF;
2675 if (wlan_cfg_get_int(pMac, WNI_CFG_HT_AMPDU_PARAMS, &nCfgValue) !=
2676 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302677 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678 "Failed to get WNI_CFG_HT_AMPDU_PARAMS");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302679 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680 }
2681 /* tSirMacHTParametersInfo */
2682 nCfgValue8 = (uint8_t) nCfgValue;
2683 roam_offload_params->ampdu_param = (nCfgValue8) & 0xFF;
2684
2685 val = ROAM_OFFLOAD_NUM_MCS_SET;
2686 if (wlan_cfg_get_str(pMac, WNI_CFG_SUPPORTED_MCS_SET,
2687 (uint8_t *) roam_offload_params->mcsset,
2688 &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302689 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690 "Failed to get WNI_CFG_SUPPORTED_MCS_SET");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302691 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002692 }
2693 if (wlan_cfg_get_int(pMac, WNI_CFG_EXT_HT_CAP_INFO, &nCfgValue) !=
2694 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302695 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696 "Failed to get WNI_CFG_EXT_HT_CAP_INFO");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302697 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698 }
2699 /* uHTCapabilityInfo.extHtCapInfo */
2700 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2701 roam_offload_params->ht_ext_cap =
2702 uHTCapabilityInfo.nCfgValue16 & 0xFFFF;
2703
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002704 if (wlan_cfg_get_int(pMac, WNI_CFG_TX_BF_CAP, &nCfgValue) !=
2705 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302706 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002707 "Failed to get WNI_CFG_TX_BF_CAP");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302708 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002709 }
2710 /* tSirMacTxBFCapabilityInfo */
2711 nCfgValue8 = (uint8_t) nCfgValue;
2712 roam_offload_params->ht_txbf = nCfgValue8 & 0xFF;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002713 if (wlan_cfg_get_int(pMac, WNI_CFG_AS_CAP, &nCfgValue) !=
2714 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302715 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002716 "Failed to get WNI_CFG_AS_CAP");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302717 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002718 }
2719 /* tSirMacASCapabilityInfo */
2720 nCfgValue8 = (uint8_t) nCfgValue;
2721 roam_offload_params->asel_cap = nCfgValue8 & 0xFF;
2722
2723 /* QOS Info */
2724 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &nCfgValue) !=
2725 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302726 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002727 "Failed to get WNI_CFG_MAX_SP_LENGTH");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302728 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 }
2730 nCfgValue8 = (uint8_t) nCfgValue;
2731 macQosInfoSta.maxSpLen = nCfgValue8;
2732 macQosInfoSta.moreDataAck = 0;
2733 macQosInfoSta.qack = 0;
2734 macQosInfoSta.acbe_uapsd = roam_req->AcUapsd.acbe_uapsd;
2735 macQosInfoSta.acbk_uapsd = roam_req->AcUapsd.acbk_uapsd;
2736 macQosInfoSta.acvi_uapsd = roam_req->AcUapsd.acvi_uapsd;
2737 macQosInfoSta.acvo_uapsd = roam_req->AcUapsd.acvo_uapsd;
2738 pCfgValue8 = (uint8_t *) &macQosInfoSta;
2739 /* macQosInfoSta Only queue_request is set.Refer to
2740 * populate_dot11f_wmm_caps for more details
2741 */
2742 roam_offload_params->qos_caps = (*pCfgValue8) & 0xFF;
Naveen Rawat08340742016-11-17 14:54:39 -08002743 if (roam_offload_params->qos_caps)
2744 roam_offload_params->qos_enabled = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002745 roam_offload_params->wmm_caps = 0x4 & 0xFF;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302746 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747}
2748
2749/**
2750 * wma_set_ric_req() - set ric request element
2751 * @wma: wma handle
2752 * @msg: message
2753 * @is_add_ts: is addts required
2754 *
2755 * This function sets ric request element for 11r roaming.
2756 *
2757 * Return: none
2758 */
2759void wma_set_ric_req(tp_wma_handle wma, void *msg, uint8_t is_add_ts)
2760{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05302761 if (!wma) {
2762 WMA_LOGE("%s: wma handle is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002763 return;
2764 }
2765
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05302766 wmi_unified_set_ric_req_cmd(wma->wmi_handle, msg, is_add_ts);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002767}
2768#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
2769
2770/**
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08002771 * wma_rssi_breached_event_handler() - rssi breached event handler
2772 * @handle: wma handle
2773 * @cmd_param_info: event handler data
2774 * @len: length of @cmd_param_info
2775 *
2776 * Return: 0 on success; error number otherwise
2777 */
2778int wma_rssi_breached_event_handler(void *handle,
2779 u_int8_t *cmd_param_info, u_int32_t len)
2780{
2781 WMI_RSSI_BREACH_EVENTID_param_tlvs *param_buf;
2782 wmi_rssi_breach_event_fixed_param *event;
2783 struct rssi_breach_event rssi;
2784 tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
2785
2786 if (!mac) {
2787 WMA_LOGE("%s: Invalid mac context", __func__);
2788 return -EINVAL;
2789 }
2790 if (!mac->sme.rssi_threshold_breached_cb) {
2791 WMA_LOGE("%s: Callback not registered", __func__);
2792 return -EINVAL;
2793 }
2794 param_buf = (WMI_RSSI_BREACH_EVENTID_param_tlvs *)cmd_param_info;
2795 if (!param_buf) {
2796 WMA_LOGE("%s: Invalid rssi breached event", __func__);
2797 return -EINVAL;
2798 }
2799 event = param_buf->fixed_param;
2800
2801 rssi.request_id = event->request_id;
2802 rssi.session_id = event->vdev_id;
2803 rssi.curr_rssi = event->rssi + WMA_TGT_NOISE_FLOOR_DBM;
2804 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->bssid, rssi.curr_bssid.bytes);
2805
2806 WMA_LOGD("%s: req_id: %u vdev_id: %d curr_rssi: %d", __func__,
2807 rssi.request_id, rssi.session_id, rssi.curr_rssi);
2808 WMA_LOGI("%s: curr_bssid: %pM", __func__, rssi.curr_bssid.bytes);
2809
2810 mac->sme.rssi_threshold_breached_cb(mac->hHdd, &rssi);
2811 WMA_LOGD("%s: Invoke HDD rssi breached callback", __func__);
2812 return 0;
2813}
2814
2815/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002816 * wma_process_unit_test_cmd() - send unit test command to fw.
2817 * @handle: wma handle
2818 * @wma_utest: unit test command
2819 *
2820 * This function send unit test command to fw.
2821 *
2822 * Return: none
2823 */
2824void wma_process_unit_test_cmd(WMA_HANDLE handle,
2825 t_wma_unit_test_cmd *wma_utest)
2826{
2827 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002828
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002829 if (!wma_handle || !wma_handle->wmi_handle) {
2830 WMA_LOGE("%s: WMA is closed, can not issue fw unit test cmd",
2831 __func__);
2832 return;
2833 }
Govind Singh64b5e112016-03-08 11:53:50 +05302834
2835 if (wmi_unified_unit_test_cmd(wma_handle->wmi_handle,
2836 (struct wmi_unit_test_cmd *)wma_utest)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002837 return;
2838 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002839}
2840
2841#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002842/**
2843 * wma_roam_ho_fail_handler() - LFR3.0 roam hand off failed handler
2844 * @wma: wma handle
2845 * @vdev_id: vdev id
2846 *
2847 * Return: none
2848 */
2849static void wma_roam_ho_fail_handler(tp_wma_handle wma, uint32_t vdev_id)
2850{
2851 tSirSmeHOFailureInd *ho_failure_ind;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08002852 struct scheduler_msg sme_msg = { 0 };
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302853 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002854
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302855 ho_failure_ind = qdf_mem_malloc(sizeof(tSirSmeHOFailureInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002856
2857 if (NULL == ho_failure_ind) {
2858 WMA_LOGE("%s: Memory allocation failure", __func__);
2859 return;
2860 }
2861 ho_failure_ind->sessionId = vdev_id;
2862 sme_msg.type = eWNI_SME_HO_FAIL_IND;
2863 sme_msg.bodyptr = ho_failure_ind;
2864 sme_msg.bodyval = 0;
2865
Rajeev Kumarb60abe42017-01-21 15:39:31 -08002866 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302867 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002868 WMA_LOGE("Fail to post eWNI_SME_HO_FAIL_IND msg to SME");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302869 qdf_mem_free(ho_failure_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002870 return;
2871 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002872}
2873
2874/**
2875 * wma_process_roam_synch_complete() - roam synch complete command to fw.
2876 * @handle: wma handle
2877 * @synchcnf: offload synch confirmation params
2878 *
2879 * This function sends roam synch complete event to fw.
2880 *
2881 * Return: none
2882 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002883void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002884{
2885 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002886
2887 if (!wma_handle || !wma_handle->wmi_handle) {
2888 WMA_LOGE("%s: WMA is closed, can not issue roam synch cnf",
2889 __func__);
2890 return;
2891 }
Govind Singh64b5e112016-03-08 11:53:50 +05302892
2893 if (wmi_unified_roam_synch_complete_cmd(wma_handle->wmi_handle,
2894 vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002895 return;
2896 }
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302897
2898 DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07002899 vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
2900 QDF_PROTO_TYPE_EVENT, QDF_ROAM_COMPLETE));
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302901
Srinivas Girigowda6598eea2017-07-06 19:26:19 -07002902 WMA_LOGI("LFR3: Posting WMA_ROAM_OFFLOAD_SYNCH_CNF");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002903}
2904#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
2905
2906/**
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002907 * wma_switch_channel() - WMA api to switch channel dynamically
2908 * @wma: Pointer of WMA context
2909 * @req: Pointer vdev_start having channel switch info.
2910 *
2911 * Return: 0 for success, otherwise appropriate error code
2912 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002913static QDF_STATUS wma_switch_channel(tp_wma_handle wma,
2914 struct wma_vdev_start_req *req)
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002915{
2916
2917 wmi_buf_t buf;
2918 wmi_channel *cmd;
2919 int32_t len, ret;
2920 WLAN_PHY_MODE chanmode;
2921 struct wma_txrx_node *intr = wma->interfaces;
2922 tpAniSirGlobal pmac;
2923
2924 pmac = cds_get_context(QDF_MODULE_ID_PE);
2925
2926 if (pmac == NULL) {
2927 WMA_LOGE("%s: vdev start failed as pmac is NULL", __func__);
2928 return QDF_STATUS_E_FAILURE;
2929 }
2930
2931 len = sizeof(*cmd);
2932 buf = wmi_buf_alloc(wma->wmi_handle, len);
2933 if (!buf) {
2934 WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
2935 return QDF_STATUS_E_NOMEM;
2936 }
2937 cmd = (wmi_channel *)wmi_buf_data(buf);
2938 WMITLV_SET_HDR(&cmd->tlv_header,
2939 WMITLV_TAG_STRUC_wmi_channel,
2940 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
2941
2942 /* Fill channel info */
2943 cmd->mhz = cds_chan_to_freq(req->chan);
Amar Singhal046eb8a2016-05-05 12:50:15 -07002944 chanmode = wma_chan_phy_mode(req->chan, req->chan_width,
2945 req->dot11_mode);
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002946
2947 intr[req->vdev_id].chanmode = chanmode; /* save channel mode */
2948 intr[req->vdev_id].ht_capable = req->ht_capable;
2949 intr[req->vdev_id].vht_capable = req->vht_capable;
2950 intr[req->vdev_id].config.gtx_info.gtxRTMask[0] =
2951 CFG_TGT_DEFAULT_GTX_HT_MASK;
2952 intr[req->vdev_id].config.gtx_info.gtxRTMask[1] =
2953 CFG_TGT_DEFAULT_GTX_VHT_MASK;
Rajeev Kumar Sirasanagandlaaf474742016-09-06 17:54:50 +05302954
2955 if (wlan_cfg_get_int(pmac, WNI_CFG_TGT_GTX_USR_CFG,
2956 &intr[req->vdev_id].config.gtx_info.gtxUsrcfg) != eSIR_SUCCESS) {
2957 intr[req->vdev_id].config.gtx_info.gtxUsrcfg =
2958 WNI_CFG_TGT_GTX_USR_CFG_STADEF;
2959 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_WARN,
2960 "Failed to get WNI_CFG_TGT_GTX_USR_CFG");
2961 }
2962
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002963 intr[req->vdev_id].config.gtx_info.gtxPERThreshold =
2964 CFG_TGT_DEFAULT_GTX_PER_THRESHOLD;
2965 intr[req->vdev_id].config.gtx_info.gtxPERMargin =
2966 CFG_TGT_DEFAULT_GTX_PER_MARGIN;
2967 intr[req->vdev_id].config.gtx_info.gtxTPCstep =
2968 CFG_TGT_DEFAULT_GTX_TPC_STEP;
2969 intr[req->vdev_id].config.gtx_info.gtxTPCMin =
2970 CFG_TGT_DEFAULT_GTX_TPC_MIN;
2971 intr[req->vdev_id].config.gtx_info.gtxBWMask =
2972 CFG_TGT_DEFAULT_GTX_BW_MASK;
2973 intr[req->vdev_id].mhz = cmd->mhz;
2974
2975 WMI_SET_CHANNEL_MODE(cmd, chanmode);
2976 cmd->band_center_freq1 = cmd->mhz;
2977
2978 if (chanmode == MODE_11AC_VHT80)
2979 cmd->band_center_freq1 =
2980 cds_chan_to_freq(req->ch_center_freq_seg0);
2981
2982 if ((chanmode == MODE_11NA_HT40) || (chanmode == MODE_11NG_HT40) ||
2983 (chanmode == MODE_11AC_VHT40)) {
2984 if (req->chan_width == CH_WIDTH_80MHZ)
2985 cmd->band_center_freq1 += 10;
2986 else
2987 cmd->band_center_freq1 -= 10;
2988 }
2989 cmd->band_center_freq2 = 0;
2990
2991 /* Set half or quarter rate WMI flags */
2992 if (req->is_half_rate)
2993 WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_HALF_RATE);
2994 else if (req->is_quarter_rate)
2995 WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_QUARTER_RATE);
2996
2997 /* Find out min, max and regulatory power levels */
2998 WMI_SET_CHANNEL_REG_POWER(cmd, req->max_txpow);
2999 WMI_SET_CHANNEL_MAX_TX_POWER(cmd, req->max_txpow);
3000
3001
3002 WMA_LOGE("%s: freq %d channel %d chanmode %d center_chan %d center_freq2 %d reg_info_1: 0x%x reg_info_2: 0x%x, req->max_txpow: 0x%x",
3003 __func__, cmd->mhz, req->chan, chanmode,
3004 cmd->band_center_freq1, cmd->band_center_freq2,
3005 cmd->reg_info_1, cmd->reg_info_2, req->max_txpow);
3006
3007
3008 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
3009 WMI_PDEV_SET_CHANNEL_CMDID);
3010
3011 if (ret < 0) {
3012 WMA_LOGP("%s: Failed to send vdev start command", __func__);
Dustin Brown2afb6f52016-12-02 14:47:48 -08003013 wmi_buf_free(buf);
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003014 return QDF_STATUS_E_FAILURE;
3015 }
3016
3017 return QDF_STATUS_SUCCESS;
3018}
3019
3020/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003021 * wma_set_channel() - set channel
3022 * @wma: wma handle
3023 * @params: switch channel parameters
3024 *
3025 * Return: none
3026 */
3027void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
3028{
3029 struct wma_vdev_start_req req;
3030 struct wma_target_req *msg;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303031 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003032 uint8_t vdev_id, peer_id;
Leo Chang96464902016-10-28 11:10:54 -07003033 void *peer;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003034 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003035 struct wma_txrx_node *intr = wma->interfaces;
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003036 struct policy_mgr_hw_mode_params hw_mode = {0};
Leo Chang96464902016-10-28 11:10:54 -07003037 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003038
3039 WMA_LOGD("%s: Enter", __func__);
3040 if (!wma_find_vdev_by_addr(wma, params->selfStaMacAddr, &vdev_id)) {
3041 WMA_LOGP("%s: Failed to find vdev id for %pM",
3042 __func__, params->selfStaMacAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303043 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003044 goto send_resp;
3045 }
Anurag Chouhan6d760662016-02-20 16:05:43 +05303046 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003047 if (NULL == pdev) {
3048 WMA_LOGE("%s: Failed to get pdev", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303049 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003050 goto send_resp;
3051 }
3052
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08003053 peer = cdp_peer_find_by_addr(soc,
3054 pdev,
3055 intr[vdev_id].bssid, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003056
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303057 qdf_mem_zero(&req, sizeof(req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003058 req.vdev_id = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003059 req.chan = params->channelNumber;
3060 req.chan_width = params->ch_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07003061
3062 if (params->ch_width == CH_WIDTH_10MHZ)
3063 req.is_half_rate = 1;
3064 else if (params->ch_width == CH_WIDTH_5MHZ)
3065 req.is_quarter_rate = 1;
3066
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003067 req.vht_capable = params->vhtCapable;
3068 req.ch_center_freq_seg0 = params->ch_center_freq_seg0;
3069 req.ch_center_freq_seg1 = params->ch_center_freq_seg1;
3070 req.dot11_mode = params->dot11_mode;
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08003071 wma_update_vdev_he_capable(&req, params);
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08003072
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08003073 WMA_LOGI(FL("vht_capable: %d, dot11_mode: %d"),
3074 req.vht_capable, req.dot11_mode);
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08003075
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003076 status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303077 if (!QDF_IS_STATUS_SUCCESS(status))
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07003078 WMA_LOGE("policy_mgr_get_current_hw_mode failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003079
Tushnim Bhattacharyya825b0f72017-07-14 15:21:04 -07003080 if (params->nss == 2) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003081 req.preferred_rx_streams = 2;
3082 req.preferred_tx_streams = 2;
3083 } else {
3084 req.preferred_rx_streams = 1;
3085 req.preferred_tx_streams = 1;
3086 }
3087
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003088 req.max_txpow = params->maxTxPower;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003089 req.beacon_intval = 100;
3090 req.dtim_period = 1;
3091 req.is_dfs = params->isDfsChannel;
Arif Hussain671a1902017-03-17 09:08:32 -07003092 req.cac_duration_ms = params->cac_duration_ms;
3093 req.dfs_regdomain = params->dfs_regdomain;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003094
3095 /* In case of AP mode, once radar is detected, we need to
3096 * issuse VDEV RESTART, so we making is_channel_switch as
3097 * true
3098 */
3099 if ((wma_is_vdev_in_ap_mode(wma, req.vdev_id) == true) ||
3100 (params->restart_on_chan_switch == true))
3101 wma->interfaces[req.vdev_id].is_channel_switch = true;
3102
Kiran Kumar Lokeref9dc7912017-06-28 18:10:58 -07003103 if (params->restart_on_chan_switch == true &&
3104 wma->interfaces[req.vdev_id].beacon_filter_enabled)
3105 wma_remove_beacon_filter(wma,
3106 &wma->interfaces[req.vdev_id].beacon_filter);
3107
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003108 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() &&
3109 wma_is_vdev_up(vdev_id)) {
3110 status = wma_switch_channel(wma, &req);
3111 if (status != QDF_STATUS_SUCCESS)
3112 WMA_LOGE("%s: wma_switch_channel failed %d\n", __func__,
3113 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003114
Leo Chang96464902016-10-28 11:10:54 -07003115 /* This is temporary, should be removed */
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003116 ol_htt_mon_note_chan(pdev, req.chan);
Arif Hussainf73e8432017-02-22 11:45:50 -08003117 goto send_resp;
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003118 } else {
Sandeep Puligillafe426b62017-02-07 18:07:14 -08003119
3120 msg = wma_fill_vdev_req(wma, req.vdev_id, WMA_CHNL_SWITCH_REQ,
3121 WMA_TARGET_REQ_TYPE_VDEV_START, params,
3122 WMA_VDEV_START_REQUEST_TIMEOUT);
3123 if (!msg) {
3124 WMA_LOGP("%s: Failed to fill channel switch request for vdev %d",
3125 __func__, req.vdev_id);
3126 status = QDF_STATUS_E_NOMEM;
3127 goto send_resp;
3128 }
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003129 status = wma_vdev_start(wma, &req,
3130 wma->interfaces[req.vdev_id].is_channel_switch);
3131 if (status != QDF_STATUS_SUCCESS) {
3132 wma_remove_vdev_req(wma, req.vdev_id,
3133 WMA_TARGET_REQ_TYPE_VDEV_START);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003134 WMA_LOGP("%s: vdev start failed status = %d", __func__,
3135 status);
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003136 goto send_resp;
3137 }
3138
Leo Chang96464902016-10-28 11:10:54 -07003139 /* This is temporary, should be removed */
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003140 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
3141 ol_htt_mon_note_chan(pdev, req.chan);
3142 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003143 return;
3144send_resp:
3145 WMA_LOGD("%s: channel %d ch_width %d txpower %d status %d", __func__,
3146 params->channelNumber, params->ch_width,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003147 params->maxTxPower,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003148 status);
3149 params->status = status;
3150 WMA_LOGI("%s: sending WMA_SWITCH_CHANNEL_RSP, status = 0x%x",
3151 __func__, status);
Abhishek Singh2d775fd2017-08-18 10:51:33 +05303152 wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
3153 (void *)params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003154}
3155
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003156#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003157/**
3158 * wma_plm_start() - plm start request
3159 * @wma: wma handle
3160 * @plm: plm request parameters
3161 *
3162 * This function request FW to start PLM.
3163 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303164 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003165 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303166QDF_STATUS wma_plm_start(tp_wma_handle wma, const tpSirPlmReq plm)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003167{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303168 struct plm_req_params params = {0};
3169 uint32_t num_channels;
3170 uint32_t *channel_list = NULL;
3171 uint32_t i;
3172 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003173
3174 if (NULL == plm || NULL == wma) {
3175 WMA_LOGE("%s: input pointer is NULL ", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303176 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003177 }
3178 WMA_LOGD("PLM Start");
3179
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303180 num_channels = plm->plmNumCh;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003181
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303182 if (num_channels) {
3183 channel_list = qdf_mem_malloc(sizeof(uint32_t) * num_channels);
3184 if (!channel_list)
3185 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003186
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303187 for (i = 0; i < num_channels; i++) {
3188 channel_list[i] = plm->plmChList[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003189
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303190 if (channel_list[i] < WMA_NLO_FREQ_THRESH)
3191 channel_list[i] =
3192 cds_chan_to_freq(channel_list[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003193 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003194 }
3195
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303196 params.diag_token = plm->diag_token;
3197 params.meas_token = plm->meas_token;
3198 params.num_bursts = plm->numBursts;
3199 params.burst_int = plm->burstInt;
3200 params.meas_duration = plm->measDuration;
3201 params.burst_len = plm->burstLen;
3202 params.desired_tx_pwr = plm->desiredTxPwr;
3203 params.plm_num_ch = plm->plmNumCh;
3204 params.session_id = plm->sessionId;
3205 params.enable = plm->enable;
3206 qdf_mem_copy(&params.mac_addr, &plm->mac_addr,
3207 sizeof(struct qdf_mac_addr));
3208 qdf_mem_copy(params.plm_ch_list, plm->plmChList,
3209 WMI_CFG_VALID_CHANNEL_LIST_LEN);
3210
3211 status = wmi_unified_plm_start_cmd(wma->wmi_handle,
3212 &params, channel_list);
3213 if (QDF_IS_STATUS_ERROR(status)) {
3214 qdf_mem_free(channel_list);
3215 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003216 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303217
3218 qdf_mem_free(channel_list);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219 wma->interfaces[plm->sessionId].plm_in_progress = true;
3220
3221 WMA_LOGD("Plm start request sent successfully for vdev %d",
3222 plm->sessionId);
3223
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303224 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225}
3226
3227/**
3228 * wma_plm_stop() - plm stop request
3229 * @wma: wma handle
3230 * @plm: plm request parameters
3231 *
3232 * This function request FW to stop PLM.
3233 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303234 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003235 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303236QDF_STATUS wma_plm_stop(tp_wma_handle wma, const tpSirPlmReq plm)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003237{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303238 struct plm_req_params params = {0};
3239 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003240
3241 if (NULL == plm || NULL == wma) {
3242 WMA_LOGE("%s: input pointer is NULL ", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303243 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003244 }
3245
3246 if (false == wma->interfaces[plm->sessionId].plm_in_progress) {
3247 WMA_LOGE("No active plm req found, skip plm stop req");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303248 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249 }
3250
3251 WMA_LOGD("PLM Stop");
3252
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303253 params.diag_token = plm->diag_token;
3254 params.meas_token = plm->meas_token;
3255 params.num_bursts = plm->numBursts;
3256 params.burst_int = plm->burstInt;
3257 params.meas_duration = plm->measDuration;
3258 params.burst_len = plm->burstLen;
3259 params.desired_tx_pwr = plm->desiredTxPwr;
3260 params.plm_num_ch = plm->plmNumCh;
3261 params.session_id = plm->sessionId;
3262 params.enable = plm->enable;
3263 qdf_mem_copy(&params.mac_addr, &plm->mac_addr,
3264 sizeof(struct qdf_mac_addr));
3265 qdf_mem_copy(params.plm_ch_list, plm->plmChList,
3266 WMI_CFG_VALID_CHANNEL_LIST_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303268 status = wmi_unified_plm_stop_cmd(wma->wmi_handle,
3269 &params);
3270 if (QDF_IS_STATUS_ERROR(status))
3271 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003272
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003273 wma->interfaces[plm->sessionId].plm_in_progress = false;
3274
3275 WMA_LOGD("Plm stop request sent successfully for vdev %d",
3276 plm->sessionId);
3277
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303278 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279}
3280
3281/**
3282 * wma_config_plm()- config PLM
3283 * @wma: wma handle
3284 * @plm: plm request parameters
3285 *
3286 * Return: none
3287 */
3288void wma_config_plm(tp_wma_handle wma, tpSirPlmReq plm)
3289{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303290 QDF_STATUS ret = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003291
3292 if (NULL == plm || NULL == wma)
3293 return;
3294
3295 if (plm->enable)
3296 ret = wma_plm_start(wma, plm);
3297 else
3298 ret = wma_plm_stop(wma, plm);
3299
3300 if (ret)
3301 WMA_LOGE("%s: PLM %s failed %d", __func__,
3302 plm->enable ? "start" : "stop", ret);
3303
3304 /* SME expects WMA to free tpSirPlmReq memory after
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003305 * processing PLM request.
3306 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303307 qdf_mem_free(plm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003308 plm = NULL;
3309}
3310#endif
3311
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003312#ifdef FEATURE_WLAN_EXTSCAN
3313/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003314 * wma_extscan_wow_event_callback() - extscan wow event callback
3315 * @handle: WMA handle
3316 * @event: event buffer
3317 * @len: length of @event buffer
3318 *
3319 * In wow case, the wow event is followed by the payload of the event
3320 * which generated the wow event.
3321 * payload is 4 bytes of length followed by event buffer. the first 4 bytes
3322 * of event buffer is common tlv header, which is a combination
3323 * of tag (higher 2 bytes) and length (lower 2 bytes). The tag is used to
3324 * identify the event which triggered wow event.
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003325 * Payload is extracted and converted into generic tlv structure before
3326 * being passed to this function.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003327 *
Dustin Browne2206fb2017-04-20 13:39:25 -07003328 * @Return: Errno
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003329 */
Dustin Browne2206fb2017-04-20 13:39:25 -07003330int wma_extscan_wow_event_callback(void *handle, void *event, uint32_t len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003331{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003332 uint32_t tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(event));
3333
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003334 switch (tag) {
3335 case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003336 return wma_extscan_start_stop_event_handler(handle, event, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003337
3338 case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003339 return wma_extscan_operations_event_handler(handle, event, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003340
3341 case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003342 return wma_extscan_table_usage_event_handler(handle, event,
3343 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003344
3345 case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003346 return wma_extscan_cached_results_event_handler(handle, event,
3347 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003348
3349 case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003350 return wma_extscan_change_results_event_handler(handle, event,
3351 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003352
3353 case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003354 return wma_extscan_hotlist_match_event_handler(handle, event,
3355 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003356
3357 case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003358 return wma_extscan_capabilities_event_handler(handle, event,
3359 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003360
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003361 default:
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003362 WMA_LOGE(FL("Unknown tag: %d"), tag);
Dustin Browne2206fb2017-04-20 13:39:25 -07003363 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003364 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003365}
3366#endif
3367
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368/**
3369 * wma_register_extscan_event_handler() - register extscan event handler
3370 * @wma_handle: wma handle
3371 *
3372 * This function register extscan related event handlers.
3373 *
3374 * Return: none
3375 */
3376void wma_register_extscan_event_handler(tp_wma_handle wma_handle)
3377{
3378 if (!wma_handle) {
3379 WMA_LOGE("%s: extscan wma_handle is NULL", __func__);
3380 return;
3381 }
3382 wmi_unified_register_event_handler(wma_handle->wmi_handle,
3383 WMI_EXTSCAN_START_STOP_EVENTID,
Govind Singhd76a5b02016-03-08 15:12:14 +05303384 wma_extscan_start_stop_event_handler,
3385 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003386
3387 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303388 WMI_EXTSCAN_CAPABILITIES_EVENTID,
3389 wma_extscan_capabilities_event_handler,
3390 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003391
3392 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303393 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID,
3394 wma_extscan_hotlist_match_event_handler,
3395 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003396
3397 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303398 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID,
3399 wma_extscan_change_results_event_handler,
3400 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003401
3402 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303403 WMI_EXTSCAN_OPERATION_EVENTID,
3404 wma_extscan_operations_event_handler,
3405 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003406 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303407 WMI_EXTSCAN_TABLE_USAGE_EVENTID,
3408 wma_extscan_table_usage_event_handler,
3409 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410
3411 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303412 WMI_EXTSCAN_CACHED_RESULTS_EVENTID,
3413 wma_extscan_cached_results_event_handler,
3414 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003415
3416 wmi_unified_register_event_handler(wma_handle->wmi_handle,
3417 WMI_PASSPOINT_MATCH_EVENTID,
Govind Singhd76a5b02016-03-08 15:12:14 +05303418 wma_passpoint_match_event_handler,
3419 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003420}
3421
3422#ifdef FEATURE_WLAN_EXTSCAN
3423
3424/**
3425 * wma_extscan_start_stop_event_handler() - extscan start/stop event handler
3426 * @handle: wma handle
3427 * @cmd_param_info: event buffer
3428 * @len: data length
3429 *
3430 * This function handles different extscan related commands
3431 * like start/stop/get results etc and indicate to upper layers.
3432 *
3433 * Return: 0 for success or error code.
3434 */
3435int wma_extscan_start_stop_event_handler(void *handle,
3436 uint8_t *cmd_param_info,
3437 uint32_t len)
3438{
3439 WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *param_buf;
3440 wmi_extscan_start_stop_event_fixed_param *event;
3441 struct sir_extscan_generic_response *extscan_ind;
3442 uint16_t event_type;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303443 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003444
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003445 if (!pMac) {
3446 WMA_LOGE("%s: Invalid pMac", __func__);
3447 return -EINVAL;
3448 }
3449 if (!pMac->sme.pExtScanIndCb) {
3450 WMA_LOGE("%s: Callback not registered", __func__);
3451 return -EINVAL;
3452 }
3453 param_buf = (WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *)
3454 cmd_param_info;
3455 if (!param_buf) {
3456 WMA_LOGE("%s: Invalid extscan event", __func__);
3457 return -EINVAL;
3458 }
3459 event = param_buf->fixed_param;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303460 extscan_ind = qdf_mem_malloc(sizeof(*extscan_ind));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003461 if (!extscan_ind) {
3462 WMA_LOGE("%s: extscan memory allocation failed", __func__);
3463 return -ENOMEM;
3464 }
3465 switch (event->command) {
3466 case WMI_EXTSCAN_START_CMDID:
3467 event_type = eSIR_EXTSCAN_START_RSP;
3468 extscan_ind->status = event->status;
3469 extscan_ind->request_id = event->request_id;
3470 break;
3471 case WMI_EXTSCAN_STOP_CMDID:
3472 event_type = eSIR_EXTSCAN_STOP_RSP;
3473 extscan_ind->status = event->status;
3474 extscan_ind->request_id = event->request_id;
3475 break;
3476 case WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID:
3477 extscan_ind->status = event->status;
3478 extscan_ind->request_id = event->request_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003479 if (event->mode == WMI_EXTSCAN_MODE_STOP)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003480 event_type =
3481 eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003482 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003483 event_type =
3484 eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003485 break;
3486 case WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID:
3487 extscan_ind->status = event->status;
3488 extscan_ind->request_id = event->request_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003489 if (event->mode == WMI_EXTSCAN_MODE_STOP)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003490 event_type = eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003491 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003492 event_type = eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003493 break;
3494 case WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID:
3495 extscan_ind->status = event->status;
3496 extscan_ind->request_id = event->request_id;
3497 event_type = eSIR_EXTSCAN_CACHED_RESULTS_RSP;
3498 break;
3499 case WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID:
3500 extscan_ind->status = event->status;
3501 extscan_ind->request_id = event->request_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003502 if (event->mode == WMI_EXTSCAN_MODE_STOP)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003503 event_type =
3504 eSIR_EXTSCAN_RESET_SSID_HOTLIST_RSP;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003505 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003506 event_type =
3507 eSIR_EXTSCAN_SET_SSID_HOTLIST_RSP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003508 break;
3509 default:
3510 WMA_LOGE("%s: Unknown event(%d) from target",
3511 __func__, event->status);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303512 qdf_mem_free(extscan_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003513 return -EINVAL;
3514 }
3515 pMac->sme.pExtScanIndCb(pMac->hHdd, event_type, extscan_ind);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003516 WMA_LOGD("%s: sending event to umac for requestid %u with status %d",
3517 __func__, extscan_ind->request_id, extscan_ind->status);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303518 qdf_mem_free(extscan_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003519 return 0;
3520}
3521
3522/**
3523 * wma_extscan_operations_event_handler() - extscan operation event handler
3524 * @handle: wma handle
3525 * @cmd_param_info: event buffer
3526 * @len: length
3527 *
3528 * This function handles different operations related event and indicate
3529 * upper layers with appropriate callback.
3530 *
3531 * Return: 0 for success or error code.
3532 */
3533int wma_extscan_operations_event_handler(void *handle,
3534 uint8_t *cmd_param_info,
3535 uint32_t len)
3536{
3537 tp_wma_handle wma = (tp_wma_handle) handle;
3538 WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *param_buf;
3539 wmi_extscan_operation_event_fixed_param *oprn_event;
3540 tSirExtScanOnScanEventIndParams *oprn_ind;
Mukul Sharmafa937be2016-08-12 18:13:36 +05303541 uint32_t cnt;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303542 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003543
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003544 if (!pMac) {
3545 WMA_LOGE("%s: Invalid pMac", __func__);
3546 return -EINVAL;
3547 }
3548 if (!pMac->sme.pExtScanIndCb) {
3549 WMA_LOGE("%s: Callback not registered", __func__);
3550 return -EINVAL;
3551 }
3552 param_buf = (WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *)
3553 cmd_param_info;
3554 if (!param_buf) {
3555 WMA_LOGE("%s: Invalid scan operation event", __func__);
3556 return -EINVAL;
3557 }
3558 oprn_event = param_buf->fixed_param;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303559 oprn_ind = qdf_mem_malloc(sizeof(*oprn_ind));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003560 if (!oprn_ind) {
3561 WMA_LOGE("%s: extscan memory allocation failed", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303562 qdf_mem_free(oprn_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003563 return -ENOMEM;
3564 }
3565
3566 oprn_ind->requestId = oprn_event->request_id;
3567
3568 switch (oprn_event->event) {
3569 case WMI_EXTSCAN_BUCKET_COMPLETED_EVENT:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003570 oprn_ind->status = 0;
Mukul Sharma45114d92016-08-12 19:34:14 +05303571 goto exit_handler;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003572 case WMI_EXTSCAN_CYCLE_STARTED_EVENT:
3573 WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_STARTED_EVENT",
3574 __func__);
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303575 cds_host_diag_log_work(&wma->extscan_wake_lock,
3576 WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION,
3577 WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303578 qdf_wake_lock_timeout_acquire(&wma->extscan_wake_lock,
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303579 WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION);
Mukul Sharmafa937be2016-08-12 18:13:36 +05303580 oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_STARTED_EVENT;
3581 oprn_ind->status = 0;
3582 oprn_ind->buckets_scanned = 0;
3583 for (cnt = 0; cnt < oprn_event->num_buckets; cnt++)
3584 oprn_ind->buckets_scanned |=
3585 (1 << param_buf->bucket_id[cnt]);
3586 WMA_LOGD(FL("num_buckets %u request_id %u buckets_scanned %u"),
3587 oprn_event->num_buckets, oprn_ind->requestId,
3588 oprn_ind->buckets_scanned);
3589 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003590 case WMI_EXTSCAN_CYCLE_COMPLETED_EVENT:
3591 WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_COMPLETED_EVENT",
3592 __func__);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303593 qdf_wake_lock_release(&wma->extscan_wake_lock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003594 WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
Mukul Sharmafa937be2016-08-12 18:13:36 +05303595 oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT;
3596 oprn_ind->status = 0;
3597 /* Set bucket scanned mask to zero on cycle complete */
3598 oprn_ind->buckets_scanned = 0;
3599 break;
3600 case WMI_EXTSCAN_BUCKET_STARTED_EVENT:
Mukul Sharma45114d92016-08-12 19:34:14 +05303601 WMA_LOGD("%s: received WMI_EXTSCAN_BUCKET_STARTED_EVENT",
Mukul Sharmafa937be2016-08-12 18:13:36 +05303602 __func__);
3603 oprn_ind->scanEventType = WIFI_EXTSCAN_BUCKET_STARTED_EVENT;
3604 oprn_ind->status = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003605 goto exit_handler;
Mukul Sharmafa937be2016-08-12 18:13:36 +05303606 case WMI_EXTSCAN_THRESHOLD_NUM_SCANS:
Mukul Sharma45114d92016-08-12 19:34:14 +05303607 WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_NUM_SCANS",
Mukul Sharmafa937be2016-08-12 18:13:36 +05303608 __func__);
3609 oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_NUM_SCANS;
3610 oprn_ind->status = 0;
3611 break;
3612 case WMI_EXTSCAN_THRESHOLD_PERCENT:
Mukul Sharma45114d92016-08-12 19:34:14 +05303613 WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_PERCENT",
Mukul Sharmafa937be2016-08-12 18:13:36 +05303614 __func__);
3615 oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_PERCENT;
3616 oprn_ind->status = 0;
3617 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003618 default:
3619 WMA_LOGE("%s: Unknown event(%d) from target",
3620 __func__, oprn_event->event);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303621 qdf_mem_free(oprn_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003622 return -EINVAL;
3623 }
3624 pMac->sme.pExtScanIndCb(pMac->hHdd,
3625 eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND, oprn_ind);
3626 WMA_LOGI("%s: sending scan progress event to hdd", __func__);
3627exit_handler:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303628 qdf_mem_free(oprn_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003629 return 0;
3630}
3631
3632/**
3633 * wma_extscan_table_usage_event_handler() - extscan table usage event handler
3634 * @handle: wma handle
3635 * @cmd_param_info: event buffer
3636 * @len: length
3637 *
3638 * This function handles table usage related event and indicate
3639 * upper layers with appropriate callback.
3640 *
3641 * Return: 0 for success or error code.
3642 */
3643int wma_extscan_table_usage_event_handler(void *handle,
3644 uint8_t *cmd_param_info,
3645 uint32_t len)
3646{
3647 WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *param_buf;
3648 wmi_extscan_table_usage_event_fixed_param *event;
3649 tSirExtScanResultsAvailableIndParams *tbl_usg_ind;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303650 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003651
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003652 if (!pMac) {
3653 WMA_LOGE("%s: Invalid pMac", __func__);
3654 return -EINVAL;
3655 }
3656 if (!pMac->sme.pExtScanIndCb) {
3657 WMA_LOGE("%s: Callback not registered", __func__);
3658 return -EINVAL;
3659 }
3660 param_buf = (WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *)
3661 cmd_param_info;
3662 if (!param_buf) {
3663 WMA_LOGE("%s: Invalid table usage event", __func__);
3664 return -EINVAL;
3665 }
3666 event = param_buf->fixed_param;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303667 tbl_usg_ind = qdf_mem_malloc(sizeof(*tbl_usg_ind));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003668 if (!tbl_usg_ind) {
3669 WMA_LOGE("%s: table usage allocation failed", __func__);
3670 return -ENOMEM;
3671 }
3672 tbl_usg_ind->requestId = event->request_id;
3673 tbl_usg_ind->numResultsAvailable = event->entries_in_use;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003674 pMac->sme.pExtScanIndCb(pMac->hHdd,
3675 eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND,
3676 tbl_usg_ind);
3677 WMA_LOGI("%s: sending scan_res available event to hdd", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303678 qdf_mem_free(tbl_usg_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003679 return 0;
3680}
3681
3682/**
3683 * wma_extscan_capabilities_event_handler() - extscan capabilities event handler
3684 * @handle: wma handle
3685 * @cmd_param_info: event buffer
3686 * @len: length
3687 *
3688 * This function handles capabilities event and indicate
3689 * upper layers with registered callback.
3690 *
3691 * Return: 0 for success or error code.
3692 */
3693int wma_extscan_capabilities_event_handler(void *handle,
3694 uint8_t *cmd_param_info,
3695 uint32_t len)
3696{
3697 WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *param_buf;
3698 wmi_extscan_capabilities_event_fixed_param *event;
3699 wmi_extscan_cache_capabilities *src_cache;
3700 wmi_extscan_hotlist_monitor_capabilities *src_hotlist;
3701 wmi_extscan_wlan_change_monitor_capabilities *src_change;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003702 struct ext_scan_capabilities_response *dest_capab;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303703 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003704
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003705 if (!pMac) {
3706 WMA_LOGE("%s: Invalid pMac", __func__);
3707 return -EINVAL;
3708 }
3709 if (!pMac->sme.pExtScanIndCb) {
3710 WMA_LOGE("%s: Callback not registered", __func__);
3711 return -EINVAL;
3712 }
3713 param_buf = (WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *)
3714 cmd_param_info;
3715 if (!param_buf) {
3716 WMA_LOGE("%s: Invalid capabilities event", __func__);
3717 return -EINVAL;
3718 }
3719 event = param_buf->fixed_param;
3720 src_cache = param_buf->extscan_cache_capabilities;
3721 src_hotlist = param_buf->hotlist_capabilities;
3722 src_change = param_buf->wlan_change_capabilities;
3723
3724 if (!src_cache || !src_hotlist || !src_change) {
3725 WMA_LOGE("%s: Invalid capabilities list", __func__);
3726 return -EINVAL;
3727 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303728 dest_capab = qdf_mem_malloc(sizeof(*dest_capab));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003729 if (!dest_capab) {
3730 WMA_LOGE("%s: Allocation failed for capabilities buffer",
3731 __func__);
3732 return -ENOMEM;
3733 }
3734 dest_capab->requestId = event->request_id;
3735 dest_capab->max_scan_buckets = src_cache->max_buckets;
3736 dest_capab->max_scan_cache_size = src_cache->scan_cache_entry_size;
3737 dest_capab->max_ap_cache_per_scan = src_cache->max_bssid_per_scan;
3738 dest_capab->max_scan_reporting_threshold =
3739 src_cache->max_table_usage_threshold;
3740
3741 dest_capab->max_hotlist_bssids = src_hotlist->max_hotlist_entries;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003742 dest_capab->max_rssi_sample_size =
3743 src_change->max_rssi_averaging_samples;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003744 dest_capab->max_bssid_history_entries =
3745 src_change->max_rssi_history_entries;
3746 dest_capab->max_significant_wifi_change_aps =
3747 src_change->max_wlan_change_entries;
3748 dest_capab->max_hotlist_ssids =
3749 event->num_extscan_hotlist_ssid;
3750 dest_capab->max_number_epno_networks =
3751 event->num_epno_networks;
3752 dest_capab->max_number_epno_networks_by_ssid =
3753 event->num_epno_networks;
3754 dest_capab->max_number_of_white_listed_ssid =
3755 event->num_roam_ssid_whitelist;
Padma, Santhosh Kumar1ac02402016-11-02 18:04:14 +05303756 dest_capab->max_number_of_black_listed_bssid =
3757 event->num_roam_bssid_blacklist;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003758 dest_capab->status = 0;
3759
3760 WMA_LOGD("%s: request_id: %u status: %d",
3761 __func__, dest_capab->requestId, dest_capab->status);
3762
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003763 WMA_LOGD("%s: Capabilities: max_scan_buckets: %d, max_hotlist_bssids: %d, max_scan_cache_size: %d, max_ap_cache_per_scan: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003764 __func__, dest_capab->max_scan_buckets,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003765 dest_capab->max_hotlist_bssids, dest_capab->max_scan_cache_size,
3766 dest_capab->max_ap_cache_per_scan);
3767 WMA_LOGD("%s: max_scan_reporting_threshold: %d, max_rssi_sample_size: %d, max_bssid_history_entries: %d, max_significant_wifi_change_aps: %d",
3768 __func__, dest_capab->max_scan_reporting_threshold,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003769 dest_capab->max_rssi_sample_size,
3770 dest_capab->max_bssid_history_entries,
3771 dest_capab->max_significant_wifi_change_aps);
3772
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003773 WMA_LOGD("%s: Capabilities: max_hotlist_ssids: %d, max_number_epno_networks: %d, max_number_epno_networks_by_ssid: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003774 __func__, dest_capab->max_hotlist_ssids,
3775 dest_capab->max_number_epno_networks,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003776 dest_capab->max_number_epno_networks_by_ssid);
3777 WMA_LOGD("%s: max_number_of_white_listed_ssid: %d, max_number_of_black_listed_bssid: %d",
3778 __func__, dest_capab->max_number_of_white_listed_ssid,
Padma, Santhosh Kumar1ac02402016-11-02 18:04:14 +05303779 dest_capab->max_number_of_black_listed_bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003780
3781 pMac->sme.pExtScanIndCb(pMac->hHdd,
3782 eSIR_EXTSCAN_GET_CAPABILITIES_IND, dest_capab);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303783 qdf_mem_free(dest_capab);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003784 return 0;
3785}
3786
3787/**
3788 * wma_extscan_hotlist_match_event_handler() - hotlist match event handler
3789 * @handle: wma handle
3790 * @cmd_param_info: event buffer
3791 * @len: length
3792 *
3793 * This function handles hotlist match event and indicate
3794 * upper layers with registered callback.
3795 *
3796 * Return: 0 for success or error code.
3797 */
3798int wma_extscan_hotlist_match_event_handler(void *handle,
3799 uint8_t *cmd_param_info,
3800 uint32_t len)
3801{
3802 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *param_buf;
3803 wmi_extscan_hotlist_match_event_fixed_param *event;
3804 struct extscan_hotlist_match *dest_hotlist;
3805 tSirWifiScanResult *dest_ap;
3806 wmi_extscan_wlan_descriptor *src_hotlist;
Sridhar Selvaraj22943572017-07-26 15:06:40 +05303807 uint32_t numap;
3808 int j, ap_found = 0;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303809 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003810
3811 if (!pMac) {
3812 WMA_LOGE("%s: Invalid pMac", __func__);
3813 return -EINVAL;
3814 }
3815 if (!pMac->sme.pExtScanIndCb) {
3816 WMA_LOGE("%s: Callback not registered", __func__);
3817 return -EINVAL;
3818 }
3819 param_buf = (WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *)
3820 cmd_param_info;
3821 if (!param_buf) {
3822 WMA_LOGE("%s: Invalid hotlist match event", __func__);
3823 return -EINVAL;
3824 }
3825 event = param_buf->fixed_param;
3826 src_hotlist = param_buf->hotlist_match;
3827 numap = event->total_entries;
3828
3829 if (!src_hotlist || !numap) {
3830 WMA_LOGE("%s: Hotlist AP's list invalid", __func__);
3831 return -EINVAL;
3832 }
Sridhar Selvaraj22943572017-07-26 15:06:40 +05303833 if (numap > WMA_EXTSCAN_MAX_HOTLIST_ENTRIES) {
3834 WMA_LOGE("%s: Total Entries %u greater than max",
3835 __func__, numap);
3836 numap = WMA_EXTSCAN_MAX_HOTLIST_ENTRIES;
3837 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303838 dest_hotlist = qdf_mem_malloc(sizeof(*dest_hotlist) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003839 sizeof(*dest_ap) * numap);
3840 if (!dest_hotlist) {
3841 WMA_LOGE("%s: Allocation failed for hotlist buffer", __func__);
3842 return -ENOMEM;
3843 }
3844 dest_ap = &dest_hotlist->ap[0];
3845 dest_hotlist->numOfAps = event->total_entries;
3846 dest_hotlist->requestId = event->config_request_id;
3847
3848 if (event->first_entry_index +
3849 event->num_entries_in_page < event->total_entries)
3850 dest_hotlist->moreData = 1;
3851 else
3852 dest_hotlist->moreData = 0;
3853
3854 WMA_LOGD("%s: Hotlist match: requestId: %u,"
3855 "numOfAps: %d", __func__,
3856 dest_hotlist->requestId, dest_hotlist->numOfAps);
3857
3858 /*
3859 * Currently firmware sends only one bss information in-case
3860 * of both hotlist ap found and lost.
3861 */
3862 for (j = 0; j < numap; j++) {
3863 dest_ap->rssi = 0;
3864 dest_ap->channel = src_hotlist->channel;
3865 dest_ap->ts = src_hotlist->tstamp;
3866 ap_found = src_hotlist->flags & WMI_HOTLIST_FLAG_PRESENCE;
3867 dest_ap->rtt = src_hotlist->rtt;
3868 dest_ap->rtt_sd = src_hotlist->rtt_sd;
3869 dest_ap->beaconPeriod = src_hotlist->beacon_interval;
3870 dest_ap->capability = src_hotlist->capabilities;
3871 dest_ap->ieLength = src_hotlist->ie_length;
3872 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid,
3873 dest_ap->bssid.bytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303874 qdf_mem_copy(dest_ap->ssid, src_hotlist->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003875 src_hotlist->ssid.ssid_len);
3876 dest_ap->ssid[src_hotlist->ssid.ssid_len] = '\0';
3877 dest_ap++;
3878 src_hotlist++;
3879 }
3880 dest_hotlist->ap_found = ap_found;
3881 pMac->sme.pExtScanIndCb(pMac->hHdd,
3882 eSIR_EXTSCAN_HOTLIST_MATCH_IND, dest_hotlist);
3883 WMA_LOGI("%s: sending hotlist match event to hdd", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303884 qdf_mem_free(dest_hotlist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003885 return 0;
3886}
3887
3888/** wma_extscan_find_unique_scan_ids() - find unique scan ids
3889 * @cmd_param_info: event data.
3890 *
3891 * This utility function parses the input bss table of information
3892 * and find the unique number of scan ids
3893 *
3894 * Return: 0 on success; error number otherwise
3895 */
3896static int wma_extscan_find_unique_scan_ids(const u_int8_t *cmd_param_info)
3897{
3898 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
3899 wmi_extscan_cached_results_event_fixed_param *event;
3900 wmi_extscan_wlan_descriptor *src_hotlist;
3901 wmi_extscan_rssi_info *src_rssi;
3902 int prev_scan_id, scan_ids_cnt, i;
3903
3904 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
3905 cmd_param_info;
3906 event = param_buf->fixed_param;
3907 src_hotlist = param_buf->bssid_list;
3908 src_rssi = param_buf->rssi_list;
3909
3910 /* Find the unique number of scan_id's for grouping */
3911 prev_scan_id = src_rssi->scan_cycle_id;
3912 scan_ids_cnt = 1;
3913 for (i = 1; i < event->num_entries_in_page; i++) {
3914 src_rssi++;
3915
3916 if (prev_scan_id != src_rssi->scan_cycle_id) {
3917 scan_ids_cnt++;
3918 prev_scan_id = src_rssi->scan_cycle_id;
3919 }
3920 }
3921
3922 return scan_ids_cnt;
3923}
3924
3925/** wma_fill_num_results_per_scan_id() - fill number of bss per scan id
3926 * @cmd_param_info: event data.
3927 * @scan_id_group: pointer to scan id group.
3928 *
3929 * This utility function parses the input bss table of information
3930 * and finds how many bss are there per unique scan id.
3931 *
3932 * Return: 0 on success; error number otherwise
3933 */
3934static int wma_fill_num_results_per_scan_id(const u_int8_t *cmd_param_info,
3935 struct extscan_cached_scan_result *scan_id_group)
3936{
3937 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
3938 wmi_extscan_cached_results_event_fixed_param *event;
3939 wmi_extscan_wlan_descriptor *src_hotlist;
3940 wmi_extscan_rssi_info *src_rssi;
3941 struct extscan_cached_scan_result *t_scan_id_grp;
3942 int i, prev_scan_id;
3943
3944 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
3945 cmd_param_info;
3946 event = param_buf->fixed_param;
3947 src_hotlist = param_buf->bssid_list;
3948 src_rssi = param_buf->rssi_list;
3949 t_scan_id_grp = scan_id_group;
3950
3951 prev_scan_id = src_rssi->scan_cycle_id;
3952
3953 t_scan_id_grp->scan_id = src_rssi->scan_cycle_id;
3954 t_scan_id_grp->flags = src_rssi->flags;
Mukul Sharmaf7cb3ab2016-08-12 19:53:52 +05303955 t_scan_id_grp->buckets_scanned = src_rssi->buckets_scanned;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003956 t_scan_id_grp->num_results = 1;
3957 for (i = 1; i < event->num_entries_in_page; i++) {
3958 src_rssi++;
3959 if (prev_scan_id == src_rssi->scan_cycle_id) {
3960 t_scan_id_grp->num_results++;
3961 } else {
3962 t_scan_id_grp++;
3963 prev_scan_id = t_scan_id_grp->scan_id =
3964 src_rssi->scan_cycle_id;
3965 t_scan_id_grp->flags = src_rssi->flags;
Mukul Sharmaf7cb3ab2016-08-12 19:53:52 +05303966 t_scan_id_grp->buckets_scanned =
3967 src_rssi->buckets_scanned;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003968 t_scan_id_grp->num_results = 1;
3969 }
3970 }
3971 return 0;
3972}
3973
3974/** wma_group_num_bss_to_scan_id() - group bss to scan id table
3975 * @cmd_param_info: event data.
3976 * @cached_result: pointer to cached table.
3977 *
3978 * This function reads the bss information from the format
3979 * ------------------------------------------------------------------------
3980 * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_1 | flags |
3981 * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_2 | flags |
3982 * ........................................................................
3983 * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_N | flags |
3984 * ------------------------------------------------------------------------
3985 *
3986 * and converts it into the below format and store it
3987 *
3988 * ------------------------------------------------------------------------
3989 * | scan id_1 | -> bss info_1 -> bss info_2 -> .... bss info_M1
3990 * | scan id_2 | -> bss info_1 -> bss info_2 -> .... bss info_M2
3991 * ......................
3992 * | scan id_N | -> bss info_1 -> bss info_2 -> .... bss info_Mn
3993 * ------------------------------------------------------------------------
3994 *
3995 * Return: 0 on success; error number otherwise
3996 */
3997static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info,
3998 struct extscan_cached_scan_results *cached_result)
3999{
4000 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
4001 wmi_extscan_cached_results_event_fixed_param *event;
4002 wmi_extscan_wlan_descriptor *src_hotlist;
4003 wmi_extscan_rssi_info *src_rssi;
4004 struct extscan_cached_scan_results *t_cached_result;
4005 struct extscan_cached_scan_result *t_scan_id_grp;
4006 int i, j;
4007 tSirWifiScanResult *ap;
4008
4009 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
4010 cmd_param_info;
4011 event = param_buf->fixed_param;
4012 src_hotlist = param_buf->bssid_list;
4013 src_rssi = param_buf->rssi_list;
4014 t_cached_result = cached_result;
4015 t_scan_id_grp = &t_cached_result->result[0];
4016
4017 WMA_LOGD("%s: num_scan_ids:%d", __func__,
4018 t_cached_result->num_scan_ids);
4019 for (i = 0; i < t_cached_result->num_scan_ids; i++) {
4020 WMA_LOGD("%s: num_results:%d", __func__,
4021 t_scan_id_grp->num_results);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304022 t_scan_id_grp->ap = qdf_mem_malloc(t_scan_id_grp->num_results *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004023 sizeof(*ap));
4024 if (!t_scan_id_grp->ap) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304025 WMA_LOGD("%s: qdf_mem_malloc failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004026 return -ENOMEM;
4027 }
4028
4029 ap = &t_scan_id_grp->ap[0];
4030 for (j = 0; j < t_scan_id_grp->num_results; j++) {
4031 ap->channel = src_hotlist->channel;
4032 ap->ts = WMA_MSEC_TO_USEC(src_rssi->tstamp);
4033 ap->rtt = src_hotlist->rtt;
4034 ap->rtt_sd = src_hotlist->rtt_sd;
4035 ap->beaconPeriod = src_hotlist->beacon_interval;
4036 ap->capability = src_hotlist->capabilities;
4037 ap->ieLength = src_hotlist->ie_length;
4038
4039 /* Firmware already applied noise floor adjustment and
4040 * due to WMI interface "UINT32 rssi", host driver
4041 * receives a positive value, hence convert to
4042 * signed char to get the absolute rssi.
4043 */
4044 ap->rssi = (signed char) src_rssi->rssi;
4045 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid,
4046 ap->bssid.bytes);
4047
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304048 qdf_mem_copy(ap->ssid, src_hotlist->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004049 src_hotlist->ssid.ssid_len);
4050 ap->ssid[src_hotlist->ssid.ssid_len] = '\0';
4051 ap++;
4052 src_rssi++;
4053 src_hotlist++;
4054 }
4055 t_scan_id_grp++;
4056 }
4057 return 0;
4058}
4059
4060/**
4061 * wma_extscan_cached_results_event_handler() - cached results event handler
4062 * @handle: wma handle
4063 * @cmd_param_info: event buffer
4064 * @len: length of @cmd_param_info
4065 *
4066 * This function handles cached results event and indicate
4067 * cached results to upper layer.
4068 *
4069 * Return: 0 for success or error code.
4070 */
4071int wma_extscan_cached_results_event_handler(void *handle,
4072 uint8_t *cmd_param_info,
4073 uint32_t len)
4074{
4075 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
4076 wmi_extscan_cached_results_event_fixed_param *event;
4077 struct extscan_cached_scan_results *dest_cachelist;
4078 struct extscan_cached_scan_result *dest_result;
4079 struct extscan_cached_scan_results empty_cachelist;
4080 wmi_extscan_wlan_descriptor *src_hotlist;
4081 wmi_extscan_rssi_info *src_rssi;
4082 int numap, i, moredata, scan_ids_cnt, buf_len;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304083 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Varun Reddy Yeturu46ba20c2017-08-17 15:03:27 -07004084 uint32_t total_len;
4085 bool excess_data = false;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004086
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004087 if (!pMac) {
4088 WMA_LOGE("%s: Invalid pMac", __func__);
4089 return -EINVAL;
4090 }
4091 if (!pMac->sme.pExtScanIndCb) {
4092 WMA_LOGE("%s: Callback not registered", __func__);
4093 return -EINVAL;
4094 }
4095 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
4096 cmd_param_info;
4097 if (!param_buf) {
4098 WMA_LOGE("%s: Invalid cached results event", __func__);
4099 return -EINVAL;
4100 }
4101 event = param_buf->fixed_param;
4102 src_hotlist = param_buf->bssid_list;
4103 src_rssi = param_buf->rssi_list;
4104 numap = event->num_entries_in_page;
Srinivas Girigowdadbfb2642016-08-28 21:32:38 -07004105 WMA_LOGI("Total_entries: %u first_entry_index: %u num_entries_in_page: %d",
4106 event->total_entries,
4107 event->first_entry_index, numap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004108 if (!src_hotlist || !src_rssi || !numap) {
Srinivas Girigowdaf2599dd2015-11-16 18:20:46 -08004109 WMA_LOGW("%s: Cached results empty, send 0 results", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004110 goto noresults;
4111 }
4112 if (event->first_entry_index +
4113 event->num_entries_in_page < event->total_entries)
4114 moredata = 1;
4115 else
4116 moredata = 0;
4117
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304118 dest_cachelist = qdf_mem_malloc(sizeof(*dest_cachelist));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004119 if (!dest_cachelist) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304120 WMA_LOGE("%s: qdf_mem_malloc failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004121 return -ENOMEM;
4122 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304123 qdf_mem_zero(dest_cachelist, sizeof(*dest_cachelist));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004124 dest_cachelist->request_id = event->request_id;
4125 dest_cachelist->more_data = moredata;
4126
4127 scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info);
4128 WMA_LOGI("%s: scan_ids_cnt %d", __func__, scan_ids_cnt);
4129 dest_cachelist->num_scan_ids = scan_ids_cnt;
4130
Varun Reddy Yeturu46ba20c2017-08-17 15:03:27 -07004131 if (event->num_entries_in_page >
4132 (WMI_SVC_MSG_MAX_SIZE - sizeof(*event))/sizeof(*src_hotlist)) {
4133 WMA_LOGE("%s:excess num_entries_in_page %d in WMI event",
4134 __func__, event->num_entries_in_page);
4135 qdf_mem_free(dest_cachelist);
4136 QDF_ASSERT(0);
4137 return -EINVAL;
4138 } else {
4139 total_len = sizeof(*event) +
4140 (event->num_entries_in_page * sizeof(*src_hotlist));
4141 }
4142 for (i = 0; i < event->num_entries_in_page; i++) {
4143 if (src_hotlist[i].ie_length > WMI_SVC_MSG_MAX_SIZE -
4144 total_len) {
4145 excess_data = true;
4146 break;
4147 } else {
4148 total_len += src_hotlist[i].ie_length;
4149 WMA_LOGD("total len IE: %d", total_len);
4150 }
4151
4152 if (src_hotlist[i].number_rssi_samples >
4153 (WMI_SVC_MSG_MAX_SIZE - total_len)/sizeof(*src_rssi)) {
4154 excess_data = true;
4155 break;
4156 } else {
4157 total_len += (src_hotlist[i].number_rssi_samples *
4158 sizeof(*src_rssi));
4159 WMA_LOGD("total len RSSI samples: %d", total_len);
4160 }
4161 }
4162 if (excess_data) {
4163 WMA_LOGE("%s:excess data in WMI event",
4164 __func__);
4165 qdf_mem_free(dest_cachelist);
4166 QDF_ASSERT(0);
4167 return -EINVAL;
4168 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004169 buf_len = sizeof(*dest_result) * scan_ids_cnt;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304170 dest_cachelist->result = qdf_mem_malloc(buf_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004171 if (!dest_cachelist->result) {
4172 WMA_LOGE("%s: Allocation failed for scanid grouping", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304173 qdf_mem_free(dest_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004174 return -ENOMEM;
4175 }
4176
4177 dest_result = dest_cachelist->result;
4178 wma_fill_num_results_per_scan_id(cmd_param_info, dest_result);
4179 wma_group_num_bss_to_scan_id(cmd_param_info, dest_cachelist);
4180
4181 pMac->sme.pExtScanIndCb(pMac->hHdd,
4182 eSIR_EXTSCAN_CACHED_RESULTS_IND,
4183 dest_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 dest_result = dest_cachelist->result;
4185 for (i = 0; i < dest_cachelist->num_scan_ids; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304186 qdf_mem_free(dest_result->ap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004187 dest_result++;
4188 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304189 qdf_mem_free(dest_cachelist->result);
4190 qdf_mem_free(dest_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004191 return 0;
4192
4193noresults:
4194 empty_cachelist.request_id = event->request_id;
4195 empty_cachelist.more_data = 0;
4196 empty_cachelist.num_scan_ids = 0;
4197
4198 pMac->sme.pExtScanIndCb(pMac->hHdd,
4199 eSIR_EXTSCAN_CACHED_RESULTS_IND,
4200 &empty_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004201 return 0;
4202}
4203
4204/**
4205 * wma_extscan_change_results_event_handler() - change results event handler
4206 * @handle: wma handle
4207 * @cmd_param_info: event buffer
4208 * @len: length
4209 *
4210 * This function handles change results event and indicate
4211 * change results to upper layer.
4212 *
4213 * Return: 0 for success or error code.
4214 */
4215int wma_extscan_change_results_event_handler(void *handle,
4216 uint8_t *cmd_param_info,
4217 uint32_t len)
4218{
4219 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *param_buf;
4220 wmi_extscan_wlan_change_results_event_fixed_param *event;
4221 tSirWifiSignificantChangeEvent *dest_chglist;
4222 tSirWifiSignificantChange *dest_ap;
4223 wmi_extscan_wlan_change_result_bssid *src_chglist;
4224
4225 int numap;
4226 int i, k;
4227 uint8_t *src_rssi;
4228 int count = 0;
4229 int moredata;
4230 int rssi_num = 0;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304231 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Varun Reddy Yeturu46ba20c2017-08-17 15:03:27 -07004232 uint32_t buf_len;
4233 bool excess_data = false;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004234
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004235 if (!pMac) {
4236 WMA_LOGE("%s: Invalid pMac", __func__);
4237 return -EINVAL;
4238 }
4239 if (!pMac->sme.pExtScanIndCb) {
4240 WMA_LOGE("%s: Callback not registered", __func__);
4241 return -EINVAL;
4242 }
4243 param_buf = (WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *)
4244 cmd_param_info;
4245 if (!param_buf) {
4246 WMA_LOGE("%s: Invalid change monitor event", __func__);
4247 return -EINVAL;
4248 }
4249 event = param_buf->fixed_param;
4250 src_chglist = param_buf->bssid_signal_descriptor_list;
4251 src_rssi = param_buf->rssi_list;
4252 numap = event->num_entries_in_page;
4253
4254 if (!src_chglist || !numap) {
4255 WMA_LOGE("%s: Results invalid", __func__);
4256 return -EINVAL;
4257 }
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004258 for (i = 0; i < numap; i++)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004259 rssi_num += src_chglist->num_rssi_samples;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004260
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004261 if (event->first_entry_index +
4262 event->num_entries_in_page < event->total_entries) {
4263 moredata = 1;
4264 } else {
4265 moredata = 0;
4266 }
Varun Reddy Yeturu46ba20c2017-08-17 15:03:27 -07004267
4268 do {
4269 if (event->num_entries_in_page >
4270 (WMI_SVC_MSG_MAX_SIZE - sizeof(*event))/
4271 sizeof(*src_chglist)) {
4272 excess_data = true;
4273 break;
4274 } else {
4275 buf_len =
4276 sizeof(*event) + (event->num_entries_in_page *
4277 sizeof(*src_chglist));
4278 }
4279 if (rssi_num >
4280 (WMI_SVC_MSG_MAX_SIZE - buf_len)/sizeof(int32_t)) {
4281 excess_data = true;
4282 break;
4283 }
4284 } while (0);
4285
4286 if (excess_data) {
4287 WMA_LOGE("buffer len exceeds WMI payload,numap:%d, rssi_num:%d",
4288 numap, rssi_num);
4289 QDF_ASSERT(0);
4290 return -EINVAL;
4291 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304292 dest_chglist = qdf_mem_malloc(sizeof(*dest_chglist) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004293 sizeof(*dest_ap) * numap +
4294 sizeof(int32_t) * rssi_num);
4295 if (!dest_chglist) {
4296 WMA_LOGE("%s: Allocation failed for change monitor", __func__);
4297 return -ENOMEM;
4298 }
4299 dest_ap = &dest_chglist->ap[0];
4300 for (i = 0; i < numap; i++) {
4301 dest_ap->channel = src_chglist->channel;
4302 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_chglist->bssid,
4303 dest_ap->bssid.bytes);
4304 dest_ap->numOfRssi = src_chglist->num_rssi_samples;
4305 if (dest_ap->numOfRssi) {
4306 for (k = 0; k < dest_ap->numOfRssi; k++) {
4307 dest_ap->rssi[k] = WMA_TGT_NOISE_FLOOR_DBM +
4308 src_rssi[count++];
4309 }
4310 }
4311 dest_ap += dest_ap->numOfRssi * sizeof(int32_t);
4312 src_chglist++;
4313 }
4314 dest_chglist->requestId = event->request_id;
4315 dest_chglist->moreData = moredata;
4316 dest_chglist->numResults = event->total_entries;
4317
4318 pMac->sme.pExtScanIndCb(pMac->hHdd,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004319 eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND,
4320 dest_chglist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004321 WMA_LOGI("%s: sending change monitor results", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304322 qdf_mem_free(dest_chglist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004323 return 0;
4324}
4325
4326/**
4327 * wma_passpoint_match_event_handler() - passpoint match found event handler
4328 * @handle: WMA handle
4329 * @cmd_param_info: event data
4330 * @len: event data length
4331 *
4332 * This is the passpoint match found event handler; it reads event data from
4333 * @cmd_param_info and fill in the destination buffer and sends indication
4334 * up layer.
4335 *
4336 * Return: 0 on success; error number otherwise
4337 */
4338int wma_passpoint_match_event_handler(void *handle,
4339 uint8_t *cmd_param_info,
4340 uint32_t len)
4341{
4342 WMI_PASSPOINT_MATCH_EVENTID_param_tlvs *param_buf;
4343 wmi_passpoint_event_hdr *event;
4344 struct wifi_passpoint_match *dest_match;
4345 tSirWifiScanResult *dest_ap;
4346 uint8_t *buf_ptr;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304347 tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004348
4349 if (!mac) {
4350 WMA_LOGE("%s: Invalid mac", __func__);
4351 return -EINVAL;
4352 }
4353 if (!mac->sme.pExtScanIndCb) {
4354 WMA_LOGE("%s: Callback not registered", __func__);
4355 return -EINVAL;
4356 }
4357
4358 param_buf = (WMI_PASSPOINT_MATCH_EVENTID_param_tlvs *) cmd_param_info;
4359 if (!param_buf) {
4360 WMA_LOGE("%s: Invalid passpoint match event", __func__);
4361 return -EINVAL;
4362 }
4363 event = param_buf->fixed_param;
4364 buf_ptr = (uint8_t *)param_buf->fixed_param;
4365
Varun Reddy Yeturu46ba20c2017-08-17 15:03:27 -07004366 /*
4367 * All the below lengths are UINT32 and summing up and checking
4368 * against a constant should not be an issue.
4369 */
4370 if ((sizeof(*event) + event->ie_length + event->anqp_length) >
4371 WMI_SVC_MSG_MAX_SIZE) {
4372 WMA_LOGE("IE Length: %d or ANQP Length: %d is huge",
4373 event->ie_length, event->anqp_length);
4374 QDF_ASSERT(0);
4375 return -EINVAL;
4376 }
4377
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304378 dest_match = qdf_mem_malloc(sizeof(*dest_match) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004379 event->ie_length + event->anqp_length);
4380 if (!dest_match) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304381 WMA_LOGE("%s: qdf_mem_malloc failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004382 return -EINVAL;
4383 }
4384 dest_ap = &dest_match->ap;
4385 dest_match->request_id = 0;
4386 dest_match->id = event->id;
4387 dest_match->anqp_len = event->anqp_length;
4388 WMA_LOGI("%s: passpoint match: id: %u anqp length %u", __func__,
4389 dest_match->id, dest_match->anqp_len);
4390
4391 dest_ap->channel = event->channel_mhz;
4392 dest_ap->ts = event->timestamp;
4393 dest_ap->rtt = event->rtt;
4394 dest_ap->rssi = event->rssi;
4395 dest_ap->rtt_sd = event->rtt_sd;
4396 dest_ap->beaconPeriod = event->beacon_period;
4397 dest_ap->capability = event->capability;
4398 dest_ap->ieLength = event->ie_length;
4399 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->bssid, dest_ap->bssid.bytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304400 qdf_mem_copy(dest_ap->ssid, event->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004401 event->ssid.ssid_len);
4402 dest_ap->ssid[event->ssid.ssid_len] = '\0';
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304403 qdf_mem_copy(dest_ap->ieData, buf_ptr + sizeof(*event) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004404 WMI_TLV_HDR_SIZE, dest_ap->ieLength);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304405 qdf_mem_copy(dest_match->anqp, buf_ptr + sizeof(*event) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004406 WMI_TLV_HDR_SIZE + dest_ap->ieLength,
4407 dest_match->anqp_len);
4408
4409 mac->sme.pExtScanIndCb(mac->hHdd,
4410 eSIR_PASSPOINT_NETWORK_FOUND_IND,
4411 dest_match);
4412 WMA_LOGI("%s: sending passpoint match event to hdd", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304413 qdf_mem_free(dest_match);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004414 return 0;
4415}
4416
4417/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004418 * wma_get_buf_extscan_start_cmd() - Fill extscan start request
4419 * @handle: wma handle
4420 * @pstart: scan command request params
4421 * @buf: event buffer
4422 * @buf_len: length of buffer
4423 *
4424 * This function fills individual elements of extscan request and
4425 * TLV for buckets, channel list.
4426 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304427 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004428 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304429QDF_STATUS wma_get_buf_extscan_start_cmd(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004430 tSirWifiScanCmdReqParams *pstart,
4431 wmi_buf_t *buf, int *buf_len)
4432{
4433 wmi_extscan_start_cmd_fixed_param *cmd;
4434 wmi_extscan_bucket *dest_blist;
4435 wmi_extscan_bucket_channel *dest_clist;
4436 tSirWifiScanBucketSpec *src_bucket = pstart->buckets;
4437 tSirWifiScanChannelSpec *src_channel = src_bucket->channels;
4438 tSirWifiScanChannelSpec save_channel[WLAN_EXTSCAN_MAX_CHANNELS];
4439
4440 uint8_t *buf_ptr;
4441 int i, k, count = 0;
4442 int len = sizeof(*cmd);
4443 int nbuckets = pstart->numBuckets;
4444 int nchannels = 0;
4445
4446 /* These TLV's are are NULL by default */
4447 uint32_t ie_len_with_pad = 0;
4448 int num_ssid = 0;
4449 int num_bssid = 0;
4450 int ie_len = 0;
4451
4452 uint32_t base_period = pstart->basePeriod;
4453
4454 /* TLV placeholder for ssid_list (NULL) */
4455 len += WMI_TLV_HDR_SIZE;
4456 len += num_ssid * sizeof(wmi_ssid);
4457
4458 /* TLV placeholder for bssid_list (NULL) */
4459 len += WMI_TLV_HDR_SIZE;
4460 len += num_bssid * sizeof(wmi_mac_addr);
4461
4462 /* TLV placeholder for ie_data (NULL) */
4463 len += WMI_TLV_HDR_SIZE;
4464 len += ie_len * sizeof(uint32_t);
4465
4466 /* TLV placeholder for bucket */
4467 len += WMI_TLV_HDR_SIZE;
4468 len += nbuckets * sizeof(wmi_extscan_bucket);
4469
4470 /* TLV channel placeholder */
4471 len += WMI_TLV_HDR_SIZE;
4472 for (i = 0; i < nbuckets; i++) {
4473 nchannels += src_bucket->numChannels;
4474 src_bucket++;
4475 }
4476
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004477 len += nchannels * sizeof(wmi_extscan_bucket_channel);
4478 /* Allocate the memory */
4479 *buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
4480 if (!*buf) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004481 WMA_LOGP("%s: failed to allocate memory for start extscan cmd",
4482 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304483 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004484 }
4485 buf_ptr = (uint8_t *) wmi_buf_data(*buf);
4486 cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr;
4487 WMITLV_SET_HDR(&cmd->tlv_header,
4488 WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param,
4489 WMITLV_GET_STRUCT_TLVLEN
4490 (wmi_extscan_start_cmd_fixed_param));
4491
4492 cmd->request_id = pstart->requestId;
4493 cmd->vdev_id = pstart->sessionId;
4494 cmd->base_period = pstart->basePeriod;
4495 cmd->num_buckets = nbuckets;
4496 cmd->configuration_flags = 0;
4497 if (pstart->configuration_flags & EXTSCAN_LP_EXTENDED_BATCHING)
4498 cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN;
Srinivas Girigowdadbfb2642016-08-28 21:32:38 -07004499 WMA_LOGI("%s: Total buckets: %d total #of channels is %d cfgn_flags: 0x%x",
4500 __func__, nbuckets, nchannels,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004501 cmd->configuration_flags);
4502
4503 cmd->min_rest_time = WMA_EXTSCAN_REST_TIME;
4504 cmd->max_rest_time = WMA_EXTSCAN_REST_TIME;
4505 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
4506
4507 /* The max dwell time is retrieved from the first channel
4508 * of the first bucket and kept common for all channels.
4509 */
4510 cmd->min_dwell_time_active = pstart->min_dwell_time_active;
4511 cmd->max_dwell_time_active = pstart->max_dwell_time_active;
4512 cmd->min_dwell_time_passive = pstart->min_dwell_time_passive;
4513 cmd->max_dwell_time_passive = pstart->max_dwell_time_passive;
4514 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
4515 cmd->max_table_usage = pstart->report_threshold_percent;
4516 cmd->report_threshold_num_scans = pstart->report_threshold_num_scans;
4517
4518 cmd->repeat_probe_time = cmd->max_dwell_time_active /
4519 WMA_SCAN_NPROBES_DEFAULT;
4520 cmd->max_scan_time = WMA_EXTSCAN_MAX_SCAN_TIME;
4521 cmd->probe_delay = 0;
4522 cmd->probe_spacing_time = 0;
4523 cmd->idle_time = 0;
4524 cmd->burst_duration = WMA_EXTSCAN_BURST_DURATION;
4525 cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ |
4526 WMI_SCAN_ADD_CCK_RATES |
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +05304527 WMI_SCAN_ADD_OFDM_RATES |
4528 WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ |
4529 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05304530
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004531 cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH;
4532 cmd->num_ssids = 0;
4533 cmd->num_bssid = 0;
4534 cmd->ie_len = 0;
4535 cmd->n_probes = (cmd->repeat_probe_time > 0) ?
4536 cmd->max_dwell_time_active / cmd->repeat_probe_time : 0;
4537
4538 buf_ptr += sizeof(*cmd);
4539 WMITLV_SET_HDR(buf_ptr,
4540 WMITLV_TAG_ARRAY_FIXED_STRUC,
4541 num_ssid * sizeof(wmi_ssid));
4542 buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid));
4543
4544 WMITLV_SET_HDR(buf_ptr,
4545 WMITLV_TAG_ARRAY_FIXED_STRUC,
4546 num_bssid * sizeof(wmi_mac_addr));
4547 buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr));
4548
4549 ie_len_with_pad = 0;
4550 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_with_pad);
4551 buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad;
4552
4553 WMITLV_SET_HDR(buf_ptr,
4554 WMITLV_TAG_ARRAY_STRUC,
4555 nbuckets * sizeof(wmi_extscan_bucket));
4556 dest_blist = (wmi_extscan_bucket *)
4557 (buf_ptr + WMI_TLV_HDR_SIZE);
4558 src_bucket = pstart->buckets;
4559
4560 /* Retrieve scanning information from each bucket and
4561 * channels and send it to the target
4562 */
4563 for (i = 0; i < nbuckets; i++) {
4564 WMITLV_SET_HDR(dest_blist,
4565 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
4566 WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket));
4567
4568 dest_blist->bucket_id = src_bucket->bucket;
4569 dest_blist->base_period_multiplier =
4570 src_bucket->period / base_period;
4571 dest_blist->min_period = src_bucket->period;
4572 dest_blist->max_period = src_bucket->max_period;
4573 dest_blist->exp_backoff = src_bucket->exponent;
4574 dest_blist->exp_max_step_count = src_bucket->step_count;
4575 dest_blist->channel_band = src_bucket->band;
4576 dest_blist->num_channels = src_bucket->numChannels;
4577 dest_blist->notify_extscan_events = 0;
4578
4579 if (src_bucket->reportEvents & EXTSCAN_REPORT_EVENTS_EACH_SCAN)
4580 dest_blist->notify_extscan_events =
4581 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT;
4582
4583 if (src_bucket->reportEvents &
4584 EXTSCAN_REPORT_EVENTS_FULL_RESULTS) {
4585 dest_blist->forwarding_flags =
4586 WMI_EXTSCAN_FORWARD_FRAME_TO_HOST;
4587 dest_blist->notify_extscan_events |=
4588 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT |
4589 WMI_EXTSCAN_CYCLE_STARTED_EVENT |
4590 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT;
4591 } else {
4592 dest_blist->forwarding_flags =
4593 WMI_EXTSCAN_NO_FORWARDING;
4594 }
4595
4596 if (src_bucket->reportEvents & EXTSCAN_REPORT_EVENTS_NO_BATCH)
4597 dest_blist->configuration_flags = 0;
4598 else
4599 dest_blist->configuration_flags =
4600 WMI_EXTSCAN_BUCKET_CACHE_RESULTS;
4601
Mukul Sharmafa937be2016-08-12 18:13:36 +05304602 if (src_bucket->reportEvents &
4603 EXTSCAN_REPORT_EVENTS_CONTEXT_HUB)
4604 dest_blist->configuration_flags |=
4605 WMI_EXTSCAN_REPORT_EVENT_CONTEXT_HUB;
4606
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004607 WMA_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u",
4608 __func__, dest_blist->notify_extscan_events,
4609 dest_blist->configuration_flags,
4610 dest_blist->forwarding_flags);
4611
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004612 dest_blist->min_dwell_time_active =
4613 src_bucket->min_dwell_time_active;
4614 dest_blist->max_dwell_time_active =
4615 src_bucket->max_dwell_time_active;
4616 dest_blist->min_dwell_time_passive =
4617 src_bucket->min_dwell_time_passive;
4618 dest_blist->max_dwell_time_passive =
4619 src_bucket->max_dwell_time_passive;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004620 src_channel = src_bucket->channels;
4621
4622 /* save the channel info to later populate
4623 * the channel TLV
4624 */
4625 for (k = 0; k < src_bucket->numChannels; k++) {
4626 save_channel[count++].channel = src_channel->channel;
4627 src_channel++;
4628 }
4629 dest_blist++;
4630 src_bucket++;
4631 }
4632 buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket));
4633 WMITLV_SET_HDR(buf_ptr,
4634 WMITLV_TAG_ARRAY_STRUC,
4635 nchannels * sizeof(wmi_extscan_bucket_channel));
4636 dest_clist = (wmi_extscan_bucket_channel *)
4637 (buf_ptr + WMI_TLV_HDR_SIZE);
4638
4639 /* Active or passive scan is based on the bucket dwell time
4640 * and channel specific active,passive scans are not
4641 * supported yet
4642 */
4643 for (i = 0; i < nchannels; i++) {
4644 WMITLV_SET_HDR(dest_clist,
4645 WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param,
4646 WMITLV_GET_STRUCT_TLVLEN
4647 (wmi_extscan_bucket_channel));
4648 dest_clist->channel = save_channel[i].channel;
4649 dest_clist++;
4650 }
4651 buf_ptr += WMI_TLV_HDR_SIZE +
4652 (nchannels * sizeof(wmi_extscan_bucket_channel));
4653 *buf_len = len;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304654 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004655}
4656
4657/**
4658 * wma_start_extscan() - start extscan command to fw.
4659 * @handle: wma handle
4660 * @pstart: scan command request params
4661 *
4662 * This function sends start extscan request to fw.
4663 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304664 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004665 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304666QDF_STATUS wma_start_extscan(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004667 tSirWifiScanCmdReqParams *pstart)
4668{
Abhishek Singhb61b5452017-04-10 10:14:18 +05304669 struct wifi_scan_cmd_req_params *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304670 int i, j;
4671 QDF_STATUS status;
4672
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004673 if (!wma || !wma->wmi_handle) {
4674 WMA_LOGE("%s: WMA is closed,can not issue extscan cmd",
4675 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304676 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004677 }
4678 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4679 WMI_SERVICE_EXTSCAN)) {
4680 WMA_LOGE("%s: extscan feature bit not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304681 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004682 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304683
4684 params = qdf_mem_malloc(sizeof(struct wifi_scan_cmd_req_params));
Naveen Rawat35804772016-06-27 15:40:28 -07004685 if (params == NULL) {
4686 WMA_LOGE("%s : Memory allocation failed", __func__);
4687 return QDF_STATUS_E_NOMEM;
4688 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304689
4690 params->basePeriod = pstart->basePeriod;
4691 params->maxAPperScan = pstart->maxAPperScan;
4692 params->report_threshold_percent = pstart->report_threshold_percent;
4693 params->report_threshold_num_scans = pstart->report_threshold_num_scans;
4694 params->requestId = pstart->requestId;
4695 params->sessionId = pstart->sessionId;
4696 params->numBuckets = pstart->numBuckets;
4697 params->min_dwell_time_active = pstart->min_dwell_time_active;
4698 params->min_dwell_time_passive = pstart->min_dwell_time_passive;
4699 params->max_dwell_time_active = pstart->max_dwell_time_active;
4700 params->max_dwell_time_passive = pstart->max_dwell_time_passive;
4701 params->configuration_flags = pstart->configuration_flags;
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05304702 params->extscan_adaptive_dwell_mode =
4703 pstart->extscan_adaptive_dwell_mode;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304704 for (i = 0; i < WMI_WLAN_EXTSCAN_MAX_BUCKETS; i++) {
4705 params->buckets[i].bucket = pstart->buckets[i].bucket;
4706 params->buckets[i].band =
4707 (enum wmi_wifi_band) pstart->buckets[i].band;
4708 params->buckets[i].period = pstart->buckets[i].period;
4709 params->buckets[i].reportEvents =
4710 pstart->buckets[i].reportEvents;
4711 params->buckets[i].max_period = pstart->buckets[i].max_period;
4712 params->buckets[i].exponent = pstart->buckets[i].exponent;
4713 params->buckets[i].step_count = pstart->buckets[i].step_count;
4714 params->buckets[i].numChannels = pstart->buckets[i].numChannels;
4715 params->buckets[i].min_dwell_time_active =
4716 pstart->buckets[i].min_dwell_time_active;
4717 params->buckets[i].min_dwell_time_passive =
4718 pstart->buckets[i].min_dwell_time_passive;
4719 params->buckets[i].max_dwell_time_active =
4720 pstart->buckets[i].max_dwell_time_active;
4721 params->buckets[i].max_dwell_time_passive =
4722 pstart->buckets[i].max_dwell_time_passive;
4723 for (j = 0; j < WLAN_EXTSCAN_MAX_CHANNELS; j++) {
4724 params->buckets[i].channels[j].channel =
4725 pstart->buckets[i].channels[j].channel;
4726 params->buckets[i].channels[j].dwellTimeMs =
4727 pstart->buckets[i].channels[j].dwellTimeMs;
4728 params->buckets[i].channels[j].passive =
4729 pstart->buckets[i].channels[j].passive;
4730 params->buckets[i].channels[j].chnlClass =
4731 pstart->buckets[i].channels[j].chnlClass;
4732 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004733 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304734
4735 status = wmi_unified_start_extscan_cmd(wma->wmi_handle,
4736 params);
Abhishek Singhb61b5452017-04-10 10:14:18 +05304737 qdf_mem_free(params);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304738 if (QDF_IS_STATUS_ERROR(status))
4739 return status;
4740
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004741 wma->interfaces[pstart->sessionId].extscan_in_progress = true;
4742 WMA_LOGD("Extscan start request sent successfully for vdev %d",
4743 pstart->sessionId);
4744
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304745 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004746}
4747
4748/**
4749 * wma_stop_extscan() - stop extscan command to fw.
4750 * @handle: wma handle
4751 * @pstopcmd: stop scan command request params
4752 *
4753 * This function sends stop extscan request to fw.
4754 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304755 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004756 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304757QDF_STATUS wma_stop_extscan(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004758 tSirExtScanStopReqParams *pstopcmd)
4759{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304760 struct extscan_stop_req_params params = {0};
4761 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004762
4763 if (!wma || !wma->wmi_handle) {
4764 WMA_LOGE("%s: WMA is closed, cannot issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304765 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004766 }
4767 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4768 WMI_SERVICE_EXTSCAN)) {
4769 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304770 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004771 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004772
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304773 params.request_id = pstopcmd->requestId;
4774 params.session_id = pstopcmd->sessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004775
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304776 status = wmi_unified_stop_extscan_cmd(wma->wmi_handle,
4777 &params);
4778 if (QDF_IS_STATUS_ERROR(status))
4779 return status;
4780
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004781 wma->interfaces[pstopcmd->sessionId].extscan_in_progress = false;
4782 WMA_LOGD("Extscan stop request sent successfully for vdev %d",
4783 pstopcmd->sessionId);
4784
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304785 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004786}
4787
4788/** wma_get_hotlist_entries_per_page() - hotlist entries per page
4789 * @wmi_handle: wmi handle.
4790 * @cmd: size of command structure.
4791 * @per_entry_size: per entry size.
4792 *
4793 * This utility function calculates how many hotlist entries can
4794 * fit in one page.
4795 *
4796 * Return: number of entries
4797 */
4798static inline int wma_get_hotlist_entries_per_page(wmi_unified_t wmi_handle,
4799 size_t cmd_size,
4800 size_t per_entry_size)
4801{
4802 uint32_t avail_space = 0;
4803 int num_entries = 0;
4804 uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle);
4805
4806 /* Calculate number of hotlist entries that can
4807 * be passed in wma message request.
4808 */
4809 avail_space = max_msg_len - cmd_size;
4810 num_entries = avail_space / per_entry_size;
4811 return num_entries;
4812}
4813
4814/**
4815 * wma_get_buf_extscan_hotlist_cmd() - prepare hotlist command
4816 * @handle: wma handle
4817 * @photlist: hotlist command params
4818 * @buf_len: buffer length
4819 *
4820 * This function fills individual elements for hotlist request and
4821 * TLV for bssid entries
4822 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304823 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004824 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304825QDF_STATUS wma_get_buf_extscan_hotlist_cmd(tp_wma_handle wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004826 tSirExtScanSetBssidHotListReqParams *photlist,
4827 int *buf_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004828{
Govind Singh64b5e112016-03-08 11:53:50 +05304829 return wmi_unified_get_buf_extscan_hotlist_cmd(wma_handle->wmi_handle,
4830 (struct ext_scan_setbssi_hotlist_params *)photlist,
4831 buf_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004832}
4833
4834/**
4835 * wma_extscan_start_hotlist_monitor() - start hotlist monitor
4836 * @wma: wma handle
4837 * @photlist: hotlist request params
4838 *
4839 * This function configures hotlist monitor in fw.
4840 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304841 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004842 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304843QDF_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004844 tSirExtScanSetBssidHotListReqParams *photlist)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004845{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304846 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004847 int len;
4848
4849 if (!wma || !wma->wmi_handle) {
4850 WMA_LOGE("%s: WMA is closed, can not issue hotlist cmd",
4851 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304852 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004853 }
4854 /* Fill individual elements for hotlist request and
4855 * TLV for bssid entries
4856 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304857 qdf_status = wma_get_buf_extscan_hotlist_cmd(wma, photlist, &len);
4858 if (qdf_status != QDF_STATUS_SUCCESS) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004859 WMA_LOGE("%s: Failed to get buffer for hotlist scan cmd",
4860 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304861 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004862 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304863 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004864}
4865
4866/**
4867 * wma_extscan_stop_hotlist_monitor() - stop hotlist monitor
4868 * @wma: wma handle
4869 * @photlist_reset: hotlist reset params
4870 *
4871 * This function configures hotlist monitor to stop in fw.
4872 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304873 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004874 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304875QDF_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004876 tSirExtScanResetBssidHotlistReqParams *photlist_reset)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004877{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304878 struct extscan_bssid_hotlist_reset_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004879
4880 if (!wma || !wma->wmi_handle) {
4881 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304882 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004883 }
4884 if (!photlist_reset) {
4885 WMA_LOGE("%s: Invalid reset hotlist buffer", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304886 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004887 }
4888 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4889 WMI_SERVICE_EXTSCAN)) {
4890 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304891 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004892 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004893
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304894 params.request_id = photlist_reset->requestId;
4895 params.session_id = photlist_reset->requestId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004896
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304897 return wmi_unified_extscan_stop_hotlist_monitor_cmd(wma->wmi_handle,
4898 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004899}
4900
4901/**
4902 * wma_get_buf_extscan_change_monitor_cmd() - fill change monitor request
4903 * @wma: wma handle
4904 * @psigchange: change monitor request params
4905 * @buf: wmi buffer
4906 * @buf_len: buffer length
4907 *
4908 * This function fills elements of change monitor request buffer.
4909 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304910 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004911 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304912QDF_STATUS wma_get_buf_extscan_change_monitor_cmd(tp_wma_handle wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004913 tSirExtScanSetSigChangeReqParams *psigchange,
4914 wmi_buf_t *buf, int *buf_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004915{
4916 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd;
4917 wmi_extscan_wlan_change_bssid_param *dest_chglist;
4918 uint8_t *buf_ptr;
4919 int j;
4920 int len = sizeof(*cmd);
4921 int numap = psigchange->numAp;
4922 tSirAPThresholdParam *src_ap = psigchange->ap;
4923
4924 if (!numap) {
4925 WMA_LOGE("%s: Invalid number of bssid's", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304926 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004927 }
4928 len += WMI_TLV_HDR_SIZE;
4929 len += numap * sizeof(wmi_extscan_wlan_change_bssid_param);
4930
4931 *buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
4932 if (!*buf) {
4933 WMA_LOGP("%s: failed to allocate memory for change monitor cmd",
4934 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304935 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004936 }
4937 buf_ptr = (uint8_t *) wmi_buf_data(*buf);
4938 cmd =
4939 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)
4940 buf_ptr;
4941 WMITLV_SET_HDR(&cmd->tlv_header,
4942 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param,
4943 WMITLV_GET_STRUCT_TLVLEN
4944 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param));
4945
4946 cmd->request_id = psigchange->requestId;
4947 cmd->vdev_id = psigchange->sessionId;
4948 cmd->total_entries = numap;
4949 cmd->mode = 1;
4950 cmd->num_entries_in_page = numap;
4951 cmd->lost_ap_scan_count = psigchange->lostApSampleSize;
4952 cmd->max_rssi_samples = psigchange->rssiSampleSize;
4953 cmd->rssi_averaging_samples = psigchange->rssiSampleSize;
4954 cmd->max_out_of_range_count = psigchange->minBreaching;
4955
4956 buf_ptr += sizeof(*cmd);
4957 WMITLV_SET_HDR(buf_ptr,
4958 WMITLV_TAG_ARRAY_STRUC,
4959 numap * sizeof(wmi_extscan_wlan_change_bssid_param));
4960 dest_chglist = (wmi_extscan_wlan_change_bssid_param *)
4961 (buf_ptr + WMI_TLV_HDR_SIZE);
4962
4963 for (j = 0; j < numap; j++) {
4964 WMITLV_SET_HDR(dest_chglist,
4965 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
4966 WMITLV_GET_STRUCT_TLVLEN
4967 (wmi_extscan_wlan_change_bssid_param));
4968
4969 dest_chglist->lower_rssi_limit = src_ap->low;
4970 dest_chglist->upper_rssi_limit = src_ap->high;
4971 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes,
4972 &dest_chglist->bssid);
4973
4974 WMA_LOGD("%s: min_rssi %d", __func__,
4975 dest_chglist->lower_rssi_limit);
4976 dest_chglist++;
4977 src_ap++;
4978 }
4979 buf_ptr += WMI_TLV_HDR_SIZE +
4980 (numap * sizeof(wmi_extscan_wlan_change_bssid_param));
4981 *buf_len = len;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304982 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004983}
4984
4985/**
4986 * wma_extscan_start_change_monitor() - send start change monitor cmd
4987 * @wma: wma handle
4988 * @psigchange: change monitor request params
4989 *
4990 * This function sends start change monitor request to fw.
4991 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304992 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004993 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304994QDF_STATUS wma_extscan_start_change_monitor(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004995 tSirExtScanSetSigChangeReqParams *
4996 psigchange)
4997{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304998 int i = 0;
Mohit Khanna0fe61672016-05-19 16:53:39 -07004999 QDF_STATUS status;
5000 struct extscan_set_sig_changereq_params *params_ptr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005001
5002 if (!wma || !wma->wmi_handle) {
5003 WMA_LOGE("%s: WMA is closed,can not issue extscan cmd",
5004 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305005 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005006 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005007
Mohit Khanna0fe61672016-05-19 16:53:39 -07005008 params_ptr = qdf_mem_malloc(sizeof(*params_ptr));
5009
5010 if (!params_ptr) {
5011 WMA_LOGE(
5012 "%s: unable to allocate memory for extscan_set_sig_changereq_params",
5013 __func__);
5014 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005015 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305016
Mohit Khanna0fe61672016-05-19 16:53:39 -07005017 params_ptr->request_id = psigchange->requestId;
5018 params_ptr->session_id = psigchange->sessionId;
5019 params_ptr->rssi_sample_size = psigchange->rssiSampleSize;
5020 params_ptr->lostap_sample_size = psigchange->lostApSampleSize;
5021 params_ptr->min_breaching = psigchange->minBreaching;
5022 params_ptr->num_ap = psigchange->numAp;
5023 for (i = 0; i < WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS; i++) {
5024 qdf_mem_copy(&params_ptr->ap[i].bssid,
5025 &psigchange->ap[i].bssid,
5026 sizeof(struct qdf_mac_addr));
5027 params_ptr->ap[i].high = psigchange->ap[i].high;
5028 params_ptr->ap[i].low = psigchange->ap[i].low;
5029 }
5030
5031 status = wmi_unified_extscan_start_change_monitor_cmd
5032 (wma->wmi_handle,
5033 params_ptr);
5034 qdf_mem_free(params_ptr);
5035 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005036}
5037
5038/**
5039 * wma_extscan_stop_change_monitor() - send stop change monitor cmd
5040 * @wma: wma handle
5041 * @pResetReq: Reset change request params
5042 *
5043 * This function sends stop change monitor request to fw.
5044 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305045 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005046 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305047QDF_STATUS wma_extscan_stop_change_monitor(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005048 tSirExtScanResetSignificantChangeReqParams *pResetReq)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005049{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305050 struct extscan_capabilities_reset_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005051
5052 if (!wma || !wma->wmi_handle) {
5053 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305054 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005055 }
5056 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5057 WMI_SERVICE_EXTSCAN)) {
5058 WMA_LOGE("%s: ext scan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305059 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005060 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005061
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305062 params.request_id = pResetReq->requestId;
5063 params.session_id = pResetReq->sessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005064
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305065 return wmi_unified_extscan_stop_change_monitor_cmd(wma->wmi_handle,
5066 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005067}
5068
5069/**
5070 * wma_extscan_get_cached_results() - extscan get cached results
5071 * @wma: wma handle
5072 * @pcached_results: cached results parameters
5073 *
5074 * This function send request to fw to get cached results.
5075 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305076 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005077 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305078QDF_STATUS wma_extscan_get_cached_results(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005079 tSirExtScanGetCachedResultsReqParams *
5080 pcached_results)
5081{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305082 struct extscan_cached_result_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005083
5084 if (!wma || !wma->wmi_handle) {
5085 WMA_LOGE("%s: WMA is closed, cannot issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305086 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005087 }
5088 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5089 WMI_SERVICE_EXTSCAN)) {
5090 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305091 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005092 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005093
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305094 params.request_id = pcached_results->requestId;
5095 params.session_id = pcached_results->sessionId;
5096 params.flush = pcached_results->flush;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005097
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305098 return wmi_unified_extscan_get_cached_results_cmd(wma->wmi_handle,
5099 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005100}
5101
5102/**
5103 * wma_extscan_get_capabilities() - extscan get capabilities
5104 * @wma: wma handle
5105 * @pgetcapab: get capabilities params
5106 *
5107 * This function send request to fw to get extscan capabilities.
5108 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305109 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005110 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305111QDF_STATUS wma_extscan_get_capabilities(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005112 tSirGetExtScanCapabilitiesReqParams *
5113 pgetcapab)
5114{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305115 struct extscan_capabilities_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005116
5117 if (!wma || !wma->wmi_handle) {
5118 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305119 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005120 }
5121 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5122 WMI_SERVICE_EXTSCAN)) {
5123 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305124 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005125 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005126
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305127 params.request_id = pgetcapab->requestId;
5128 params.session_id = pgetcapab->sessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005129
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305130 return wmi_unified_extscan_get_capabilities_cmd(wma->wmi_handle,
5131 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005132}
5133
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305134QDF_STATUS wma_ipa_offload_enable_disable(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005135 struct sir_ipa_offload_enable_disable *ipa_offload)
5136{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08005137 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005138 int32_t intra_bss_fwd = 0;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305139 struct ipa_offload_control_params params = {0};
Govind Singhd76a5b02016-03-08 15:12:14 +05305140 QDF_STATUS status;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005141 uint8_t rx_fwd_disabled;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005142
5143 if (!wma || !wma->wmi_handle) {
5144 WMA_LOGE("%s: WMA is closed, can not issue cmd",
5145 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305146 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005147 }
5148
5149 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5150 ((ipa_offload->offload_type == AP_RX_DATA_OFFLOAD) ?
5151 WMI_SERVICE_HSOFFLOAD :
5152 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT))) {
5153 WMA_LOGE("%s: %s not supported", __func__,
5154 ((ipa_offload->offload_type == AP_RX_DATA_OFFLOAD) ?
5155 "WMI_SERVICE_HSOFFLOAD" :
5156 "WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305157 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005158 }
5159
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005160 if (ipa_offload->offload_type > STA_RX_DATA_OFFLOAD)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305161 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005162
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305163 params.offload_type = ipa_offload->offload_type;
5164 params.vdev_id = ipa_offload->vdev_id;
5165 params.enable = ipa_offload->enable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005166
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305167 status = wmi_unified_ipa_offload_control_cmd(wma->wmi_handle,
5168 &params);
5169 if (QDF_IS_STATUS_ERROR(status))
5170 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005171
5172 /*
5173 * Check if VDEV is already deleted. If deleted, don't
5174 * send INTRA BSS FWD WMI command
5175 */
5176 vdev = wma_find_vdev_by_id(wma, ipa_offload->vdev_id);
5177 if (!vdev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305178 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005179
5180 /* Disable Intra-BSS FWD offload when gDisableIntraBssFwd=1 in INI */
Leo Chang96464902016-10-28 11:10:54 -07005181 rx_fwd_disabled = cdp_cfg_is_rx_fwd_disabled(
5182 cds_get_context(QDF_MODULE_ID_SOC), vdev);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005183 if (!ipa_offload->enable || rx_fwd_disabled) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005184 WMA_LOGE("%s: ipa_offload->enable=%d, rx_fwd_disabled=%d",
5185 __func__,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07005186 ipa_offload->enable, rx_fwd_disabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005187 intra_bss_fwd = 1;
5188 }
5189
5190 /* Disable/enable WMI_VDEV_PARAM_INTRA_BSS_FWD */
Govind Singhd76a5b02016-03-08 15:12:14 +05305191 status = wma_vdev_set_param(wma->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005192 ipa_offload->vdev_id, WMI_VDEV_PARAM_INTRA_BSS_FWD,
Govind Singhd76a5b02016-03-08 15:12:14 +05305193 intra_bss_fwd);
5194 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005195 WMA_LOGE("Failed to disable WMI_VDEV_PARAM_INTRA_BSS_FWD");
Govind Singhd76a5b02016-03-08 15:12:14 +05305196 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005197 }
5198
Govind Singhd76a5b02016-03-08 15:12:14 +05305199 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005200}
5201
5202/** wma_set_epno_network_list() - set epno network list
5203 * @wma: WMA handle
5204 * @req: epno config params request structure
5205 *
5206 * This function reads the incoming epno config request structure
5207 * and constructs the WMI message to the firmware.
5208 *
5209 * Returns: 0 on success, error number otherwise
5210 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305211QDF_STATUS wma_set_epno_network_list(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005212 struct wifi_epno_params *req)
5213{
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005214 struct wifi_enhanched_pno_params *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305215 uint8_t i = 0;
5216 QDF_STATUS status;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005217 size_t params_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005218
5219 WMA_LOGD("wma_set_epno_network_list");
5220
5221 if (!wma || !wma->wmi_handle) {
5222 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305223 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005224 }
5225 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5226 WMI_SERVICE_EXTSCAN)) {
5227 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305228 return QDF_STATUS_E_NOSUPPORT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005229 }
5230
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005231 params_len = sizeof(*params) + (req->num_networks *
5232 sizeof(struct wifi_epno_network_params));
5233 params = qdf_mem_malloc(params_len);
5234 if (params == NULL) {
5235 WMA_LOGE(FL("memory allocation failed"));
5236 return QDF_STATUS_E_NOMEM;
5237 }
5238
5239 params->request_id = req->request_id;
5240 params->session_id = req->session_id;
5241 params->num_networks = req->num_networks;
Mukul Sharmae8c919f2016-10-02 20:35:15 +05305242
5243 /* Fill only when num_networks are non zero */
5244 if (req->num_networks) {
5245 params->min_5ghz_rssi = req->min_5ghz_rssi;
5246 params->min_24ghz_rssi = req->min_24ghz_rssi;
5247 params->initial_score_max = req->initial_score_max;
5248 params->same_network_bonus = req->same_network_bonus;
5249 params->secure_bonus = req->secure_bonus;
5250 params->band_5ghz_bonus = req->band_5ghz_bonus;
5251 params->current_connection_bonus =
5252 req->current_connection_bonus;
5253
5254 for (i = 0; i < req->num_networks; i++) {
5255 params->networks[i].flags = req->networks[i].flags;
5256 params->networks[i].auth_bit_field =
5257 req->networks[i].auth_bit_field;
5258 params->networks[i].ssid.length =
5259 req->networks[i].ssid.length;
5260 qdf_mem_copy(params->networks[i].ssid.mac_ssid,
5261 req->networks[i].ssid.ssId,
5262 WMI_MAC_MAX_SSID_LENGTH);
5263 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005264 }
Varun Reddy Yeturub43fda12015-09-10 18:16:21 -07005265
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005266 status = wmi_unified_set_epno_network_list_cmd(wma->wmi_handle, params);
5267 qdf_mem_free(params);
5268
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305269 if (QDF_IS_STATUS_ERROR(status))
5270 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005271
5272 WMA_LOGD("set ePNO list request sent successfully for vdev %d",
5273 req->session_id);
5274
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305275 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005276}
5277
5278/**
5279 * wma_set_passpoint_network_list() - set passpoint network list
5280 * @handle: WMA handle
5281 * @req: passpoint network request structure
5282 *
5283 * This function reads the incoming @req and fill in the destination
5284 * WMI structure and send down the passpoint configs down to the firmware
5285 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305286 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005287 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305288QDF_STATUS wma_set_passpoint_network_list(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005289 struct wifi_passpoint_req *req)
5290{
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005291 struct wifi_passpoint_req_param *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305292 int i = 0;
5293 QDF_STATUS status;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005294 size_t params_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005295
5296 WMA_LOGD("wma_set_passpoint_network_list");
5297
5298 if (!wma || !wma->wmi_handle) {
5299 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305300 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005301 }
5302 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5303 WMI_SERVICE_EXTSCAN)) {
5304 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305305 return QDF_STATUS_E_NOSUPPORT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005306 }
5307
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005308 params_len = sizeof(*params) + (req->num_networks *
5309 sizeof(struct wifi_passpoint_network_param));
5310 params = qdf_mem_malloc(params_len);
5311 if (params == NULL) {
5312 WMA_LOGE(FL("memory allocation failed"));
5313 return QDF_STATUS_E_NOMEM;
5314 }
5315
5316 params->request_id = req->request_id;
5317 params->session_id = req->session_id;
5318 params->num_networks = req->num_networks;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005319 for (i = 0; i < req->num_networks; i++) {
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005320 params->networks[i].id = req->networks[i].id;
5321 qdf_mem_copy(params->networks[i].realm, req->networks[i].realm,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305322 WMI_PASSPOINT_REALM_LEN);
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005323 qdf_mem_copy(params->networks[i].roaming_consortium_ids,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305324 req->networks[i].roaming_consortium_ids,
5325 WMI_PASSPOINT_ROAMING_CONSORTIUM_ID_NUM *
5326 sizeof(int64_t));
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005327 qdf_mem_copy(params->networks[i].plmn, req->networks[i].plmn,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305328 WMI_PASSPOINT_PLMN_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005329 }
5330
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305331 status = wmi_unified_set_passpoint_network_list_cmd(wma->wmi_handle,
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005332 params);
5333 qdf_mem_free(params);
5334
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305335 if (QDF_IS_STATUS_ERROR(status))
5336 return status;
5337
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005338 WMA_LOGD("Set passpoint network list request is sent successfully for vdev %d",
5339 req->session_id);
5340
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305341 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005342}
5343
5344/**
5345 * wma_reset_passpoint_network_list() - reset passpoint network list
5346 * @handle: WMA handle
5347 * @req: passpoint network request structure
5348 *
5349 * This function sends down WMI command with network id set to wildcard id.
5350 * firmware shall clear all the config entries
5351 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305352 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005353 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305354QDF_STATUS wma_reset_passpoint_network_list(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005355 struct wifi_passpoint_req *req)
5356{
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005357 struct wifi_passpoint_req_param *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305358 int i = 0;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005359 QDF_STATUS status;
5360 size_t params_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005361
5362 WMA_LOGD("wma_reset_passpoint_network_list");
5363
5364 if (!wma || !wma->wmi_handle) {
5365 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305366 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005367 }
5368 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5369 WMI_SERVICE_EXTSCAN)) {
5370 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305371 return QDF_STATUS_E_NOSUPPORT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005372 }
5373
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005374 params_len = sizeof(*params) + (req->num_networks *
5375 sizeof(struct wifi_passpoint_network_param));
5376 params = qdf_mem_malloc(params_len);
5377 if (params == NULL) {
5378 WMA_LOGE(FL("memory allocation failed"));
5379 return QDF_STATUS_E_NOMEM;
5380 }
5381
5382 params->request_id = req->request_id;
5383 params->session_id = req->session_id;
5384 params->num_networks = req->num_networks;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305385 for (i = 0; i < req->num_networks; i++) {
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005386 params->networks[i].id = req->networks[i].id;
5387 qdf_mem_copy(params->networks[i].realm, req->networks[i].realm,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305388 WMI_PASSPOINT_REALM_LEN);
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005389 qdf_mem_copy(params->networks[i].roaming_consortium_ids,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305390 req->networks[i].roaming_consortium_ids,
5391 WMI_PASSPOINT_ROAMING_CONSORTIUM_ID_NUM *
5392 sizeof(int64_t));
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005393 qdf_mem_copy(params->networks[i].plmn, req->networks[i].plmn,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305394 WMI_PASSPOINT_PLMN_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005395 }
5396
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005397 status = wmi_unified_reset_passpoint_network_list_cmd(wma->wmi_handle,
5398 params);
5399 qdf_mem_free(params);
5400
5401 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005402}
5403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005404#endif
5405
5406/**
5407 * wma_scan_probe_setoui() - set scan probe OUI
5408 * @wma: wma handle
5409 * @psetoui: OUI parameters
5410 *
5411 * set scan probe OUI parameters in firmware
5412 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305413 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005414 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305415QDF_STATUS wma_scan_probe_setoui(tp_wma_handle wma, tSirScanMacOui *psetoui)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005416{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305417 struct scan_mac_oui set_oui;
5418
5419 qdf_mem_set(&set_oui, sizeof(struct scan_mac_oui), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005420
5421 if (!wma || !wma->wmi_handle) {
5422 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305423 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005424 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005425
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305426 qdf_mem_copy(set_oui.oui, psetoui->oui,
5427 WMI_WIFI_SCANNING_MAC_OUI_LENGTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005428
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +05305429 set_oui.vdev_id = psetoui->vdev_id;
5430 set_oui.enb_probe_req_sno_randomization =
5431 psetoui->enb_probe_req_sno_randomization;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05305432 set_oui.ie_whitelist = psetoui->ie_whitelist;
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +05305433
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305434 return wmi_unified_scan_probe_setoui_cmd(wma->wmi_handle,
5435 &set_oui);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005436}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005437/**
5438 * wma_roam_better_ap_handler() - better ap event handler
5439 * @wma: wma handle
5440 * @vdev_id: vdev id
5441 *
5442 * Handler for WMI_ROAM_REASON_BETTER_AP event from roam firmware in Rome.
5443 * This event means roam algorithm in Rome has found a better matching
5444 * candidate AP. The indication is sent to SME.
5445 *
5446 * Return: none
5447 */
5448void wma_roam_better_ap_handler(tp_wma_handle wma, uint32_t vdev_id)
5449{
Rajeev Kumarcf7bd802017-04-18 11:11:42 -07005450 struct scheduler_msg cds_msg = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005451 tSirSmeCandidateFoundInd *candidate_ind;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005452 struct scan_param *params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005453
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005454 params = &wma->interfaces[vdev_id].scan_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005455 /* abort existing scans from GUI, but not roaming preauth scan */
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005456 if (params->scan_id != 0 && params->chan_freq == 0 &&
5457 params->scan_requestor_id == USER_SCAN_REQUESTOR_ID) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005458 tAbortScanParams abortScan;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005459
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005460 abortScan.SessionId = vdev_id;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005461 abortScan.scan_id = params->scan_id;
5462 abortScan.scan_requestor_id = params->scan_requestor_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005463 wma_stop_scan(wma, &abortScan);
5464 }
5465
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305466 candidate_ind = qdf_mem_malloc(sizeof(tSirSmeCandidateFoundInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005467 if (!candidate_ind) {
5468 WMA_LOGE("%s: Alloc failed for tSirSmeCandidateFoundInd",
5469 __func__);
5470 return;
5471 }
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08005472 WMA_LOGD("%s: roaming in progress for vdev %d",
5473 __func__, vdev_id);
5474 wma->interfaces[vdev_id].roaming_in_progress = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005475
5476 candidate_ind->messageType = eWNI_SME_CANDIDATE_FOUND_IND;
5477 candidate_ind->sessionId = vdev_id;
5478 candidate_ind->length = sizeof(tSirSmeCandidateFoundInd);
5479
5480 cds_msg.type = eWNI_SME_CANDIDATE_FOUND_IND;
5481 cds_msg.bodyptr = candidate_ind;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305482 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005483 FL("posting candidate ind to SME"));
5484
Rajeev Kumarb60abe42017-01-21 15:39:31 -08005485 if (QDF_STATUS_SUCCESS != scheduler_post_msg(QDF_MODULE_ID_SME,
Rajeev Kumar156188e2017-01-21 17:23:52 -08005486 &cds_msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305487 qdf_mem_free(candidate_ind);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305488 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005489 FL("Failed to post candidate ind to SME"));
5490 }
5491}
5492
5493/**
5494 * wma_roam_event_callback() - roam event callback
5495 * @handle: wma handle
5496 * @event_buf: event buffer
5497 * @len: buffer length
5498 *
5499 * Handler for all events from roam engine in firmware
5500 *
5501 * Return: 0 for success or error code
5502 */
5503int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
5504 uint32_t len)
5505{
5506 tp_wma_handle wma_handle = (tp_wma_handle) handle;
5507 WMI_ROAM_EVENTID_param_tlvs *param_buf;
5508 wmi_roam_event_fixed_param *wmi_event;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005509 struct sSirSmeRoamOffloadSynchInd *roam_synch_data;
5510 enum sir_roam_op_code op_code = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005511
5512 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) event_buf;
5513 if (!param_buf) {
5514 WMA_LOGE("Invalid roam event buffer");
5515 return -EINVAL;
5516 }
5517
5518 wmi_event = param_buf->fixed_param;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005519 WMA_LOGD("%s: Reason %x, Notif %x for vdevid %x, rssi %d",
5520 __func__, wmi_event->reason, wmi_event->notif,
5521 wmi_event->vdev_id, wmi_event->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005522
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05305523 DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07005524 wmi_event->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
5525 QDF_PROTO_TYPE_EVENT, QDF_ROAM_EVENTID));
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05305526
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005527 switch (wmi_event->reason) {
5528 case WMI_ROAM_REASON_BMISS:
5529 WMA_LOGD("Beacon Miss for vdevid %x", wmi_event->vdev_id);
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05305530 wma_beacon_miss_handler(wma_handle, wmi_event->vdev_id,
5531 wmi_event->rssi);
Sen, Devendra154b3c42017-02-13 20:44:15 +05305532 wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BMISS,
5533 wmi_event->vdev_id, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005534 break;
5535 case WMI_ROAM_REASON_BETTER_AP:
5536 WMA_LOGD("%s:Better AP found for vdevid %x, rssi %d", __func__,
5537 wmi_event->vdev_id, wmi_event->rssi);
5538 wma_handle->suitable_ap_hb_failure = false;
5539 wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
5540 break;
5541 case WMI_ROAM_REASON_SUITABLE_AP:
5542 wma_handle->suitable_ap_hb_failure = true;
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05305543 wma_handle->suitable_ap_hb_failure_rssi = wmi_event->rssi;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005544 WMA_LOGD("%s:Bmiss scan AP found for vdevid %x, rssi %d",
5545 __func__, wmi_event->vdev_id, wmi_event->rssi);
5546 wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
5547 break;
5548#ifdef WLAN_FEATURE_ROAM_OFFLOAD
5549 case WMI_ROAM_REASON_HO_FAILED:
5550 WMA_LOGE("LFR3:Hand-Off Failed for vdevid %x",
5551 wmi_event->vdev_id);
5552 wma_roam_ho_fail_handler(wma_handle, wmi_event->vdev_id);
5553 break;
5554#endif
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005555 case WMI_ROAM_REASON_INVALID:
5556 roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
5557 if (NULL == roam_synch_data) {
5558 WMA_LOGE("Memory unavailable for roam synch data");
5559 return -ENOMEM;
5560 }
5561 if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_START)
Naveen Rawat8cc23b02016-07-14 12:22:56 -07005562 op_code = SIR_ROAMING_START;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005563 if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_ABORT)
Naveen Rawat8cc23b02016-07-14 12:22:56 -07005564 op_code = SIR_ROAMING_ABORT;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005565 roam_synch_data->roamedVdevId = wmi_event->vdev_id;
5566 wma_handle->csr_roam_synch_cb(
5567 (tpAniSirGlobal)wma_handle->mac_context,
5568 roam_synch_data, NULL, op_code);
5569 qdf_mem_free(roam_synch_data);
5570 break;
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +05305571 case WMI_ROAM_REASON_RSO_STATUS:
5572 wma_rso_cmd_status_event_handler(wmi_event);
5573 break;
Arif Hussain43354e62017-05-24 11:24:25 -07005574 case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
5575 roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
5576 if (!roam_synch_data) {
5577 WMA_LOGE("Memory unavailable for roam synch data");
5578 return -ENOMEM;
5579 }
5580 roam_synch_data->roamedVdevId = wmi_event->vdev_id;
5581 wma_handle->csr_roam_synch_cb(
5582 (tpAniSirGlobal)wma_handle->mac_context,
5583 roam_synch_data, NULL, SIR_ROAMING_INVOKE_FAIL);
5584 qdf_mem_free(roam_synch_data);
5585 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005586 default:
5587 WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__,
5588 wmi_event->reason, wmi_event->vdev_id);
5589 break;
5590 }
5591 return 0;
5592}
5593
5594
5595/**
5596 * wma_set_rssi_monitoring() - set rssi monitoring
5597 * @handle: WMA handle
5598 * @req: rssi monitoring request structure
5599 *
5600 * This function reads the incoming @req and fill in the destination
5601 * WMI structure and send down the rssi monitoring configs down to the firmware
5602 *
5603 * Return: 0 on success; error number otherwise
5604 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305605QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005606 struct rssi_monitor_req *req)
5607{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305608 struct rssi_monitor_param params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005609
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305610 if (!wma) {
5611 WMA_LOGE("%s: wma handle is NULL", __func__);
5612 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005613 }
5614
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305615 params.request_id = req->request_id;
5616 params.session_id = req->session_id;
5617 params.min_rssi = req->min_rssi;
5618 params.max_rssi = req->max_rssi;
5619 params.control = req->control;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005620
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305621 return wmi_unified_set_rssi_monitoring_cmd(wma->wmi_handle,
5622 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005623}
5624
5625/**
5626 * wma_get_scan_id() - Generates scan id
5627 * @scan_id: Scan id
5628 *
5629 * This function generates the scan id.
5630 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305631 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005632 */
5633
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305634QDF_STATUS wma_get_scan_id(uint32_t *scan_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005635{
Anurag Chouhan6d760662016-02-20 16:05:43 +05305636 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005637
5638 if (!scan_id) {
5639 WMA_LOGE("Scan_id is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305640 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005641 }
5642
Abhishek Singhe6857812017-03-10 18:20:06 +05305643#ifdef NAPIER_SCAN
5644 *scan_id = ucfg_scan_get_scan_id(wma->psoc);
5645#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005646 /* host need to cycle through the lower 12 bits to generate ids */
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05305647 *scan_id = qdf_atomic_inc_return(&wma->scan_id_counter) &
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005648 WMA_SCAN_ID_MASK;
5649 /*
5650 * Firmware expects the host scan request id appended
5651 * by PREFIX 0xA000
5652 */
5653 *scan_id = *scan_id | WMI_HOST_SCAN_REQ_ID_PREFIX;
Abhishek Singhe6857812017-03-10 18:20:06 +05305654#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305655 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005656}
5657
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005658#ifdef FEATURE_LFR_SUBNET_DETECTION
5659/**
5660 * wma_set_gateway_params() - set gateway parameters
5661 * @wma: WMA handle
5662 * @req: gateway parameter update request structure
5663 *
5664 * This function reads the incoming @req and fill in the destination
5665 * WMI structure and sends down the gateway configs down to the firmware
5666 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305667 * Return: QDF_STATUS
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005668 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305669QDF_STATUS wma_set_gateway_params(tp_wma_handle wma,
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005670 struct gateway_param_update_req *req)
5671{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305672 struct gateway_update_req_param params = {0};
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005673
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305674 if (!wma) {
5675 WMA_LOGE("%s: wma handle is NULL", __func__);
5676 return QDF_STATUS_E_INVAL;
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005677 }
5678
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305679 params.request_id = req->request_id;
5680 params.session_id = req->session_id;
5681 params.max_retries = req->max_retries;
5682 params.timeout = req->timeout;
5683 params.ipv4_addr_type = req->ipv4_addr_type;
5684 params.ipv6_addr_type = req->ipv6_addr_type;
5685 qdf_mem_copy(&params.gw_mac_addr, &req->gw_mac_addr,
5686 sizeof(struct qdf_mac_addr));
5687 qdf_mem_copy(params.ipv4_addr, req->ipv4_addr,
5688 QDF_IPV4_ADDR_SIZE);
5689 qdf_mem_copy(params.ipv6_addr, req->ipv6_addr,
5690 QDF_IPV6_ADDR_SIZE);
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005691
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305692 return wmi_unified_set_gateway_params_cmd(wma->wmi_handle,
5693 &params);
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005694}
5695#endif /* FEATURE_LFR_SUBNET_DETECTION */
5696
Sandeep Puligillae0875662016-02-12 16:09:21 -08005697/**
5698 * wma_ht40_stop_obss_scan() - ht40 obss stop scan
5699 * @wma: WMA handel
5700 * @vdev_id: vdev identifier
5701 *
5702 * Return: Return QDF_STATUS, otherwise appropriate failure code
5703 */
5704QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma, int32_t vdev_id)
5705{
5706
5707 wmi_buf_t buf;
5708 wmi_obss_scan_disable_cmd_fixed_param *cmd;
5709 int ret;
5710 int len = sizeof(*cmd);
5711
5712 buf = wmi_buf_alloc(wma->wmi_handle, len);
5713 if (!buf) {
5714 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
5715 return QDF_STATUS_E_NOMEM;
5716 }
5717
5718 WMA_LOGD("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id);
5719
5720 cmd = (wmi_obss_scan_disable_cmd_fixed_param *) wmi_buf_data(buf);
5721 WMITLV_SET_HDR(&cmd->tlv_header,
5722 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param,
5723 WMITLV_GET_STRUCT_TLVLEN(
5724 wmi_obss_scan_disable_cmd_fixed_param));
5725
5726 cmd->vdev_id = vdev_id;
5727 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
5728 WMI_OBSS_SCAN_DISABLE_CMDID);
5729 if (ret != EOK) {
5730 WMA_LOGE("Failed to send gw config parameter to fw, ret: %d",
5731 ret);
5732 wmi_buf_free(buf);
5733 return QDF_STATUS_E_FAILURE;
5734 }
5735
5736 return QDF_STATUS_SUCCESS;
5737}
5738
5739/**
5740 * wma_send_ht40_obss_scanind() - ht40 obss start scan indication
5741 * @wma: WMA handel
5742 * @req: start scan request
5743 *
5744 * Return: Return QDF_STATUS, otherwise appropriate failure code
5745 */
5746QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
5747 struct obss_ht40_scanind *req)
5748{
5749 wmi_buf_t buf;
5750 wmi_obss_scan_enable_cmd_fixed_param *cmd;
5751 int ret;
5752 int len = 0;
5753 uint8_t *buf_ptr, i;
5754 uint8_t *channel_list;
5755
5756 len += sizeof(wmi_obss_scan_enable_cmd_fixed_param);
5757
5758 len += WMI_TLV_HDR_SIZE;
5759 len += qdf_roundup(sizeof(uint8_t) * req->channel_count,
5760 sizeof(uint32_t));
5761
5762 len += WMI_TLV_HDR_SIZE;
5763 len += qdf_roundup(sizeof(uint8_t) * 1, sizeof(uint32_t));
5764
5765 WMA_LOGE("cmdlen %d vdev_id %d channel count %d iefield_len %d",
5766 len, req->bss_id, req->channel_count, req->iefield_len);
5767
5768 WMA_LOGE("scantype %d active_time %d passive %d Obss interval %d",
5769 req->scan_type, req->obss_active_dwelltime,
5770 req->obss_passive_dwelltime,
5771 req->obss_width_trigger_interval);
5772
5773 buf = wmi_buf_alloc(wma->wmi_handle, len);
5774 if (!buf) {
5775 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
5776 return QDF_STATUS_E_NOMEM;
5777 }
5778
5779 cmd = (wmi_obss_scan_enable_cmd_fixed_param *) wmi_buf_data(buf);
5780 WMITLV_SET_HDR(&cmd->tlv_header,
5781 WMITLV_TAG_STRUC_wmi_obss_scan_enable_cmd_fixed_param,
5782 WMITLV_GET_STRUCT_TLVLEN(wmi_obss_scan_enable_cmd_fixed_param));
5783
5784 buf_ptr = (uint8_t *) cmd;
5785
5786 cmd->vdev_id = req->bss_id;
5787 cmd->scan_type = req->scan_type;
5788 cmd->obss_scan_active_dwell =
5789 req->obss_active_dwelltime;
5790 cmd->obss_scan_passive_dwell =
5791 req->obss_passive_dwelltime;
5792 cmd->bss_channel_width_trigger_scan_interval =
5793 req->obss_width_trigger_interval;
5794 cmd->bss_width_channel_transition_delay_factor =
5795 req->bsswidth_ch_trans_delay;
5796 cmd->obss_scan_active_total_per_channel =
5797 req->obss_active_total_per_channel;
5798 cmd->obss_scan_passive_total_per_channel =
5799 req->obss_passive_total_per_channel;
5800 cmd->obss_scan_activity_threshold =
5801 req->obss_activity_threshold;
5802
5803 cmd->channel_len = req->channel_count;
5804 cmd->forty_mhz_intolerant = req->fortymhz_intolerent;
5805 cmd->current_operating_class = req->current_operatingclass;
5806 cmd->ie_len = req->iefield_len;
5807
5808 buf_ptr += sizeof(wmi_obss_scan_enable_cmd_fixed_param);
5809 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5810 qdf_roundup(req->channel_count, sizeof(uint32_t)));
5811
5812 buf_ptr += WMI_TLV_HDR_SIZE;
5813 channel_list = (uint8_t *) buf_ptr;
5814
5815 for (i = 0; i < req->channel_count; i++) {
5816 channel_list[i] = req->channels[i];
5817 WMA_LOGD("Ch[%d]: %d ", i, channel_list[i]);
5818 }
5819
5820 buf_ptr += qdf_roundup(sizeof(uint8_t) * req->channel_count,
5821 sizeof(uint32_t));
5822 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5823 qdf_roundup(1, sizeof(uint32_t)));
5824 buf_ptr += WMI_TLV_HDR_SIZE;
5825
5826 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
5827 WMI_OBSS_SCAN_ENABLE_CMDID);
5828 if (ret != EOK) {
5829 WMA_LOGE("Failed to send gw config parameter to fw, ret: %d",
5830 ret);
5831 wmi_buf_free(buf);
5832 return QDF_STATUS_E_FAILURE;
5833 }
5834 return QDF_STATUS_SUCCESS;
5835}