blob: de3cc289f921b9897bfa664e672c3237c4f67145 [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>
78
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079#define WMA_MCC_MIRACAST_REST_TIME 400
80#define WMA_SCAN_ID_MASK 0x0fff
81
82#ifdef FEATURE_WLAN_EXTSCAN
83/**
84 * enum extscan_report_events_type - extscan report events type
85 * @EXTSCAN_REPORT_EVENTS_BUFFER_FULL: report only when scan history is % full
86 * @EXTSCAN_REPORT_EVENTS_EACH_SCAN: report a scan completion event after scan
87 * @EXTSCAN_REPORT_EVENTS_FULL_RESULTS: forward scan results
88 * (beacons/probe responses + IEs)
89 * in real time to HAL, in addition to completion events.
90 * Note: To keep backward compatibility,
91 * fire completion events regardless of REPORT_EVENTS_EACH_SCAN.
92 * @EXTSCAN_REPORT_EVENTS_NO_BATCH: controls batching,
93 * 0 => batching, 1 => no batching
Mukul Sharmafa937be2016-08-12 18:13:36 +053094 * @EXTSCAN_REPORT_EVENTS_CONTEXT_HUB: forward results to context hub
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -070095 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096enum extscan_report_events_type {
97 EXTSCAN_REPORT_EVENTS_BUFFER_FULL = 0x00,
98 EXTSCAN_REPORT_EVENTS_EACH_SCAN = 0x01,
99 EXTSCAN_REPORT_EVENTS_FULL_RESULTS = 0x02,
100 EXTSCAN_REPORT_EVENTS_NO_BATCH = 0x04,
Mukul Sharmafa937be2016-08-12 18:13:36 +0530101 EXTSCAN_REPORT_EVENTS_CONTEXT_HUB = 0x08,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102};
103
104#define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION (5 * 1000) /* in msec */
105#endif
106
107/**
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530108 * wma_dec_pending_scans() - Decrements the number of pending scans
109 * @wma: The WMA handle to operate on
Dustin Brown73fce8f2016-09-29 13:27:15 -0700110 *
111 * Return: none
112 */
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530113static void wma_dec_pending_scans(tp_wma_handle wma)
Dustin Brown73fce8f2016-09-29 13:27:15 -0700114{
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530115 int32_t scan_cnt = qdf_atomic_read(&wma->num_pending_scans);
116
117 if (scan_cnt <= 0) {
118 WMA_LOGE("Stopping pending scan, but no scans were pending!");
119 return;
120 }
121
122 qdf_atomic_dec(&wma->num_pending_scans);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800123 WMA_LOGD("Ending pending scan: %d <- %d", scan_cnt, scan_cnt - 1);
Dustin Brown73fce8f2016-09-29 13:27:15 -0700124}
125
126/**
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530127 * wma_inc_pending_scans() - Increments the number of pending scans
128 * @wma: The WMA handle to operate on
Dustin Brown73fce8f2016-09-29 13:27:15 -0700129 *
130 * Return: none
131 */
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530132static void wma_inc_pending_scans(tp_wma_handle wma)
Dustin Brown73fce8f2016-09-29 13:27:15 -0700133{
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530134 int32_t scan_cnt = qdf_atomic_inc_return(&wma->num_pending_scans);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700135
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800136 WMA_LOGD("Starting pending scan: %d -> %d", scan_cnt - 1, scan_cnt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800137}
138
139/**
140 * wma_is_mcc_24G() - check that if device is in 2.4GHz MCC
141 * @handle: wma handle
142 *
143 * Return: true/false
144 */
145static bool wma_is_mcc_24G(WMA_HANDLE handle)
146{
147 tp_wma_handle wma_handle = (tp_wma_handle) handle;
148 int32_t prev_chan = 0;
149 int32_t i;
150
151 if (NULL == wma_handle) {
152 WMA_LOGE("%s: wma_handle is NULL", __func__);
153 return false;
154 }
155 for (i = 0; i < wma_handle->max_bssid; i++) {
156 if (wma_handle->interfaces[i].handle &&
Mukul Sharmaf9047232017-03-02 16:58:56 +0530157 wma_is_vdev_up(i)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800158 if ((prev_chan != 0 &&
159 prev_chan != wma_handle->interfaces[i].mhz) &&
160 (wma_handle->interfaces[i].mhz <=
161 CDS_CHAN_14_FREQ))
162 return true;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700163 prev_chan = wma_handle->interfaces[i].mhz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800164 }
165 }
166 return false;
167}
168
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700169static inline int wma_get_burst_duration(int max_ch_time, int miracast_value)
170{
171 int burst_duration = 0;
172
173 if (miracast_value) {
174 /* When miracast is running, burst
175 * duration needs to be minimum to avoid
176 * any stutter or glitch in miracast
177 * during station scan
178 */
179 if (max_ch_time <= WMA_GO_MIN_ACTIVE_SCAN_BURST_DURATION)
180 burst_duration = max_ch_time;
181 else
182 burst_duration = WMA_GO_MIN_ACTIVE_SCAN_BURST_DURATION;
183 } else {
184 /* If miracast is not running, accommodate max
185 * stations to make the scans faster
186 */
187 burst_duration = WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS *
188 max_ch_time;
189 if (burst_duration > WMA_GO_MAX_ACTIVE_SCAN_BURST_DURATION) {
190 uint8_t channels = WMA_P2P_SCAN_MAX_BURST_DURATION /
191 max_ch_time;
192
193 if (channels)
194 burst_duration = channels * max_ch_time;
195 else
196 burst_duration =
197 WMA_GO_MAX_ACTIVE_SCAN_BURST_DURATION;
198 }
199 }
200 return burst_duration;
201}
202
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800203/**
204 * wma_get_buf_start_scan_cmd() - Fill start scan command
205 * @wma_handle: wma handle
206 * @scan_req: scan request
Govind Singh498bf2a2016-03-08 15:44:17 +0530207 * @cmd: wmi buffer to be filled in
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208 *
209 * Fill individual elements of wmi_start_scan_req and TLV for
210 * channel list, bssid, ssid etc.
211 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530212 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530214QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800215 tSirScanOffloadReq *scan_req,
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800216 struct scan_req_params *cmd)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800217{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530218 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219 uint32_t dwell_time;
220 uint8_t SSID_num;
221 int i;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530222 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800223
224 if (!pMac) {
225 WMA_LOGP("%s: pMac is NULL!", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530226 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227 }
228
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229 cmd->vdev_id = scan_req->sessionId;
230 /*
231 * host cycles through the lower 12 bits for scan id generation
232 * and prefix 0xA000 to scan id
233 */
234 if (scan_req->scan_id < WMA_HOST_SCAN_REQID_PREFIX) {
235 WMA_LOGE("Received scan_id 0x%x is wrong",
236 cmd->scan_id);
237 scan_req->scan_id = scan_req->scan_id & WMA_SCAN_ID_MASK;
238 /* Appending the 0xA000 to scan Id*/
239 cmd->scan_id = scan_req->scan_id | WMA_HOST_SCAN_REQID_PREFIX;
240 } else {
241 cmd->scan_id = scan_req->scan_id;
242 }
243 cmd->scan_priority = WMI_SCAN_PRIORITY_LOW;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700244 cmd->scan_req_id = scan_req->scan_requestor_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800245
Abhishek Singh5a331712016-08-08 18:10:20 +0530246 if (PREAUTH_REQUESTOR_ID == cmd->scan_req_id)
247 cmd->scan_priority = WMI_SCAN_PRIORITY_VERY_HIGH;
248
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800249 /* Set the scan events which the driver is intereseted to receive */
250 /* TODO: handle all the other flags also */
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800251 cmd->scan_events = WMI_SCAN_EVENT_STARTED |
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800252 WMI_SCAN_EVENT_START_FAILED |
253 WMI_SCAN_EVENT_FOREIGN_CHANNEL |
254 WMI_SCAN_EVENT_COMPLETED |
255 WMI_SCAN_EVENT_DEQUEUED |
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700256 WMI_SCAN_EVENT_PREEMPTED |
257 WMI_SCAN_EVENT_RESTARTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800258
259 cmd->dwell_time_active = scan_req->maxChannelTime;
260
261 if (scan_req->scanType == eSIR_ACTIVE_SCAN) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700262 /* In Active scan case, the firmware has to do passive scan on
263 * DFS channels So the passive scan duration should be updated
264 * properly so that the duration will be sufficient enough to
265 * receive the beacon from AP
266 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800267 if (wlan_cfg_get_int(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
268 &dwell_time) != eSIR_SUCCESS) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700269 WMA_LOGE("Failed to get passive max channel value using default value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800270 dwell_time = WMA_DWELL_TIME_PASSIVE_DEFAULT;
271 }
272 cmd->dwell_time_passive = dwell_time;
273 } else
274 cmd->dwell_time_passive = scan_req->maxChannelTime;
275
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 /* Ensure correct number of probes are sent on active channel */
277 cmd->repeat_probe_time =
278 cmd->dwell_time_active / WMA_SCAN_NPROBES_DEFAULT;
279
Agrawal Ashish17bb3902016-05-05 13:29:40 +0530280 /* CSR sends min_rest_Time, max_rest_time and idle_time
281 * for staying on home channel to continue data traffic.
282 * Rome fw has facility to monitor the traffic
283 * and move to next channel. Stay on the channel for min_rest_time
284 * and then leave if there is no traffic.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800285 */
Agrawal Ashish17bb3902016-05-05 13:29:40 +0530286 cmd->min_rest_time = scan_req->min_rest_time;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800287 cmd->max_rest_time = scan_req->restTime;
288
289 /* Check for traffic at idle_time interval after min_rest_time.
290 * Default value is 25 ms to allow full use of max_rest_time
291 * when voice packets are running at 20 ms interval.
292 */
Agrawal Ashish17bb3902016-05-05 13:29:40 +0530293 cmd->idle_time = scan_req->idle_time;
294
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295
296 /* Large timeout value for full scan cycle, 30 seconds */
297 cmd->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
298
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +0530299 /* add DS param IE in probe req frame */
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800300 cmd->scan_f_add_ds_ie_in_probe = true;
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +0530301
Kapil Gupta4f0c0c12017-02-07 15:21:15 +0530302 /* set flag to get chan stats */
303 if (pMac->snr_monitor_enabled)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800304 cmd->scan_f_chan_stat_evnt = true;
Kapil Gupta4f0c0c12017-02-07 15:21:15 +0530305
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800306 /* do not add OFDM rates in 11B mode */
307 if (scan_req->dot11mode != WNI_CFG_DOT11_MODE_11B)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800308 cmd->scan_f_ofdm_rates = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309 else
310 WMA_LOGD("OFDM_RATES not included in 11B mode");
311
Tushnim Bhattacharyya5015e982017-01-11 13:30:57 -0800312 if (scan_req->p2pScanType)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800313 cmd->adaptive_dwell_time_mode = WMI_DWELL_MODE_STATIC;
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +0530314
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800315 /* Do not combine multiple channels in a single burst. Come back
316 * to home channel for data traffic after every foreign channel.
317 * By default, prefer throughput performance over scan cycle time.
318 */
319 cmd->burst_duration = 0;
320
321 if (!scan_req->p2pScanType) {
322 WMA_LOGD("Normal Scan request");
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800323 cmd->scan_f_cck_rates = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800324 if (!scan_req->numSsid)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800325 cmd->scan_f_bcast_probe = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326 if (scan_req->scanType == eSIR_PASSIVE_SCAN)
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800327 cmd->scan_f_passive = true;
328 cmd->scan_f_add_tpc_ie_in_probe = true;
329 cmd->scan_f_filter_prb_req = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800330
331 /*
332 * Decide burst_duration and dwell_time_active based on
333 * what type of devices are active.
334 */
335 do {
336 if (wma_is_sap_active(wma_handle) &&
337 wma_is_p2p_go_active(wma_handle) &&
338 wma_is_sta_active(wma_handle)) {
339 if (scan_req->maxChannelTime <=
340 WMA_3PORT_CONC_SCAN_MAX_BURST_DURATION)
341 cmd->burst_duration =
342 scan_req->maxChannelTime;
343 else
344 cmd->burst_duration =
345 WMA_3PORT_CONC_SCAN_MAX_BURST_DURATION;
346 break;
347 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800348 if (wma_handle->miracast_value &&
349 wma_is_mcc_24G(wma_handle)) {
350 cmd->max_rest_time =
351 pMac->f_sta_miracast_mcc_rest_time_val;
352 }
353 if (wma_is_p2p_go_active(wma_handle)) {
354 /* Background scan while GO is sending beacons.
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700355 * Every off-channel transition has overhead of
356 * 2 beacon intervals for NOA. Maximize number
357 * of channels in every transition by using
358 * burst scan.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359 */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700360 cmd->burst_duration =
361 wma_get_burst_duration(
362 scan_req->maxChannelTime,
363 wma_handle->miracast_value);
364
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800365 break;
366 }
367 if (wma_is_sta_active(wma_handle) ||
368 wma_is_p2p_cli_active(wma_handle)) {
Paul Zhangd2315472017-02-22 10:02:50 +0800369 if (scan_req->burst_scan_duration)
370 cmd->burst_duration =
371 scan_req->burst_scan_duration;
372 else
373 /* Typical background scan.
374 * Disable burst scan for now.
375 */
376 cmd->burst_duration = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377 break;
378 }
379 } while (0);
380
381 } else {
382 WMA_LOGD("P2P Scan");
383 switch (scan_req->p2pScanType) {
384 case P2P_SCAN_TYPE_LISTEN:
385 WMA_LOGD("P2P_SCAN_TYPE_LISTEN");
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800386 cmd->scan_f_passive = true;
387 cmd->scan_events |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388 WMI_SCAN_EVENT_FOREIGN_CHANNEL;
389 cmd->repeat_probe_time = 0;
Nishank Aggarwalf3f22842017-03-08 11:49:20 +0530390 cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800391 break;
392 case P2P_SCAN_TYPE_SEARCH:
393 WMA_LOGD("P2P_SCAN_TYPE_SEARCH");
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800394 cmd->scan_f_filter_prb_req = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800395 /* Default P2P burst duration of 120 ms will cover
396 * 3 channels with default max dwell time 40 ms.
397 * Cap limit will be set by
398 * WMA_P2P_SCAN_MAX_BURST_DURATION. Burst duration
399 * should be such that no channel is scanned less
400 * than the dwell time in normal scenarios.
401 */
402 if (scan_req->channelList.numChannels ==
403 P2P_SOCIAL_CHANNELS
404 && (!(wma_handle->miracast_value)))
405 cmd->repeat_probe_time =
406 scan_req->maxChannelTime / 5;
407 else
408 cmd->repeat_probe_time =
409 scan_req->maxChannelTime / 3;
410
411 cmd->burst_duration =
412 WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS *
413 scan_req->maxChannelTime;
414 if (cmd->burst_duration >
415 WMA_P2P_SCAN_MAX_BURST_DURATION) {
416 uint8_t channels =
417 WMA_P2P_SCAN_MAX_BURST_DURATION /
418 scan_req->maxChannelTime;
419 if (channels)
420 cmd->burst_duration =
421 channels * scan_req->maxChannelTime;
422 else
423 cmd->burst_duration =
424 WMA_P2P_SCAN_MAX_BURST_DURATION;
425 }
Nishank Aggarwalf3f22842017-03-08 11:49:20 +0530426 cmd->scan_priority = WMI_SCAN_PRIORITY_MEDIUM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 break;
428 default:
429 WMA_LOGE("Invalid scan type");
430 goto error;
431 }
432 }
433
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530434 if (wma_is_sap_active(wma_handle)) {
435 /* P2P/STA scan while SoftAP is sending beacons.
436 * Max duration of CTS2self is 32 ms, which limits the
Krunal Soni499d3642016-09-26 16:46:03 -0700437 * dwell time. If DBS is supported and if SAP is on 2G channel
438 * then keep passive dwell time default.
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530439 */
440 cmd->dwell_time_active =
441 QDF_MIN(scan_req->maxChannelTime,
442 (WMA_CTS_DURATION_MS_MAX -
443 WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME));
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -0700444 if (!policy_mgr_is_hw_dbs_capable(wma_handle->psoc) ||
445 (policy_mgr_is_hw_dbs_capable(wma_handle->psoc) &&
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700446 WLAN_REG_IS_5GHZ_CH(
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -0700447 policy_mgr_get_channel(wma_handle->psoc,
448 PM_SAP_MODE, NULL)))) {
Krunal Soni499d3642016-09-26 16:46:03 -0700449 cmd->dwell_time_passive = cmd->dwell_time_active;
450 }
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530451 cmd->burst_duration = 0;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700452 if (wlan_reg_is_dfs_ch(wma_handle->pdev,
453 policy_mgr_get_channel(wma_handle->psoc,
454 PM_SAP_MODE, NULL)))
Nitesh Shah77442572017-03-09 17:06:34 +0530455 cmd->burst_duration =
456 WMA_BURST_SCAN_MAX_NUM_OFFCHANNELS *
457 scan_req->maxChannelTime;
458 WMA_LOGI("SAP: burst_duration: %d", cmd->burst_duration);
Manishekar Chandrasekaran39044362016-04-27 13:02:05 +0530459 }
460
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 cmd->n_probes = (cmd->repeat_probe_time > 0) ?
462 cmd->dwell_time_active / cmd->repeat_probe_time : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 if (scan_req->channelList.numChannels) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464 cmd->num_chan = scan_req->channelList.numChannels;
465 for (i = 0; i < scan_req->channelList.numChannels; ++i) {
Govind Singh498bf2a2016-03-08 15:44:17 +0530466 cmd->chan_list[i] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800467 cds_chan_to_freq(scan_req->channelList.
468 channelNumber[i]);
469 }
470 }
Govind Singh498bf2a2016-03-08 15:44:17 +0530471
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800472 if (scan_req->numSsid > SIR_SCAN_MAX_NUM_SSID) {
473 WMA_LOGE("Invalid value for numSsid");
474 goto error;
475 }
Govind Singh498bf2a2016-03-08 15:44:17 +0530476
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800477 cmd->num_ssids = scan_req->numSsid;
Govind Singh498bf2a2016-03-08 15:44:17 +0530478
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479 if (scan_req->numSsid) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800480 for (i = 0; i < scan_req->numSsid; ++i) {
Govind Singh498bf2a2016-03-08 15:44:17 +0530481 cmd->ssid[i].length = scan_req->ssId[i].length;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800482 qdf_mem_copy(cmd->ssid[i].ssid,
Govind Singh498bf2a2016-03-08 15:44:17 +0530483 scan_req->ssId[i].ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 scan_req->ssId[i].length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800485 }
486 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800488 if (!scan_req->p2pScanType) {
489 if (wma_is_sap_active(wma_handle)) {
490 SSID_num = cmd->num_ssids * cmd->num_bssid;
491 cmd->repeat_probe_time = probe_time_dwell_time_map[
Anurag Chouhan6d760662016-02-20 16:05:43 +0530492 QDF_MIN(SSID_num,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800493 WMA_DWELL_TIME_PROBE_TIME_MAP_SIZE
494 - 1)].probe_time;
Liangwei Dong271f92f2016-09-28 06:05:08 -0400495 cmd->n_probes = (cmd->repeat_probe_time > 0) ?
496 cmd->dwell_time_active/
497 cmd->repeat_probe_time : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800498 }
499 }
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800500 WMA_LOGD("Scan Type 0x%x, Active dwell time %u, Passive dwell time %u",
Liangwei Dong271f92f2016-09-28 06:05:08 -0400501 scan_req->scanType, cmd->dwell_time_active,
502 cmd->dwell_time_passive);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800503 WMA_LOGD("Scan repeat_probe_time %u n_probes %u num_ssids %u num_bssid %u",
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700504 cmd->repeat_probe_time, cmd->n_probes, cmd->num_ssids,
Liangwei Dong271f92f2016-09-28 06:05:08 -0400505 cmd->num_bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800506
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800507 cmd->num_bssid = 1;
508 qdf_mem_copy(cmd->bssid_list, scan_req->bssId.bytes, QDF_MAC_ADDR_SIZE);
509 cmd->extraie.len = scan_req->uIEFieldLen;
510 cmd->extraie.ptr = (uint8_t *) scan_req +
511 (scan_req->uIEFieldOffset);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530512 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530515 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516}
517
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518/**
519 * wma_start_scan() - start scan command
520 * @wma_handle: wma handle
521 * @scan_req: scan request params
522 * @msg_type: message time
523 *
524 * Send start scan command to fw.
525 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530526 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530528QDF_STATUS wma_start_scan(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529 tSirScanOffloadReq *scan_req, uint16_t msg_type)
530{
531 uint32_t vdev_id, scan_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530532 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800533 struct scan_req_params cmd = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800534 tSirScanOffloadEvent *scan_event;
535
536 if (scan_req->sessionId > wma_handle->max_bssid) {
537 WMA_LOGE("%s: Invalid vdev_id %d, msg_type : 0x%x", __func__,
538 scan_req->sessionId, msg_type);
Govind Singh498bf2a2016-03-08 15:44:17 +0530539 goto error1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800540 }
541
542 /* Sanity check to find whether vdev id active or not */
543 if (msg_type != WMA_START_SCAN_OFFLOAD_REQ &&
544 !wma_handle->interfaces[scan_req->sessionId].handle) {
545 WMA_LOGA("vdev id [%d] is not active", scan_req->sessionId);
Govind Singh498bf2a2016-03-08 15:44:17 +0530546 goto error1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800547 }
548
549 /* Fill individual elements of wmi_start_scan_req and
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700550 * TLV for channel list, bssid, ssid etc ...
551 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530552 qdf_status = wma_get_buf_start_scan_cmd(wma_handle, scan_req,
Govind Singh498bf2a2016-03-08 15:44:17 +0530553 &cmd);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530554 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555 WMA_LOGE("Failed to get buffer for start scan cmd");
Govind Singh498bf2a2016-03-08 15:44:17 +0530556 goto error1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800557 }
558
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530559 wma_inc_pending_scans(wma_handle);
Dustin Brown73fce8f2016-09-29 13:27:15 -0700560
Archana Ramachandran31b5b652016-09-21 15:37:58 -0700561 WMA_LOGI("scan_id 0x%x, vdev_id %d, p2pScanType %d, msg_type 0x%x",
Govind Singh498bf2a2016-03-08 15:44:17 +0530562 cmd.scan_id, cmd.vdev_id, scan_req->p2pScanType, msg_type);
Kapil Gupta139c3302016-09-22 16:48:12 +0530563
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564 /*
565 * Cache vdev_id and scan_id because cmd is freed after calling
566 * wmi_unified_cmd_send cmd. WMI internally frees cmd buffer after
567 * getting TX complete from CE
568 */
Govind Singh498bf2a2016-03-08 15:44:17 +0530569 vdev_id = cmd.vdev_id;
570 scan_id = cmd.scan_id;
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800571 WMA_LOGD("ActiveDwell %d, PassiveDwell %d, ScanFlags 0x%x NumChan %d",
Govind Singh498bf2a2016-03-08 15:44:17 +0530572 cmd.dwell_time_active, cmd.dwell_time_passive,
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800573 cmd.scan_flags, cmd.num_chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800575 /* Call the wmi api to request the scan */
Govind Singh498bf2a2016-03-08 15:44:17 +0530576 qdf_status = wmi_unified_scan_start_cmd_send(wma_handle->wmi_handle,
577 &cmd);
578 if (QDF_IS_STATUS_ERROR(qdf_status)) {
579 WMA_LOGE("wmi_unified_cmd_send returned Error %d", qdf_status);
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530580 goto dec_scans;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800581 }
582
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800583 WMA_LOGD("WMA --> WMI_START_SCAN_CMDID");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530585 return QDF_STATUS_SUCCESS;
Govind Singh498bf2a2016-03-08 15:44:17 +0530586
Nitesh Shah0f3fce52016-10-13 22:01:41 +0530587dec_scans:
588 wma_dec_pending_scans(wma_handle);
589
Govind Singh498bf2a2016-03-08 15:44:17 +0530590error1:
591 if (NULL != cmd.chan_list)
592 qdf_mem_free(cmd.chan_list);
593
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594 /* Send completion event for only for start scan request */
595 if (msg_type == WMA_START_SCAN_OFFLOAD_REQ) {
596 scan_event =
597 (tSirScanOffloadEvent *)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530598 qdf_mem_malloc(sizeof(tSirScanOffloadEvent));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599 if (!scan_event) {
600 WMA_LOGP("%s: Failed to allocate memory for scan rsp",
601 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530602 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800603 }
604 memset(scan_event, 0x00, sizeof(*scan_event));
605 scan_event->event = WMI_SCAN_EVENT_COMPLETED;
606 scan_event->reasonCode = eSIR_SME_SCAN_FAILED;
607 scan_event->sessionId = scan_req->sessionId;
608 scan_event->p2pScanType = scan_req->p2pScanType;
609 scan_event->scanId = scan_req->scan_id;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700610 scan_event->requestor = scan_req->scan_requestor_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 wma_send_msg(wma_handle, WMA_RX_SCAN_EVENT, (void *)scan_event,
612 0);
613 }
Govind Singh498bf2a2016-03-08 15:44:17 +0530614
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530615 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800616}
617
618/**
619 * wma_stop_scan() - stop scan command
620 * @wma_handle: wma handle
621 * @abort_scan_req: abort scan params
622 *
623 * Send stop scan command to fw.
624 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530625 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800626 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530627QDF_STATUS wma_stop_scan(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628 tAbortScanParams *abort_scan_req)
629{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530630 QDF_STATUS qdf_status;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800631 struct scan_cancel_param scan_param = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632
Govind Singh498bf2a2016-03-08 15:44:17 +0530633 scan_param.vdev_id = abort_scan_req->SessionId;
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800634 scan_param.requester = abort_scan_req->scan_requestor_id;
Govind Singh498bf2a2016-03-08 15:44:17 +0530635 scan_param.scan_id = abort_scan_req->scan_id;
636 /* stop the scan with the corresponding scan_id */
Sandeep Puligilla1fcdb772017-02-22 21:14:59 -0800637 scan_param.req_type = WLAN_SCAN_CANCEL_SINGLE;
Govind Singh498bf2a2016-03-08 15:44:17 +0530638 qdf_status = wmi_unified_scan_stop_cmd_send(wma_handle->wmi_handle,
639 &scan_param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800640 /* Call the wmi api to request the scan */
Govind Singh498bf2a2016-03-08 15:44:17 +0530641 if (QDF_IS_STATUS_ERROR(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800642 WMA_LOGE("wmi_unified_cmd_send WMI_STOP_SCAN_CMDID returned Error %d",
Govind Singh498bf2a2016-03-08 15:44:17 +0530643 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800644 goto error;
645 }
Archana Ramachandran31b5b652016-09-21 15:37:58 -0700646 WMA_LOGI("scan_id 0x%x, scan_requestor_id 0x%x, vdev_id %d",
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700647 abort_scan_req->scan_id,
648 abort_scan_req->scan_requestor_id,
649 abort_scan_req->SessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650 WMA_LOGI("WMA --> WMI_STOP_SCAN_CMDID");
651
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530652 return QDF_STATUS_SUCCESS;
Govind Singh498bf2a2016-03-08 15:44:17 +0530653
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800654error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530655 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800656}
657
658/**
659 * wma_update_channel_list() - update channel list
660 * @handle: wma handle
661 * @chan_list: channel list
662 *
663 * Function is used to update the support channel list in fw.
664 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530665 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530667QDF_STATUS wma_update_channel_list(WMA_HANDLE handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800668 tSirUpdateChanList *chan_list)
669{
670 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530671 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Govind Singhbc64c9e2016-02-25 17:42:38 +0530672 int i;
673 struct scan_chan_list_params scan_ch_param = {0};
Himanshu Agarwalb56ad2e2016-07-19 15:43:09 +0530674 wmi_channel_param *tchan_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800675
Govind Singhbc64c9e2016-02-25 17:42:38 +0530676 scan_ch_param.chan_info = qdf_mem_malloc(sizeof(wmi_channel) *
677 chan_list->numChan);
678 if (NULL == scan_ch_param.chan_info) {
679 WMA_LOGE("%s: Failed to allocate channel info", __func__);
680 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800681 }
Govind Singhbc64c9e2016-02-25 17:42:38 +0530682 qdf_mem_zero(scan_ch_param.chan_info, sizeof(wmi_channel) *
683 chan_list->numChan);
684 WMA_LOGD("no of channels = %d", chan_list->numChan);
685 tchan_info = scan_ch_param.chan_info;
686 scan_ch_param.num_scan_chans = chan_list->numChan;
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +0530687 wma_handle->saved_chan.num_channels = chan_list->numChan;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700688 WMA_LOGD("ht %d, vht %d, vht_24 %d", chan_list->ht_en,
689 chan_list->vht_en, chan_list->vht_24_en);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800690
691 for (i = 0; i < chan_list->numChan; ++i) {
Govind Singhbc64c9e2016-02-25 17:42:38 +0530692 tchan_info->mhz =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 cds_chan_to_freq(chan_list->chanParam[i].chanId);
Govind Singhbc64c9e2016-02-25 17:42:38 +0530694 tchan_info->band_center_freq1 =
695 tchan_info->mhz;
696 tchan_info->band_center_freq2 = 0;
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +0530697 wma_handle->saved_chan.channel_list[i] =
698 chan_list->chanParam[i].chanId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699
Amar Singhal4b7b78b2016-08-23 15:49:41 -0700700 WMA_LOGD("chan[%d] = freq:%u chan:%d DFS:%d tx power:%d",
701 i, tchan_info->mhz,
702 chan_list->chanParam[i].chanId,
703 chan_list->chanParam[i].dfsSet,
704 chan_list->chanParam[i].pwr);
705
706 if (chan_list->chanParam[i].dfsSet)
707 WMI_SET_CHANNEL_FLAG(tchan_info,
708 WMI_CHAN_FLAG_PASSIVE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700710 if (tchan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) {
Govind Singhbc64c9e2016-02-25 17:42:38 +0530711 WMI_SET_CHANNEL_MODE(tchan_info, MODE_11G);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700712 if (chan_list->vht_en && chan_list->vht_24_en)
713 WMI_SET_CHANNEL_FLAG(tchan_info,
714 WMI_CHAN_FLAG_ALLOW_VHT);
715 } else {
Govind Singhbc64c9e2016-02-25 17:42:38 +0530716 WMI_SET_CHANNEL_MODE(tchan_info, MODE_11A);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -0700717 if (chan_list->vht_en)
718 WMI_SET_CHANNEL_FLAG(tchan_info,
719 WMI_CHAN_FLAG_ALLOW_VHT);
720 }
721
722 if (chan_list->ht_en)
723 WMI_SET_CHANNEL_FLAG(tchan_info,
724 WMI_CHAN_FLAG_ALLOW_HT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725
726 if (chan_list->chanParam[i].half_rate)
Govind Singhbc64c9e2016-02-25 17:42:38 +0530727 WMI_SET_CHANNEL_FLAG(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728 WMI_CHAN_FLAG_HALF_RATE);
729 else if (chan_list->chanParam[i].quarter_rate)
Govind Singhbc64c9e2016-02-25 17:42:38 +0530730 WMI_SET_CHANNEL_FLAG(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 WMI_CHAN_FLAG_QUARTER_RATE);
732
Govind Singhbc64c9e2016-02-25 17:42:38 +0530733 WMI_SET_CHANNEL_MAX_TX_POWER(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800734 chan_list->chanParam[i].pwr);
735
Govind Singhbc64c9e2016-02-25 17:42:38 +0530736 WMI_SET_CHANNEL_REG_POWER(tchan_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800737 chan_list->chanParam[i].pwr);
Govind Singhbc64c9e2016-02-25 17:42:38 +0530738 tchan_info++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739 }
740
Govind Singhbc64c9e2016-02-25 17:42:38 +0530741 qdf_status = wmi_unified_scan_chan_list_cmd_send(wma_handle->wmi_handle,
742 &scan_ch_param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800743
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700744 if (QDF_IS_STATUS_ERROR(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800745 WMA_LOGE("Failed to send WMI_SCAN_CHAN_LIST_CMDID");
Govind Singhbc64c9e2016-02-25 17:42:38 +0530746
747 qdf_mem_free(scan_ch_param.chan_info);
748
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530749 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750}
751
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800752/**
753 * wma_roam_scan_offload_mode() - send roam scan mode request to fw
754 * @wma_handle: wma handle
755 * @scan_cmd_fp: start scan command ptr
756 * @roam_req: roam request param
757 * @mode: mode
758 * @vdev_id: vdev id
759 *
760 * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback
761 * of WMI_ROAM_SCAN_MODE.
762 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530763 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800764 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530765QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 wmi_start_scan_cmd_fixed_param *
767 scan_cmd_fp,
768 tSirRoamOffloadScanReq *roam_req,
769 uint32_t mode, uint32_t vdev_id)
770{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530771 QDF_STATUS status = QDF_STATUS_SUCCESS;
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530772 struct roam_offload_scan_params *params =
773 qdf_mem_malloc(sizeof(*params));
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530774
Arif Hussaincf6b9602016-10-25 14:46:53 -0700775 if (!params) {
776 WMA_LOGE("%s: Failed to allocate scan params", __func__);
777 return QDF_STATUS_E_NOMEM;
778 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800779#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Arif Hussaincf6b9602016-10-25 14:46:53 -0700780 params->auth_mode = WMI_AUTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781 if (roam_req)
Arif Hussaincf6b9602016-10-25 14:46:53 -0700782 params->auth_mode = e_csr_auth_type_to_rsn_authmode
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800783 (roam_req->ConnectedNetwork.authentication,
784 roam_req->ConnectedNetwork.encryption);
Arif Hussaincf6b9602016-10-25 14:46:53 -0700785 WMA_LOGD("%s : auth mode = %d", __func__, params->auth_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530787
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530788 params->is_roam_req_valid = 0;
789 params->mode = mode;
790 params->vdev_id = vdev_id;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530791 if (roam_req) {
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530792 params->is_roam_req_valid = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530794 params->roam_offload_enabled = roam_req->RoamOffloadEnabled;
795 params->prefer_5ghz = roam_req->Prefer5GHz;
796 params->roam_rssi_cat_gap = roam_req->RoamRssiCatGap;
797 params->select_5ghz_margin = roam_req->Select5GHzMargin;
798 params->reassoc_failure_timeout =
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530799 roam_req->ReassocFailureTimeout;
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530800 params->rokh_id_length = roam_req->R0KH_ID_Length;
801 qdf_mem_copy(params->rokh_id, roam_req->R0KH_ID,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530802 WMI_ROAM_R0KH_ID_MAX_LEN);
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530803 qdf_mem_copy(params->krk, roam_req->KRK, WMI_KRK_KEY_LEN);
804 qdf_mem_copy(params->btk, roam_req->BTK, WMI_BTK_KEY_LEN);
805 qdf_mem_copy(params->psk_pmk, roam_req->PSK_PMK,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530806 WMI_ROAM_SCAN_PSK_SIZE);
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530807 params->pmk_len = roam_req->pmk_len;
808 params->roam_key_mgmt_offload_enabled =
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530809 roam_req->RoamKeyMgmtOffloadEnabled;
810 wma_roam_scan_fill_self_caps(wma_handle,
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530811 &params->roam_offload_params, roam_req);
Deepak Dhamdhere828f1892017-02-09 11:51:19 -0800812 params->fw_okc = roam_req->pmkid_modes.fw_okc;
813 params->fw_pmksa_cache = roam_req->pmkid_modes.fw_pmksa_cache;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530814#endif
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530815 params->is_ese_assoc = roam_req->IsESEAssoc;
816 params->mdid.mdie_present = roam_req->MDID.mdiePresent;
817 params->mdid.mobility_domain = roam_req->MDID.mobilityDomain;
818 params->assoc_ie_length = roam_req->assoc_ie.length;
819 qdf_mem_copy(params->assoc_ie, roam_req->assoc_ie.addIEdata,
820 roam_req->assoc_ie.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800821 }
822
Naveen Rawatcd118312016-11-22 10:46:21 -0800823 WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d"),
Naveen Rawat08340742016-11-17 14:54:39 -0800824 params->roam_offload_params.qos_caps,
825 params->roam_offload_params.qos_enabled);
826
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530827 status = wmi_unified_roam_scan_offload_mode_cmd(wma_handle->wmi_handle,
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530828 scan_cmd_fp, params);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530829 if (QDF_IS_STATUS_ERROR(status))
830 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800832 WMA_LOGD("%s: WMA --> WMI_ROAM_SCAN_MODE", __func__);
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +0530833 qdf_mem_free(params);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530834 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835}
836
837/**
838 * wma_roam_scan_offload_rssi_threshold() - set scan offload rssi threashold
839 * @wma_handle: wma handle
840 * @roam_req: Roaming request buffer
841 *
842 * Send WMI_ROAM_SCAN_RSSI_THRESHOLD TLV to firmware
843 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530844 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530846QDF_STATUS wma_roam_scan_offload_rssi_thresh(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847 tSirRoamOffloadScanReq *roam_req)
848{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530849 struct roam_offload_scan_rssi_params params = {0};
850 QDF_STATUS status = QDF_STATUS_SUCCESS;
851 int rssi_thresh, rssi_thresh_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 struct roam_ext_params *roam_params;
853 int32_t good_rssi_threshold;
854 uint32_t hirssi_scan_max_count;
855 uint32_t hirssi_scan_delta;
856 int32_t hirssi_upper_bound;
857
858 /* Send rssi threshold */
859 roam_params = &roam_req->roam_params;
860 rssi_thresh = roam_req->LookupThreshold - WMA_NOISE_FLOOR_DBM_DEFAULT;
861 rssi_thresh_diff = roam_req->OpportunisticScanThresholdDiff;
862 hirssi_scan_max_count = roam_req->hi_rssi_scan_max_count;
863 hirssi_scan_delta = roam_req->hi_rssi_scan_rssi_delta;
864 hirssi_upper_bound = roam_req->hi_rssi_scan_rssi_ub -
865 WMA_NOISE_FLOOR_DBM_DEFAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800867 /* fill in threshold values */
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530868 params.session_id = roam_req->sessionId;
869 params.rssi_thresh = rssi_thresh & 0x000000ff;
870 params.rssi_thresh_diff = rssi_thresh_diff & 0x000000ff;
871 params.hi_rssi_scan_max_count = hirssi_scan_max_count;
872 params.hi_rssi_scan_rssi_delta = hirssi_scan_delta;
873 params.hi_rssi_scan_rssi_ub = hirssi_upper_bound & 0x00000ff;
874 params.raise_rssi_thresh_5g = roam_params->raise_rssi_thresh_5g;
Gupta, Kapilc68ad462016-02-01 19:17:23 +0530875 params.dense_rssi_thresh_offset =
876 roam_params->dense_rssi_thresh_offset;
877 params.dense_min_aps_cnt = roam_params->dense_min_aps_cnt;
878 params.traffic_threshold =
879 roam_params->traffic_threshold;
Kapil Gupta0a2477b2016-08-23 18:00:34 +0530880 params.initial_dense_status = roam_params->initial_dense_status;
Gupta, Kapilc68ad462016-02-01 19:17:23 +0530881
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 /*
884 * The current Noise floor in firmware is -96dBm. Penalty/Boost
885 * threshold is applied on a weaker signal to make it even more weaker.
886 * So, there is a chance that the user may configure a very low
887 * Penalty/Boost threshold beyond the noise floor. If that is the case,
888 * then suppress the penalty/boost threshold to the noise floor.
889 */
890 if (roam_params->raise_rssi_thresh_5g < WMA_NOISE_FLOOR_DBM_DEFAULT)
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530891 params.penalty_threshold_5g = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800892 else
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530893 params.boost_threshold_5g =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894 (roam_params->raise_rssi_thresh_5g -
895 WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
896 if (roam_params->drop_rssi_thresh_5g < WMA_NOISE_FLOOR_DBM_DEFAULT)
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530897 params.penalty_threshold_5g = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898 else
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530899 params.penalty_threshold_5g =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900 (roam_params->drop_rssi_thresh_5g -
901 WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530902 params.raise_factor_5g = roam_params->raise_factor_5g;
903 params.drop_factor_5g = roam_params->drop_factor_5g;
904 params.max_raise_rssi_5g = roam_params->max_raise_rssi_5g;
905 params.max_drop_rssi_5g = roam_params->max_drop_rssi_5g;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800906
907 if (roam_params->good_rssi_roam)
908 good_rssi_threshold = WMA_NOISE_FLOOR_DBM_DEFAULT;
909 else
910 good_rssi_threshold = 0;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530911 params.good_rssi_threshold =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912 (good_rssi_threshold - WMA_NOISE_FLOOR_DBM_DEFAULT) & 0x000000ff;
913
914 WMA_LOGD("WMA --> good_rssi_threshold=%d",
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530915 params.good_rssi_threshold);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800916
Varun Reddy Yeturu21953a22016-05-17 15:16:44 -0700917 if (roam_req->early_stop_scan_enable) {
918 params.roam_earlystop_thres_min =
919 roam_req->early_stop_scan_min_threshold -
920 WMA_NOISE_FLOOR_DBM_DEFAULT;
921 params.roam_earlystop_thres_max =
922 roam_req->early_stop_scan_max_threshold -
923 WMA_NOISE_FLOOR_DBM_DEFAULT;
924 } else {
925 params.roam_earlystop_thres_min = 0;
926 params.roam_earlystop_thres_max = 0;
927 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530928
Varun Reddy Yeturu05186292015-09-28 17:12:33 -0700929 WMA_LOGD("early_stop_thresholds en=%d, min=%d, max=%d",
930 roam_req->early_stop_scan_enable,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530931 params.roam_earlystop_thres_min,
932 params.roam_earlystop_thres_max);
Varun Reddy Yeturu05186292015-09-28 17:12:33 -0700933
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530934 status = wmi_unified_roam_scan_offload_rssi_thresh_cmd(
935 wma_handle->wmi_handle, &params);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700936 if (QDF_IS_STATUS_ERROR(status))
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530937 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800939 WMA_LOGD(FL("roam_scan_rssi_thresh=%d, roam_rssi_thresh_diff=%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 rssi_thresh, rssi_thresh_diff);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800941 WMA_LOGD(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800942 FL("hirssi_scan max_count=%d, delta=%d, hirssi_upper_bound=%d"),
943 hirssi_scan_max_count, hirssi_scan_delta, hirssi_upper_bound);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -0800944 WMA_LOGD(
Kapil Gupta0a2477b2016-08-23 18:00:34 +0530945 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 +0530946 roam_params->dense_rssi_thresh_offset,
947 roam_params->dense_min_aps_cnt,
Kapil Gupta0a2477b2016-08-23 18:00:34 +0530948 roam_params->traffic_threshold,
949 roam_params->initial_dense_status);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +0530950 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800951}
952
953/**
954 * wma_roam_scan_offload_scan_period() - set roam offload scan period
955 * @wma_handle: wma handle
956 * @scan_period: scan period
957 * @scan_age: scan age
958 * @vdev_id: vdev id
959 *
960 * Send WMI_ROAM_SCAN_PERIOD parameters to fw.
961 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530962 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530964QDF_STATUS wma_roam_scan_offload_scan_period(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800965 uint32_t scan_period,
966 uint32_t scan_age,
967 uint32_t vdev_id)
968{
Govind Singh64b5e112016-03-08 11:53:50 +0530969 return wmi_unified_roam_scan_offload_scan_period(wma_handle->wmi_handle,
970 scan_period, scan_age, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971}
972
973/**
974 * wma_roam_scan_offload_rssi_change() - set roam offload RSSI change threshold
975 * @wma_handle: wma handle
976 * @rssi_change_thresh: RSSI Change threshold
977 * @bcn_rssi_weight: beacon RSSI weight
978 * @vdev_id: vdev id
979 *
980 * Send WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD parameters to fw.
981 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530982 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800983 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530984QDF_STATUS wma_roam_scan_offload_rssi_change(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800985 uint32_t vdev_id,
986 int32_t rssi_change_thresh,
987 uint32_t bcn_rssi_weight,
988 uint32_t hirssi_delay_btw_scans)
989{
Govind Singh64b5e112016-03-08 11:53:50 +0530990 int status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -0700992 status = wmi_unified_roam_scan_offload_rssi_change_cmd(
993 wma_handle->wmi_handle,
994 vdev_id, rssi_change_thresh,
995 bcn_rssi_weight, hirssi_delay_btw_scans);
Govind Singh64b5e112016-03-08 11:53:50 +0530996 if (status != EOK)
997 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800998
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800999
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301000 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001}
1002
1003/**
1004 * wma_roam_scan_offload_chan_list() - set roam offload channel list
1005 * @wma_handle: wma handle
1006 * @chan_count: channel count
1007 * @chan_list: channel list
1008 * @list_type: list type
1009 * @vdev_id: vdev id
1010 *
1011 * Set roam offload channel list.
1012 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301013 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001014 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301015QDF_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001016 uint8_t chan_count,
1017 uint8_t *chan_list,
1018 uint8_t list_type, uint32_t vdev_id)
1019{
Govind Singh64b5e112016-03-08 11:53:50 +05301020 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021 int i;
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001022 uint32_t *chan_list_mhz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023
1024 if (chan_count == 0) {
1025 WMA_LOGD("%s : invalid number of channels %d", __func__,
1026 chan_count);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301027 return QDF_STATUS_E_EMPTY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001028 }
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001029 chan_list_mhz = qdf_mem_malloc(chan_count * sizeof(*chan_list_mhz));
1030 if (chan_list_mhz == NULL) {
Naveen Rawat35804772016-06-27 15:40:28 -07001031 WMA_LOGE("%s : Memory allocation failed", __func__);
1032 return QDF_STATUS_E_NOMEM;
1033 }
1034
Govind Singh64b5e112016-03-08 11:53:50 +05301035 for (i = 0; ((i < chan_count) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 (i < SIR_ROAM_MAX_CHANNELS)); i++) {
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001037 chan_list_mhz[i] = cds_chan_to_freq(chan_list[i]);
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08001038 WMA_LOGD("%d,", chan_list_mhz[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001039 }
1040
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001041 status = wmi_unified_roam_scan_offload_chan_list_cmd(
1042 wma_handle->wmi_handle,
1043 chan_count, chan_list_mhz,
1044 list_type, vdev_id);
Varun Reddy Yeturu823e9c22016-07-07 17:38:44 -07001045 qdf_mem_free(chan_list_mhz);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001046
Govind Singh64b5e112016-03-08 11:53:50 +05301047 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048}
1049
1050/**
1051 * e_csr_auth_type_to_rsn_authmode() - map csr auth type to rsn authmode
1052 * @authtype: CSR authtype
1053 * @encr: CSR Encryption
1054 *
1055 * Map CSR's authentication type into RSN auth mode used by firmware
1056 *
1057 * Return: WMI RSN auth mode
1058 */
1059A_UINT32 e_csr_auth_type_to_rsn_authmode(eCsrAuthType authtype,
1060 eCsrEncryptionType encr)
1061{
1062 switch (authtype) {
1063 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
1064 return WMI_AUTH_OPEN;
1065 case eCSR_AUTH_TYPE_WPA:
1066 return WMI_AUTH_WPA;
1067 case eCSR_AUTH_TYPE_WPA_PSK:
1068 return WMI_AUTH_WPA_PSK;
1069 case eCSR_AUTH_TYPE_RSN:
1070 return WMI_AUTH_RSNA;
1071 case eCSR_AUTH_TYPE_RSN_PSK:
1072 return WMI_AUTH_RSNA_PSK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001073 case eCSR_AUTH_TYPE_FT_RSN:
1074 return WMI_AUTH_FT_RSNA;
1075 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1076 return WMI_AUTH_FT_RSNA_PSK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001077#ifdef FEATURE_WLAN_WAPI
1078 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1079 return WMI_AUTH_WAPI;
1080 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1081 return WMI_AUTH_WAPI_PSK;
1082#endif /* FEATURE_WLAN_WAPI */
1083#ifdef FEATURE_WLAN_ESE
1084 case eCSR_AUTH_TYPE_CCKM_WPA:
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001085 return WMI_AUTH_CCKM_WPA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001086 case eCSR_AUTH_TYPE_CCKM_RSN:
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001087 return WMI_AUTH_CCKM_RSNA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001088#endif /* FEATURE_WLAN_ESE */
1089#ifdef WLAN_FEATURE_11W
1090 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1091 return WMI_AUTH_RSNA_PSK_SHA256;
1092 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1093 return WMI_AUTH_RSNA_8021X_SHA256;
1094#endif /* WLAN_FEATURE_11W */
1095 case eCSR_AUTH_TYPE_NONE:
1096 case eCSR_AUTH_TYPE_AUTOSWITCH:
1097 /* In case of WEP and other keys, NONE means OPEN auth */
1098 if (encr == eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ||
1099 encr == eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ||
1100 encr == eCSR_ENCRYPT_TYPE_WEP40 ||
1101 encr == eCSR_ENCRYPT_TYPE_WEP104 ||
1102 encr == eCSR_ENCRYPT_TYPE_TKIP ||
1103 encr == eCSR_ENCRYPT_TYPE_AES) {
1104 return WMI_AUTH_OPEN;
1105 }
1106 return WMI_AUTH_NONE;
1107 default:
1108 return WMI_AUTH_NONE;
1109 }
1110}
1111
1112/**
1113 * e_csr_encryption_type_to_rsn_cipherset() - map csr enc type to ESN cipher
1114 * @encr: CSR Encryption
1115 *
1116 * Map CSR's encryption type into RSN cipher types used by firmware
1117 *
1118 * Return: WMI RSN cipher
1119 */
1120A_UINT32 e_csr_encryption_type_to_rsn_cipherset(eCsrEncryptionType encr)
1121{
1122
1123 switch (encr) {
1124 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
1125 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
1126 case eCSR_ENCRYPT_TYPE_WEP40:
1127 case eCSR_ENCRYPT_TYPE_WEP104:
1128 return WMI_CIPHER_WEP;
1129 case eCSR_ENCRYPT_TYPE_TKIP:
1130 return WMI_CIPHER_TKIP;
1131 case eCSR_ENCRYPT_TYPE_AES:
1132 return WMI_CIPHER_AES_CCM;
1133#ifdef FEATURE_WLAN_WAPI
1134 case eCSR_ENCRYPT_TYPE_WPI:
1135 return WMI_CIPHER_WAPI;
1136#endif /* FEATURE_WLAN_WAPI */
1137 case eCSR_ENCRYPT_TYPE_ANY:
1138 return WMI_CIPHER_ANY;
1139 case eCSR_ENCRYPT_TYPE_NONE:
1140 default:
1141 return WMI_CIPHER_NONE;
1142 }
1143}
1144
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001145#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1146/**
1147 * wma_roam_scan_get_cckm_mode() - Get the CCKM auth mode
1148 * @roam_req: Roaming request buffer
1149 * @auth_mode: Auth mode to be converted
1150 *
1151 * Based on LFR2.0 or LFR3.0, return the proper auth type
1152 *
1153 * Return: if LFR2.0, then return WMI_AUTH_CCKM for backward compatibility
1154 * if LFR3.0 then return the appropriate auth type
1155 */
1156static uint32_t wma_roam_scan_get_cckm_mode(tSirRoamOffloadScanReq *roam_req,
1157 uint32_t auth_mode)
1158{
1159 if (roam_req->RoamOffloadEnabled)
1160 return auth_mode;
1161 else
1162 return WMI_AUTH_CCKM;
1163
1164}
1165#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166/**
1167 * wma_roam_scan_fill_ap_profile() - fill ap_profile
1168 * @wma_handle: wma handle
1169 * @pMac: Mac ptr
1170 * @roam_req: roam offload scan request
1171 * @ap_profile_p: ap profile
1172 *
1173 * Fill ap_profile structure from configured parameters
1174 *
1175 * Return: none
1176 */
1177void wma_roam_scan_fill_ap_profile(tp_wma_handle wma_handle,
1178 tpAniSirGlobal pMac,
1179 tSirRoamOffloadScanReq *roam_req,
1180 wmi_ap_profile *ap_profile_p)
1181{
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001182 uint32_t rsn_authmode;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001183
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301184 qdf_mem_zero(ap_profile_p, sizeof(wmi_ap_profile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001185 if (roam_req == NULL) {
1186 ap_profile_p->ssid.ssid_len = 0;
1187 ap_profile_p->ssid.ssid[0] = 0;
1188 ap_profile_p->rsn_authmode = WMI_AUTH_NONE;
1189 ap_profile_p->rsn_ucastcipherset = WMI_CIPHER_NONE;
1190 ap_profile_p->rsn_mcastcipherset = WMI_CIPHER_NONE;
1191 ap_profile_p->rsn_mcastmgmtcipherset = WMI_CIPHER_NONE;
1192 ap_profile_p->rssi_threshold = WMA_ROAM_RSSI_DIFF_DEFAULT;
1193 } else {
1194 ap_profile_p->ssid.ssid_len =
1195 roam_req->ConnectedNetwork.ssId.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301196 qdf_mem_copy(ap_profile_p->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 roam_req->ConnectedNetwork.ssId.ssId,
1198 ap_profile_p->ssid.ssid_len);
1199 ap_profile_p->rsn_authmode =
Varun Reddy Yeturu101f9542016-05-24 10:07:52 -07001200 e_csr_auth_type_to_rsn_authmode(
1201 roam_req->ConnectedNetwork.authentication,
1202 roam_req->ConnectedNetwork.encryption);
1203 rsn_authmode = ap_profile_p->rsn_authmode;
1204
1205 if ((rsn_authmode == WMI_AUTH_CCKM_WPA) ||
1206 (rsn_authmode == WMI_AUTH_CCKM_RSNA))
1207 ap_profile_p->rsn_authmode =
1208 wma_roam_scan_get_cckm_mode(
1209 roam_req, rsn_authmode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 ap_profile_p->rsn_ucastcipherset =
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001211 e_csr_encryption_type_to_rsn_cipherset(
1212 roam_req->ConnectedNetwork.encryption);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001213 ap_profile_p->rsn_mcastcipherset =
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001214 e_csr_encryption_type_to_rsn_cipherset(
1215 roam_req->ConnectedNetwork.mcencryption);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216 ap_profile_p->rsn_mcastmgmtcipherset =
1217 ap_profile_p->rsn_mcastcipherset;
1218 ap_profile_p->rssi_threshold = roam_req->RoamRssiDiff;
1219#ifdef WLAN_FEATURE_11W
1220 if (roam_req->ConnectedNetwork.mfp_enabled)
1221 ap_profile_p->flags |= WMI_AP_PROFILE_FLAG_PMF;
1222#endif
1223 }
1224}
1225
1226/**
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001227 * wma_process_set_pdev_ie_req() - process the pdev set IE req
1228 * @wma: Pointer to wma handle
1229 * @ie_params: Pointer to IE data.
1230 *
1231 * Sends the WMI req to set the IE to FW.
1232 *
1233 * Return: None
1234 */
1235void wma_process_set_pdev_ie_req(tp_wma_handle wma,
1236 struct set_ie_param *ie_params)
1237{
1238 if (ie_params->ie_type == DOT11_HT_IE)
1239 wma_process_set_pdev_ht_ie_req(wma, ie_params);
1240 if (ie_params->ie_type == DOT11_VHT_IE)
1241 wma_process_set_pdev_vht_ie_req(wma, ie_params);
1242
1243 qdf_mem_free(ie_params->ie_ptr);
1244}
1245
1246/**
1247 * wma_process_set_pdev_ht_ie_req() - sends HT IE data to FW
1248 * @wma: Pointer to wma handle
1249 * @ie_params: Pointer to IE data.
1250 * @nss: Nss values to prepare the HT IE.
1251 *
1252 * Sends the WMI req to set the HT IE to FW.
1253 *
1254 * Return: None
1255 */
1256void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
1257 struct set_ie_param *ie_params)
1258{
1259 int ret;
1260 wmi_pdev_set_ht_ie_cmd_fixed_param *cmd;
1261 wmi_buf_t buf;
1262 uint16_t len;
1263 uint16_t ie_len_pad;
1264 uint8_t *buf_ptr;
1265
1266 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1267 ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_t));
1268 len += ie_len_pad;
1269
1270 buf = wmi_buf_alloc(wma->wmi_handle, len);
1271 if (!buf) {
1272 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1273 return;
1274 }
1275 cmd = (wmi_pdev_set_ht_ie_cmd_fixed_param *) wmi_buf_data(buf);
1276 WMITLV_SET_HDR(&cmd->tlv_header,
1277 WMITLV_TAG_STRUC_wmi_pdev_set_ht_ie_cmd_fixed_param,
1278 WMITLV_GET_STRUCT_TLVLEN(
1279 wmi_pdev_set_ht_ie_cmd_fixed_param));
1280 cmd->reserved0 = 0;
1281 cmd->ie_len = ie_params->ie_len;
1282 cmd->tx_streams = ie_params->nss;
1283 cmd->rx_streams = ie_params->nss;
1284 WMA_LOGD("Setting pdev HT ie with Nss = %u",
1285 ie_params->nss);
1286 buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
1287 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
1288 if (ie_params->ie_len) {
1289 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
1290 (uint8_t *)ie_params->ie_ptr,
1291 ie_params->ie_len);
1292 }
1293 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
1294 WMI_PDEV_SET_HT_CAP_IE_CMDID);
1295 if (ret != EOK) {
1296 WMA_LOGE("Failed to send set param command ret = %d", ret);
1297 wmi_buf_free(buf);
1298 }
1299}
1300
1301/**
1302 * wma_process_set_pdev_vht_ie_req() - sends VHT IE data to FW
1303 * @wma: Pointer to wma handle
1304 * @ie_params: Pointer to IE data.
1305 * @nss: Nss values to prepare the VHT IE.
1306 *
1307 * Sends the WMI req to set the VHT IE to FW.
1308 *
1309 * Return: None
1310 */
1311void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
1312 struct set_ie_param *ie_params)
1313{
1314 int ret;
1315 wmi_pdev_set_vht_ie_cmd_fixed_param *cmd;
1316 wmi_buf_t buf;
1317 uint16_t len;
1318 uint16_t ie_len_pad;
1319 uint8_t *buf_ptr;
1320
1321 len = sizeof(*cmd) + WMI_TLV_HDR_SIZE;
1322 ie_len_pad = roundup(ie_params->ie_len, sizeof(uint32_t));
1323 len += ie_len_pad;
1324
1325 buf = wmi_buf_alloc(wma->wmi_handle, len);
1326 if (!buf) {
1327 WMA_LOGE("%s:wmi_buf_alloc failed", __func__);
1328 return;
1329 }
1330 cmd = (wmi_pdev_set_vht_ie_cmd_fixed_param *) wmi_buf_data(buf);
1331 WMITLV_SET_HDR(&cmd->tlv_header,
1332 WMITLV_TAG_STRUC_wmi_pdev_set_vht_ie_cmd_fixed_param,
1333 WMITLV_GET_STRUCT_TLVLEN(
1334 wmi_pdev_set_vht_ie_cmd_fixed_param));
1335 cmd->reserved0 = 0;
1336 cmd->ie_len = ie_params->ie_len;
1337 cmd->tx_streams = ie_params->nss;
1338 cmd->rx_streams = ie_params->nss;
1339 WMA_LOGD("Setting pdev VHT ie with Nss = %u",
1340 ie_params->nss);
1341 buf_ptr = (uint8_t *)cmd + sizeof(*cmd);
1342 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_pad);
1343 if (ie_params->ie_len) {
1344 qdf_mem_copy(buf_ptr + WMI_TLV_HDR_SIZE,
1345 (uint8_t *)ie_params->ie_ptr,
1346 ie_params->ie_len);
1347 }
1348 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
1349 WMI_PDEV_SET_VHT_CAP_IE_CMDID);
1350 if (ret != EOK) {
1351 WMA_LOGE("Failed to send set param command ret = %d", ret);
1352 wmi_buf_free(buf);
1353 }
1354}
1355
1356/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357 * wma_roam_scan_scan_params() - fill roam scan params
1358 * @wma_handle: wma handle
1359 * @pMac: Mac ptr
1360 * @scan_params: scan parameters
1361 * @roam_req: NULL if this routine is called before connect
1362 * It will be non-NULL if called after assoc.
1363 *
1364 * Fill scan_params structure from configured parameters
1365 *
1366 * Return: none
1367 */
1368void wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle,
1369 tpAniSirGlobal pMac,
1370 tSirRoamOffloadScanReq *roam_req,
1371 wmi_start_scan_cmd_fixed_param *
1372 scan_params)
1373{
1374 uint8_t channels_per_burst = 0;
1375 uint32_t val = 0;
1376
1377 if (NULL == pMac) {
1378 WMA_LOGE("%s: pMac is NULL", __func__);
1379 return;
1380 }
1381
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301382 qdf_mem_zero(scan_params, sizeof(wmi_start_scan_cmd_fixed_param));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001383 scan_params->scan_ctrl_flags = WMI_SCAN_ADD_CCK_RATES |
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +05301384 WMI_SCAN_ADD_OFDM_RATES |
1385 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 if (roam_req != NULL) {
1387 /* Parameters updated after association is complete */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001388 WMA_LOGD("%s: NeighborScanChannelMinTime: %d NeighborScanChannelMaxTime: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001389 __func__,
1390 roam_req->NeighborScanChannelMinTime,
1391 roam_req->NeighborScanChannelMaxTime);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001392 WMA_LOGD("%s: NeighborScanTimerPeriod: %d HomeAwayTime: %d nProbes: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393 __func__,
1394 roam_req->NeighborScanTimerPeriod,
1395 roam_req->HomeAwayTime, roam_req->nProbes);
1396
1397 /*
1398 * roam_req->NeighborScanChannelMaxTime = SCAN_CHANNEL_TIME
1399 * roam_req->HomeAwayTime = SCAN_HOME_AWAY_TIME
1400 * roam_req->NeighborScanTimerPeriod = SCAN_HOME_TIME
1401 *
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001402 * scan_params->dwell_time_active :time station stays on channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001403 * and sends probes;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001404 * scan_params->dwell_time_passive:time station stays on channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001405 * and listens probes;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001406 * scan_params->burst_duration :time station goes off channel
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001407 * to scan;
1408 */
1409
1410 if (wlan_cfg_get_int
1411 (pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
1412 &val) != eSIR_SUCCESS) {
1413 /*
1414 * Could not get max channel value from CFG. Log error.
1415 */
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001416 WMA_LOGE("could not retrieve passive max channel value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001417
1418 /* use a default value of 110ms */
1419 val = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
1420 }
1421
1422 scan_params->dwell_time_passive = val;
1423 /*
1424 * Here is the formula,
1425 * T(HomeAway) = N * T(dwell) + (N+1) * T(cs)
1426 * where N is number of channels scanned in single burst
1427 */
1428 scan_params->dwell_time_active =
1429 roam_req->NeighborScanChannelMaxTime;
1430 if (roam_req->HomeAwayTime <
1431 2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME) {
1432 /* clearly we can't follow home away time.
1433 * Make it a split scan.
1434 */
1435 scan_params->burst_duration = 0;
1436 } else {
1437 channels_per_burst =
1438 (roam_req->HomeAwayTime -
1439 WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME)
1440 / (scan_params->dwell_time_active +
1441 WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME);
1442
1443 if (channels_per_burst < 1) {
1444 /* dwell time and home away time conflicts */
1445 /* we will override dwell time */
1446 scan_params->dwell_time_active =
1447 roam_req->HomeAwayTime -
1448 2 * WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME;
1449 scan_params->burst_duration =
1450 scan_params->dwell_time_active;
1451 } else {
1452 scan_params->burst_duration =
1453 channels_per_burst *
1454 scan_params->dwell_time_active;
1455 }
1456 }
1457 if (roam_req->allowDFSChannelRoam ==
1458 SIR_ROAMING_DFS_CHANNEL_ENABLED_NORMAL
1459 && roam_req->HomeAwayTime > 0
1460 && roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) {
1461 /* Roaming on DFS channels is supported and it is not
1462 * app channel list. It is ok to override homeAwayTime
1463 * to accomodate DFS dwell time in burst
1464 * duration.
1465 */
1466 scan_params->burst_duration =
Anurag Chouhan6d760662016-02-20 16:05:43 +05301467 QDF_MAX(scan_params->burst_duration,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001468 scan_params->dwell_time_passive);
1469 }
1470 scan_params->min_rest_time = roam_req->NeighborScanTimerPeriod;
1471 scan_params->max_rest_time = roam_req->NeighborScanTimerPeriod;
1472 scan_params->repeat_probe_time = (roam_req->nProbes > 0) ?
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001473 QDF_MAX(scan_params->dwell_time_active /
1474 roam_req->nProbes, 1) : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475 scan_params->probe_spacing_time = 0;
1476 scan_params->probe_delay = 0;
1477 /* 30 seconds for full scan cycle */
1478 scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
1479 scan_params->idle_time = scan_params->min_rest_time;
1480 scan_params->n_probes = roam_req->nProbes;
1481 if (roam_req->allowDFSChannelRoam ==
1482 SIR_ROAMING_DFS_CHANNEL_DISABLED) {
1483 scan_params->scan_ctrl_flags |= WMI_SCAN_BYPASS_DFS_CHN;
1484 } else {
1485 /* Roaming scan on DFS channel is allowed.
1486 * No need to change any flags for default
1487 * allowDFSChannelRoam = 1.
1488 * Special case where static channel list is given by\
1489 * application that contains DFS channels.
1490 * Assume that the application has knowledge of matching
1491 * APs being active and that probe request transmission
1492 * is permitted on those channel.
1493 * Force active scans on those channels.
1494 */
1495
1496 if (roam_req->allowDFSChannelRoam ==
1497 SIR_ROAMING_DFS_CHANNEL_ENABLED_ACTIVE &&
1498 roam_req->ChannelCacheType == CHANNEL_LIST_STATIC &&
1499 roam_req->ConnectedNetwork.ChannelCount > 0) {
1500 scan_params->scan_ctrl_flags |=
1501 WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
1502 }
1503 }
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05301504 WMI_SCAN_SET_DWELL_MODE(scan_params->scan_ctrl_flags,
1505 roam_req->roamscan_adaptive_dwell_mode);
1506
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001507 } else {
1508 /* roam_req = NULL during initial or pre-assoc invocation */
1509 scan_params->dwell_time_active =
1510 WMA_ROAM_DWELL_TIME_ACTIVE_DEFAULT;
1511 scan_params->dwell_time_passive =
1512 WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT;
1513 scan_params->min_rest_time = WMA_ROAM_MIN_REST_TIME_DEFAULT;
1514 scan_params->max_rest_time = WMA_ROAM_MAX_REST_TIME_DEFAULT;
1515 scan_params->repeat_probe_time = 0;
1516 scan_params->probe_spacing_time = 0;
1517 scan_params->probe_delay = 0;
1518 scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION;
1519 scan_params->idle_time = scan_params->min_rest_time;
1520 scan_params->burst_duration = 0;
1521 scan_params->n_probes = 0;
1522 }
1523
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001524 WMA_LOGD("%s: Rome roam scan parameters: dwell_time_active = %d, dwell_time_passive = %d",
1525 __func__, scan_params->dwell_time_active,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526 scan_params->dwell_time_passive);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001527 WMA_LOGD("%s: min_rest_time = %d, max_rest_time = %d, repeat_probe_time = %d n_probes = %d",
1528 __func__, scan_params->min_rest_time,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529 scan_params->max_rest_time,
1530 scan_params->repeat_probe_time, scan_params->n_probes);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001531 WMA_LOGD("%s: max_scan_time = %d, idle_time = %d, burst_duration = %d, scan_ctrl_flags = 0x%x",
1532 __func__, scan_params->max_scan_time, scan_params->idle_time,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533 scan_params->burst_duration, scan_params->scan_ctrl_flags);
1534}
1535
1536/**
1537 * wma_roam_scan_offload_ap_profile() - set roam ap profile in fw
1538 * @wma_handle: wma handle
1539 * @ap_profile_p: ap profile
1540 * @vdev_id: vdev id
1541 *
1542 * Send WMI_ROAM_AP_PROFILE to firmware
1543 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301544 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001545 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301546QDF_STATUS wma_roam_scan_offload_ap_profile(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 wmi_ap_profile *ap_profile_p,
1548 uint32_t vdev_id)
1549{
Govind Singh64b5e112016-03-08 11:53:50 +05301550 return wmi_unified_send_roam_scan_offload_ap_cmd(wma_handle->wmi_handle,
1551 ap_profile_p, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001552}
1553
1554/**
1555 * wma_roam_scan_filter() - Filter to be applied while roaming
1556 * @wma_handle: Global WMA Handle
1557 * @roam_req: Request which contains the filters
1558 *
1559 * There are filters such as whitelist, blacklist and preferred
1560 * list that need to be applied to the scan results to form the
1561 * probable candidates for roaming.
1562 *
1563 * Return: Return success upon succesfully passing the
1564 * parameters to the firmware, otherwise failure.
1565 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07001566static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle,
1567 tSirRoamOffloadScanReq *roam_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001568{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301569 int i;
1570 QDF_STATUS status = QDF_STATUS_SUCCESS;
1571 uint32_t len = 0, num_bssid_black_list = 0, num_ssid_white_list = 0,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572 num_bssid_preferred_list = 0;
1573 uint32_t op_bitmap = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001574 struct roam_ext_params *roam_params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301575 struct roam_scan_filter_params *params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301577 params = qdf_mem_malloc(sizeof(struct roam_scan_filter_params));
Naveen Rawat35804772016-06-27 15:40:28 -07001578 if (params == NULL) {
1579 WMA_LOGE("%s : Memory allocation failed", __func__);
1580 return QDF_STATUS_E_NOMEM;
1581 }
1582
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001583 roam_params = &roam_req->roam_params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 if (roam_req->Command != ROAM_SCAN_OFFLOAD_STOP) {
1585 switch (roam_req->reason) {
1586 case REASON_ROAM_SET_BLACKLIST_BSSID:
1587 op_bitmap |= 0x1;
1588 num_bssid_black_list =
1589 roam_params->num_bssid_avoid_list;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301590 len = num_bssid_black_list * sizeof(wmi_mac_addr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001591 len += WMI_TLV_HDR_SIZE;
1592 break;
1593 case REASON_ROAM_SET_SSID_ALLOWED:
1594 op_bitmap |= 0x2;
1595 num_ssid_white_list =
1596 roam_params->num_ssid_allowed_list;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301597 len = num_ssid_white_list * sizeof(wmi_ssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001598 len += WMI_TLV_HDR_SIZE;
1599 break;
1600 case REASON_ROAM_SET_FAVORED_BSSID:
1601 op_bitmap |= 0x4;
1602 num_bssid_preferred_list =
1603 roam_params->num_bssid_favored;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301604 len = num_bssid_preferred_list * sizeof(wmi_mac_addr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001605 len += WMI_TLV_HDR_SIZE;
1606 len += num_bssid_preferred_list * sizeof(A_UINT32);
1607 break;
1608 default:
1609 WMA_LOGD("%s : Roam Filter need not be sent", __func__);
Arif Hussaina915f492016-07-29 15:29:42 -07001610 qdf_mem_free(params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301611 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 }
1613 } else {
1614 /* In case of STOP command, reset all the variables
1615 * except for blacklist BSSID which should be retained
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001616 * across connections.
1617 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001618 op_bitmap = 0x2 | 0x4;
1619 num_ssid_white_list = roam_params->num_ssid_allowed_list;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301620 len = num_ssid_white_list * sizeof(wmi_ssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001621 num_bssid_preferred_list = roam_params->num_bssid_favored;
1622 len += num_bssid_preferred_list * sizeof(wmi_mac_addr);
1623 len += num_bssid_preferred_list * sizeof(A_UINT32);
1624 len += (2 * WMI_TLV_HDR_SIZE);
1625 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 /* fill in fixed values */
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301628 params->session_id = roam_req->sessionId;
1629 params->op_bitmap = op_bitmap;
1630 params->num_bssid_black_list = num_bssid_black_list;
1631 params->num_ssid_white_list = num_ssid_white_list;
1632 params->num_bssid_preferred_list = num_bssid_preferred_list;
1633 params->len = len;
1634 qdf_mem_copy(params->bssid_avoid_list, roam_params->bssid_avoid_list,
1635 MAX_BSSID_AVOID_LIST * sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001636
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 for (i = 0; i < num_ssid_white_list; i++) {
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301638 qdf_mem_copy(params->ssid_allowed_list[i].mac_ssid,
1639 roam_params->ssid_allowed_list[i].ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640 roam_params->ssid_allowed_list[i].length);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301641 params->ssid_allowed_list[i].length =
1642 roam_params->ssid_allowed_list[i].length;
1643 WMA_LOGD("%s: SSID length=%d", __func__,
1644 params->ssid_allowed_list[i].length);
1645 qdf_trace_hex_dump(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
1646 (uint8_t *)params->ssid_allowed_list[i].mac_ssid,
1647 params->ssid_allowed_list[i].length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05301649 qdf_mem_copy(params->bssid_favored, roam_params->bssid_favored,
1650 MAX_BSSID_FAVORED * sizeof(struct qdf_mac_addr));
1651 qdf_mem_copy(params->bssid_favored_factor,
1652 roam_params->bssid_favored_factor, MAX_BSSID_FAVORED);
1653
1654 status = wmi_unified_roam_scan_filter_cmd(wma_handle->wmi_handle,
1655 params);
1656
1657 qdf_mem_free(params);
1658 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659}
1660
1661/**
1662 * wma_roam_scan_bmiss_cnt() - set bmiss count to fw
1663 * @wma_handle: wma handle
1664 * @first_bcnt: first bmiss count
1665 * @final_bcnt: final bmiss count
1666 * @vdev_id: vdev id
1667 *
1668 * set first & final biss count to fw.
1669 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301670 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001671 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301672QDF_STATUS wma_roam_scan_bmiss_cnt(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673 A_INT32 first_bcnt,
1674 A_UINT32 final_bcnt, uint32_t vdev_id)
1675{
Govind Singhd76a5b02016-03-08 15:12:14 +05301676 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08001678 WMA_LOGD("%s: first_bcnt: %d, final_bcnt: %d", __func__, first_bcnt,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679 final_bcnt);
1680
Govind Singhd76a5b02016-03-08 15:12:14 +05301681 status = wma_vdev_set_param(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001682 vdev_id, WMI_VDEV_PARAM_BMISS_FIRST_BCNT,
1683 first_bcnt);
Govind Singhd76a5b02016-03-08 15:12:14 +05301684 if (QDF_IS_STATUS_ERROR(status)) {
1685 WMA_LOGE("wma_vdev_set_param WMI_VDEV_PARAM_BMISS_FIRST_BCNT returned Error %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001686 status);
Govind Singhd76a5b02016-03-08 15:12:14 +05301687 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 }
1689
Govind Singhd76a5b02016-03-08 15:12:14 +05301690 status = wma_vdev_set_param(wma_handle->wmi_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001691 vdev_id, WMI_VDEV_PARAM_BMISS_FINAL_BCNT,
1692 final_bcnt);
Govind Singhd76a5b02016-03-08 15:12:14 +05301693 if (QDF_IS_STATUS_ERROR(status)) {
1694 WMA_LOGE("wma_vdev_set_param WMI_VDEV_PARAM_BMISS_FINAL_BCNT returned Error %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695 status);
Govind Singhd76a5b02016-03-08 15:12:14 +05301696 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697 }
1698
Govind Singhd76a5b02016-03-08 15:12:14 +05301699 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001700}
1701
1702/**
1703 * wma_roam_scan_offload_command() - set roam offload command
1704 * @wma_handle: wma handle
1705 * @command: command
1706 * @vdev_id: vdev id
1707 *
1708 * This function set roam offload command to fw.
1709 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301710 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001711 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301712QDF_STATUS wma_roam_scan_offload_command(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001713 uint32_t command, uint32_t vdev_id)
1714{
Govind Singh64b5e112016-03-08 11:53:50 +05301715 return wmi_unified_roam_scan_offload_cmd(wma_handle->wmi_handle,
1716 command, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717}
1718
1719/**
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08001720 * wma_process_roaming_config() - process roam request
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 * @wma_handle: wma handle
1722 * @roam_req: roam request parameters
1723 *
1724 * Main routine to handle ROAM commands coming from CSR module.
1725 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301726 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 */
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08001728QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001729 tSirRoamOffloadScanReq *roam_req)
1730{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301731 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 wmi_start_scan_cmd_fixed_param scan_params;
1733 wmi_ap_profile ap_profile;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301734 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001735 uint32_t mode = 0;
1736 struct wma_txrx_node *intr = NULL;
1737
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738 if (NULL == pMac) {
1739 WMA_LOGE("%s: pMac is NULL", __func__);
Selvaraj, Sridhar8fe6c672017-01-10 11:37:29 +05301740 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301741 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742 }
1743
1744 if (!wma_handle->roam_offload_enabled) {
1745 /* roam scan offload is not enabled in firmware.
1746 * Cannot initialize it in the middle of connection.
1747 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301748 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301749 return QDF_STATUS_E_PERM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001750 }
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08001751 WMA_LOGD("%s: roaming in progress set to false for vdev %d",
1752 __func__, roam_req->sessionId);
1753 wma_handle->interfaces[roam_req->sessionId].roaming_in_progress = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754 switch (roam_req->Command) {
1755 case ROAM_SCAN_OFFLOAD_START:
1756 intr = &wma_handle->interfaces[roam_req->sessionId];
1757 intr->delay_before_vdev_stop = roam_req->delay_before_vdev_stop;
1758 /*
1759 * Scan/Roam threshold parameters are translated from fields of
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001760 * tSirRoamOffloadScanReq to WMITLV values sent to Rome firmware
1761 * some of these parameters are configurable in qcom_cfg.ini
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001762 */
1763
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001764 /* First param is positive rssi value to trigger rssi based scan
1765 * Opportunistic scan is started at 30dB > trigger rssi.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001766 */
1767 wma_handle->suitable_ap_hb_failure = false;
1768
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301769 qdf_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001770 roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301771 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001772 break;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301773 qdf_status = wma_roam_scan_bmiss_cnt(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001774 roam_req->RoamBmissFirstBcnt,
1775 roam_req->RoamBmissFinalBcnt,
1776 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301777 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778 break;
1779
1780 /* Opportunistic scan runs on a timer, value set by
1781 * EmptyRefreshScanPeriod. Age out the entries after 3 such
1782 * cycles.
1783 */
1784 if (roam_req->EmptyRefreshScanPeriod > 0) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301785 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786 wma_roam_scan_offload_scan_period(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001787 roam_req->EmptyRefreshScanPeriod,
1788 roam_req->EmptyRefreshScanPeriod * 3,
1789 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301790 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001791 break;
1792
1793 mode = WMI_ROAM_SCAN_MODE_PERIODIC;
1794 /* Don't use rssi triggered roam scans if external app
1795 * is in control of channel list.
1796 */
1797 if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC)
1798 mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
1799
1800 } else {
1801 mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
1802 }
1803
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001804 /* Start new rssi triggered scan only if it changes by
1805 * RoamRssiDiff value. Beacon weight of 14 means average rssi
1806 * is taken over 14 previous samples + 2 times the current
1807 * beacon's rssi.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301809 qdf_status = wma_roam_scan_offload_rssi_change(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001810 roam_req->sessionId,
1811 roam_req->RoamRescanRssiDiff,
1812 roam_req->RoamBeaconRssiWeight,
1813 roam_req->hi_rssi_scan_delay);
1814
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301815 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001816 break;
1817
1818 wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req,
1819 &ap_profile);
1820
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301821 qdf_status = wma_roam_scan_offload_ap_profile(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001822 &ap_profile, roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301823 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001824 break;
1825
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301826 qdf_status = wma_roam_scan_offload_chan_list(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001827 roam_req->ConnectedNetwork.ChannelCount,
1828 &roam_req->ConnectedNetwork.ChannelCache[0],
1829 roam_req->ChannelCacheType,
1830 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301831 if ((qdf_status != QDF_STATUS_SUCCESS) &&
1832 (qdf_status != QDF_STATUS_E_EMPTY))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001833 break;
1834
1835
1836 wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
1837 &scan_params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301838 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001839 wma_roam_scan_offload_mode(wma_handle, &scan_params,
1840 roam_req, mode,
1841 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301842 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001843 break;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301844 qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
1845 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001846 WMA_LOGE("Sending start for roam scan filter failed");
1847 break;
1848 }
1849 break;
1850
1851 case ROAM_SCAN_OFFLOAD_STOP:
1852 wma_handle->suitable_ap_hb_failure = false;
1853 if (wma_handle->roam_offload_enabled) {
Abhishek Singh533c9da2017-05-04 10:23:34 +05301854 uint32_t mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001855
1856 wma_roam_scan_fill_scan_params(wma_handle, pMac,
1857 NULL, &scan_params);
Abhishek Singh533c9da2017-05-04 10:23:34 +05301858
1859 if (roam_req->reason == REASON_ROAM_STOP_ALL)
1860 mode = WMI_ROAM_SCAN_MODE_NONE;
1861 else
1862 mode = WMI_ROAM_SCAN_MODE_NONE |
1863 WMI_ROAM_SCAN_MODE_ROAMOFFLOAD;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301864 qdf_status = wma_roam_scan_offload_mode(wma_handle,
Abhishek Singh533c9da2017-05-04 10:23:34 +05301865 &scan_params, NULL, mode,
Selvaraj, Sridharecc81df2016-10-14 23:26:16 +05301866 roam_req->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001867 }
1868 /*
1869 * If the STOP command is due to a disconnect, then
1870 * send the filter command to clear all the filter
1871 * entries. If it is roaming scenario, then do not
1872 * send the cleared entries.
1873 */
1874 if (!roam_req->middle_of_roaming) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301875 qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
1876 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001877 WMA_LOGE("clear for roam scan filter failed");
1878 break;
1879 }
1880 }
1881
1882 if (roam_req->reason ==
1883 REASON_OS_REQUESTED_ROAMING_NOW) {
Rajeev Kumarcf7bd802017-04-18 11:11:42 -07001884 struct scheduler_msg cds_msg = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001885 tSirRoamOffloadScanRsp *scan_offload_rsp;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001886
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887 scan_offload_rsp =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301888 qdf_mem_malloc(sizeof(*scan_offload_rsp));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001889 if (!scan_offload_rsp) {
1890 WMA_LOGE("%s: Alloc failed for scan_offload_rsp",
1891 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301892 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301893 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001894 }
1895 cds_msg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP;
1896 scan_offload_rsp->sessionId = roam_req->sessionId;
1897 scan_offload_rsp->reason = roam_req->reason;
1898 cds_msg.bodyptr = scan_offload_rsp;
1899 /*
1900 * Since REASSOC request is processed in
1901 * Roam_Scan_Offload_Rsp post a dummy rsp msg back to
1902 * SME with proper reason code.
1903 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301904 if (QDF_STATUS_SUCCESS !=
Rajeev Kumarb60abe42017-01-21 15:39:31 -08001905 scheduler_post_msg(QDF_MODULE_ID_SME,
Rajeev Kumar156188e2017-01-21 17:23:52 -08001906 &cds_msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301907 qdf_mem_free(scan_offload_rsp);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301908 QDF_TRACE(QDF_MODULE_ID_WMA,
1909 QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910 "%s: Failed to post Scan Offload Rsp to UMAC",
1911 __func__);
1912 }
1913 }
1914 break;
1915
1916 case ROAM_SCAN_OFFLOAD_ABORT_SCAN:
1917 /* If roam scan is running, stop that cycle.
1918 * It will continue automatically on next trigger.
1919 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301920 qdf_status = wma_roam_scan_offload_command(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001921 WMI_ROAM_SCAN_STOP_CMD,
1922 roam_req->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001923 break;
1924
1925 case ROAM_SCAN_OFFLOAD_RESTART:
1926 /* Rome offload engine does not stop after any scan.
1927 * If this command is sent because all preauth attempts failed
1928 * and WMI_ROAM_REASON_SUITABLE_AP event was received earlier,
1929 * now it is time to call it heartbeat failure.
1930 */
1931 if ((roam_req->reason == REASON_PREAUTH_FAILED_FOR_ALL)
1932 && wma_handle->suitable_ap_hb_failure) {
1933 WMA_LOGE("%s: Sending heartbeat failure after preauth failures",
1934 __func__);
1935 wma_beacon_miss_handler(wma_handle,
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05301936 roam_req->sessionId,
1937 wma_handle->suitable_ap_hb_failure_rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001938 wma_handle->suitable_ap_hb_failure = false;
1939 }
1940 break;
1941
1942 case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
1943 wma_handle->suitable_ap_hb_failure = false;
1944 wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
1945 &scan_params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301946 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001947 wma_roam_scan_offload_mode(wma_handle, &scan_params,
1948 roam_req,
1949 WMI_ROAM_SCAN_MODE_NONE,
1950 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301951 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001952 break;
1953
1954 if (roam_req->RoamScanOffloadEnabled == false)
1955 break;
1956
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301957 qdf_status = wma_roam_scan_bmiss_cnt(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001958 roam_req->RoamBmissFirstBcnt,
1959 roam_req->RoamBmissFinalBcnt,
1960 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301961 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001962 break;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301963 qdf_status = wma_roam_scan_filter(wma_handle, roam_req);
1964 if (qdf_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 WMA_LOGE("Sending update for roam scan filter failed");
1966 break;
1967 }
1968
1969
1970 /*
1971 * Runtime (after association) changes to rssi thresholds and
1972 * other parameters.
1973 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301974 qdf_status = wma_roam_scan_offload_chan_list(wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001975 roam_req->ConnectedNetwork.ChannelCount,
1976 &roam_req->ConnectedNetwork.ChannelCache[0],
1977 roam_req->ChannelCacheType,
1978 roam_req->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979 /*
1980 * Even though the channel list is empty, we can
1981 * still go ahead and start Roaming.
1982 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301983 if ((qdf_status != QDF_STATUS_SUCCESS) &&
1984 (qdf_status != QDF_STATUS_E_EMPTY))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985 break;
1986
1987
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301988 qdf_status = wma_roam_scan_offload_rssi_thresh(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989 roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301990 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001991 break;
1992
1993 if (roam_req->EmptyRefreshScanPeriod > 0) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07001994 qdf_status = wma_roam_scan_offload_scan_period(
1995 wma_handle,
1996 roam_req->EmptyRefreshScanPeriod,
1997 roam_req->EmptyRefreshScanPeriod * 3,
1998 roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301999 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002000 break;
2001
2002 mode = WMI_ROAM_SCAN_MODE_PERIODIC;
2003 /* Don't use rssi triggered roam scans if external app
2004 * is in control of channel list.
2005 */
2006 if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC)
2007 mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
2008
2009 } else {
2010 mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE;
2011 }
2012
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302013 qdf_status = wma_roam_scan_offload_rssi_change(wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014 roam_req->sessionId,
2015 roam_req->RoamRescanRssiDiff,
2016 roam_req->RoamBeaconRssiWeight,
2017 roam_req->hi_rssi_scan_delay);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302018 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019 break;
2020
2021 wma_roam_scan_fill_ap_profile(wma_handle, pMac, roam_req,
2022 &ap_profile);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002023 qdf_status = wma_roam_scan_offload_ap_profile(wma_handle,
2024 &ap_profile, roam_req->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302025 if (qdf_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002026 break;
2027
2028 wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req,
2029 &scan_params);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302030 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031 wma_roam_scan_offload_mode(wma_handle, &scan_params,
2032 roam_req, mode,
2033 roam_req->sessionId);
2034
2035 break;
2036
2037 default:
2038 break;
2039 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302040 qdf_mem_free(roam_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302041 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002042}
2043
Kapil Gupta5cda2252016-12-29 18:44:26 +05302044void wma_update_per_roam_config(WMA_HANDLE handle,
2045 struct wmi_per_roam_config_req *req_buf)
2046{
2047 int status;
2048 tp_wma_handle wma_handle = (tp_wma_handle) handle;
2049
2050 if (!wma_handle || !wma_handle->wmi_handle) {
2051 WMA_LOGE("%s: WMA is closed, cannot send per roam config",
2052 __func__);
2053 return;
2054 }
2055
2056 status = wmi_unified_set_per_roam_config(wma_handle->wmi_handle,
2057 req_buf);
2058 if (status != EOK)
2059 WMA_LOGE("%s: failed to set per roam config to FW",
2060 __func__);
2061}
2062
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002063#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2064
2065/**
2066 * wma_process_roam_invoke() - send roam invoke command to fw.
2067 * @handle: wma handle
2068 * @roaminvoke: roam invoke command
2069 *
2070 * Send roam invoke command to fw for fastreassoc.
2071 *
2072 * Return: none
2073 */
2074void wma_process_roam_invoke(WMA_HANDLE handle,
2075 struct wma_roam_invoke_cmd *roaminvoke)
2076{
2077 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Govind Singh64b5e112016-03-08 11:53:50 +05302078 uint32_t ch_hz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002079
2080 if (!wma_handle || !wma_handle->wmi_handle) {
2081 WMA_LOGE("%s: WMA is closed, can not send roam invoke",
2082 __func__);
Naveen Rawat664a7cb2017-01-19 17:58:14 -08002083 goto free_frame_buf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002084 }
Govind Singh64b5e112016-03-08 11:53:50 +05302085 ch_hz = (A_UINT32)cds_chan_to_freq(roaminvoke->channel);
2086 wmi_unified_roam_invoke_cmd(wma_handle->wmi_handle,
2087 (struct wmi_roam_invoke_cmd *)roaminvoke,
2088 ch_hz);
Naveen Rawat664a7cb2017-01-19 17:58:14 -08002089free_frame_buf:
2090 if (roaminvoke->frame_len) {
2091 qdf_mem_free(roaminvoke->frame_buf);
2092 roaminvoke->frame_buf = NULL;
2093 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094}
2095
2096/**
2097 * wma_process_roam_synch_fail() -roam synch failure handle
2098 * @handle: wma handle
2099 * @synch_fail: roam synch fail parameters
2100 *
2101 * Return: none
2102 */
2103void wma_process_roam_synch_fail(WMA_HANDLE handle,
2104 struct roam_offload_synch_fail *synch_fail)
2105{
2106 tp_wma_handle wma_handle = (tp_wma_handle) handle;
2107 if (!wma_handle || !wma_handle->wmi_handle) {
2108 WMA_LOGE("%s: WMA is closed, can not clean-up roam synch",
2109 __func__);
2110 return;
2111 }
2112 /* Hand Off Failure could happen as an exception, when a roam synch
2113 * indication is posted to Host, but a roam synch complete is not
2114 * posted to the firmware.So, clear the roam synch in progress
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002115 * flag before disconnecting the session through this event.
2116 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002117 wma_handle->interfaces[synch_fail->session_id].roam_synch_in_progress =
2118 false;
2119}
2120
2121/**
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002122 * wma_fill_roam_synch_buffer() - Fill the the roam sync buffer
2123 * @wma: Global WMA Handle
2124 * @roam_synch_ind_ptr: Buffer to be filled
2125 * @param_buf: Source buffer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002126 *
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002127 * Firmware sends all the required information required for roam
2128 * synch propagation as TLV's and stored in param_buf. These
2129 * parameters are parsed and filled into the roam synch indication
2130 * buffer which will be used at different layers for propagation.
2131 *
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002132 * Return: Success or Failure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002133 */
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002134static int wma_fill_roam_synch_buffer(tp_wma_handle wma,
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002135 roam_offload_synch_ind *roam_synch_ind_ptr,
2136 WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002137{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002138 wmi_roam_synch_event_fixed_param *synch_event;
2139 uint8_t *bcn_probersp_ptr;
2140 uint8_t *reassoc_rsp_ptr;
2141 uint8_t *reassoc_req_ptr;
2142 wmi_channel *chan;
2143 wmi_key_material *key;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002144
2145 synch_event = param_buf->fixed_param;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002146 roam_synch_ind_ptr->roamedVdevId = synch_event->vdev_id;
2147 roam_synch_ind_ptr->authStatus = synch_event->auth_status;
2148 roam_synch_ind_ptr->roamReason = synch_event->roam_reason;
2149 roam_synch_ind_ptr->rssi = synch_event->rssi;
2150 roam_synch_ind_ptr->isBeacon = synch_event->is_beacon;
2151 WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid,
Srinivas Girigowda198b2032015-11-24 11:37:34 -08002152 roam_synch_ind_ptr->bssid.bytes);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002153 WMA_LOGI("%s: roamedVdevId %d authStatus %d roamReason %d rssi %d isBeacon %d",
2154 __func__, roam_synch_ind_ptr->roamedVdevId,
2155 roam_synch_ind_ptr->authStatus, roam_synch_ind_ptr->roamReason,
2156 roam_synch_ind_ptr->rssi, roam_synch_ind_ptr->isBeacon);
Padma, Santhosh Kumarcd35f532016-12-27 12:07:39 +05302157
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002158 if (!QDF_IS_STATUS_SUCCESS(
2159 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2160 roam_synch_ind_ptr, NULL, SIR_ROAMING_DEREGISTER_STA))) {
2161 WMA_LOGE("LFR3: CSR Roam synch cb failed");
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002162 return -EINVAL;
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002163 }
Naveen Rawat14298b92015-11-25 16:27:41 -08002164 /* Beacon/Probe Rsp data */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002165 roam_synch_ind_ptr->beaconProbeRespOffset =
2166 sizeof(roam_offload_synch_ind);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002167 bcn_probersp_ptr = (uint8_t *) roam_synch_ind_ptr +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002168 roam_synch_ind_ptr->beaconProbeRespOffset;
2169 roam_synch_ind_ptr->beaconProbeRespLength =
2170 synch_event->bcn_probe_rsp_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302171 qdf_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002172 roam_synch_ind_ptr->beaconProbeRespLength);
Naveen Rawat14298b92015-11-25 16:27:41 -08002173 /* ReAssoc Rsp data */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002174 roam_synch_ind_ptr->reassocRespOffset =
2175 sizeof(roam_offload_synch_ind) +
2176 roam_synch_ind_ptr->beaconProbeRespLength;
2177 roam_synch_ind_ptr->reassocRespLength = synch_event->reassoc_rsp_len;
2178 reassoc_rsp_ptr = (uint8_t *) roam_synch_ind_ptr +
2179 roam_synch_ind_ptr->reassocRespOffset;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302180 qdf_mem_copy(reassoc_rsp_ptr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002181 param_buf->reassoc_rsp_frame,
2182 roam_synch_ind_ptr->reassocRespLength);
Naveen Rawat14298b92015-11-25 16:27:41 -08002183
2184 /* ReAssoc Req data */
2185 roam_synch_ind_ptr->reassoc_req_offset =
2186 sizeof(roam_offload_synch_ind) +
2187 roam_synch_ind_ptr->beaconProbeRespLength +
2188 roam_synch_ind_ptr->reassocRespLength;
2189 roam_synch_ind_ptr->reassoc_req_length = synch_event->reassoc_req_len;
2190 reassoc_req_ptr = (uint8_t *) roam_synch_ind_ptr +
2191 roam_synch_ind_ptr->reassoc_req_offset;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302192 qdf_mem_copy(reassoc_req_ptr, param_buf->reassoc_req_frame,
Naveen Rawat14298b92015-11-25 16:27:41 -08002193 roam_synch_ind_ptr->reassoc_req_length);
2194
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002195 chan = (wmi_channel *) param_buf->chan;
2196 roam_synch_ind_ptr->chan_freq = chan->mhz;
2197 key = (wmi_key_material *) param_buf->key;
2198 if (key != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302199 qdf_mem_copy(roam_synch_ind_ptr->kck, key->kck,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 SIR_KCK_KEY_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302201 qdf_mem_copy(roam_synch_ind_ptr->kek, key->kek,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002202 SIR_KEK_KEY_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302203 qdf_mem_copy(roam_synch_ind_ptr->replay_ctr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002204 key->replay_counter, SIR_REPLAY_CTR_LEN);
Naveen Rawat14298b92015-11-25 16:27:41 -08002205 WMA_LOGD("%s: KCK dump", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302206 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002207 key->kck, SIR_KCK_KEY_LEN);
2208 WMA_LOGD("%s: KEK dump", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302209 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002210 key->kek, SIR_KEK_KEY_LEN);
2211 WMA_LOGD("%s: Key Replay Counter dump", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302212 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002213 key->replay_counter, SIR_REPLAY_CTR_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002214 }
Naveen Rawat8cc23b02016-07-14 12:22:56 -07002215 if (param_buf->hw_mode_transition_fixed_param)
2216 wma_process_pdev_hw_mode_trans_ind(wma,
2217 param_buf->hw_mode_transition_fixed_param,
2218 param_buf->wmi_pdev_set_hw_mode_response_vdev_mac_mapping,
2219 &roam_synch_ind_ptr->hw_mode_trans_ind);
2220 else
2221 WMA_LOGD(FL("hw_mode transition fixed param is NULL"));
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002222
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002223 return 0;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002224}
2225
2226/**
2227 * wma_roam_update_vdev() - Update the STA and BSS
2228 * @wma: Global WMA Handle
2229 * @roam_synch_ind_ptr: Information needed for roam sync propagation
2230 *
2231 * This function will perform all the vdev related operations with
2232 * respect to the self sta and the peer after roaming and completes
2233 * the roam synch propagation with respect to WMA layer.
2234 *
2235 * Return: None
2236 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002237static void wma_roam_update_vdev(tp_wma_handle wma,
2238 roam_offload_synch_ind *roam_synch_ind_ptr)
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002239{
2240 tDeleteBssParams *del_bss_params;
2241 tDeleteStaParams *del_sta_params;
2242 tLinkStateParams *set_link_params;
2243 tAddStaParams *add_sta_params;
2244 uint8_t vdev_id;
2245
Naveen Rawat746a90b2017-06-07 15:16:35 -07002246 vdev_id = roam_synch_ind_ptr->roamedVdevId;
2247 wma->interfaces[vdev_id].nss = roam_synch_ind_ptr->nss;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302248 del_bss_params = qdf_mem_malloc(sizeof(*del_bss_params));
2249 del_sta_params = qdf_mem_malloc(sizeof(*del_sta_params));
2250 set_link_params = qdf_mem_malloc(sizeof(*set_link_params));
2251 add_sta_params = qdf_mem_malloc(sizeof(*add_sta_params));
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002252 if (!del_bss_params || !del_sta_params ||
2253 !set_link_params || !add_sta_params) {
2254 WMA_LOGE("%s: failed to allocate memory", __func__);
2255 return;
2256 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302257 qdf_mem_zero(del_bss_params, sizeof(*del_bss_params));
2258 qdf_mem_zero(del_sta_params, sizeof(*del_sta_params));
2259 qdf_mem_zero(set_link_params, sizeof(*set_link_params));
2260 qdf_mem_zero(add_sta_params, sizeof(*add_sta_params));
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002261
2262 del_bss_params->smesessionId = vdev_id;
2263 del_sta_params->smesessionId = vdev_id;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302264 qdf_mem_copy(del_bss_params->bssid, wma->interfaces[vdev_id].bssid,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002265 IEEE80211_ADDR_LEN);
2266 set_link_params->state = eSIR_LINK_PREASSOC_STATE;
Varun Reddy Yeturu28925b42016-02-08 07:18:50 -08002267 qdf_mem_copy(set_link_params->selfMacAddr,
2268 roam_synch_ind_ptr->self_mac.bytes, IEEE80211_ADDR_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302269 qdf_mem_copy(set_link_params->bssid, roam_synch_ind_ptr->bssid.bytes,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002270 IEEE80211_ADDR_LEN);
2271 add_sta_params->staType = STA_ENTRY_SELF;
2272 add_sta_params->smesessionId = vdev_id;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302273 qdf_mem_copy(&add_sta_params->bssId, &roam_synch_ind_ptr->bssid.bytes,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002274 IEEE80211_ADDR_LEN);
2275 add_sta_params->staIdx = STA_INVALID_IDX;
2276 add_sta_params->assocId = roam_synch_ind_ptr->aid;
2277
2278 wma_delete_sta(wma, del_sta_params);
2279 wma_delete_bss(wma, del_bss_params);
2280 wma_set_linkstate(wma, set_link_params);
2281 wma_add_bss(wma, (tpAddBssParams)roam_synch_ind_ptr->add_bss_params);
2282 wma_add_sta(wma, add_sta_params);
Mukul Sharmaf9047232017-03-02 16:58:56 +05302283 wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_RUN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302284 qdf_mem_copy(wma->interfaces[vdev_id].bssid,
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002285 roam_synch_ind_ptr->bssid.bytes, IEEE80211_ADDR_LEN);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302286 qdf_mem_free(del_bss_params);
2287 qdf_mem_free(del_sta_params);
2288 qdf_mem_free(set_link_params);
2289 qdf_mem_free(add_sta_params);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002290}
2291
2292/**
2293 * wma_roam_synch_event_handler() - roam synch event handler
2294 * @handle: wma handle
2295 * @event: event data
2296 * @len: length of data
2297 *
2298 * This function is roam synch event handler. It sends roam
2299 * indication for upper layer.
2300 *
2301 * Return: Success or Failure status
2302 */
2303int wma_roam_synch_event_handler(void *handle, uint8_t *event,
2304 uint32_t len)
2305{
2306 WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf = NULL;
2307 wmi_roam_synch_event_fixed_param *synch_event = NULL;
2308 tp_wma_handle wma = (tp_wma_handle) handle;
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002309 roam_offload_synch_ind *roam_synch_ind_ptr = NULL;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002310 tpSirBssDescription bss_desc_ptr = NULL;
2311 uint16_t ie_len = 0;
2312 int status = -EINVAL;
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002313 tSirRoamOffloadScanReq *roam_req;
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07002314 qdf_time_t roam_synch_received = qdf_get_system_timestamp();
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002315
2316 WMA_LOGD("LFR3:%s", __func__);
2317 if (!event) {
2318 WMA_LOGE("%s: event param null", __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002319 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002320 }
2321
2322 param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *) event;
2323 if (!param_buf) {
2324 WMA_LOGE("%s: received null buf from target", __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002325 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002326 }
2327
2328 synch_event = param_buf->fixed_param;
2329 if (!synch_event) {
2330 WMA_LOGE("%s: received null event data from target", __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002331 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002332 }
2333
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302334 DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07002335 synch_event->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
2336 QDF_PROTO_TYPE_EVENT, QDF_ROAM_SYNCH));
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302337
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002338 if (wma_is_roam_synch_in_progress(wma, synch_event->vdev_id)) {
2339 WMA_LOGE("%s: Ignoring RSI since one is already in progress",
2340 __func__);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002341 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002342 }
Varun Reddy Yeturu90444892016-02-04 10:43:20 -08002343 WMA_LOGE("LFR3: Received WMA_ROAM_OFFLOAD_SYNCH_IND");
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002344
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302345 qdf_wake_lock_timeout_acquire(&wma->wow_wake_lock,
2346 WMA_ROAM_HO_WAKE_LOCK_DURATION);
2347
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002348 wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = true;
2349 len = sizeof(roam_offload_synch_ind) +
2350 synch_event->bcn_probe_rsp_len + synch_event->reassoc_rsp_len +
2351 synch_event->reassoc_req_len;
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302352 roam_synch_ind_ptr = (roam_offload_synch_ind *)qdf_mem_malloc(len);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002353 if (!roam_synch_ind_ptr) {
2354 WMA_LOGE("%s: failed to allocate memory for roam_synch_event",
2355 __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302356 QDF_ASSERT(roam_synch_ind_ptr != NULL);
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302357 status = -ENOMEM;
2358 goto cleanup_label;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002359 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302360 qdf_mem_zero(roam_synch_ind_ptr, len);
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002361 status = wma_fill_roam_synch_buffer(wma,
2362 roam_synch_ind_ptr, param_buf);
2363 if (status != 0)
Varun Reddy Yeturu88f123c2017-03-14 18:24:32 -07002364 goto cleanup_label;
Naveen Rawat8cc23b02016-07-14 12:22:56 -07002365 /* 24 byte MAC header and 12 byte to ssid IE */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002366 if (roam_synch_ind_ptr->beaconProbeRespLength >
2367 (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
2368 ie_len = roam_synch_ind_ptr->beaconProbeRespLength -
2369 (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
2370 } else {
2371 WMA_LOGE("LFR3: Invalid Beacon Length");
2372 goto cleanup_label;
2373 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302374 bss_desc_ptr = qdf_mem_malloc(sizeof(tSirBssDescription) + ie_len);
Kiran Kumar Lokereba3b4312016-04-29 16:40:20 -07002375 if (NULL == bss_desc_ptr) {
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002376 WMA_LOGE("LFR3: mem alloc failed!");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302377 QDF_ASSERT(bss_desc_ptr != NULL);
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302378 status = -ENOMEM;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002379 goto cleanup_label;
2380 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302381 qdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription) + ie_len);
Selvaraj, Sridhara6e3eba2017-03-14 19:52:39 +05302382 if (QDF_IS_STATUS_ERROR(wma->pe_roam_synch_cb(
2383 (tpAniSirGlobal)wma->mac_context,
2384 roam_synch_ind_ptr, bss_desc_ptr))) {
2385 WMA_LOGE("LFR3: PE roam synch cb failed");
2386 status = -EBUSY;
2387 goto cleanup_label;
2388 }
Naveen Rawat746a90b2017-06-07 15:16:35 -07002389
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002390 wma_roam_update_vdev(wma, roam_synch_ind_ptr);
2391 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07002392 roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_PROPAGATION);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002393 wma_process_roam_synch_complete(wma, synch_event->vdev_id);
Naveen Rawat8cc23b02016-07-14 12:22:56 -07002394
2395 /* update freq and channel width */
2396 wma->interfaces[synch_event->vdev_id].mhz =
2397 roam_synch_ind_ptr->chan_freq;
2398 if (roam_synch_ind_ptr->join_rsp)
2399 wma->interfaces[synch_event->vdev_id].chan_width =
2400 roam_synch_ind_ptr->join_rsp->vht_channel_width;
2401
2402 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2403 roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_COMPLETE);
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07002404 wma->interfaces[synch_event->vdev_id].roam_synch_delay =
2405 qdf_get_system_timestamp() - roam_synch_received;
2406 WMA_LOGD("LFR3: roam_synch_delay:%d",
2407 wma->interfaces[synch_event->vdev_id].roam_synch_delay);
Varun Reddy Yeturu04251862016-09-16 10:33:19 -07002408 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2409 roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_NAPI_OFF);
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302410
2411 status = 0;
2412
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002413cleanup_label:
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002414 if (status != 0) {
2415 if (roam_synch_ind_ptr)
2416 wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
2417 roam_synch_ind_ptr, NULL, SIR_ROAMING_ABORT);
2418 roam_req = qdf_mem_malloc(sizeof(tSirRoamOffloadScanReq));
Krunal Sonifea06802017-04-13 14:44:48 -07002419 if (roam_req) {
2420 roam_req->Command = ROAM_SCAN_OFFLOAD_STOP;
2421 roam_req->reason = REASON_ROAM_SYNCH_FAILED;
2422 wma_process_roaming_config(wma, roam_req);
2423 }
Varun Reddy Yeturu1ce7aff2017-03-15 16:14:03 -07002424 }
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302425 if (roam_synch_ind_ptr && roam_synch_ind_ptr->join_rsp)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302426 qdf_mem_free(roam_synch_ind_ptr->join_rsp);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002427 if (roam_synch_ind_ptr)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302428 qdf_mem_free(roam_synch_ind_ptr);
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002429 if (bss_desc_ptr)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302430 qdf_mem_free(bss_desc_ptr);
Krunal Sonifea06802017-04-13 14:44:48 -07002431 if (wma && synch_event)
2432 wma->interfaces[synch_event->vdev_id].roam_synch_in_progress =
2433 false;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002434
yeshwanth sriram guntuka37c09822017-01-24 18:30:15 +05302435 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002436}
2437
2438/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002439 * wma_roam_scan_fill_self_caps() - fill capabilities
2440 * @wma_handle: wma handle
2441 * @roam_offload_params: offload parameters
2442 * @roam_req: roam request
2443 *
2444 * This function fills roam self capablities.
2445 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302446 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302448QDF_STATUS wma_roam_scan_fill_self_caps(tp_wma_handle wma_handle,
Himanshu Agarwalb56ad2e2016-07-19 15:43:09 +05302449 roam_offload_param *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450 roam_offload_params,
2451 tSirRoamOffloadScanReq *roam_req)
2452{
2453 struct sAniSirGlobal *pMac = NULL;
2454 tSirMacCapabilityInfo selfCaps;
2455 uint32_t val = 0;
2456 uint32_t nCfgValue;
2457 uint16_t *pCfgValue16;
2458 uint8_t nCfgValue8, *pCfgValue8;
2459 tSirMacQosInfoStation macQosInfoSta;
2460 union {
2461 uint16_t nCfgValue16;
2462 tSirMacHTCapabilityInfo htCapInfo;
2463 tSirMacExtendedHTCapabilityInfo extHtCapInfo;
2464 } uHTCapabilityInfo;
2465
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302466 qdf_mem_set(&macQosInfoSta, sizeof(tSirMacQosInfoStation), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002467 /* Roaming is done only for INFRA STA type.
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002468 * So, ess will be one and ibss will be Zero
2469 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302470 pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 if (!pMac) {
2472 WMA_LOGE("%s:NULL pMac ptr. Exiting", __func__);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302473 QDF_ASSERT(0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302474 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002475 }
2476
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002477 if (wlan_cfg_get_int(pMac, WNI_CFG_PRIVACY_ENABLED, &val) !=
2478 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302479 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002480 "Failed to get WNI_CFG_PRIVACY_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302481 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002482 }
2483 selfCaps.ess = 1;
2484 selfCaps.ibss = 0;
2485 if (val)
2486 selfCaps.privacy = 1;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002487 if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) !=
2488 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302489 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490 "Failed to get WNI_CFG_SHORT_PREAMBLE");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302491 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492 }
2493 if (val)
2494 selfCaps.shortPreamble = 1;
2495
2496 selfCaps.pbcc = 0;
2497 selfCaps.channelAgility = 0;
2498 if (wlan_cfg_get_int(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
2499 &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302500 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002501 "Failed to get WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302502 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002503 }
2504 if (val)
2505 selfCaps.shortSlotTime = 1;
2506 if (wlan_cfg_get_int(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302507 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002508 "Failed to get WNI_CFG_11H_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302509 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002510 }
2511 if (val)
2512 selfCaps.spectrumMgt = 1;
2513 if (wlan_cfg_get_int(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302514 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002515 "Failed to get WNI_CFG_QOS_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302516 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002517 }
2518 if (val)
2519 selfCaps.qos = 1;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002520 if (wlan_cfg_get_int(pMac, WNI_CFG_APSD_ENABLED, &val) !=
2521 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302522 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002523 "Failed to get WNI_CFG_APSD_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302524 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002525 }
2526 if (val)
2527 selfCaps.apsd = 1;
Krishna Kumaar Natarajan4340c682015-11-03 12:09:00 -08002528
2529 selfCaps.rrm = pMac->rrm.rrmSmeContext.rrmConfig.rrm_enabled;
2530
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002531 if (wlan_cfg_get_int(pMac, WNI_CFG_BLOCK_ACK_ENABLED, &val) !=
2532 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302533 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534 "Failed to get WNI_CFG_BLOCK_ACK_ENABLED");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302535 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002536 }
2537 selfCaps.delayedBA =
2538 (uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
2539 selfCaps.immediateBA =
2540 (uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
2541 pCfgValue16 = (uint16_t *) &selfCaps;
2542 roam_offload_params->capability = (*pCfgValue16) & 0xFFFF;
2543
2544 if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &nCfgValue) !=
2545 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302546 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547 "Failed to get WNI_CFG_HT_CAP_INFO");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302548 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002549 }
2550 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2551 roam_offload_params->ht_caps_info =
2552 uHTCapabilityInfo.nCfgValue16 & 0xFFFF;
2553 if (wlan_cfg_get_int(pMac, WNI_CFG_HT_AMPDU_PARAMS, &nCfgValue) !=
2554 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302555 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002556 "Failed to get WNI_CFG_HT_AMPDU_PARAMS");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302557 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558 }
2559 /* tSirMacHTParametersInfo */
2560 nCfgValue8 = (uint8_t) nCfgValue;
2561 roam_offload_params->ampdu_param = (nCfgValue8) & 0xFF;
2562
2563 val = ROAM_OFFLOAD_NUM_MCS_SET;
2564 if (wlan_cfg_get_str(pMac, WNI_CFG_SUPPORTED_MCS_SET,
2565 (uint8_t *) roam_offload_params->mcsset,
2566 &val) != eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302567 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568 "Failed to get WNI_CFG_SUPPORTED_MCS_SET");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302569 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002570 }
2571 if (wlan_cfg_get_int(pMac, WNI_CFG_EXT_HT_CAP_INFO, &nCfgValue) !=
2572 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302573 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002574 "Failed to get WNI_CFG_EXT_HT_CAP_INFO");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302575 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002576 }
2577 /* uHTCapabilityInfo.extHtCapInfo */
2578 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2579 roam_offload_params->ht_ext_cap =
2580 uHTCapabilityInfo.nCfgValue16 & 0xFFFF;
2581
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002582 if (wlan_cfg_get_int(pMac, WNI_CFG_TX_BF_CAP, &nCfgValue) !=
2583 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302584 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002585 "Failed to get WNI_CFG_TX_BF_CAP");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302586 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002587 }
2588 /* tSirMacTxBFCapabilityInfo */
2589 nCfgValue8 = (uint8_t) nCfgValue;
2590 roam_offload_params->ht_txbf = nCfgValue8 & 0xFF;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07002591 if (wlan_cfg_get_int(pMac, WNI_CFG_AS_CAP, &nCfgValue) !=
2592 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302593 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002594 "Failed to get WNI_CFG_AS_CAP");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302595 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002596 }
2597 /* tSirMacASCapabilityInfo */
2598 nCfgValue8 = (uint8_t) nCfgValue;
2599 roam_offload_params->asel_cap = nCfgValue8 & 0xFF;
2600
2601 /* QOS Info */
2602 if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &nCfgValue) !=
2603 eSIR_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302604 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002605 "Failed to get WNI_CFG_MAX_SP_LENGTH");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302606 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002607 }
2608 nCfgValue8 = (uint8_t) nCfgValue;
2609 macQosInfoSta.maxSpLen = nCfgValue8;
2610 macQosInfoSta.moreDataAck = 0;
2611 macQosInfoSta.qack = 0;
2612 macQosInfoSta.acbe_uapsd = roam_req->AcUapsd.acbe_uapsd;
2613 macQosInfoSta.acbk_uapsd = roam_req->AcUapsd.acbk_uapsd;
2614 macQosInfoSta.acvi_uapsd = roam_req->AcUapsd.acvi_uapsd;
2615 macQosInfoSta.acvo_uapsd = roam_req->AcUapsd.acvo_uapsd;
2616 pCfgValue8 = (uint8_t *) &macQosInfoSta;
2617 /* macQosInfoSta Only queue_request is set.Refer to
2618 * populate_dot11f_wmm_caps for more details
2619 */
2620 roam_offload_params->qos_caps = (*pCfgValue8) & 0xFF;
Naveen Rawat08340742016-11-17 14:54:39 -08002621 if (roam_offload_params->qos_caps)
2622 roam_offload_params->qos_enabled = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002623 roam_offload_params->wmm_caps = 0x4 & 0xFF;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302624 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002625}
2626
2627/**
2628 * wma_set_ric_req() - set ric request element
2629 * @wma: wma handle
2630 * @msg: message
2631 * @is_add_ts: is addts required
2632 *
2633 * This function sets ric request element for 11r roaming.
2634 *
2635 * Return: none
2636 */
2637void wma_set_ric_req(tp_wma_handle wma, void *msg, uint8_t is_add_ts)
2638{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05302639 if (!wma) {
2640 WMA_LOGE("%s: wma handle is NULL", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002641 return;
2642 }
2643
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05302644 wmi_unified_set_ric_req_cmd(wma->wmi_handle, msg, is_add_ts);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002645}
2646#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
2647
2648/**
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08002649 * wma_rssi_breached_event_handler() - rssi breached event handler
2650 * @handle: wma handle
2651 * @cmd_param_info: event handler data
2652 * @len: length of @cmd_param_info
2653 *
2654 * Return: 0 on success; error number otherwise
2655 */
2656int wma_rssi_breached_event_handler(void *handle,
2657 u_int8_t *cmd_param_info, u_int32_t len)
2658{
2659 WMI_RSSI_BREACH_EVENTID_param_tlvs *param_buf;
2660 wmi_rssi_breach_event_fixed_param *event;
2661 struct rssi_breach_event rssi;
2662 tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
2663
2664 if (!mac) {
2665 WMA_LOGE("%s: Invalid mac context", __func__);
2666 return -EINVAL;
2667 }
2668 if (!mac->sme.rssi_threshold_breached_cb) {
2669 WMA_LOGE("%s: Callback not registered", __func__);
2670 return -EINVAL;
2671 }
2672 param_buf = (WMI_RSSI_BREACH_EVENTID_param_tlvs *)cmd_param_info;
2673 if (!param_buf) {
2674 WMA_LOGE("%s: Invalid rssi breached event", __func__);
2675 return -EINVAL;
2676 }
2677 event = param_buf->fixed_param;
2678
2679 rssi.request_id = event->request_id;
2680 rssi.session_id = event->vdev_id;
2681 rssi.curr_rssi = event->rssi + WMA_TGT_NOISE_FLOOR_DBM;
2682 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->bssid, rssi.curr_bssid.bytes);
2683
2684 WMA_LOGD("%s: req_id: %u vdev_id: %d curr_rssi: %d", __func__,
2685 rssi.request_id, rssi.session_id, rssi.curr_rssi);
2686 WMA_LOGI("%s: curr_bssid: %pM", __func__, rssi.curr_bssid.bytes);
2687
2688 mac->sme.rssi_threshold_breached_cb(mac->hHdd, &rssi);
2689 WMA_LOGD("%s: Invoke HDD rssi breached callback", __func__);
2690 return 0;
2691}
2692
2693/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694 * wma_process_unit_test_cmd() - send unit test command to fw.
2695 * @handle: wma handle
2696 * @wma_utest: unit test command
2697 *
2698 * This function send unit test command to fw.
2699 *
2700 * Return: none
2701 */
2702void wma_process_unit_test_cmd(WMA_HANDLE handle,
2703 t_wma_unit_test_cmd *wma_utest)
2704{
2705 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002706
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002707 if (!wma_handle || !wma_handle->wmi_handle) {
2708 WMA_LOGE("%s: WMA is closed, can not issue fw unit test cmd",
2709 __func__);
2710 return;
2711 }
Govind Singh64b5e112016-03-08 11:53:50 +05302712
2713 if (wmi_unified_unit_test_cmd(wma_handle->wmi_handle,
2714 (struct wmi_unit_test_cmd *)wma_utest)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002715 return;
2716 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002717}
2718
2719#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720/**
2721 * wma_roam_ho_fail_handler() - LFR3.0 roam hand off failed handler
2722 * @wma: wma handle
2723 * @vdev_id: vdev id
2724 *
2725 * Return: none
2726 */
2727static void wma_roam_ho_fail_handler(tp_wma_handle wma, uint32_t vdev_id)
2728{
2729 tSirSmeHOFailureInd *ho_failure_ind;
Rajeev Kumarb60abe42017-01-21 15:39:31 -08002730 struct scheduler_msg sme_msg = { 0 };
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302731 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002732
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302733 ho_failure_ind = qdf_mem_malloc(sizeof(tSirSmeHOFailureInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002734
2735 if (NULL == ho_failure_ind) {
2736 WMA_LOGE("%s: Memory allocation failure", __func__);
2737 return;
2738 }
2739 ho_failure_ind->sessionId = vdev_id;
2740 sme_msg.type = eWNI_SME_HO_FAIL_IND;
2741 sme_msg.bodyptr = ho_failure_ind;
2742 sme_msg.bodyval = 0;
2743
Rajeev Kumarb60abe42017-01-21 15:39:31 -08002744 qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302745 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002746 WMA_LOGE("Fail to post eWNI_SME_HO_FAIL_IND msg to SME");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302747 qdf_mem_free(ho_failure_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002748 return;
2749 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002750}
2751
2752/**
2753 * wma_process_roam_synch_complete() - roam synch complete command to fw.
2754 * @handle: wma handle
2755 * @synchcnf: offload synch confirmation params
2756 *
2757 * This function sends roam synch complete event to fw.
2758 *
2759 * Return: none
2760 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002761void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762{
2763 tp_wma_handle wma_handle = (tp_wma_handle) handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002764
2765 if (!wma_handle || !wma_handle->wmi_handle) {
2766 WMA_LOGE("%s: WMA is closed, can not issue roam synch cnf",
2767 __func__);
2768 return;
2769 }
Govind Singh64b5e112016-03-08 11:53:50 +05302770
2771 if (wmi_unified_roam_synch_complete_cmd(wma_handle->wmi_handle,
2772 vdev_id)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773 return;
2774 }
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302775
2776 DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07002777 vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
2778 QDF_PROTO_TYPE_EVENT, QDF_ROAM_COMPLETE));
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05302779
Varun Reddy Yeturu90444892016-02-04 10:43:20 -08002780 WMA_LOGE("LFR3: Posting WMA_ROAM_OFFLOAD_SYNCH_CNF");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002781}
2782#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
2783
2784/**
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002785 * wma_switch_channel() - WMA api to switch channel dynamically
2786 * @wma: Pointer of WMA context
2787 * @req: Pointer vdev_start having channel switch info.
2788 *
2789 * Return: 0 for success, otherwise appropriate error code
2790 */
Jeff Johnsonc4b47a92016-10-07 12:34:41 -07002791static QDF_STATUS wma_switch_channel(tp_wma_handle wma,
2792 struct wma_vdev_start_req *req)
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002793{
2794
2795 wmi_buf_t buf;
2796 wmi_channel *cmd;
2797 int32_t len, ret;
2798 WLAN_PHY_MODE chanmode;
2799 struct wma_txrx_node *intr = wma->interfaces;
2800 tpAniSirGlobal pmac;
2801
2802 pmac = cds_get_context(QDF_MODULE_ID_PE);
2803
2804 if (pmac == NULL) {
2805 WMA_LOGE("%s: vdev start failed as pmac is NULL", __func__);
2806 return QDF_STATUS_E_FAILURE;
2807 }
2808
2809 len = sizeof(*cmd);
2810 buf = wmi_buf_alloc(wma->wmi_handle, len);
2811 if (!buf) {
2812 WMA_LOGE("%s : wmi_buf_alloc failed", __func__);
2813 return QDF_STATUS_E_NOMEM;
2814 }
2815 cmd = (wmi_channel *)wmi_buf_data(buf);
2816 WMITLV_SET_HDR(&cmd->tlv_header,
2817 WMITLV_TAG_STRUC_wmi_channel,
2818 WMITLV_GET_STRUCT_TLVLEN(wmi_channel));
2819
2820 /* Fill channel info */
2821 cmd->mhz = cds_chan_to_freq(req->chan);
Amar Singhal046eb8a2016-05-05 12:50:15 -07002822 chanmode = wma_chan_phy_mode(req->chan, req->chan_width,
2823 req->dot11_mode);
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002824
2825 intr[req->vdev_id].chanmode = chanmode; /* save channel mode */
2826 intr[req->vdev_id].ht_capable = req->ht_capable;
2827 intr[req->vdev_id].vht_capable = req->vht_capable;
2828 intr[req->vdev_id].config.gtx_info.gtxRTMask[0] =
2829 CFG_TGT_DEFAULT_GTX_HT_MASK;
2830 intr[req->vdev_id].config.gtx_info.gtxRTMask[1] =
2831 CFG_TGT_DEFAULT_GTX_VHT_MASK;
Rajeev Kumar Sirasanagandlaaf474742016-09-06 17:54:50 +05302832
2833 if (wlan_cfg_get_int(pmac, WNI_CFG_TGT_GTX_USR_CFG,
2834 &intr[req->vdev_id].config.gtx_info.gtxUsrcfg) != eSIR_SUCCESS) {
2835 intr[req->vdev_id].config.gtx_info.gtxUsrcfg =
2836 WNI_CFG_TGT_GTX_USR_CFG_STADEF;
2837 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_WARN,
2838 "Failed to get WNI_CFG_TGT_GTX_USR_CFG");
2839 }
2840
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002841 intr[req->vdev_id].config.gtx_info.gtxPERThreshold =
2842 CFG_TGT_DEFAULT_GTX_PER_THRESHOLD;
2843 intr[req->vdev_id].config.gtx_info.gtxPERMargin =
2844 CFG_TGT_DEFAULT_GTX_PER_MARGIN;
2845 intr[req->vdev_id].config.gtx_info.gtxTPCstep =
2846 CFG_TGT_DEFAULT_GTX_TPC_STEP;
2847 intr[req->vdev_id].config.gtx_info.gtxTPCMin =
2848 CFG_TGT_DEFAULT_GTX_TPC_MIN;
2849 intr[req->vdev_id].config.gtx_info.gtxBWMask =
2850 CFG_TGT_DEFAULT_GTX_BW_MASK;
2851 intr[req->vdev_id].mhz = cmd->mhz;
2852
2853 WMI_SET_CHANNEL_MODE(cmd, chanmode);
2854 cmd->band_center_freq1 = cmd->mhz;
2855
2856 if (chanmode == MODE_11AC_VHT80)
2857 cmd->band_center_freq1 =
2858 cds_chan_to_freq(req->ch_center_freq_seg0);
2859
2860 if ((chanmode == MODE_11NA_HT40) || (chanmode == MODE_11NG_HT40) ||
2861 (chanmode == MODE_11AC_VHT40)) {
2862 if (req->chan_width == CH_WIDTH_80MHZ)
2863 cmd->band_center_freq1 += 10;
2864 else
2865 cmd->band_center_freq1 -= 10;
2866 }
2867 cmd->band_center_freq2 = 0;
2868
2869 /* Set half or quarter rate WMI flags */
2870 if (req->is_half_rate)
2871 WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_HALF_RATE);
2872 else if (req->is_quarter_rate)
2873 WMI_SET_CHANNEL_FLAG(cmd, WMI_CHAN_FLAG_QUARTER_RATE);
2874
2875 /* Find out min, max and regulatory power levels */
2876 WMI_SET_CHANNEL_REG_POWER(cmd, req->max_txpow);
2877 WMI_SET_CHANNEL_MAX_TX_POWER(cmd, req->max_txpow);
2878
2879
2880 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",
2881 __func__, cmd->mhz, req->chan, chanmode,
2882 cmd->band_center_freq1, cmd->band_center_freq2,
2883 cmd->reg_info_1, cmd->reg_info_2, req->max_txpow);
2884
2885
2886 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
2887 WMI_PDEV_SET_CHANNEL_CMDID);
2888
2889 if (ret < 0) {
2890 WMA_LOGP("%s: Failed to send vdev start command", __func__);
Dustin Brown2afb6f52016-12-02 14:47:48 -08002891 wmi_buf_free(buf);
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002892 return QDF_STATUS_E_FAILURE;
2893 }
2894
2895 return QDF_STATUS_SUCCESS;
2896}
2897
2898/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002899 * wma_set_channel() - set channel
2900 * @wma: wma handle
2901 * @params: switch channel parameters
2902 *
2903 * Return: none
2904 */
2905void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
2906{
2907 struct wma_vdev_start_req req;
2908 struct wma_target_req *msg;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302909 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002910 uint8_t vdev_id, peer_id;
Leo Chang96464902016-10-28 11:10:54 -07002911 void *peer;
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002912 struct cdp_pdev *pdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002913 struct wma_txrx_node *intr = wma->interfaces;
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07002914 struct policy_mgr_hw_mode_params hw_mode = {0};
Leo Chang96464902016-10-28 11:10:54 -07002915 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002916
2917 WMA_LOGD("%s: Enter", __func__);
2918 if (!wma_find_vdev_by_addr(wma, params->selfStaMacAddr, &vdev_id)) {
2919 WMA_LOGP("%s: Failed to find vdev id for %pM",
2920 __func__, params->selfStaMacAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302921 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002922 goto send_resp;
2923 }
Anurag Chouhan6d760662016-02-20 16:05:43 +05302924 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002925 if (NULL == pdev) {
2926 WMA_LOGE("%s: Failed to get pdev", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302927 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002928 goto send_resp;
2929 }
2930
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08002931 peer = cdp_peer_find_by_addr(soc,
2932 pdev,
2933 intr[vdev_id].bssid, &peer_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002934
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302935 qdf_mem_zero(&req, sizeof(req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002936 req.vdev_id = vdev_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002937 req.chan = params->channelNumber;
2938 req.chan_width = params->ch_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07002939
2940 if (params->ch_width == CH_WIDTH_10MHZ)
2941 req.is_half_rate = 1;
2942 else if (params->ch_width == CH_WIDTH_5MHZ)
2943 req.is_quarter_rate = 1;
2944
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002945 req.vht_capable = params->vhtCapable;
2946 req.ch_center_freq_seg0 = params->ch_center_freq_seg0;
2947 req.ch_center_freq_seg1 = params->ch_center_freq_seg1;
2948 req.dot11_mode = params->dot11_mode;
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08002949 wma_update_vdev_he_capable(&req, params);
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08002950
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08002951 WMA_LOGI(FL("vht_capable: %d, dot11_mode: %d"),
2952 req.vht_capable, req.dot11_mode);
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08002953
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07002954 status = policy_mgr_get_current_hw_mode(wma->psoc, &hw_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302955 if (!QDF_IS_STATUS_SUCCESS(status))
Tushnim Bhattacharyya51258a72017-03-13 12:55:02 -07002956 WMA_LOGE("policy_mgr_get_current_hw_mode failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002957
2958 if ((params->nss == 2) && !hw_mode.dbs_cap) {
2959 req.preferred_rx_streams = 2;
2960 req.preferred_tx_streams = 2;
2961 } else {
2962 req.preferred_rx_streams = 1;
2963 req.preferred_tx_streams = 1;
2964 }
2965
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002966 req.max_txpow = params->maxTxPower;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002967 req.beacon_intval = 100;
2968 req.dtim_period = 1;
2969 req.is_dfs = params->isDfsChannel;
Arif Hussain671a1902017-03-17 09:08:32 -07002970 req.cac_duration_ms = params->cac_duration_ms;
2971 req.dfs_regdomain = params->dfs_regdomain;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002972
2973 /* In case of AP mode, once radar is detected, we need to
2974 * issuse VDEV RESTART, so we making is_channel_switch as
2975 * true
2976 */
2977 if ((wma_is_vdev_in_ap_mode(wma, req.vdev_id) == true) ||
2978 (params->restart_on_chan_switch == true))
2979 wma->interfaces[req.vdev_id].is_channel_switch = true;
2980
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002981 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() &&
2982 wma_is_vdev_up(vdev_id)) {
2983 status = wma_switch_channel(wma, &req);
2984 if (status != QDF_STATUS_SUCCESS)
2985 WMA_LOGE("%s: wma_switch_channel failed %d\n", __func__,
2986 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002987
Leo Chang96464902016-10-28 11:10:54 -07002988 /* This is temporary, should be removed */
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07002989 ol_htt_mon_note_chan(pdev, req.chan);
2990 } else {
Sandeep Puligillafe426b62017-02-07 18:07:14 -08002991
2992 msg = wma_fill_vdev_req(wma, req.vdev_id, WMA_CHNL_SWITCH_REQ,
2993 WMA_TARGET_REQ_TYPE_VDEV_START, params,
2994 WMA_VDEV_START_REQUEST_TIMEOUT);
2995 if (!msg) {
2996 WMA_LOGP("%s: Failed to fill channel switch request for vdev %d",
2997 __func__, req.vdev_id);
2998 status = QDF_STATUS_E_NOMEM;
2999 goto send_resp;
3000 }
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003001 status = wma_vdev_start(wma, &req,
3002 wma->interfaces[req.vdev_id].is_channel_switch);
3003 if (status != QDF_STATUS_SUCCESS) {
3004 wma_remove_vdev_req(wma, req.vdev_id,
3005 WMA_TARGET_REQ_TYPE_VDEV_START);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003006 WMA_LOGP("%s: vdev start failed status = %d", __func__,
3007 status);
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003008 goto send_resp;
3009 }
3010
Leo Chang96464902016-10-28 11:10:54 -07003011 /* This is temporary, should be removed */
Manjunathappa Prakash0e6e6b52016-04-21 11:48:48 -07003012 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
3013 ol_htt_mon_note_chan(pdev, req.chan);
3014 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003015 return;
3016send_resp:
3017 WMA_LOGD("%s: channel %d ch_width %d txpower %d status %d", __func__,
3018 params->channelNumber, params->ch_width,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003019 params->maxTxPower,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003020 status);
3021 params->status = status;
3022 WMA_LOGI("%s: sending WMA_SWITCH_CHANNEL_RSP, status = 0x%x",
3023 __func__, status);
3024 wma_send_msg(wma, WMA_SWITCH_CHANNEL_RSP, (void *)params, 0);
3025}
3026
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003027#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003028/**
3029 * wma_plm_start() - plm start request
3030 * @wma: wma handle
3031 * @plm: plm request parameters
3032 *
3033 * This function request FW to start PLM.
3034 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303035 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003036 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303037QDF_STATUS wma_plm_start(tp_wma_handle wma, const tpSirPlmReq plm)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003038{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303039 struct plm_req_params params = {0};
3040 uint32_t num_channels;
3041 uint32_t *channel_list = NULL;
3042 uint32_t i;
3043 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003044
3045 if (NULL == plm || NULL == wma) {
3046 WMA_LOGE("%s: input pointer is NULL ", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303047 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003048 }
3049 WMA_LOGD("PLM Start");
3050
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303051 num_channels = plm->plmNumCh;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003052
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303053 if (num_channels) {
3054 channel_list = qdf_mem_malloc(sizeof(uint32_t) * num_channels);
3055 if (!channel_list)
3056 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003057
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303058 for (i = 0; i < num_channels; i++) {
3059 channel_list[i] = plm->plmChList[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003060
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303061 if (channel_list[i] < WMA_NLO_FREQ_THRESH)
3062 channel_list[i] =
3063 cds_chan_to_freq(channel_list[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003064 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065 }
3066
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303067 params.diag_token = plm->diag_token;
3068 params.meas_token = plm->meas_token;
3069 params.num_bursts = plm->numBursts;
3070 params.burst_int = plm->burstInt;
3071 params.meas_duration = plm->measDuration;
3072 params.burst_len = plm->burstLen;
3073 params.desired_tx_pwr = plm->desiredTxPwr;
3074 params.plm_num_ch = plm->plmNumCh;
3075 params.session_id = plm->sessionId;
3076 params.enable = plm->enable;
3077 qdf_mem_copy(&params.mac_addr, &plm->mac_addr,
3078 sizeof(struct qdf_mac_addr));
3079 qdf_mem_copy(params.plm_ch_list, plm->plmChList,
3080 WMI_CFG_VALID_CHANNEL_LIST_LEN);
3081
3082 status = wmi_unified_plm_start_cmd(wma->wmi_handle,
3083 &params, channel_list);
3084 if (QDF_IS_STATUS_ERROR(status)) {
3085 qdf_mem_free(channel_list);
3086 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003087 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303088
3089 qdf_mem_free(channel_list);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003090 wma->interfaces[plm->sessionId].plm_in_progress = true;
3091
3092 WMA_LOGD("Plm start request sent successfully for vdev %d",
3093 plm->sessionId);
3094
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303095 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003096}
3097
3098/**
3099 * wma_plm_stop() - plm stop request
3100 * @wma: wma handle
3101 * @plm: plm request parameters
3102 *
3103 * This function request FW to stop PLM.
3104 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303105 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003106 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303107QDF_STATUS wma_plm_stop(tp_wma_handle wma, const tpSirPlmReq plm)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003108{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303109 struct plm_req_params params = {0};
3110 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003111
3112 if (NULL == plm || NULL == wma) {
3113 WMA_LOGE("%s: input pointer is NULL ", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303114 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003115 }
3116
3117 if (false == wma->interfaces[plm->sessionId].plm_in_progress) {
3118 WMA_LOGE("No active plm req found, skip plm stop req");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303119 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003120 }
3121
3122 WMA_LOGD("PLM Stop");
3123
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303124 params.diag_token = plm->diag_token;
3125 params.meas_token = plm->meas_token;
3126 params.num_bursts = plm->numBursts;
3127 params.burst_int = plm->burstInt;
3128 params.meas_duration = plm->measDuration;
3129 params.burst_len = plm->burstLen;
3130 params.desired_tx_pwr = plm->desiredTxPwr;
3131 params.plm_num_ch = plm->plmNumCh;
3132 params.session_id = plm->sessionId;
3133 params.enable = plm->enable;
3134 qdf_mem_copy(&params.mac_addr, &plm->mac_addr,
3135 sizeof(struct qdf_mac_addr));
3136 qdf_mem_copy(params.plm_ch_list, plm->plmChList,
3137 WMI_CFG_VALID_CHANNEL_LIST_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003138
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303139 status = wmi_unified_plm_stop_cmd(wma->wmi_handle,
3140 &params);
3141 if (QDF_IS_STATUS_ERROR(status))
3142 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003143
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003144 wma->interfaces[plm->sessionId].plm_in_progress = false;
3145
3146 WMA_LOGD("Plm stop request sent successfully for vdev %d",
3147 plm->sessionId);
3148
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05303149 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003150}
3151
3152/**
3153 * wma_config_plm()- config PLM
3154 * @wma: wma handle
3155 * @plm: plm request parameters
3156 *
3157 * Return: none
3158 */
3159void wma_config_plm(tp_wma_handle wma, tpSirPlmReq plm)
3160{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303161 QDF_STATUS ret = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003162
3163 if (NULL == plm || NULL == wma)
3164 return;
3165
3166 if (plm->enable)
3167 ret = wma_plm_start(wma, plm);
3168 else
3169 ret = wma_plm_stop(wma, plm);
3170
3171 if (ret)
3172 WMA_LOGE("%s: PLM %s failed %d", __func__,
3173 plm->enable ? "start" : "stop", ret);
3174
3175 /* SME expects WMA to free tpSirPlmReq memory after
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003176 * processing PLM request.
3177 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303178 qdf_mem_free(plm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003179 plm = NULL;
3180}
3181#endif
3182
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003183#ifdef FEATURE_WLAN_EXTSCAN
3184/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003185 * wma_extscan_wow_event_callback() - extscan wow event callback
3186 * @handle: WMA handle
3187 * @event: event buffer
3188 * @len: length of @event buffer
3189 *
3190 * In wow case, the wow event is followed by the payload of the event
3191 * which generated the wow event.
3192 * payload is 4 bytes of length followed by event buffer. the first 4 bytes
3193 * of event buffer is common tlv header, which is a combination
3194 * of tag (higher 2 bytes) and length (lower 2 bytes). The tag is used to
3195 * identify the event which triggered wow event.
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003196 * Payload is extracted and converted into generic tlv structure before
3197 * being passed to this function.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003198 *
Dustin Browne2206fb2017-04-20 13:39:25 -07003199 * @Return: Errno
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003200 */
Dustin Browne2206fb2017-04-20 13:39:25 -07003201int wma_extscan_wow_event_callback(void *handle, void *event, uint32_t len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003202{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003203 uint32_t tag = WMITLV_GET_TLVTAG(WMITLV_GET_HDR(event));
3204
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003205 switch (tag) {
3206 case WMITLV_TAG_STRUC_wmi_extscan_start_stop_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003207 return wma_extscan_start_stop_event_handler(handle, event, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003208
3209 case WMITLV_TAG_STRUC_wmi_extscan_operation_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003210 return wma_extscan_operations_event_handler(handle, event, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003211
3212 case WMITLV_TAG_STRUC_wmi_extscan_table_usage_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003213 return wma_extscan_table_usage_event_handler(handle, event,
3214 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003215
3216 case WMITLV_TAG_STRUC_wmi_extscan_cached_results_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003217 return wma_extscan_cached_results_event_handler(handle, event,
3218 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219
3220 case WMITLV_TAG_STRUC_wmi_extscan_wlan_change_results_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003221 return wma_extscan_change_results_event_handler(handle, event,
3222 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003223
3224 case WMITLV_TAG_STRUC_wmi_extscan_hotlist_match_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003225 return wma_extscan_hotlist_match_event_handler(handle, event,
3226 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003227
3228 case WMITLV_TAG_STRUC_wmi_extscan_capabilities_event_fixed_param:
Dustin Browne2206fb2017-04-20 13:39:25 -07003229 return wma_extscan_capabilities_event_handler(handle, event,
3230 len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003231
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003232 default:
Krishna Kumaar Natarajan36e5aa02016-07-02 17:44:25 -07003233 WMA_LOGE(FL("Unknown tag: %d"), tag);
Dustin Browne2206fb2017-04-20 13:39:25 -07003234 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003235 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003236}
3237#endif
3238
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003239/**
3240 * wma_register_extscan_event_handler() - register extscan event handler
3241 * @wma_handle: wma handle
3242 *
3243 * This function register extscan related event handlers.
3244 *
3245 * Return: none
3246 */
3247void wma_register_extscan_event_handler(tp_wma_handle wma_handle)
3248{
3249 if (!wma_handle) {
3250 WMA_LOGE("%s: extscan wma_handle is NULL", __func__);
3251 return;
3252 }
3253 wmi_unified_register_event_handler(wma_handle->wmi_handle,
3254 WMI_EXTSCAN_START_STOP_EVENTID,
Govind Singhd76a5b02016-03-08 15:12:14 +05303255 wma_extscan_start_stop_event_handler,
3256 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003257
3258 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303259 WMI_EXTSCAN_CAPABILITIES_EVENTID,
3260 wma_extscan_capabilities_event_handler,
3261 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003262
3263 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303264 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID,
3265 wma_extscan_hotlist_match_event_handler,
3266 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267
3268 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303269 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID,
3270 wma_extscan_change_results_event_handler,
3271 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003272
3273 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303274 WMI_EXTSCAN_OPERATION_EVENTID,
3275 wma_extscan_operations_event_handler,
3276 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303278 WMI_EXTSCAN_TABLE_USAGE_EVENTID,
3279 wma_extscan_table_usage_event_handler,
3280 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003281
3282 wmi_unified_register_event_handler(wma_handle->wmi_handle,
Govind Singhd76a5b02016-03-08 15:12:14 +05303283 WMI_EXTSCAN_CACHED_RESULTS_EVENTID,
3284 wma_extscan_cached_results_event_handler,
3285 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003286
3287 wmi_unified_register_event_handler(wma_handle->wmi_handle,
3288 WMI_PASSPOINT_MATCH_EVENTID,
Govind Singhd76a5b02016-03-08 15:12:14 +05303289 wma_passpoint_match_event_handler,
3290 WMA_RX_SERIALIZER_CTX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003291}
3292
3293#ifdef FEATURE_WLAN_EXTSCAN
3294
3295/**
3296 * wma_extscan_start_stop_event_handler() - extscan start/stop event handler
3297 * @handle: wma handle
3298 * @cmd_param_info: event buffer
3299 * @len: data length
3300 *
3301 * This function handles different extscan related commands
3302 * like start/stop/get results etc and indicate to upper layers.
3303 *
3304 * Return: 0 for success or error code.
3305 */
3306int wma_extscan_start_stop_event_handler(void *handle,
3307 uint8_t *cmd_param_info,
3308 uint32_t len)
3309{
3310 WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *param_buf;
3311 wmi_extscan_start_stop_event_fixed_param *event;
3312 struct sir_extscan_generic_response *extscan_ind;
3313 uint16_t event_type;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303314 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003315
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003316 if (!pMac) {
3317 WMA_LOGE("%s: Invalid pMac", __func__);
3318 return -EINVAL;
3319 }
3320 if (!pMac->sme.pExtScanIndCb) {
3321 WMA_LOGE("%s: Callback not registered", __func__);
3322 return -EINVAL;
3323 }
3324 param_buf = (WMI_EXTSCAN_START_STOP_EVENTID_param_tlvs *)
3325 cmd_param_info;
3326 if (!param_buf) {
3327 WMA_LOGE("%s: Invalid extscan event", __func__);
3328 return -EINVAL;
3329 }
3330 event = param_buf->fixed_param;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303331 extscan_ind = qdf_mem_malloc(sizeof(*extscan_ind));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003332 if (!extscan_ind) {
3333 WMA_LOGE("%s: extscan memory allocation failed", __func__);
3334 return -ENOMEM;
3335 }
3336 switch (event->command) {
3337 case WMI_EXTSCAN_START_CMDID:
3338 event_type = eSIR_EXTSCAN_START_RSP;
3339 extscan_ind->status = event->status;
3340 extscan_ind->request_id = event->request_id;
3341 break;
3342 case WMI_EXTSCAN_STOP_CMDID:
3343 event_type = eSIR_EXTSCAN_STOP_RSP;
3344 extscan_ind->status = event->status;
3345 extscan_ind->request_id = event->request_id;
3346 break;
3347 case WMI_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID:
3348 extscan_ind->status = event->status;
3349 extscan_ind->request_id = event->request_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003350 if (event->mode == WMI_EXTSCAN_MODE_STOP)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003351 event_type =
3352 eSIR_EXTSCAN_RESET_SIGNIFICANT_WIFI_CHANGE_RSP;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003353 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003354 event_type =
3355 eSIR_EXTSCAN_SET_SIGNIFICANT_WIFI_CHANGE_RSP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003356 break;
3357 case WMI_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID:
3358 extscan_ind->status = event->status;
3359 extscan_ind->request_id = event->request_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003360 if (event->mode == WMI_EXTSCAN_MODE_STOP)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003361 event_type = eSIR_EXTSCAN_RESET_BSSID_HOTLIST_RSP;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003362 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003363 event_type = eSIR_EXTSCAN_SET_BSSID_HOTLIST_RSP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003364 break;
3365 case WMI_EXTSCAN_GET_CACHED_RESULTS_CMDID:
3366 extscan_ind->status = event->status;
3367 extscan_ind->request_id = event->request_id;
3368 event_type = eSIR_EXTSCAN_CACHED_RESULTS_RSP;
3369 break;
3370 case WMI_EXTSCAN_CONFIGURE_HOTLIST_SSID_MONITOR_CMDID:
3371 extscan_ind->status = event->status;
3372 extscan_ind->request_id = event->request_id;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003373 if (event->mode == WMI_EXTSCAN_MODE_STOP)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003374 event_type =
3375 eSIR_EXTSCAN_RESET_SSID_HOTLIST_RSP;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003376 else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003377 event_type =
3378 eSIR_EXTSCAN_SET_SSID_HOTLIST_RSP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003379 break;
3380 default:
3381 WMA_LOGE("%s: Unknown event(%d) from target",
3382 __func__, event->status);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303383 qdf_mem_free(extscan_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003384 return -EINVAL;
3385 }
3386 pMac->sme.pExtScanIndCb(pMac->hHdd, event_type, extscan_ind);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003387 WMA_LOGD("%s: sending event to umac for requestid %u with status %d",
3388 __func__, extscan_ind->request_id, extscan_ind->status);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303389 qdf_mem_free(extscan_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003390 return 0;
3391}
3392
3393/**
3394 * wma_extscan_operations_event_handler() - extscan operation event handler
3395 * @handle: wma handle
3396 * @cmd_param_info: event buffer
3397 * @len: length
3398 *
3399 * This function handles different operations related event and indicate
3400 * upper layers with appropriate callback.
3401 *
3402 * Return: 0 for success or error code.
3403 */
3404int wma_extscan_operations_event_handler(void *handle,
3405 uint8_t *cmd_param_info,
3406 uint32_t len)
3407{
3408 tp_wma_handle wma = (tp_wma_handle) handle;
3409 WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *param_buf;
3410 wmi_extscan_operation_event_fixed_param *oprn_event;
3411 tSirExtScanOnScanEventIndParams *oprn_ind;
Mukul Sharmafa937be2016-08-12 18:13:36 +05303412 uint32_t cnt;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303413 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003414
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003415 if (!pMac) {
3416 WMA_LOGE("%s: Invalid pMac", __func__);
3417 return -EINVAL;
3418 }
3419 if (!pMac->sme.pExtScanIndCb) {
3420 WMA_LOGE("%s: Callback not registered", __func__);
3421 return -EINVAL;
3422 }
3423 param_buf = (WMI_EXTSCAN_OPERATION_EVENTID_param_tlvs *)
3424 cmd_param_info;
3425 if (!param_buf) {
3426 WMA_LOGE("%s: Invalid scan operation event", __func__);
3427 return -EINVAL;
3428 }
3429 oprn_event = param_buf->fixed_param;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303430 oprn_ind = qdf_mem_malloc(sizeof(*oprn_ind));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003431 if (!oprn_ind) {
3432 WMA_LOGE("%s: extscan memory allocation failed", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303433 qdf_mem_free(oprn_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003434 return -ENOMEM;
3435 }
3436
3437 oprn_ind->requestId = oprn_event->request_id;
3438
3439 switch (oprn_event->event) {
3440 case WMI_EXTSCAN_BUCKET_COMPLETED_EVENT:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003441 oprn_ind->status = 0;
Mukul Sharma45114d92016-08-12 19:34:14 +05303442 goto exit_handler;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003443 case WMI_EXTSCAN_CYCLE_STARTED_EVENT:
3444 WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_STARTED_EVENT",
3445 __func__);
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303446 cds_host_diag_log_work(&wma->extscan_wake_lock,
3447 WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION,
3448 WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303449 qdf_wake_lock_timeout_acquire(&wma->extscan_wake_lock,
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05303450 WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION);
Mukul Sharmafa937be2016-08-12 18:13:36 +05303451 oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_STARTED_EVENT;
3452 oprn_ind->status = 0;
3453 oprn_ind->buckets_scanned = 0;
3454 for (cnt = 0; cnt < oprn_event->num_buckets; cnt++)
3455 oprn_ind->buckets_scanned |=
3456 (1 << param_buf->bucket_id[cnt]);
3457 WMA_LOGD(FL("num_buckets %u request_id %u buckets_scanned %u"),
3458 oprn_event->num_buckets, oprn_ind->requestId,
3459 oprn_ind->buckets_scanned);
3460 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003461 case WMI_EXTSCAN_CYCLE_COMPLETED_EVENT:
3462 WMA_LOGD("%s: received WMI_EXTSCAN_CYCLE_COMPLETED_EVENT",
3463 __func__);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05303464 qdf_wake_lock_release(&wma->extscan_wake_lock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003465 WIFI_POWER_EVENT_WAKELOCK_EXT_SCAN);
Mukul Sharmafa937be2016-08-12 18:13:36 +05303466 oprn_ind->scanEventType = WIFI_EXTSCAN_CYCLE_COMPLETED_EVENT;
3467 oprn_ind->status = 0;
3468 /* Set bucket scanned mask to zero on cycle complete */
3469 oprn_ind->buckets_scanned = 0;
3470 break;
3471 case WMI_EXTSCAN_BUCKET_STARTED_EVENT:
Mukul Sharma45114d92016-08-12 19:34:14 +05303472 WMA_LOGD("%s: received WMI_EXTSCAN_BUCKET_STARTED_EVENT",
Mukul Sharmafa937be2016-08-12 18:13:36 +05303473 __func__);
3474 oprn_ind->scanEventType = WIFI_EXTSCAN_BUCKET_STARTED_EVENT;
3475 oprn_ind->status = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003476 goto exit_handler;
Mukul Sharmafa937be2016-08-12 18:13:36 +05303477 case WMI_EXTSCAN_THRESHOLD_NUM_SCANS:
Mukul Sharma45114d92016-08-12 19:34:14 +05303478 WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_NUM_SCANS",
Mukul Sharmafa937be2016-08-12 18:13:36 +05303479 __func__);
3480 oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_NUM_SCANS;
3481 oprn_ind->status = 0;
3482 break;
3483 case WMI_EXTSCAN_THRESHOLD_PERCENT:
Mukul Sharma45114d92016-08-12 19:34:14 +05303484 WMA_LOGD("%s: received WMI_EXTSCAN_THRESHOLD_PERCENT",
Mukul Sharmafa937be2016-08-12 18:13:36 +05303485 __func__);
3486 oprn_ind->scanEventType = WIFI_EXTSCAN_THRESHOLD_PERCENT;
3487 oprn_ind->status = 0;
3488 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003489 default:
3490 WMA_LOGE("%s: Unknown event(%d) from target",
3491 __func__, oprn_event->event);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303492 qdf_mem_free(oprn_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003493 return -EINVAL;
3494 }
3495 pMac->sme.pExtScanIndCb(pMac->hHdd,
3496 eSIR_EXTSCAN_SCAN_PROGRESS_EVENT_IND, oprn_ind);
3497 WMA_LOGI("%s: sending scan progress event to hdd", __func__);
3498exit_handler:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303499 qdf_mem_free(oprn_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003500 return 0;
3501}
3502
3503/**
3504 * wma_extscan_table_usage_event_handler() - extscan table usage event handler
3505 * @handle: wma handle
3506 * @cmd_param_info: event buffer
3507 * @len: length
3508 *
3509 * This function handles table usage related event and indicate
3510 * upper layers with appropriate callback.
3511 *
3512 * Return: 0 for success or error code.
3513 */
3514int wma_extscan_table_usage_event_handler(void *handle,
3515 uint8_t *cmd_param_info,
3516 uint32_t len)
3517{
3518 WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *param_buf;
3519 wmi_extscan_table_usage_event_fixed_param *event;
3520 tSirExtScanResultsAvailableIndParams *tbl_usg_ind;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303521 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003522
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003523 if (!pMac) {
3524 WMA_LOGE("%s: Invalid pMac", __func__);
3525 return -EINVAL;
3526 }
3527 if (!pMac->sme.pExtScanIndCb) {
3528 WMA_LOGE("%s: Callback not registered", __func__);
3529 return -EINVAL;
3530 }
3531 param_buf = (WMI_EXTSCAN_TABLE_USAGE_EVENTID_param_tlvs *)
3532 cmd_param_info;
3533 if (!param_buf) {
3534 WMA_LOGE("%s: Invalid table usage event", __func__);
3535 return -EINVAL;
3536 }
3537 event = param_buf->fixed_param;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303538 tbl_usg_ind = qdf_mem_malloc(sizeof(*tbl_usg_ind));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003539 if (!tbl_usg_ind) {
3540 WMA_LOGE("%s: table usage allocation failed", __func__);
3541 return -ENOMEM;
3542 }
3543 tbl_usg_ind->requestId = event->request_id;
3544 tbl_usg_ind->numResultsAvailable = event->entries_in_use;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003545 pMac->sme.pExtScanIndCb(pMac->hHdd,
3546 eSIR_EXTSCAN_SCAN_RES_AVAILABLE_IND,
3547 tbl_usg_ind);
3548 WMA_LOGI("%s: sending scan_res available event to hdd", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303549 qdf_mem_free(tbl_usg_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003550 return 0;
3551}
3552
3553/**
3554 * wma_extscan_capabilities_event_handler() - extscan capabilities event handler
3555 * @handle: wma handle
3556 * @cmd_param_info: event buffer
3557 * @len: length
3558 *
3559 * This function handles capabilities event and indicate
3560 * upper layers with registered callback.
3561 *
3562 * Return: 0 for success or error code.
3563 */
3564int wma_extscan_capabilities_event_handler(void *handle,
3565 uint8_t *cmd_param_info,
3566 uint32_t len)
3567{
3568 WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *param_buf;
3569 wmi_extscan_capabilities_event_fixed_param *event;
3570 wmi_extscan_cache_capabilities *src_cache;
3571 wmi_extscan_hotlist_monitor_capabilities *src_hotlist;
3572 wmi_extscan_wlan_change_monitor_capabilities *src_change;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003573 struct ext_scan_capabilities_response *dest_capab;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303574 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003575
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003576 if (!pMac) {
3577 WMA_LOGE("%s: Invalid pMac", __func__);
3578 return -EINVAL;
3579 }
3580 if (!pMac->sme.pExtScanIndCb) {
3581 WMA_LOGE("%s: Callback not registered", __func__);
3582 return -EINVAL;
3583 }
3584 param_buf = (WMI_EXTSCAN_CAPABILITIES_EVENTID_param_tlvs *)
3585 cmd_param_info;
3586 if (!param_buf) {
3587 WMA_LOGE("%s: Invalid capabilities event", __func__);
3588 return -EINVAL;
3589 }
3590 event = param_buf->fixed_param;
3591 src_cache = param_buf->extscan_cache_capabilities;
3592 src_hotlist = param_buf->hotlist_capabilities;
3593 src_change = param_buf->wlan_change_capabilities;
3594
3595 if (!src_cache || !src_hotlist || !src_change) {
3596 WMA_LOGE("%s: Invalid capabilities list", __func__);
3597 return -EINVAL;
3598 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303599 dest_capab = qdf_mem_malloc(sizeof(*dest_capab));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003600 if (!dest_capab) {
3601 WMA_LOGE("%s: Allocation failed for capabilities buffer",
3602 __func__);
3603 return -ENOMEM;
3604 }
3605 dest_capab->requestId = event->request_id;
3606 dest_capab->max_scan_buckets = src_cache->max_buckets;
3607 dest_capab->max_scan_cache_size = src_cache->scan_cache_entry_size;
3608 dest_capab->max_ap_cache_per_scan = src_cache->max_bssid_per_scan;
3609 dest_capab->max_scan_reporting_threshold =
3610 src_cache->max_table_usage_threshold;
3611
3612 dest_capab->max_hotlist_bssids = src_hotlist->max_hotlist_entries;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003613 dest_capab->max_rssi_sample_size =
3614 src_change->max_rssi_averaging_samples;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003615 dest_capab->max_bssid_history_entries =
3616 src_change->max_rssi_history_entries;
3617 dest_capab->max_significant_wifi_change_aps =
3618 src_change->max_wlan_change_entries;
3619 dest_capab->max_hotlist_ssids =
3620 event->num_extscan_hotlist_ssid;
3621 dest_capab->max_number_epno_networks =
3622 event->num_epno_networks;
3623 dest_capab->max_number_epno_networks_by_ssid =
3624 event->num_epno_networks;
3625 dest_capab->max_number_of_white_listed_ssid =
3626 event->num_roam_ssid_whitelist;
Padma, Santhosh Kumar1ac02402016-11-02 18:04:14 +05303627 dest_capab->max_number_of_black_listed_bssid =
3628 event->num_roam_bssid_blacklist;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003629 dest_capab->status = 0;
3630
3631 WMA_LOGD("%s: request_id: %u status: %d",
3632 __func__, dest_capab->requestId, dest_capab->status);
3633
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003634 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 -08003635 __func__, dest_capab->max_scan_buckets,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003636 dest_capab->max_hotlist_bssids, dest_capab->max_scan_cache_size,
3637 dest_capab->max_ap_cache_per_scan);
3638 WMA_LOGD("%s: max_scan_reporting_threshold: %d, max_rssi_sample_size: %d, max_bssid_history_entries: %d, max_significant_wifi_change_aps: %d",
3639 __func__, dest_capab->max_scan_reporting_threshold,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003640 dest_capab->max_rssi_sample_size,
3641 dest_capab->max_bssid_history_entries,
3642 dest_capab->max_significant_wifi_change_aps);
3643
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003644 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 -08003645 __func__, dest_capab->max_hotlist_ssids,
3646 dest_capab->max_number_epno_networks,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003647 dest_capab->max_number_epno_networks_by_ssid);
3648 WMA_LOGD("%s: max_number_of_white_listed_ssid: %d, max_number_of_black_listed_bssid: %d",
3649 __func__, dest_capab->max_number_of_white_listed_ssid,
Padma, Santhosh Kumar1ac02402016-11-02 18:04:14 +05303650 dest_capab->max_number_of_black_listed_bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003651
3652 pMac->sme.pExtScanIndCb(pMac->hHdd,
3653 eSIR_EXTSCAN_GET_CAPABILITIES_IND, dest_capab);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303654 qdf_mem_free(dest_capab);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003655 return 0;
3656}
3657
3658/**
3659 * wma_extscan_hotlist_match_event_handler() - hotlist match event handler
3660 * @handle: wma handle
3661 * @cmd_param_info: event buffer
3662 * @len: length
3663 *
3664 * This function handles hotlist match event and indicate
3665 * upper layers with registered callback.
3666 *
3667 * Return: 0 for success or error code.
3668 */
3669int wma_extscan_hotlist_match_event_handler(void *handle,
3670 uint8_t *cmd_param_info,
3671 uint32_t len)
3672{
3673 WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *param_buf;
3674 wmi_extscan_hotlist_match_event_fixed_param *event;
3675 struct extscan_hotlist_match *dest_hotlist;
3676 tSirWifiScanResult *dest_ap;
3677 wmi_extscan_wlan_descriptor *src_hotlist;
3678 int numap, j, ap_found = 0;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303679 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003680
3681 if (!pMac) {
3682 WMA_LOGE("%s: Invalid pMac", __func__);
3683 return -EINVAL;
3684 }
3685 if (!pMac->sme.pExtScanIndCb) {
3686 WMA_LOGE("%s: Callback not registered", __func__);
3687 return -EINVAL;
3688 }
3689 param_buf = (WMI_EXTSCAN_HOTLIST_MATCH_EVENTID_param_tlvs *)
3690 cmd_param_info;
3691 if (!param_buf) {
3692 WMA_LOGE("%s: Invalid hotlist match event", __func__);
3693 return -EINVAL;
3694 }
3695 event = param_buf->fixed_param;
3696 src_hotlist = param_buf->hotlist_match;
3697 numap = event->total_entries;
3698
3699 if (!src_hotlist || !numap) {
3700 WMA_LOGE("%s: Hotlist AP's list invalid", __func__);
3701 return -EINVAL;
3702 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303703 dest_hotlist = qdf_mem_malloc(sizeof(*dest_hotlist) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003704 sizeof(*dest_ap) * numap);
3705 if (!dest_hotlist) {
3706 WMA_LOGE("%s: Allocation failed for hotlist buffer", __func__);
3707 return -ENOMEM;
3708 }
3709 dest_ap = &dest_hotlist->ap[0];
3710 dest_hotlist->numOfAps = event->total_entries;
3711 dest_hotlist->requestId = event->config_request_id;
3712
3713 if (event->first_entry_index +
3714 event->num_entries_in_page < event->total_entries)
3715 dest_hotlist->moreData = 1;
3716 else
3717 dest_hotlist->moreData = 0;
3718
3719 WMA_LOGD("%s: Hotlist match: requestId: %u,"
3720 "numOfAps: %d", __func__,
3721 dest_hotlist->requestId, dest_hotlist->numOfAps);
3722
3723 /*
3724 * Currently firmware sends only one bss information in-case
3725 * of both hotlist ap found and lost.
3726 */
3727 for (j = 0; j < numap; j++) {
3728 dest_ap->rssi = 0;
3729 dest_ap->channel = src_hotlist->channel;
3730 dest_ap->ts = src_hotlist->tstamp;
3731 ap_found = src_hotlist->flags & WMI_HOTLIST_FLAG_PRESENCE;
3732 dest_ap->rtt = src_hotlist->rtt;
3733 dest_ap->rtt_sd = src_hotlist->rtt_sd;
3734 dest_ap->beaconPeriod = src_hotlist->beacon_interval;
3735 dest_ap->capability = src_hotlist->capabilities;
3736 dest_ap->ieLength = src_hotlist->ie_length;
3737 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid,
3738 dest_ap->bssid.bytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303739 qdf_mem_copy(dest_ap->ssid, src_hotlist->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003740 src_hotlist->ssid.ssid_len);
3741 dest_ap->ssid[src_hotlist->ssid.ssid_len] = '\0';
3742 dest_ap++;
3743 src_hotlist++;
3744 }
3745 dest_hotlist->ap_found = ap_found;
3746 pMac->sme.pExtScanIndCb(pMac->hHdd,
3747 eSIR_EXTSCAN_HOTLIST_MATCH_IND, dest_hotlist);
3748 WMA_LOGI("%s: sending hotlist match event to hdd", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303749 qdf_mem_free(dest_hotlist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003750 return 0;
3751}
3752
3753/** wma_extscan_find_unique_scan_ids() - find unique scan ids
3754 * @cmd_param_info: event data.
3755 *
3756 * This utility function parses the input bss table of information
3757 * and find the unique number of scan ids
3758 *
3759 * Return: 0 on success; error number otherwise
3760 */
3761static int wma_extscan_find_unique_scan_ids(const u_int8_t *cmd_param_info)
3762{
3763 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
3764 wmi_extscan_cached_results_event_fixed_param *event;
3765 wmi_extscan_wlan_descriptor *src_hotlist;
3766 wmi_extscan_rssi_info *src_rssi;
3767 int prev_scan_id, scan_ids_cnt, i;
3768
3769 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
3770 cmd_param_info;
3771 event = param_buf->fixed_param;
3772 src_hotlist = param_buf->bssid_list;
3773 src_rssi = param_buf->rssi_list;
3774
3775 /* Find the unique number of scan_id's for grouping */
3776 prev_scan_id = src_rssi->scan_cycle_id;
3777 scan_ids_cnt = 1;
3778 for (i = 1; i < event->num_entries_in_page; i++) {
3779 src_rssi++;
3780
3781 if (prev_scan_id != src_rssi->scan_cycle_id) {
3782 scan_ids_cnt++;
3783 prev_scan_id = src_rssi->scan_cycle_id;
3784 }
3785 }
3786
3787 return scan_ids_cnt;
3788}
3789
3790/** wma_fill_num_results_per_scan_id() - fill number of bss per scan id
3791 * @cmd_param_info: event data.
3792 * @scan_id_group: pointer to scan id group.
3793 *
3794 * This utility function parses the input bss table of information
3795 * and finds how many bss are there per unique scan id.
3796 *
3797 * Return: 0 on success; error number otherwise
3798 */
3799static int wma_fill_num_results_per_scan_id(const u_int8_t *cmd_param_info,
3800 struct extscan_cached_scan_result *scan_id_group)
3801{
3802 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
3803 wmi_extscan_cached_results_event_fixed_param *event;
3804 wmi_extscan_wlan_descriptor *src_hotlist;
3805 wmi_extscan_rssi_info *src_rssi;
3806 struct extscan_cached_scan_result *t_scan_id_grp;
3807 int i, prev_scan_id;
3808
3809 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
3810 cmd_param_info;
3811 event = param_buf->fixed_param;
3812 src_hotlist = param_buf->bssid_list;
3813 src_rssi = param_buf->rssi_list;
3814 t_scan_id_grp = scan_id_group;
3815
3816 prev_scan_id = src_rssi->scan_cycle_id;
3817
3818 t_scan_id_grp->scan_id = src_rssi->scan_cycle_id;
3819 t_scan_id_grp->flags = src_rssi->flags;
Mukul Sharmaf7cb3ab2016-08-12 19:53:52 +05303820 t_scan_id_grp->buckets_scanned = src_rssi->buckets_scanned;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003821 t_scan_id_grp->num_results = 1;
3822 for (i = 1; i < event->num_entries_in_page; i++) {
3823 src_rssi++;
3824 if (prev_scan_id == src_rssi->scan_cycle_id) {
3825 t_scan_id_grp->num_results++;
3826 } else {
3827 t_scan_id_grp++;
3828 prev_scan_id = t_scan_id_grp->scan_id =
3829 src_rssi->scan_cycle_id;
3830 t_scan_id_grp->flags = src_rssi->flags;
Mukul Sharmaf7cb3ab2016-08-12 19:53:52 +05303831 t_scan_id_grp->buckets_scanned =
3832 src_rssi->buckets_scanned;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003833 t_scan_id_grp->num_results = 1;
3834 }
3835 }
3836 return 0;
3837}
3838
3839/** wma_group_num_bss_to_scan_id() - group bss to scan id table
3840 * @cmd_param_info: event data.
3841 * @cached_result: pointer to cached table.
3842 *
3843 * This function reads the bss information from the format
3844 * ------------------------------------------------------------------------
3845 * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_1 | flags |
3846 * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_2 | flags |
3847 * ........................................................................
3848 * | bss info {rssi, channel, ssid, bssid, timestamp} | scan id_N | flags |
3849 * ------------------------------------------------------------------------
3850 *
3851 * and converts it into the below format and store it
3852 *
3853 * ------------------------------------------------------------------------
3854 * | scan id_1 | -> bss info_1 -> bss info_2 -> .... bss info_M1
3855 * | scan id_2 | -> bss info_1 -> bss info_2 -> .... bss info_M2
3856 * ......................
3857 * | scan id_N | -> bss info_1 -> bss info_2 -> .... bss info_Mn
3858 * ------------------------------------------------------------------------
3859 *
3860 * Return: 0 on success; error number otherwise
3861 */
3862static int wma_group_num_bss_to_scan_id(const u_int8_t *cmd_param_info,
3863 struct extscan_cached_scan_results *cached_result)
3864{
3865 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
3866 wmi_extscan_cached_results_event_fixed_param *event;
3867 wmi_extscan_wlan_descriptor *src_hotlist;
3868 wmi_extscan_rssi_info *src_rssi;
3869 struct extscan_cached_scan_results *t_cached_result;
3870 struct extscan_cached_scan_result *t_scan_id_grp;
3871 int i, j;
3872 tSirWifiScanResult *ap;
3873
3874 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
3875 cmd_param_info;
3876 event = param_buf->fixed_param;
3877 src_hotlist = param_buf->bssid_list;
3878 src_rssi = param_buf->rssi_list;
3879 t_cached_result = cached_result;
3880 t_scan_id_grp = &t_cached_result->result[0];
3881
3882 WMA_LOGD("%s: num_scan_ids:%d", __func__,
3883 t_cached_result->num_scan_ids);
3884 for (i = 0; i < t_cached_result->num_scan_ids; i++) {
3885 WMA_LOGD("%s: num_results:%d", __func__,
3886 t_scan_id_grp->num_results);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303887 t_scan_id_grp->ap = qdf_mem_malloc(t_scan_id_grp->num_results *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003888 sizeof(*ap));
3889 if (!t_scan_id_grp->ap) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303890 WMA_LOGD("%s: qdf_mem_malloc failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003891 return -ENOMEM;
3892 }
3893
3894 ap = &t_scan_id_grp->ap[0];
3895 for (j = 0; j < t_scan_id_grp->num_results; j++) {
3896 ap->channel = src_hotlist->channel;
3897 ap->ts = WMA_MSEC_TO_USEC(src_rssi->tstamp);
3898 ap->rtt = src_hotlist->rtt;
3899 ap->rtt_sd = src_hotlist->rtt_sd;
3900 ap->beaconPeriod = src_hotlist->beacon_interval;
3901 ap->capability = src_hotlist->capabilities;
3902 ap->ieLength = src_hotlist->ie_length;
3903
3904 /* Firmware already applied noise floor adjustment and
3905 * due to WMI interface "UINT32 rssi", host driver
3906 * receives a positive value, hence convert to
3907 * signed char to get the absolute rssi.
3908 */
3909 ap->rssi = (signed char) src_rssi->rssi;
3910 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_hotlist->bssid,
3911 ap->bssid.bytes);
3912
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303913 qdf_mem_copy(ap->ssid, src_hotlist->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003914 src_hotlist->ssid.ssid_len);
3915 ap->ssid[src_hotlist->ssid.ssid_len] = '\0';
3916 ap++;
3917 src_rssi++;
3918 src_hotlist++;
3919 }
3920 t_scan_id_grp++;
3921 }
3922 return 0;
3923}
3924
3925/**
3926 * wma_extscan_cached_results_event_handler() - cached results event handler
3927 * @handle: wma handle
3928 * @cmd_param_info: event buffer
3929 * @len: length of @cmd_param_info
3930 *
3931 * This function handles cached results event and indicate
3932 * cached results to upper layer.
3933 *
3934 * Return: 0 for success or error code.
3935 */
3936int wma_extscan_cached_results_event_handler(void *handle,
3937 uint8_t *cmd_param_info,
3938 uint32_t len)
3939{
3940 WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *param_buf;
3941 wmi_extscan_cached_results_event_fixed_param *event;
3942 struct extscan_cached_scan_results *dest_cachelist;
3943 struct extscan_cached_scan_result *dest_result;
3944 struct extscan_cached_scan_results empty_cachelist;
3945 wmi_extscan_wlan_descriptor *src_hotlist;
3946 wmi_extscan_rssi_info *src_rssi;
3947 int numap, i, moredata, scan_ids_cnt, buf_len;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303948 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07003949
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003950 if (!pMac) {
3951 WMA_LOGE("%s: Invalid pMac", __func__);
3952 return -EINVAL;
3953 }
3954 if (!pMac->sme.pExtScanIndCb) {
3955 WMA_LOGE("%s: Callback not registered", __func__);
3956 return -EINVAL;
3957 }
3958 param_buf = (WMI_EXTSCAN_CACHED_RESULTS_EVENTID_param_tlvs *)
3959 cmd_param_info;
3960 if (!param_buf) {
3961 WMA_LOGE("%s: Invalid cached results event", __func__);
3962 return -EINVAL;
3963 }
3964 event = param_buf->fixed_param;
3965 src_hotlist = param_buf->bssid_list;
3966 src_rssi = param_buf->rssi_list;
3967 numap = event->num_entries_in_page;
Srinivas Girigowdadbfb2642016-08-28 21:32:38 -07003968 WMA_LOGI("Total_entries: %u first_entry_index: %u num_entries_in_page: %d",
3969 event->total_entries,
3970 event->first_entry_index, numap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971 if (!src_hotlist || !src_rssi || !numap) {
Srinivas Girigowdaf2599dd2015-11-16 18:20:46 -08003972 WMA_LOGW("%s: Cached results empty, send 0 results", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003973 goto noresults;
3974 }
3975 if (event->first_entry_index +
3976 event->num_entries_in_page < event->total_entries)
3977 moredata = 1;
3978 else
3979 moredata = 0;
3980
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303981 dest_cachelist = qdf_mem_malloc(sizeof(*dest_cachelist));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003982 if (!dest_cachelist) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303983 WMA_LOGE("%s: qdf_mem_malloc failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003984 return -ENOMEM;
3985 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303986 qdf_mem_zero(dest_cachelist, sizeof(*dest_cachelist));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003987 dest_cachelist->request_id = event->request_id;
3988 dest_cachelist->more_data = moredata;
3989
3990 scan_ids_cnt = wma_extscan_find_unique_scan_ids(cmd_param_info);
3991 WMA_LOGI("%s: scan_ids_cnt %d", __func__, scan_ids_cnt);
3992 dest_cachelist->num_scan_ids = scan_ids_cnt;
3993
3994 buf_len = sizeof(*dest_result) * scan_ids_cnt;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303995 dest_cachelist->result = qdf_mem_malloc(buf_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003996 if (!dest_cachelist->result) {
3997 WMA_LOGE("%s: Allocation failed for scanid grouping", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303998 qdf_mem_free(dest_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003999 return -ENOMEM;
4000 }
4001
4002 dest_result = dest_cachelist->result;
4003 wma_fill_num_results_per_scan_id(cmd_param_info, dest_result);
4004 wma_group_num_bss_to_scan_id(cmd_param_info, dest_cachelist);
4005
4006 pMac->sme.pExtScanIndCb(pMac->hHdd,
4007 eSIR_EXTSCAN_CACHED_RESULTS_IND,
4008 dest_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004009 dest_result = dest_cachelist->result;
4010 for (i = 0; i < dest_cachelist->num_scan_ids; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304011 qdf_mem_free(dest_result->ap);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004012 dest_result++;
4013 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304014 qdf_mem_free(dest_cachelist->result);
4015 qdf_mem_free(dest_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004016 return 0;
4017
4018noresults:
4019 empty_cachelist.request_id = event->request_id;
4020 empty_cachelist.more_data = 0;
4021 empty_cachelist.num_scan_ids = 0;
4022
4023 pMac->sme.pExtScanIndCb(pMac->hHdd,
4024 eSIR_EXTSCAN_CACHED_RESULTS_IND,
4025 &empty_cachelist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004026 return 0;
4027}
4028
4029/**
4030 * wma_extscan_change_results_event_handler() - change results event handler
4031 * @handle: wma handle
4032 * @cmd_param_info: event buffer
4033 * @len: length
4034 *
4035 * This function handles change results event and indicate
4036 * change results to upper layer.
4037 *
4038 * Return: 0 for success or error code.
4039 */
4040int wma_extscan_change_results_event_handler(void *handle,
4041 uint8_t *cmd_param_info,
4042 uint32_t len)
4043{
4044 WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *param_buf;
4045 wmi_extscan_wlan_change_results_event_fixed_param *event;
4046 tSirWifiSignificantChangeEvent *dest_chglist;
4047 tSirWifiSignificantChange *dest_ap;
4048 wmi_extscan_wlan_change_result_bssid *src_chglist;
4049
4050 int numap;
4051 int i, k;
4052 uint8_t *src_rssi;
4053 int count = 0;
4054 int moredata;
4055 int rssi_num = 0;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304056 tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE);
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004057
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004058 if (!pMac) {
4059 WMA_LOGE("%s: Invalid pMac", __func__);
4060 return -EINVAL;
4061 }
4062 if (!pMac->sme.pExtScanIndCb) {
4063 WMA_LOGE("%s: Callback not registered", __func__);
4064 return -EINVAL;
4065 }
4066 param_buf = (WMI_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID_param_tlvs *)
4067 cmd_param_info;
4068 if (!param_buf) {
4069 WMA_LOGE("%s: Invalid change monitor event", __func__);
4070 return -EINVAL;
4071 }
4072 event = param_buf->fixed_param;
4073 src_chglist = param_buf->bssid_signal_descriptor_list;
4074 src_rssi = param_buf->rssi_list;
4075 numap = event->num_entries_in_page;
4076
4077 if (!src_chglist || !numap) {
4078 WMA_LOGE("%s: Results invalid", __func__);
4079 return -EINVAL;
4080 }
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004081 for (i = 0; i < numap; i++)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082 rssi_num += src_chglist->num_rssi_samples;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004083
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004084 if (event->first_entry_index +
4085 event->num_entries_in_page < event->total_entries) {
4086 moredata = 1;
4087 } else {
4088 moredata = 0;
4089 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304090 dest_chglist = qdf_mem_malloc(sizeof(*dest_chglist) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004091 sizeof(*dest_ap) * numap +
4092 sizeof(int32_t) * rssi_num);
4093 if (!dest_chglist) {
4094 WMA_LOGE("%s: Allocation failed for change monitor", __func__);
4095 return -ENOMEM;
4096 }
4097 dest_ap = &dest_chglist->ap[0];
4098 for (i = 0; i < numap; i++) {
4099 dest_ap->channel = src_chglist->channel;
4100 WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_chglist->bssid,
4101 dest_ap->bssid.bytes);
4102 dest_ap->numOfRssi = src_chglist->num_rssi_samples;
4103 if (dest_ap->numOfRssi) {
4104 for (k = 0; k < dest_ap->numOfRssi; k++) {
4105 dest_ap->rssi[k] = WMA_TGT_NOISE_FLOOR_DBM +
4106 src_rssi[count++];
4107 }
4108 }
4109 dest_ap += dest_ap->numOfRssi * sizeof(int32_t);
4110 src_chglist++;
4111 }
4112 dest_chglist->requestId = event->request_id;
4113 dest_chglist->moreData = moredata;
4114 dest_chglist->numResults = event->total_entries;
4115
4116 pMac->sme.pExtScanIndCb(pMac->hHdd,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004117 eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND,
4118 dest_chglist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004119 WMA_LOGI("%s: sending change monitor results", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304120 qdf_mem_free(dest_chglist);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004121 return 0;
4122}
4123
4124/**
4125 * wma_passpoint_match_event_handler() - passpoint match found event handler
4126 * @handle: WMA handle
4127 * @cmd_param_info: event data
4128 * @len: event data length
4129 *
4130 * This is the passpoint match found event handler; it reads event data from
4131 * @cmd_param_info and fill in the destination buffer and sends indication
4132 * up layer.
4133 *
4134 * Return: 0 on success; error number otherwise
4135 */
4136int wma_passpoint_match_event_handler(void *handle,
4137 uint8_t *cmd_param_info,
4138 uint32_t len)
4139{
4140 WMI_PASSPOINT_MATCH_EVENTID_param_tlvs *param_buf;
4141 wmi_passpoint_event_hdr *event;
4142 struct wifi_passpoint_match *dest_match;
4143 tSirWifiScanResult *dest_ap;
4144 uint8_t *buf_ptr;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304145 tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004146
4147 if (!mac) {
4148 WMA_LOGE("%s: Invalid mac", __func__);
4149 return -EINVAL;
4150 }
4151 if (!mac->sme.pExtScanIndCb) {
4152 WMA_LOGE("%s: Callback not registered", __func__);
4153 return -EINVAL;
4154 }
4155
4156 param_buf = (WMI_PASSPOINT_MATCH_EVENTID_param_tlvs *) cmd_param_info;
4157 if (!param_buf) {
4158 WMA_LOGE("%s: Invalid passpoint match event", __func__);
4159 return -EINVAL;
4160 }
4161 event = param_buf->fixed_param;
4162 buf_ptr = (uint8_t *)param_buf->fixed_param;
4163
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304164 dest_match = qdf_mem_malloc(sizeof(*dest_match) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004165 event->ie_length + event->anqp_length);
4166 if (!dest_match) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304167 WMA_LOGE("%s: qdf_mem_malloc failed", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004168 return -EINVAL;
4169 }
4170 dest_ap = &dest_match->ap;
4171 dest_match->request_id = 0;
4172 dest_match->id = event->id;
4173 dest_match->anqp_len = event->anqp_length;
4174 WMA_LOGI("%s: passpoint match: id: %u anqp length %u", __func__,
4175 dest_match->id, dest_match->anqp_len);
4176
4177 dest_ap->channel = event->channel_mhz;
4178 dest_ap->ts = event->timestamp;
4179 dest_ap->rtt = event->rtt;
4180 dest_ap->rssi = event->rssi;
4181 dest_ap->rtt_sd = event->rtt_sd;
4182 dest_ap->beaconPeriod = event->beacon_period;
4183 dest_ap->capability = event->capability;
4184 dest_ap->ieLength = event->ie_length;
4185 WMI_MAC_ADDR_TO_CHAR_ARRAY(&event->bssid, dest_ap->bssid.bytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304186 qdf_mem_copy(dest_ap->ssid, event->ssid.ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004187 event->ssid.ssid_len);
4188 dest_ap->ssid[event->ssid.ssid_len] = '\0';
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304189 qdf_mem_copy(dest_ap->ieData, buf_ptr + sizeof(*event) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004190 WMI_TLV_HDR_SIZE, dest_ap->ieLength);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304191 qdf_mem_copy(dest_match->anqp, buf_ptr + sizeof(*event) +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004192 WMI_TLV_HDR_SIZE + dest_ap->ieLength,
4193 dest_match->anqp_len);
4194
4195 mac->sme.pExtScanIndCb(mac->hHdd,
4196 eSIR_PASSPOINT_NETWORK_FOUND_IND,
4197 dest_match);
4198 WMA_LOGI("%s: sending passpoint match event to hdd", __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304199 qdf_mem_free(dest_match);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004200 return 0;
4201}
4202
4203/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004204 * wma_get_buf_extscan_start_cmd() - Fill extscan start request
4205 * @handle: wma handle
4206 * @pstart: scan command request params
4207 * @buf: event buffer
4208 * @buf_len: length of buffer
4209 *
4210 * This function fills individual elements of extscan request and
4211 * TLV for buckets, channel list.
4212 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304213 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004214 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304215QDF_STATUS wma_get_buf_extscan_start_cmd(tp_wma_handle wma_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004216 tSirWifiScanCmdReqParams *pstart,
4217 wmi_buf_t *buf, int *buf_len)
4218{
4219 wmi_extscan_start_cmd_fixed_param *cmd;
4220 wmi_extscan_bucket *dest_blist;
4221 wmi_extscan_bucket_channel *dest_clist;
4222 tSirWifiScanBucketSpec *src_bucket = pstart->buckets;
4223 tSirWifiScanChannelSpec *src_channel = src_bucket->channels;
4224 tSirWifiScanChannelSpec save_channel[WLAN_EXTSCAN_MAX_CHANNELS];
4225
4226 uint8_t *buf_ptr;
4227 int i, k, count = 0;
4228 int len = sizeof(*cmd);
4229 int nbuckets = pstart->numBuckets;
4230 int nchannels = 0;
4231
4232 /* These TLV's are are NULL by default */
4233 uint32_t ie_len_with_pad = 0;
4234 int num_ssid = 0;
4235 int num_bssid = 0;
4236 int ie_len = 0;
4237
4238 uint32_t base_period = pstart->basePeriod;
4239
4240 /* TLV placeholder for ssid_list (NULL) */
4241 len += WMI_TLV_HDR_SIZE;
4242 len += num_ssid * sizeof(wmi_ssid);
4243
4244 /* TLV placeholder for bssid_list (NULL) */
4245 len += WMI_TLV_HDR_SIZE;
4246 len += num_bssid * sizeof(wmi_mac_addr);
4247
4248 /* TLV placeholder for ie_data (NULL) */
4249 len += WMI_TLV_HDR_SIZE;
4250 len += ie_len * sizeof(uint32_t);
4251
4252 /* TLV placeholder for bucket */
4253 len += WMI_TLV_HDR_SIZE;
4254 len += nbuckets * sizeof(wmi_extscan_bucket);
4255
4256 /* TLV channel placeholder */
4257 len += WMI_TLV_HDR_SIZE;
4258 for (i = 0; i < nbuckets; i++) {
4259 nchannels += src_bucket->numChannels;
4260 src_bucket++;
4261 }
4262
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004263 len += nchannels * sizeof(wmi_extscan_bucket_channel);
4264 /* Allocate the memory */
4265 *buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
4266 if (!*buf) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004267 WMA_LOGP("%s: failed to allocate memory for start extscan cmd",
4268 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304269 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004270 }
4271 buf_ptr = (uint8_t *) wmi_buf_data(*buf);
4272 cmd = (wmi_extscan_start_cmd_fixed_param *) buf_ptr;
4273 WMITLV_SET_HDR(&cmd->tlv_header,
4274 WMITLV_TAG_STRUC_wmi_extscan_start_cmd_fixed_param,
4275 WMITLV_GET_STRUCT_TLVLEN
4276 (wmi_extscan_start_cmd_fixed_param));
4277
4278 cmd->request_id = pstart->requestId;
4279 cmd->vdev_id = pstart->sessionId;
4280 cmd->base_period = pstart->basePeriod;
4281 cmd->num_buckets = nbuckets;
4282 cmd->configuration_flags = 0;
4283 if (pstart->configuration_flags & EXTSCAN_LP_EXTENDED_BATCHING)
4284 cmd->configuration_flags |= WMI_EXTSCAN_EXTENDED_BATCHING_EN;
Srinivas Girigowdadbfb2642016-08-28 21:32:38 -07004285 WMA_LOGI("%s: Total buckets: %d total #of channels is %d cfgn_flags: 0x%x",
4286 __func__, nbuckets, nchannels,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004287 cmd->configuration_flags);
4288
4289 cmd->min_rest_time = WMA_EXTSCAN_REST_TIME;
4290 cmd->max_rest_time = WMA_EXTSCAN_REST_TIME;
4291 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
4292
4293 /* The max dwell time is retrieved from the first channel
4294 * of the first bucket and kept common for all channels.
4295 */
4296 cmd->min_dwell_time_active = pstart->min_dwell_time_active;
4297 cmd->max_dwell_time_active = pstart->max_dwell_time_active;
4298 cmd->min_dwell_time_passive = pstart->min_dwell_time_passive;
4299 cmd->max_dwell_time_passive = pstart->max_dwell_time_passive;
4300 cmd->max_bssids_per_scan_cycle = pstart->maxAPperScan;
4301 cmd->max_table_usage = pstart->report_threshold_percent;
4302 cmd->report_threshold_num_scans = pstart->report_threshold_num_scans;
4303
4304 cmd->repeat_probe_time = cmd->max_dwell_time_active /
4305 WMA_SCAN_NPROBES_DEFAULT;
4306 cmd->max_scan_time = WMA_EXTSCAN_MAX_SCAN_TIME;
4307 cmd->probe_delay = 0;
4308 cmd->probe_spacing_time = 0;
4309 cmd->idle_time = 0;
4310 cmd->burst_duration = WMA_EXTSCAN_BURST_DURATION;
4311 cmd->scan_ctrl_flags = WMI_SCAN_ADD_BCAST_PROBE_REQ |
4312 WMI_SCAN_ADD_CCK_RATES |
Sreelakshmi Konamki75deb332015-09-14 10:58:03 +05304313 WMI_SCAN_ADD_OFDM_RATES |
4314 WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ |
4315 WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05304316
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004317 cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH;
4318 cmd->num_ssids = 0;
4319 cmd->num_bssid = 0;
4320 cmd->ie_len = 0;
4321 cmd->n_probes = (cmd->repeat_probe_time > 0) ?
4322 cmd->max_dwell_time_active / cmd->repeat_probe_time : 0;
4323
4324 buf_ptr += sizeof(*cmd);
4325 WMITLV_SET_HDR(buf_ptr,
4326 WMITLV_TAG_ARRAY_FIXED_STRUC,
4327 num_ssid * sizeof(wmi_ssid));
4328 buf_ptr += WMI_TLV_HDR_SIZE + (num_ssid * sizeof(wmi_ssid));
4329
4330 WMITLV_SET_HDR(buf_ptr,
4331 WMITLV_TAG_ARRAY_FIXED_STRUC,
4332 num_bssid * sizeof(wmi_mac_addr));
4333 buf_ptr += WMI_TLV_HDR_SIZE + (num_bssid * sizeof(wmi_mac_addr));
4334
4335 ie_len_with_pad = 0;
4336 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ie_len_with_pad);
4337 buf_ptr += WMI_TLV_HDR_SIZE + ie_len_with_pad;
4338
4339 WMITLV_SET_HDR(buf_ptr,
4340 WMITLV_TAG_ARRAY_STRUC,
4341 nbuckets * sizeof(wmi_extscan_bucket));
4342 dest_blist = (wmi_extscan_bucket *)
4343 (buf_ptr + WMI_TLV_HDR_SIZE);
4344 src_bucket = pstart->buckets;
4345
4346 /* Retrieve scanning information from each bucket and
4347 * channels and send it to the target
4348 */
4349 for (i = 0; i < nbuckets; i++) {
4350 WMITLV_SET_HDR(dest_blist,
4351 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
4352 WMITLV_GET_STRUCT_TLVLEN(wmi_extscan_bucket));
4353
4354 dest_blist->bucket_id = src_bucket->bucket;
4355 dest_blist->base_period_multiplier =
4356 src_bucket->period / base_period;
4357 dest_blist->min_period = src_bucket->period;
4358 dest_blist->max_period = src_bucket->max_period;
4359 dest_blist->exp_backoff = src_bucket->exponent;
4360 dest_blist->exp_max_step_count = src_bucket->step_count;
4361 dest_blist->channel_band = src_bucket->band;
4362 dest_blist->num_channels = src_bucket->numChannels;
4363 dest_blist->notify_extscan_events = 0;
4364
4365 if (src_bucket->reportEvents & EXTSCAN_REPORT_EVENTS_EACH_SCAN)
4366 dest_blist->notify_extscan_events =
4367 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT;
4368
4369 if (src_bucket->reportEvents &
4370 EXTSCAN_REPORT_EVENTS_FULL_RESULTS) {
4371 dest_blist->forwarding_flags =
4372 WMI_EXTSCAN_FORWARD_FRAME_TO_HOST;
4373 dest_blist->notify_extscan_events |=
4374 WMI_EXTSCAN_BUCKET_COMPLETED_EVENT |
4375 WMI_EXTSCAN_CYCLE_STARTED_EVENT |
4376 WMI_EXTSCAN_CYCLE_COMPLETED_EVENT;
4377 } else {
4378 dest_blist->forwarding_flags =
4379 WMI_EXTSCAN_NO_FORWARDING;
4380 }
4381
4382 if (src_bucket->reportEvents & EXTSCAN_REPORT_EVENTS_NO_BATCH)
4383 dest_blist->configuration_flags = 0;
4384 else
4385 dest_blist->configuration_flags =
4386 WMI_EXTSCAN_BUCKET_CACHE_RESULTS;
4387
Mukul Sharmafa937be2016-08-12 18:13:36 +05304388 if (src_bucket->reportEvents &
4389 EXTSCAN_REPORT_EVENTS_CONTEXT_HUB)
4390 dest_blist->configuration_flags |=
4391 WMI_EXTSCAN_REPORT_EVENT_CONTEXT_HUB;
4392
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004393 WMA_LOGI("%s: ntfy_extscan_events:%u cfg_flags:%u fwd_flags:%u",
4394 __func__, dest_blist->notify_extscan_events,
4395 dest_blist->configuration_flags,
4396 dest_blist->forwarding_flags);
4397
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004398 dest_blist->min_dwell_time_active =
4399 src_bucket->min_dwell_time_active;
4400 dest_blist->max_dwell_time_active =
4401 src_bucket->max_dwell_time_active;
4402 dest_blist->min_dwell_time_passive =
4403 src_bucket->min_dwell_time_passive;
4404 dest_blist->max_dwell_time_passive =
4405 src_bucket->max_dwell_time_passive;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004406 src_channel = src_bucket->channels;
4407
4408 /* save the channel info to later populate
4409 * the channel TLV
4410 */
4411 for (k = 0; k < src_bucket->numChannels; k++) {
4412 save_channel[count++].channel = src_channel->channel;
4413 src_channel++;
4414 }
4415 dest_blist++;
4416 src_bucket++;
4417 }
4418 buf_ptr += WMI_TLV_HDR_SIZE + (nbuckets * sizeof(wmi_extscan_bucket));
4419 WMITLV_SET_HDR(buf_ptr,
4420 WMITLV_TAG_ARRAY_STRUC,
4421 nchannels * sizeof(wmi_extscan_bucket_channel));
4422 dest_clist = (wmi_extscan_bucket_channel *)
4423 (buf_ptr + WMI_TLV_HDR_SIZE);
4424
4425 /* Active or passive scan is based on the bucket dwell time
4426 * and channel specific active,passive scans are not
4427 * supported yet
4428 */
4429 for (i = 0; i < nchannels; i++) {
4430 WMITLV_SET_HDR(dest_clist,
4431 WMITLV_TAG_STRUC_wmi_extscan_bucket_channel_event_fixed_param,
4432 WMITLV_GET_STRUCT_TLVLEN
4433 (wmi_extscan_bucket_channel));
4434 dest_clist->channel = save_channel[i].channel;
4435 dest_clist++;
4436 }
4437 buf_ptr += WMI_TLV_HDR_SIZE +
4438 (nchannels * sizeof(wmi_extscan_bucket_channel));
4439 *buf_len = len;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304440 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004441}
4442
4443/**
4444 * wma_start_extscan() - start extscan command to fw.
4445 * @handle: wma handle
4446 * @pstart: scan command request params
4447 *
4448 * This function sends start extscan request to fw.
4449 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304450 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304452QDF_STATUS wma_start_extscan(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004453 tSirWifiScanCmdReqParams *pstart)
4454{
Abhishek Singhb61b5452017-04-10 10:14:18 +05304455 struct wifi_scan_cmd_req_params *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304456 int i, j;
4457 QDF_STATUS status;
4458
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004459 if (!wma || !wma->wmi_handle) {
4460 WMA_LOGE("%s: WMA is closed,can not issue extscan cmd",
4461 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304462 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004463 }
4464 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4465 WMI_SERVICE_EXTSCAN)) {
4466 WMA_LOGE("%s: extscan feature bit not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304467 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004468 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304469
4470 params = qdf_mem_malloc(sizeof(struct wifi_scan_cmd_req_params));
Naveen Rawat35804772016-06-27 15:40:28 -07004471 if (params == NULL) {
4472 WMA_LOGE("%s : Memory allocation failed", __func__);
4473 return QDF_STATUS_E_NOMEM;
4474 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304475
4476 params->basePeriod = pstart->basePeriod;
4477 params->maxAPperScan = pstart->maxAPperScan;
4478 params->report_threshold_percent = pstart->report_threshold_percent;
4479 params->report_threshold_num_scans = pstart->report_threshold_num_scans;
4480 params->requestId = pstart->requestId;
4481 params->sessionId = pstart->sessionId;
4482 params->numBuckets = pstart->numBuckets;
4483 params->min_dwell_time_active = pstart->min_dwell_time_active;
4484 params->min_dwell_time_passive = pstart->min_dwell_time_passive;
4485 params->max_dwell_time_active = pstart->max_dwell_time_active;
4486 params->max_dwell_time_passive = pstart->max_dwell_time_passive;
4487 params->configuration_flags = pstart->configuration_flags;
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +05304488 params->extscan_adaptive_dwell_mode =
4489 pstart->extscan_adaptive_dwell_mode;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304490 for (i = 0; i < WMI_WLAN_EXTSCAN_MAX_BUCKETS; i++) {
4491 params->buckets[i].bucket = pstart->buckets[i].bucket;
4492 params->buckets[i].band =
4493 (enum wmi_wifi_band) pstart->buckets[i].band;
4494 params->buckets[i].period = pstart->buckets[i].period;
4495 params->buckets[i].reportEvents =
4496 pstart->buckets[i].reportEvents;
4497 params->buckets[i].max_period = pstart->buckets[i].max_period;
4498 params->buckets[i].exponent = pstart->buckets[i].exponent;
4499 params->buckets[i].step_count = pstart->buckets[i].step_count;
4500 params->buckets[i].numChannels = pstart->buckets[i].numChannels;
4501 params->buckets[i].min_dwell_time_active =
4502 pstart->buckets[i].min_dwell_time_active;
4503 params->buckets[i].min_dwell_time_passive =
4504 pstart->buckets[i].min_dwell_time_passive;
4505 params->buckets[i].max_dwell_time_active =
4506 pstart->buckets[i].max_dwell_time_active;
4507 params->buckets[i].max_dwell_time_passive =
4508 pstart->buckets[i].max_dwell_time_passive;
4509 for (j = 0; j < WLAN_EXTSCAN_MAX_CHANNELS; j++) {
4510 params->buckets[i].channels[j].channel =
4511 pstart->buckets[i].channels[j].channel;
4512 params->buckets[i].channels[j].dwellTimeMs =
4513 pstart->buckets[i].channels[j].dwellTimeMs;
4514 params->buckets[i].channels[j].passive =
4515 pstart->buckets[i].channels[j].passive;
4516 params->buckets[i].channels[j].chnlClass =
4517 pstart->buckets[i].channels[j].chnlClass;
4518 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004519 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304520
4521 status = wmi_unified_start_extscan_cmd(wma->wmi_handle,
4522 params);
Abhishek Singhb61b5452017-04-10 10:14:18 +05304523 qdf_mem_free(params);
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304524 if (QDF_IS_STATUS_ERROR(status))
4525 return status;
4526
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004527 wma->interfaces[pstart->sessionId].extscan_in_progress = true;
4528 WMA_LOGD("Extscan start request sent successfully for vdev %d",
4529 pstart->sessionId);
4530
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304531 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004532}
4533
4534/**
4535 * wma_stop_extscan() - stop extscan command to fw.
4536 * @handle: wma handle
4537 * @pstopcmd: stop scan command request params
4538 *
4539 * This function sends stop extscan request to fw.
4540 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304541 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004542 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304543QDF_STATUS wma_stop_extscan(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004544 tSirExtScanStopReqParams *pstopcmd)
4545{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304546 struct extscan_stop_req_params params = {0};
4547 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004548
4549 if (!wma || !wma->wmi_handle) {
4550 WMA_LOGE("%s: WMA is closed, cannot issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304551 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004552 }
4553 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4554 WMI_SERVICE_EXTSCAN)) {
4555 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304556 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004557 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004558
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304559 params.request_id = pstopcmd->requestId;
4560 params.session_id = pstopcmd->sessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004561
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304562 status = wmi_unified_stop_extscan_cmd(wma->wmi_handle,
4563 &params);
4564 if (QDF_IS_STATUS_ERROR(status))
4565 return status;
4566
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004567 wma->interfaces[pstopcmd->sessionId].extscan_in_progress = false;
4568 WMA_LOGD("Extscan stop request sent successfully for vdev %d",
4569 pstopcmd->sessionId);
4570
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304571 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004572}
4573
4574/** wma_get_hotlist_entries_per_page() - hotlist entries per page
4575 * @wmi_handle: wmi handle.
4576 * @cmd: size of command structure.
4577 * @per_entry_size: per entry size.
4578 *
4579 * This utility function calculates how many hotlist entries can
4580 * fit in one page.
4581 *
4582 * Return: number of entries
4583 */
4584static inline int wma_get_hotlist_entries_per_page(wmi_unified_t wmi_handle,
4585 size_t cmd_size,
4586 size_t per_entry_size)
4587{
4588 uint32_t avail_space = 0;
4589 int num_entries = 0;
4590 uint16_t max_msg_len = wmi_get_max_msg_len(wmi_handle);
4591
4592 /* Calculate number of hotlist entries that can
4593 * be passed in wma message request.
4594 */
4595 avail_space = max_msg_len - cmd_size;
4596 num_entries = avail_space / per_entry_size;
4597 return num_entries;
4598}
4599
4600/**
4601 * wma_get_buf_extscan_hotlist_cmd() - prepare hotlist command
4602 * @handle: wma handle
4603 * @photlist: hotlist command params
4604 * @buf_len: buffer length
4605 *
4606 * This function fills individual elements for hotlist request and
4607 * TLV for bssid entries
4608 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304609 * Return: QDF Status.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004610 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304611QDF_STATUS wma_get_buf_extscan_hotlist_cmd(tp_wma_handle wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004612 tSirExtScanSetBssidHotListReqParams *photlist,
4613 int *buf_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004614{
Govind Singh64b5e112016-03-08 11:53:50 +05304615 return wmi_unified_get_buf_extscan_hotlist_cmd(wma_handle->wmi_handle,
4616 (struct ext_scan_setbssi_hotlist_params *)photlist,
4617 buf_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004618}
4619
4620/**
4621 * wma_extscan_start_hotlist_monitor() - start hotlist monitor
4622 * @wma: wma handle
4623 * @photlist: hotlist request params
4624 *
4625 * This function configures hotlist monitor in fw.
4626 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304627 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004628 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304629QDF_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004630 tSirExtScanSetBssidHotListReqParams *photlist)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004631{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304632 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004633 int len;
4634
4635 if (!wma || !wma->wmi_handle) {
4636 WMA_LOGE("%s: WMA is closed, can not issue hotlist cmd",
4637 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304638 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004639 }
4640 /* Fill individual elements for hotlist request and
4641 * TLV for bssid entries
4642 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304643 qdf_status = wma_get_buf_extscan_hotlist_cmd(wma, photlist, &len);
4644 if (qdf_status != QDF_STATUS_SUCCESS) {
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004645 WMA_LOGE("%s: Failed to get buffer for hotlist scan cmd",
4646 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304647 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004648 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304649 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004650}
4651
4652/**
4653 * wma_extscan_stop_hotlist_monitor() - stop hotlist monitor
4654 * @wma: wma handle
4655 * @photlist_reset: hotlist reset params
4656 *
4657 * This function configures hotlist monitor to stop in fw.
4658 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304659 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004660 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304661QDF_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004662 tSirExtScanResetBssidHotlistReqParams *photlist_reset)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004663{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304664 struct extscan_bssid_hotlist_reset_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004665
4666 if (!wma || !wma->wmi_handle) {
4667 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304668 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004669 }
4670 if (!photlist_reset) {
4671 WMA_LOGE("%s: Invalid reset hotlist buffer", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304672 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004673 }
4674 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4675 WMI_SERVICE_EXTSCAN)) {
4676 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304677 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004678 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004679
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304680 params.request_id = photlist_reset->requestId;
4681 params.session_id = photlist_reset->requestId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004682
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304683 return wmi_unified_extscan_stop_hotlist_monitor_cmd(wma->wmi_handle,
4684 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004685}
4686
4687/**
4688 * wma_get_buf_extscan_change_monitor_cmd() - fill change monitor request
4689 * @wma: wma handle
4690 * @psigchange: change monitor request params
4691 * @buf: wmi buffer
4692 * @buf_len: buffer length
4693 *
4694 * This function fills elements of change monitor request buffer.
4695 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304696 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004697 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304698QDF_STATUS wma_get_buf_extscan_change_monitor_cmd(tp_wma_handle wma_handle,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004699 tSirExtScanSetSigChangeReqParams *psigchange,
4700 wmi_buf_t *buf, int *buf_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004701{
4702 wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *cmd;
4703 wmi_extscan_wlan_change_bssid_param *dest_chglist;
4704 uint8_t *buf_ptr;
4705 int j;
4706 int len = sizeof(*cmd);
4707 int numap = psigchange->numAp;
4708 tSirAPThresholdParam *src_ap = psigchange->ap;
4709
4710 if (!numap) {
4711 WMA_LOGE("%s: Invalid number of bssid's", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304712 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004713 }
4714 len += WMI_TLV_HDR_SIZE;
4715 len += numap * sizeof(wmi_extscan_wlan_change_bssid_param);
4716
4717 *buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
4718 if (!*buf) {
4719 WMA_LOGP("%s: failed to allocate memory for change monitor cmd",
4720 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304721 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004722 }
4723 buf_ptr = (uint8_t *) wmi_buf_data(*buf);
4724 cmd =
4725 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param *)
4726 buf_ptr;
4727 WMITLV_SET_HDR(&cmd->tlv_header,
4728 WMITLV_TAG_STRUC_wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param,
4729 WMITLV_GET_STRUCT_TLVLEN
4730 (wmi_extscan_configure_wlan_change_monitor_cmd_fixed_param));
4731
4732 cmd->request_id = psigchange->requestId;
4733 cmd->vdev_id = psigchange->sessionId;
4734 cmd->total_entries = numap;
4735 cmd->mode = 1;
4736 cmd->num_entries_in_page = numap;
4737 cmd->lost_ap_scan_count = psigchange->lostApSampleSize;
4738 cmd->max_rssi_samples = psigchange->rssiSampleSize;
4739 cmd->rssi_averaging_samples = psigchange->rssiSampleSize;
4740 cmd->max_out_of_range_count = psigchange->minBreaching;
4741
4742 buf_ptr += sizeof(*cmd);
4743 WMITLV_SET_HDR(buf_ptr,
4744 WMITLV_TAG_ARRAY_STRUC,
4745 numap * sizeof(wmi_extscan_wlan_change_bssid_param));
4746 dest_chglist = (wmi_extscan_wlan_change_bssid_param *)
4747 (buf_ptr + WMI_TLV_HDR_SIZE);
4748
4749 for (j = 0; j < numap; j++) {
4750 WMITLV_SET_HDR(dest_chglist,
4751 WMITLV_TAG_STRUC_wmi_extscan_bucket_cmd_fixed_param,
4752 WMITLV_GET_STRUCT_TLVLEN
4753 (wmi_extscan_wlan_change_bssid_param));
4754
4755 dest_chglist->lower_rssi_limit = src_ap->low;
4756 dest_chglist->upper_rssi_limit = src_ap->high;
4757 WMI_CHAR_ARRAY_TO_MAC_ADDR(src_ap->bssid.bytes,
4758 &dest_chglist->bssid);
4759
4760 WMA_LOGD("%s: min_rssi %d", __func__,
4761 dest_chglist->lower_rssi_limit);
4762 dest_chglist++;
4763 src_ap++;
4764 }
4765 buf_ptr += WMI_TLV_HDR_SIZE +
4766 (numap * sizeof(wmi_extscan_wlan_change_bssid_param));
4767 *buf_len = len;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304768 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004769}
4770
4771/**
4772 * wma_extscan_start_change_monitor() - send start change monitor cmd
4773 * @wma: wma handle
4774 * @psigchange: change monitor request params
4775 *
4776 * This function sends start change monitor request to fw.
4777 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304778 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004779 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304780QDF_STATUS wma_extscan_start_change_monitor(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004781 tSirExtScanSetSigChangeReqParams *
4782 psigchange)
4783{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304784 int i = 0;
Mohit Khanna0fe61672016-05-19 16:53:39 -07004785 QDF_STATUS status;
4786 struct extscan_set_sig_changereq_params *params_ptr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004787
4788 if (!wma || !wma->wmi_handle) {
4789 WMA_LOGE("%s: WMA is closed,can not issue extscan cmd",
4790 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304791 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004792 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004793
Mohit Khanna0fe61672016-05-19 16:53:39 -07004794 params_ptr = qdf_mem_malloc(sizeof(*params_ptr));
4795
4796 if (!params_ptr) {
4797 WMA_LOGE(
4798 "%s: unable to allocate memory for extscan_set_sig_changereq_params",
4799 __func__);
4800 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004801 }
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304802
Mohit Khanna0fe61672016-05-19 16:53:39 -07004803 params_ptr->request_id = psigchange->requestId;
4804 params_ptr->session_id = psigchange->sessionId;
4805 params_ptr->rssi_sample_size = psigchange->rssiSampleSize;
4806 params_ptr->lostap_sample_size = psigchange->lostApSampleSize;
4807 params_ptr->min_breaching = psigchange->minBreaching;
4808 params_ptr->num_ap = psigchange->numAp;
4809 for (i = 0; i < WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS; i++) {
4810 qdf_mem_copy(&params_ptr->ap[i].bssid,
4811 &psigchange->ap[i].bssid,
4812 sizeof(struct qdf_mac_addr));
4813 params_ptr->ap[i].high = psigchange->ap[i].high;
4814 params_ptr->ap[i].low = psigchange->ap[i].low;
4815 }
4816
4817 status = wmi_unified_extscan_start_change_monitor_cmd
4818 (wma->wmi_handle,
4819 params_ptr);
4820 qdf_mem_free(params_ptr);
4821 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004822}
4823
4824/**
4825 * wma_extscan_stop_change_monitor() - send stop change monitor cmd
4826 * @wma: wma handle
4827 * @pResetReq: Reset change request params
4828 *
4829 * This function sends stop change monitor request to fw.
4830 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304831 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004832 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304833QDF_STATUS wma_extscan_stop_change_monitor(tp_wma_handle wma,
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004834 tSirExtScanResetSignificantChangeReqParams *pResetReq)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004835{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304836 struct extscan_capabilities_reset_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004837
4838 if (!wma || !wma->wmi_handle) {
4839 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304840 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004841 }
4842 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4843 WMI_SERVICE_EXTSCAN)) {
4844 WMA_LOGE("%s: ext scan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304845 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004846 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004847
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304848 params.request_id = pResetReq->requestId;
4849 params.session_id = pResetReq->sessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004850
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304851 return wmi_unified_extscan_stop_change_monitor_cmd(wma->wmi_handle,
4852 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004853}
4854
4855/**
4856 * wma_extscan_get_cached_results() - extscan get cached results
4857 * @wma: wma handle
4858 * @pcached_results: cached results parameters
4859 *
4860 * This function send request to fw to get cached results.
4861 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304862 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004863 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304864QDF_STATUS wma_extscan_get_cached_results(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004865 tSirExtScanGetCachedResultsReqParams *
4866 pcached_results)
4867{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304868 struct extscan_cached_result_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004869
4870 if (!wma || !wma->wmi_handle) {
4871 WMA_LOGE("%s: WMA is closed, cannot issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304872 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004873 }
4874 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4875 WMI_SERVICE_EXTSCAN)) {
4876 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304877 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004878 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004879
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304880 params.request_id = pcached_results->requestId;
4881 params.session_id = pcached_results->sessionId;
4882 params.flush = pcached_results->flush;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004883
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304884 return wmi_unified_extscan_get_cached_results_cmd(wma->wmi_handle,
4885 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004886}
4887
4888/**
4889 * wma_extscan_get_capabilities() - extscan get capabilities
4890 * @wma: wma handle
4891 * @pgetcapab: get capabilities params
4892 *
4893 * This function send request to fw to get extscan capabilities.
4894 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304895 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004896 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304897QDF_STATUS wma_extscan_get_capabilities(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004898 tSirGetExtScanCapabilitiesReqParams *
4899 pgetcapab)
4900{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304901 struct extscan_capabilities_params params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004902
4903 if (!wma || !wma->wmi_handle) {
4904 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304905 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004906 }
4907 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4908 WMI_SERVICE_EXTSCAN)) {
4909 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304910 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004911 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004912
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304913 params.request_id = pgetcapab->requestId;
4914 params.session_id = pgetcapab->sessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004915
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304916 return wmi_unified_extscan_get_capabilities_cmd(wma->wmi_handle,
4917 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004918}
4919
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304920QDF_STATUS wma_ipa_offload_enable_disable(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004921 struct sir_ipa_offload_enable_disable *ipa_offload)
4922{
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -08004923 struct cdp_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004924 int32_t intra_bss_fwd = 0;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304925 struct ipa_offload_control_params params = {0};
Govind Singhd76a5b02016-03-08 15:12:14 +05304926 QDF_STATUS status;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004927 uint8_t rx_fwd_disabled;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004928
4929 if (!wma || !wma->wmi_handle) {
4930 WMA_LOGE("%s: WMA is closed, can not issue cmd",
4931 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304932 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004933 }
4934
4935 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
4936 ((ipa_offload->offload_type == AP_RX_DATA_OFFLOAD) ?
4937 WMI_SERVICE_HSOFFLOAD :
4938 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT))) {
4939 WMA_LOGE("%s: %s not supported", __func__,
4940 ((ipa_offload->offload_type == AP_RX_DATA_OFFLOAD) ?
4941 "WMI_SERVICE_HSOFFLOAD" :
4942 "WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304943 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004944 }
4945
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07004946 if (ipa_offload->offload_type > STA_RX_DATA_OFFLOAD)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304947 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004948
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304949 params.offload_type = ipa_offload->offload_type;
4950 params.vdev_id = ipa_offload->vdev_id;
4951 params.enable = ipa_offload->enable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004952
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05304953 status = wmi_unified_ipa_offload_control_cmd(wma->wmi_handle,
4954 &params);
4955 if (QDF_IS_STATUS_ERROR(status))
4956 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004957
4958 /*
4959 * Check if VDEV is already deleted. If deleted, don't
4960 * send INTRA BSS FWD WMI command
4961 */
4962 vdev = wma_find_vdev_by_id(wma, ipa_offload->vdev_id);
4963 if (!vdev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304964 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004965
4966 /* Disable Intra-BSS FWD offload when gDisableIntraBssFwd=1 in INI */
Leo Chang96464902016-10-28 11:10:54 -07004967 rx_fwd_disabled = cdp_cfg_is_rx_fwd_disabled(
4968 cds_get_context(QDF_MODULE_ID_SOC), vdev);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004969 if (!ipa_offload->enable || rx_fwd_disabled) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004970 WMA_LOGE("%s: ipa_offload->enable=%d, rx_fwd_disabled=%d",
4971 __func__,
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07004972 ipa_offload->enable, rx_fwd_disabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004973 intra_bss_fwd = 1;
4974 }
4975
4976 /* Disable/enable WMI_VDEV_PARAM_INTRA_BSS_FWD */
Govind Singhd76a5b02016-03-08 15:12:14 +05304977 status = wma_vdev_set_param(wma->wmi_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004978 ipa_offload->vdev_id, WMI_VDEV_PARAM_INTRA_BSS_FWD,
Govind Singhd76a5b02016-03-08 15:12:14 +05304979 intra_bss_fwd);
4980 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004981 WMA_LOGE("Failed to disable WMI_VDEV_PARAM_INTRA_BSS_FWD");
Govind Singhd76a5b02016-03-08 15:12:14 +05304982 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004983 }
4984
Govind Singhd76a5b02016-03-08 15:12:14 +05304985 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004986}
4987
4988/** wma_set_epno_network_list() - set epno network list
4989 * @wma: WMA handle
4990 * @req: epno config params request structure
4991 *
4992 * This function reads the incoming epno config request structure
4993 * and constructs the WMI message to the firmware.
4994 *
4995 * Returns: 0 on success, error number otherwise
4996 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304997QDF_STATUS wma_set_epno_network_list(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004998 struct wifi_epno_params *req)
4999{
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005000 struct wifi_enhanched_pno_params *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305001 uint8_t i = 0;
5002 QDF_STATUS status;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005003 size_t params_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005004
5005 WMA_LOGD("wma_set_epno_network_list");
5006
5007 if (!wma || !wma->wmi_handle) {
5008 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305009 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005010 }
5011 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5012 WMI_SERVICE_EXTSCAN)) {
5013 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305014 return QDF_STATUS_E_NOSUPPORT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005015 }
5016
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005017 params_len = sizeof(*params) + (req->num_networks *
5018 sizeof(struct wifi_epno_network_params));
5019 params = qdf_mem_malloc(params_len);
5020 if (params == NULL) {
5021 WMA_LOGE(FL("memory allocation failed"));
5022 return QDF_STATUS_E_NOMEM;
5023 }
5024
5025 params->request_id = req->request_id;
5026 params->session_id = req->session_id;
5027 params->num_networks = req->num_networks;
Mukul Sharmae8c919f2016-10-02 20:35:15 +05305028
5029 /* Fill only when num_networks are non zero */
5030 if (req->num_networks) {
5031 params->min_5ghz_rssi = req->min_5ghz_rssi;
5032 params->min_24ghz_rssi = req->min_24ghz_rssi;
5033 params->initial_score_max = req->initial_score_max;
5034 params->same_network_bonus = req->same_network_bonus;
5035 params->secure_bonus = req->secure_bonus;
5036 params->band_5ghz_bonus = req->band_5ghz_bonus;
5037 params->current_connection_bonus =
5038 req->current_connection_bonus;
5039
5040 for (i = 0; i < req->num_networks; i++) {
5041 params->networks[i].flags = req->networks[i].flags;
5042 params->networks[i].auth_bit_field =
5043 req->networks[i].auth_bit_field;
5044 params->networks[i].ssid.length =
5045 req->networks[i].ssid.length;
5046 qdf_mem_copy(params->networks[i].ssid.mac_ssid,
5047 req->networks[i].ssid.ssId,
5048 WMI_MAC_MAX_SSID_LENGTH);
5049 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005050 }
Varun Reddy Yeturub43fda12015-09-10 18:16:21 -07005051
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005052 status = wmi_unified_set_epno_network_list_cmd(wma->wmi_handle, params);
5053 qdf_mem_free(params);
5054
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305055 if (QDF_IS_STATUS_ERROR(status))
5056 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005057
5058 WMA_LOGD("set ePNO list request sent successfully for vdev %d",
5059 req->session_id);
5060
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305061 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005062}
5063
5064/**
5065 * wma_set_passpoint_network_list() - set passpoint network list
5066 * @handle: WMA handle
5067 * @req: passpoint network request structure
5068 *
5069 * This function reads the incoming @req and fill in the destination
5070 * WMI structure and send down the passpoint configs down to the firmware
5071 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305072 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005073 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305074QDF_STATUS wma_set_passpoint_network_list(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005075 struct wifi_passpoint_req *req)
5076{
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005077 struct wifi_passpoint_req_param *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305078 int i = 0;
5079 QDF_STATUS status;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005080 size_t params_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005081
5082 WMA_LOGD("wma_set_passpoint_network_list");
5083
5084 if (!wma || !wma->wmi_handle) {
5085 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305086 return QDF_STATUS_E_FAILURE;
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_NOSUPPORT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005092 }
5093
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005094 params_len = sizeof(*params) + (req->num_networks *
5095 sizeof(struct wifi_passpoint_network_param));
5096 params = qdf_mem_malloc(params_len);
5097 if (params == NULL) {
5098 WMA_LOGE(FL("memory allocation failed"));
5099 return QDF_STATUS_E_NOMEM;
5100 }
5101
5102 params->request_id = req->request_id;
5103 params->session_id = req->session_id;
5104 params->num_networks = req->num_networks;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005105 for (i = 0; i < req->num_networks; i++) {
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005106 params->networks[i].id = req->networks[i].id;
5107 qdf_mem_copy(params->networks[i].realm, req->networks[i].realm,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305108 WMI_PASSPOINT_REALM_LEN);
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005109 qdf_mem_copy(params->networks[i].roaming_consortium_ids,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305110 req->networks[i].roaming_consortium_ids,
5111 WMI_PASSPOINT_ROAMING_CONSORTIUM_ID_NUM *
5112 sizeof(int64_t));
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005113 qdf_mem_copy(params->networks[i].plmn, req->networks[i].plmn,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305114 WMI_PASSPOINT_PLMN_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005115 }
5116
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305117 status = wmi_unified_set_passpoint_network_list_cmd(wma->wmi_handle,
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005118 params);
5119 qdf_mem_free(params);
5120
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305121 if (QDF_IS_STATUS_ERROR(status))
5122 return status;
5123
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005124 WMA_LOGD("Set passpoint network list request is sent successfully for vdev %d",
5125 req->session_id);
5126
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305127 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005128}
5129
5130/**
5131 * wma_reset_passpoint_network_list() - reset passpoint network list
5132 * @handle: WMA handle
5133 * @req: passpoint network request structure
5134 *
5135 * This function sends down WMI command with network id set to wildcard id.
5136 * firmware shall clear all the config entries
5137 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305138 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005139 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305140QDF_STATUS wma_reset_passpoint_network_list(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005141 struct wifi_passpoint_req *req)
5142{
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005143 struct wifi_passpoint_req_param *params;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305144 int i = 0;
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005145 QDF_STATUS status;
5146 size_t params_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005147
5148 WMA_LOGD("wma_reset_passpoint_network_list");
5149
5150 if (!wma || !wma->wmi_handle) {
5151 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305152 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005153 }
5154 if (!WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
5155 WMI_SERVICE_EXTSCAN)) {
5156 WMA_LOGE("%s: extscan not enabled", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305157 return QDF_STATUS_E_NOSUPPORT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005158 }
5159
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005160 params_len = sizeof(*params) + (req->num_networks *
5161 sizeof(struct wifi_passpoint_network_param));
5162 params = qdf_mem_malloc(params_len);
5163 if (params == NULL) {
5164 WMA_LOGE(FL("memory allocation failed"));
5165 return QDF_STATUS_E_NOMEM;
5166 }
5167
5168 params->request_id = req->request_id;
5169 params->session_id = req->session_id;
5170 params->num_networks = req->num_networks;
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305171 for (i = 0; i < req->num_networks; i++) {
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005172 params->networks[i].id = req->networks[i].id;
5173 qdf_mem_copy(params->networks[i].realm, req->networks[i].realm,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305174 WMI_PASSPOINT_REALM_LEN);
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005175 qdf_mem_copy(params->networks[i].roaming_consortium_ids,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305176 req->networks[i].roaming_consortium_ids,
5177 WMI_PASSPOINT_ROAMING_CONSORTIUM_ID_NUM *
5178 sizeof(int64_t));
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005179 qdf_mem_copy(params->networks[i].plmn, req->networks[i].plmn,
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305180 WMI_PASSPOINT_PLMN_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005181 }
5182
Krishna Kumaar Natarajan1b909d72016-06-06 15:02:18 -07005183 status = wmi_unified_reset_passpoint_network_list_cmd(wma->wmi_handle,
5184 params);
5185 qdf_mem_free(params);
5186
5187 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005188}
5189
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005190#endif
5191
5192/**
5193 * wma_scan_probe_setoui() - set scan probe OUI
5194 * @wma: wma handle
5195 * @psetoui: OUI parameters
5196 *
5197 * set scan probe OUI parameters in firmware
5198 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305199 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005200 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305201QDF_STATUS wma_scan_probe_setoui(tp_wma_handle wma, tSirScanMacOui *psetoui)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005202{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305203 struct scan_mac_oui set_oui;
5204
5205 qdf_mem_set(&set_oui, sizeof(struct scan_mac_oui), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005206
5207 if (!wma || !wma->wmi_handle) {
5208 WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305209 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005210 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005211
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305212 qdf_mem_copy(set_oui.oui, psetoui->oui,
5213 WMI_WIFI_SCANNING_MAC_OUI_LENGTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005214
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305215 return wmi_unified_scan_probe_setoui_cmd(wma->wmi_handle,
5216 &set_oui);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005217}
5218
5219/**
5220 * wma_scan_event_callback() - scan event callback
5221 * @handle: wma handle
5222 * @data: event data
5223 * @len: data length
5224 *
5225 * This function process scan event and provide indication
5226 * to upper layers.
5227 *
5228 * Return: 0 for success or error code.
5229 */
5230int wma_scan_event_callback(WMA_HANDLE handle, uint8_t *data,
5231 uint32_t len)
5232{
5233 tp_wma_handle wma_handle = (tp_wma_handle) handle;
5234 WMI_SCAN_EVENTID_param_tlvs *param_buf = NULL;
5235 wmi_scan_event_fixed_param *wmi_event = NULL;
5236 tSirScanOffloadEvent *scan_event;
5237 uint8_t vdev_id;
5238 uint32_t scan_id;
5239
5240 param_buf = (WMI_SCAN_EVENTID_param_tlvs *) data;
5241 wmi_event = param_buf->fixed_param;
5242 vdev_id = wmi_event->vdev_id;
5243 scan_id = wma_handle->interfaces[vdev_id].scan_info.scan_id;
5244
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305245 scan_event = (tSirScanOffloadEvent *) qdf_mem_malloc
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005246 (sizeof(tSirScanOffloadEvent));
5247 if (!scan_event) {
5248 WMA_LOGE("Memory allocation failed for tSirScanOffloadEvent");
5249 return -ENOMEM;
5250 }
5251
Srinivas Girigowdaf1472122017-03-09 15:44:12 -08005252 WMA_LOGD("scan_event: %u, id: 0x%x, requestor: 0x%x, freq: %u, reason: %u",
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005253 wmi_event->event, wmi_event->scan_id, wmi_event->requestor,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005254 wmi_event->channel_freq, wmi_event->reason);
5255
Nitesh Shah0f3fce52016-10-13 22:01:41 +05305256 scan_event->event = wmi_event->event;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005257 scan_event->scanId = wmi_event->scan_id;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005258 scan_event->requestor = wmi_event->requestor;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005259 scan_event->chanFreq = wmi_event->channel_freq;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005260 scan_event->sessionId = vdev_id;
Nitesh Shah0f3fce52016-10-13 22:01:41 +05305261 scan_event->reasonCode = eSIR_SME_SCAN_FAILED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005262
5263 switch (wmi_event->event) {
5264 case WMI_SCAN_EVENT_COMPLETED:
5265 case WMI_SCAN_EVENT_DEQUEUED:
5266 /*
5267 * return success always so that SME can pick whatever scan
5268 * results is available in scan cache(due to partial or
5269 * aborted scan)
5270 */
5271 scan_event->event = WMI_SCAN_EVENT_COMPLETED;
5272 scan_event->reasonCode = eSIR_SME_SUCCESS;
5273 break;
5274 case WMI_SCAN_EVENT_START_FAILED:
5275 scan_event->event = WMI_SCAN_EVENT_COMPLETED;
5276 scan_event->reasonCode = eSIR_SME_SCAN_FAILED;
5277 break;
5278 case WMI_SCAN_EVENT_PREEMPTED:
5279 WMA_LOGW("%s: Unhandled Scan Event WMI_SCAN_EVENT_PREEMPTED",
5280 __func__);
5281 break;
5282 case WMI_SCAN_EVENT_RESTARTED:
5283 WMA_LOGW("%s: Unhandled Scan Event WMI_SCAN_EVENT_RESTARTED",
5284 __func__);
5285 break;
5286 }
5287
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005288 /* Stop scan completion timeout if event is WMI_SCAN_EVENT_COMPLETED */
Krishna Kumaar Natarajan3c443552016-02-19 18:34:40 -08005289 if (scan_event->event ==
Krishna Kumaar Natarajan3eed86b2016-03-25 16:55:21 -07005290 (enum sir_scan_event_type) WMI_SCAN_EVENT_COMPLETED) {
Archana Ramachandran31b5b652016-09-21 15:37:58 -07005291 WMA_LOGI("scan complete:scan_id 0x%x, requestor 0x%x, vdev %d",
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005292 wmi_event->scan_id, wmi_event->requestor, vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005293 }
5294
5295 wma_send_msg(wma_handle, WMA_RX_SCAN_EVENT, (void *)scan_event, 0);
Nitesh Shah0f3fce52016-10-13 22:01:41 +05305296
5297 if ((wmi_event->event & WMA_SCAN_END_EVENT) > 0)
5298 wma_dec_pending_scans(wma_handle);
5299
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005300 return 0;
5301}
5302
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005303/**
5304 * wma_roam_better_ap_handler() - better ap event handler
5305 * @wma: wma handle
5306 * @vdev_id: vdev id
5307 *
5308 * Handler for WMI_ROAM_REASON_BETTER_AP event from roam firmware in Rome.
5309 * This event means roam algorithm in Rome has found a better matching
5310 * candidate AP. The indication is sent to SME.
5311 *
5312 * Return: none
5313 */
5314void wma_roam_better_ap_handler(tp_wma_handle wma, uint32_t vdev_id)
5315{
Rajeev Kumarcf7bd802017-04-18 11:11:42 -07005316 struct scheduler_msg cds_msg = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005317 tSirSmeCandidateFoundInd *candidate_ind;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005318 struct scan_param *params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005319
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005320 params = &wma->interfaces[vdev_id].scan_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005321 /* abort existing scans from GUI, but not roaming preauth scan */
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005322 if (params->scan_id != 0 && params->chan_freq == 0 &&
5323 params->scan_requestor_id == USER_SCAN_REQUESTOR_ID) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005324 tAbortScanParams abortScan;
Manikandan Mohan1dd8b5d2017-04-18 15:54:09 -07005325
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005326 abortScan.SessionId = vdev_id;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -07005327 abortScan.scan_id = params->scan_id;
5328 abortScan.scan_requestor_id = params->scan_requestor_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005329 wma_stop_scan(wma, &abortScan);
5330 }
5331
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305332 candidate_ind = qdf_mem_malloc(sizeof(tSirSmeCandidateFoundInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005333 if (!candidate_ind) {
5334 WMA_LOGE("%s: Alloc failed for tSirSmeCandidateFoundInd",
5335 __func__);
5336 return;
5337 }
Varun Reddy Yeturu30bc42c2016-02-04 10:07:30 -08005338 WMA_LOGD("%s: roaming in progress for vdev %d",
5339 __func__, vdev_id);
5340 wma->interfaces[vdev_id].roaming_in_progress = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005341
5342 candidate_ind->messageType = eWNI_SME_CANDIDATE_FOUND_IND;
5343 candidate_ind->sessionId = vdev_id;
5344 candidate_ind->length = sizeof(tSirSmeCandidateFoundInd);
5345
5346 cds_msg.type = eWNI_SME_CANDIDATE_FOUND_IND;
5347 cds_msg.bodyptr = candidate_ind;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305348 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005349 FL("posting candidate ind to SME"));
5350
Rajeev Kumarb60abe42017-01-21 15:39:31 -08005351 if (QDF_STATUS_SUCCESS != scheduler_post_msg(QDF_MODULE_ID_SME,
Rajeev Kumar156188e2017-01-21 17:23:52 -08005352 &cds_msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305353 qdf_mem_free(candidate_ind);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305354 QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005355 FL("Failed to post candidate ind to SME"));
5356 }
5357}
5358
5359/**
5360 * wma_roam_event_callback() - roam event callback
5361 * @handle: wma handle
5362 * @event_buf: event buffer
5363 * @len: buffer length
5364 *
5365 * Handler for all events from roam engine in firmware
5366 *
5367 * Return: 0 for success or error code
5368 */
5369int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
5370 uint32_t len)
5371{
5372 tp_wma_handle wma_handle = (tp_wma_handle) handle;
5373 WMI_ROAM_EVENTID_param_tlvs *param_buf;
5374 wmi_roam_event_fixed_param *wmi_event;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005375 struct sSirSmeRoamOffloadSynchInd *roam_synch_data;
5376 enum sir_roam_op_code op_code = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005377
5378 param_buf = (WMI_ROAM_EVENTID_param_tlvs *) event_buf;
5379 if (!param_buf) {
5380 WMA_LOGE("Invalid roam event buffer");
5381 return -EINVAL;
5382 }
5383
5384 wmi_event = param_buf->fixed_param;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005385 WMA_LOGD("%s: Reason %x, Notif %x for vdevid %x, rssi %d",
5386 __func__, wmi_event->reason, wmi_event->notif,
5387 wmi_event->vdev_id, wmi_event->rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005388
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05305389 DPTRACE(qdf_dp_trace_record_event(QDF_DP_TRACE_EVENT_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07005390 wmi_event->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
5391 QDF_PROTO_TYPE_EVENT, QDF_ROAM_EVENTID));
Himanshu Agarwal67a863b2016-09-20 15:09:09 +05305392
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005393 switch (wmi_event->reason) {
5394 case WMI_ROAM_REASON_BMISS:
5395 WMA_LOGD("Beacon Miss for vdevid %x", wmi_event->vdev_id);
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05305396 wma_beacon_miss_handler(wma_handle, wmi_event->vdev_id,
5397 wmi_event->rssi);
Sen, Devendra154b3c42017-02-13 20:44:15 +05305398 wma_sta_kickout_event(HOST_STA_KICKOUT_REASON_BMISS,
5399 wmi_event->vdev_id, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005400 break;
5401 case WMI_ROAM_REASON_BETTER_AP:
5402 WMA_LOGD("%s:Better AP found for vdevid %x, rssi %d", __func__,
5403 wmi_event->vdev_id, wmi_event->rssi);
5404 wma_handle->suitable_ap_hb_failure = false;
5405 wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
5406 break;
5407 case WMI_ROAM_REASON_SUITABLE_AP:
5408 wma_handle->suitable_ap_hb_failure = true;
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +05305409 wma_handle->suitable_ap_hb_failure_rssi = wmi_event->rssi;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005410 WMA_LOGD("%s:Bmiss scan AP found for vdevid %x, rssi %d",
5411 __func__, wmi_event->vdev_id, wmi_event->rssi);
5412 wma_roam_better_ap_handler(wma_handle, wmi_event->vdev_id);
5413 break;
5414#ifdef WLAN_FEATURE_ROAM_OFFLOAD
5415 case WMI_ROAM_REASON_HO_FAILED:
5416 WMA_LOGE("LFR3:Hand-Off Failed for vdevid %x",
5417 wmi_event->vdev_id);
5418 wma_roam_ho_fail_handler(wma_handle, wmi_event->vdev_id);
5419 break;
5420#endif
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005421 case WMI_ROAM_REASON_INVALID:
5422 roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
5423 if (NULL == roam_synch_data) {
5424 WMA_LOGE("Memory unavailable for roam synch data");
5425 return -ENOMEM;
5426 }
5427 if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_START)
Naveen Rawat8cc23b02016-07-14 12:22:56 -07005428 op_code = SIR_ROAMING_START;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005429 if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_ABORT)
Naveen Rawat8cc23b02016-07-14 12:22:56 -07005430 op_code = SIR_ROAMING_ABORT;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07005431 roam_synch_data->roamedVdevId = wmi_event->vdev_id;
5432 wma_handle->csr_roam_synch_cb(
5433 (tpAniSirGlobal)wma_handle->mac_context,
5434 roam_synch_data, NULL, op_code);
5435 qdf_mem_free(roam_synch_data);
5436 break;
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +05305437 case WMI_ROAM_REASON_RSO_STATUS:
5438 wma_rso_cmd_status_event_handler(wmi_event);
5439 break;
Arif Hussain43354e62017-05-24 11:24:25 -07005440 case WMI_ROAM_REASON_INVOKE_ROAM_FAIL:
5441 roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data));
5442 if (!roam_synch_data) {
5443 WMA_LOGE("Memory unavailable for roam synch data");
5444 return -ENOMEM;
5445 }
5446 roam_synch_data->roamedVdevId = wmi_event->vdev_id;
5447 wma_handle->csr_roam_synch_cb(
5448 (tpAniSirGlobal)wma_handle->mac_context,
5449 roam_synch_data, NULL, SIR_ROAMING_INVOKE_FAIL);
5450 qdf_mem_free(roam_synch_data);
5451 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005452 default:
5453 WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__,
5454 wmi_event->reason, wmi_event->vdev_id);
5455 break;
5456 }
5457 return 0;
5458}
5459
5460
5461/**
5462 * wma_set_rssi_monitoring() - set rssi monitoring
5463 * @handle: WMA handle
5464 * @req: rssi monitoring request structure
5465 *
5466 * This function reads the incoming @req and fill in the destination
5467 * WMI structure and send down the rssi monitoring configs down to the firmware
5468 *
5469 * Return: 0 on success; error number otherwise
5470 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305471QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005472 struct rssi_monitor_req *req)
5473{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305474 struct rssi_monitor_param params = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005475
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305476 if (!wma) {
5477 WMA_LOGE("%s: wma handle is NULL", __func__);
5478 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005479 }
5480
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305481 params.request_id = req->request_id;
5482 params.session_id = req->session_id;
5483 params.min_rssi = req->min_rssi;
5484 params.max_rssi = req->max_rssi;
5485 params.control = req->control;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005486
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305487 return wmi_unified_set_rssi_monitoring_cmd(wma->wmi_handle,
5488 &params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005489}
5490
5491/**
5492 * wma_get_scan_id() - Generates scan id
5493 * @scan_id: Scan id
5494 *
5495 * This function generates the scan id.
5496 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305497 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005498 */
5499
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305500QDF_STATUS wma_get_scan_id(uint32_t *scan_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005501{
Anurag Chouhan6d760662016-02-20 16:05:43 +05305502 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005503
5504 if (!scan_id) {
5505 WMA_LOGE("Scan_id is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305506 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005507 }
5508
Abhishek Singhe6857812017-03-10 18:20:06 +05305509#ifdef NAPIER_SCAN
5510 *scan_id = ucfg_scan_get_scan_id(wma->psoc);
5511#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005512 /* host need to cycle through the lower 12 bits to generate ids */
Anurag Chouhan8e0ccd32016-02-19 15:30:20 +05305513 *scan_id = qdf_atomic_inc_return(&wma->scan_id_counter) &
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005514 WMA_SCAN_ID_MASK;
5515 /*
5516 * Firmware expects the host scan request id appended
5517 * by PREFIX 0xA000
5518 */
5519 *scan_id = *scan_id | WMI_HOST_SCAN_REQ_ID_PREFIX;
Abhishek Singhe6857812017-03-10 18:20:06 +05305520#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305521 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005522}
5523
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005524#ifdef FEATURE_LFR_SUBNET_DETECTION
5525/**
5526 * wma_set_gateway_params() - set gateway parameters
5527 * @wma: WMA handle
5528 * @req: gateway parameter update request structure
5529 *
5530 * This function reads the incoming @req and fill in the destination
5531 * WMI structure and sends down the gateway configs down to the firmware
5532 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305533 * Return: QDF_STATUS
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005534 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305535QDF_STATUS wma_set_gateway_params(tp_wma_handle wma,
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005536 struct gateway_param_update_req *req)
5537{
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305538 struct gateway_update_req_param params = {0};
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005539
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305540 if (!wma) {
5541 WMA_LOGE("%s: wma handle is NULL", __func__);
5542 return QDF_STATUS_E_INVAL;
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005543 }
5544
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305545 params.request_id = req->request_id;
5546 params.session_id = req->session_id;
5547 params.max_retries = req->max_retries;
5548 params.timeout = req->timeout;
5549 params.ipv4_addr_type = req->ipv4_addr_type;
5550 params.ipv6_addr_type = req->ipv6_addr_type;
5551 qdf_mem_copy(&params.gw_mac_addr, &req->gw_mac_addr,
5552 sizeof(struct qdf_mac_addr));
5553 qdf_mem_copy(params.ipv4_addr, req->ipv4_addr,
5554 QDF_IPV4_ADDR_SIZE);
5555 qdf_mem_copy(params.ipv6_addr, req->ipv6_addr,
5556 QDF_IPV6_ADDR_SIZE);
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005557
Himanshu Agarwalbf6a12b2016-03-09 14:48:05 +05305558 return wmi_unified_set_gateway_params_cmd(wma->wmi_handle,
5559 &params);
Ravi Joshi9e891ba2015-11-09 19:03:46 -08005560}
5561#endif /* FEATURE_LFR_SUBNET_DETECTION */
5562
Sandeep Puligillae0875662016-02-12 16:09:21 -08005563/**
5564 * wma_ht40_stop_obss_scan() - ht40 obss stop scan
5565 * @wma: WMA handel
5566 * @vdev_id: vdev identifier
5567 *
5568 * Return: Return QDF_STATUS, otherwise appropriate failure code
5569 */
5570QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma, int32_t vdev_id)
5571{
5572
5573 wmi_buf_t buf;
5574 wmi_obss_scan_disable_cmd_fixed_param *cmd;
5575 int ret;
5576 int len = sizeof(*cmd);
5577
5578 buf = wmi_buf_alloc(wma->wmi_handle, len);
5579 if (!buf) {
5580 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
5581 return QDF_STATUS_E_NOMEM;
5582 }
5583
5584 WMA_LOGD("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id);
5585
5586 cmd = (wmi_obss_scan_disable_cmd_fixed_param *) wmi_buf_data(buf);
5587 WMITLV_SET_HDR(&cmd->tlv_header,
5588 WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param,
5589 WMITLV_GET_STRUCT_TLVLEN(
5590 wmi_obss_scan_disable_cmd_fixed_param));
5591
5592 cmd->vdev_id = vdev_id;
5593 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
5594 WMI_OBSS_SCAN_DISABLE_CMDID);
5595 if (ret != EOK) {
5596 WMA_LOGE("Failed to send gw config parameter to fw, ret: %d",
5597 ret);
5598 wmi_buf_free(buf);
5599 return QDF_STATUS_E_FAILURE;
5600 }
5601
5602 return QDF_STATUS_SUCCESS;
5603}
5604
5605/**
5606 * wma_send_ht40_obss_scanind() - ht40 obss start scan indication
5607 * @wma: WMA handel
5608 * @req: start scan request
5609 *
5610 * Return: Return QDF_STATUS, otherwise appropriate failure code
5611 */
5612QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
5613 struct obss_ht40_scanind *req)
5614{
5615 wmi_buf_t buf;
5616 wmi_obss_scan_enable_cmd_fixed_param *cmd;
5617 int ret;
5618 int len = 0;
5619 uint8_t *buf_ptr, i;
5620 uint8_t *channel_list;
5621
5622 len += sizeof(wmi_obss_scan_enable_cmd_fixed_param);
5623
5624 len += WMI_TLV_HDR_SIZE;
5625 len += qdf_roundup(sizeof(uint8_t) * req->channel_count,
5626 sizeof(uint32_t));
5627
5628 len += WMI_TLV_HDR_SIZE;
5629 len += qdf_roundup(sizeof(uint8_t) * 1, sizeof(uint32_t));
5630
5631 WMA_LOGE("cmdlen %d vdev_id %d channel count %d iefield_len %d",
5632 len, req->bss_id, req->channel_count, req->iefield_len);
5633
5634 WMA_LOGE("scantype %d active_time %d passive %d Obss interval %d",
5635 req->scan_type, req->obss_active_dwelltime,
5636 req->obss_passive_dwelltime,
5637 req->obss_width_trigger_interval);
5638
5639 buf = wmi_buf_alloc(wma->wmi_handle, len);
5640 if (!buf) {
5641 WMA_LOGP("%s: wmi_buf_alloc failed", __func__);
5642 return QDF_STATUS_E_NOMEM;
5643 }
5644
5645 cmd = (wmi_obss_scan_enable_cmd_fixed_param *) wmi_buf_data(buf);
5646 WMITLV_SET_HDR(&cmd->tlv_header,
5647 WMITLV_TAG_STRUC_wmi_obss_scan_enable_cmd_fixed_param,
5648 WMITLV_GET_STRUCT_TLVLEN(wmi_obss_scan_enable_cmd_fixed_param));
5649
5650 buf_ptr = (uint8_t *) cmd;
5651
5652 cmd->vdev_id = req->bss_id;
5653 cmd->scan_type = req->scan_type;
5654 cmd->obss_scan_active_dwell =
5655 req->obss_active_dwelltime;
5656 cmd->obss_scan_passive_dwell =
5657 req->obss_passive_dwelltime;
5658 cmd->bss_channel_width_trigger_scan_interval =
5659 req->obss_width_trigger_interval;
5660 cmd->bss_width_channel_transition_delay_factor =
5661 req->bsswidth_ch_trans_delay;
5662 cmd->obss_scan_active_total_per_channel =
5663 req->obss_active_total_per_channel;
5664 cmd->obss_scan_passive_total_per_channel =
5665 req->obss_passive_total_per_channel;
5666 cmd->obss_scan_activity_threshold =
5667 req->obss_activity_threshold;
5668
5669 cmd->channel_len = req->channel_count;
5670 cmd->forty_mhz_intolerant = req->fortymhz_intolerent;
5671 cmd->current_operating_class = req->current_operatingclass;
5672 cmd->ie_len = req->iefield_len;
5673
5674 buf_ptr += sizeof(wmi_obss_scan_enable_cmd_fixed_param);
5675 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5676 qdf_roundup(req->channel_count, sizeof(uint32_t)));
5677
5678 buf_ptr += WMI_TLV_HDR_SIZE;
5679 channel_list = (uint8_t *) buf_ptr;
5680
5681 for (i = 0; i < req->channel_count; i++) {
5682 channel_list[i] = req->channels[i];
5683 WMA_LOGD("Ch[%d]: %d ", i, channel_list[i]);
5684 }
5685
5686 buf_ptr += qdf_roundup(sizeof(uint8_t) * req->channel_count,
5687 sizeof(uint32_t));
5688 WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE,
5689 qdf_roundup(1, sizeof(uint32_t)));
5690 buf_ptr += WMI_TLV_HDR_SIZE;
5691
5692 ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
5693 WMI_OBSS_SCAN_ENABLE_CMDID);
5694 if (ret != EOK) {
5695 WMA_LOGE("Failed to send gw config parameter to fw, ret: %d",
5696 ret);
5697 wmi_buf_free(buf);
5698 return QDF_STATUS_E_FAILURE;
5699 }
5700 return QDF_STATUS_SUCCESS;
5701}