blob: 4e8099149c2c60ac0ae790ab897d1432d0e7f2c8 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302 * Copyright (c) 2012-2014,2016-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/*===========================================================================
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053029 L I M _ P 2 P . C
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080030
31 OVERVIEW:
32
33 This software unit holds the implementation of the WLAN Protocol Engine for
34 P2P.
35 ===========================================================================*/
36
37/*===========================================================================
38
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053039 EDIT HISTORY FOR FILE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040
41 This section contains comments describing changes made to the module.
42 Notice that changes are listed in reverse chronological order.
43
44 $Header$$DateTime$$Author$
45
46 when who what, where, why
47 ---------- --- --------------------------------------------------------
48 2011-05-02 djindal Corrected file indentation and changed remain on channel
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053049 handling for concurrency.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050 ===========================================================================*/
51
52#include "lim_utils.h"
53#include "lim_session_utils.h"
54#include "wma_types.h"
55#include "lim_types.h"
56
57#define PROBE_RSP_IE_OFFSET 36
58#define BSSID_OFFSET 16
59#define ADDR2_OFFSET 10
60#define ACTION_OFFSET 24
61
62/* A DFS channel can be ACTIVE for max 9000 msec, from the last
63 received Beacon/Prpbe Resp. */
64#define MAX_TIME_TO_BE_ACTIVE_CHANNEL 9000
65
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053066void lim_exit_remain_on_channel(tpAniSirGlobal pMac, QDF_STATUS status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067 uint32_t *data, tpPESession psessionEntry);
68extern tSirRetStatus lim_set_link_state(tpAniSirGlobal pMac, tSirLinkState state,
69 tSirMacAddr bssId, tSirMacAddr selfMacAddr,
70 tpSetLinkStateCallback callback,
71 void *callbackArg);
72
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073/*------------------------------------------------------------------
74 *
75 * Below function is called if hdd requests a remain on channel.
76 *
77 *------------------------------------------------------------------*/
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053078static QDF_STATUS lim_send_hal_req_remain_on_chan_offload(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079 tSirRemainOnChnReq *
80 pRemOnChnReq)
81{
82 tSirScanOffloadReq *pScanOffloadReq;
83 tSirMsgQ msg;
84 tSirRetStatus rc = eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085
Anurag Chouhan600c3a02016-03-01 10:33:54 +053086 pScanOffloadReq = qdf_mem_malloc(sizeof(tSirScanOffloadReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087 if (NULL == pScanOffloadReq) {
88 lim_log(pMac, LOGE,
89 FL("Memory allocation failed for pScanOffloadReq"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053090 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091 }
92
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080093 msg.type = WMA_START_SCAN_OFFLOAD_REQ;
94 msg.bodyptr = pScanOffloadReq;
95 msg.bodyval = 0;
96
Anurag Chouhanc5548422016-02-24 18:33:27 +053097 qdf_copy_macaddr(&pScanOffloadReq->selfMacAddr,
Srinivas Girigowdaa5bf5432015-09-24 11:20:22 -070098 &pRemOnChnReq->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099
Anurag Chouhanc5548422016-02-24 18:33:27 +0530100 qdf_set_macaddr_broadcast(&pScanOffloadReq->bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800101 pScanOffloadReq->scanType = eSIR_PASSIVE_SCAN;
102 pScanOffloadReq->p2pScanType = P2P_SCAN_TYPE_LISTEN;
103 pScanOffloadReq->minChannelTime = pRemOnChnReq->duration;
104 pScanOffloadReq->maxChannelTime = pRemOnChnReq->duration;
105 pScanOffloadReq->sessionId = pRemOnChnReq->sessionId;
106 pScanOffloadReq->channelList.numChannels = 1;
107 pScanOffloadReq->channelList.channelNumber[0] = pRemOnChnReq->chnNum;
108 pScanOffloadReq->scan_id = pRemOnChnReq->scan_id;
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700109 pScanOffloadReq->scan_requestor_id = ROC_SCAN_REQUESTOR_ID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800110
111 lim_log(pMac, LOG1,
112 FL("Req-rem-on-channel: duration %u, session %hu, chan %hu"),
113 pRemOnChnReq->duration, pRemOnChnReq->sessionId,
114 pRemOnChnReq->chnNum);
115
116 rc = wma_post_ctrl_msg(pMac, &msg);
117 if (rc != eSIR_SUCCESS) {
118 lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure %u"),
119 rc);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530120 qdf_mem_free(pScanOffloadReq);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530121 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800122 }
123
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530124 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800125}
126
127/*------------------------------------------------------------------
128 *
129 * Remain on channel req handler. Initiate the INIT_SCAN, CHN_CHANGE
130 * and SET_LINK Request from SME, chnNum and duration to remain on channel.
131 *
132 *------------------------------------------------------------------*/
133int lim_process_remain_on_chnl_req(tpAniSirGlobal pMac, uint32_t *pMsg)
134{
135 tSirRemainOnChnReq *msgbuff = (tSirRemainOnChnReq *) pMsg;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530136 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800137
138 pMac->lim.gpLimRemainOnChanReq = msgbuff;
139 status = lim_send_hal_req_remain_on_chan_offload(pMac, msgbuff);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530140 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800141 /* Post the meessage to Sme */
142 lim_send_sme_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
143 status, msgbuff->sessionId, msgbuff->scan_id);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530144 qdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800145 pMac->lim.gpLimRemainOnChanReq = NULL;
146 }
147 return false;
148}
149
150/*------------------------------------------------------------------
151 *
152 * lim Insert NOA timer timeout callback - when timer fires, deactivate it and send
153 * scan rsp to csr/hdd
154 *
155 *------------------------------------------------------------------*/
156void lim_process_insert_single_shot_noa_timeout(tpAniSirGlobal pMac)
157{
158 /* timeout means start NOA did not arrive; we need to deactivate and change the timer for
159 * future activations
160 */
161 lim_deactivate_and_change_timer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER);
162
163 /* Even if insert NOA timedout, go ahead and process/send stored SME request */
164 lim_process_regd_defd_sme_req_after_noa_start(pMac);
165
166 return;
167}
168
169/*-----------------------------------------------------------------
170 * lim Insert Timer callback function to check active DFS channels
171 * and convert them to passive channels if there was no
172 * beacon/proberesp for MAX_TIME_TO_BE_ACTIVE_CHANNEL time
173 *------------------------------------------------------------------*/
174void lim_convert_active_channel_to_passive_channel(tpAniSirGlobal pMac)
175{
Deepthi Gowri6acee342016-10-28 15:00:38 +0530176 uint64_t currentTime;
177 uint64_t lastTime = 0;
178 uint64_t timeDiff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179 uint8_t i;
Deepthi Gowri6acee342016-10-28 15:00:38 +0530180 currentTime = (uint64_t)qdf_mc_timer_get_system_time();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800181 for (i = 1; i < SIR_MAX_24G_5G_CHANNEL_RANGE; i++) {
182 if ((pMac->lim.dfschannelList.timeStamp[i]) != 0) {
183 lastTime = pMac->lim.dfschannelList.timeStamp[i];
184 if (currentTime >= lastTime) {
185 timeDiff = (currentTime - lastTime);
186 } else {
187 timeDiff =
188 (0xFFFFFFFF - lastTime) + currentTime;
189 }
190
191 if (timeDiff >= MAX_TIME_TO_BE_ACTIVE_CHANNEL) {
192 lim_covert_channel_scan_type(pMac, i, false);
193 pMac->lim.dfschannelList.timeStamp[i] = 0;
194 }
195 }
196 }
197 /* lastTime is zero if there is no DFS active channels in the list.
198 * If this is non zero then we have active DFS channels so restart the timer.
199 */
200 if (lastTime != 0) {
201 if (tx_timer_activate
202 (&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer)
203 != TX_SUCCESS) {
204 lim_log(pMac, LOGE,
205 FL
206 ("Could not activate Active to Passive Channel timer"));
207 }
208 }
209
210 return;
211
212}
213
214/**
215 * lim_process_remain_on_chn_timeout() - ROC timeout handler
216 *
217 * @mac_ctx: MAC context
218 *
219 * limchannelchange callback, on success channel change, set the
220 * link_state to LISTEN
221 *
222 * Return: NULL
223 */
224void lim_process_remain_on_chn_timeout(tpAniSirGlobal mac_ctx)
225{
226 tpPESession session;
227 tSirMacAddr null_bssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
228 TX_TIMER *roc_timer;
229
230 roc_timer = &mac_ctx->lim.limTimers.gLimRemainOnChannelTimer;
231 /*
232 * Timer might get extended while Sending Action Frame
233 * In that case don't process Channel Timeout
234 */
235 if (tx_timer_running(roc_timer)) {
236 lim_log(mac_ctx, LOGE,
237 FL("already timer is running and not processing "));
238 return;
239 }
240
241 lim_deactivate_and_change_timer(mac_ctx, eLIM_REMAIN_CHN_TIMER);
242 if (NULL == mac_ctx->lim.gpLimRemainOnChanReq) {
243 lim_log(mac_ctx, LOGE, FL("No Remain on channel pending"));
244 return;
245 }
246
247 /* get the previous valid LINK state */
248 if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE, null_bssid,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530249 mac_ctx->lim.gSelfMacAddr, NULL, NULL) != eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800250 lim_log(mac_ctx, LOGE, FL("Unable to change link state"));
251 return;
252 }
253
254 if (mac_ctx->lim.gLimMlmState != eLIM_MLM_P2P_LISTEN_STATE) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530255 lim_remain_on_chn_rsp(mac_ctx, QDF_STATUS_SUCCESS, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800256 } else {
257 session = pe_find_session_by_session_id(mac_ctx,
258 roc_timer->sessionId);
259 /* get the session */
260 if (session == NULL) {
261 lim_log(mac_ctx, LOGE,
262 FL("Session Does not exist sessionID %d"),
263 roc_timer->sessionId);
264 goto error;
265 }
266
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530267 lim_exit_remain_on_channel(mac_ctx, QDF_STATUS_SUCCESS, NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800268 session);
269 return;
270error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530271 lim_remain_on_chn_rsp(mac_ctx, QDF_STATUS_E_FAILURE, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272 }
273 return;
274}
275
276/*------------------------------------------------------------------
277 *
278 * limchannelchange callback, on success channel change, set the link_state
279 * to LISTEN
280 *
281 *------------------------------------------------------------------*/
282
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530283void lim_exit_remain_on_channel(tpAniSirGlobal pMac, QDF_STATUS status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800284 uint32_t *data, tpPESession psessionEntry)
285{
286
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530287 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800288 PELOGE(lim_log(pMac, LOGE, "Remain on Channel Failed");)
289 goto error;
290 }
291 /* Set the resume channel to Any valid channel (invalid). */
292 /* This will instruct HAL to set it to any previous valid channel. */
293 pe_set_resume_channel(pMac, 0, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530294 lim_remain_on_chn_rsp(pMac, QDF_STATUS_SUCCESS, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295 return;
296error:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530297 lim_remain_on_chn_rsp(pMac, QDF_STATUS_E_FAILURE, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298 return;
299}
300
301/*------------------------------------------------------------------
302 *
303 * Send remain on channel respone: Success/ Failure
304 *
305 *------------------------------------------------------------------*/
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530306void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, QDF_STATUS status, uint32_t *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800307{
308 tpPESession psessionEntry;
309 uint8_t sessionId;
310 tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq;
311 tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
312
313 if (NULL == MsgRemainonChannel) {
314 PELOGE(lim_log(pMac, LOGP,
315 "%s: No Pointer for Remain on Channel Req",
316 __func__);
317 )
318 return;
319 }
320 /* Incase of the Remain on Channel Failure Case */
321 /* Cleanup Everything */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530322 if (QDF_STATUS_E_FAILURE == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323 /* Deactivate Remain on Channel Timer */
324 lim_deactivate_and_change_timer(pMac, eLIM_REMAIN_CHN_TIMER);
325
326 /* Set the Link State to Idle */
327 /* get the previous valid LINK state */
328 if (lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
329 pMac->lim.gSelfMacAddr, NULL,
330 NULL) != eSIR_SUCCESS) {
331 lim_log(pMac, LOGE, "Unable to change link state");
332 }
333
334 pMac->lim.gLimSystemInScanLearnMode = 0;
335 pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
336 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
337 }
338
339 /* delete the session */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530340 psessionEntry = pe_find_session_by_bssid(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341 MsgRemainonChannel->
Srinivas Girigowda450f7162015-09-24 10:58:51 -0700342 selfMacAddr.bytes,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530343 &sessionId);
344 if (psessionEntry != NULL) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800345 if (LIM_IS_P2P_DEVICE_ROLE(psessionEntry)) {
346 pe_delete_session(pMac, psessionEntry);
347 }
348 }
349
350 /* Post the meessage to Sme */
351 lim_send_sme_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
352 status,
353 MsgRemainonChannel->sessionId, 0);
354
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530355 qdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356 pMac->lim.gpLimRemainOnChanReq = NULL;
357
358 pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
359
360 /* If remain on channel timer expired and action frame is pending then
361 * indicaiton confirmation with status failure */
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530362 if (pMac->lim.mgmtFrameSessionId != 0xff)
363 lim_p2p_action_cnf(pMac, NULL, false, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800364
365 return;
366}
367
368/*------------------------------------------------------------------
369 *
370 * Indicate the Mgmt Frame received to SME to HDD callback
371 * handle Probe_req/Action frame currently
372 *
373 *------------------------------------------------------------------*/
374void lim_send_sme_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
375 uint8_t *frame, uint32_t frameLen,
376 uint16_t sessionId, uint32_t rxChannel,
377 tpPESession psessionEntry, int8_t rxRssi)
378{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 tpSirSmeMgmtFrameInd pSirSmeMgmtFrame = NULL;
380 uint16_t length;
381
382 length = sizeof(tSirSmeMgmtFrameInd) + frameLen;
383
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530384 pSirSmeMgmtFrame = qdf_mem_malloc(length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800385 if (NULL == pSirSmeMgmtFrame) {
386 lim_log(pMac, LOGP,
387 FL("AllocateMemory failed for eWNI_SME_LISTEN_RSP"));
388 return;
389 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800390
Abhishek Singh7996eb72015-12-30 17:24:02 +0530391 pSirSmeMgmtFrame->frame_len = frameLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800392 pSirSmeMgmtFrame->sessionId = sessionId;
393 pSirSmeMgmtFrame->frameType = frameType;
394 pSirSmeMgmtFrame->rxRssi = rxRssi;
395 pSirSmeMgmtFrame->rxChan = rxChannel;
396
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530397 qdf_mem_zero(pSirSmeMgmtFrame->frameBuf, frameLen);
398 qdf_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399
Abhishek Singh7996eb72015-12-30 17:24:02 +0530400 if (pMac->mgmt_frame_ind_cb)
401 pMac->mgmt_frame_ind_cb(pSirSmeMgmtFrame);
402 else
403 lim_log(pMac, LOGW,
404 FL("Management indication callback not registered!!"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530405 qdf_mem_free(pSirSmeMgmtFrame);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 return;
407}
408
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530409QDF_STATUS lim_p2p_action_cnf(void *context, qdf_nbuf_t buf,
410 uint32_t tx_status, void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800411{
Abhishek Singha6b09822016-08-08 18:18:11 +0530412 QDF_STATUS status;
413 uint32_t mgmt_frame_sessionId;
Archana Ramachandran249f0382016-10-19 16:55:00 -0700414 bool tx_complete_ack = (tx_status) ? false : true;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530415 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
Abhishek Singha6b09822016-08-08 18:18:11 +0530416
417 status = pe_acquire_global_lock(&pMac->lim);
418 if (QDF_IS_STATUS_SUCCESS(status)) {
419 mgmt_frame_sessionId = pMac->lim.mgmtFrameSessionId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420 pMac->lim.mgmtFrameSessionId = 0xff;
Abhishek Singha6b09822016-08-08 18:18:11 +0530421 pe_release_global_lock(&pMac->lim);
422
423 if (mgmt_frame_sessionId != 0xff) {
424 /*
425 * The session entry might be invalid(0xff)
426 * action confirmation received after
427 * remain on channel timer expired.
428 */
429 lim_log(pMac, LOG1,
430 FL("mgmt_frame_sessionId %d"),
431 mgmt_frame_sessionId);
432 if (pMac->p2p_ack_ind_cb)
433 pMac->p2p_ack_ind_cb(mgmt_frame_sessionId,
Archana Ramachandran249f0382016-10-19 16:55:00 -0700434 tx_complete_ack);
Abhishek Singha6b09822016-08-08 18:18:11 +0530435 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 }
437
Abhishek Singha6b09822016-08-08 18:18:11 +0530438 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439}
440
441/**
442 * lim_tx_action_frame() - Handles action frame transmission request
443 * @mac_ctx: Pointer to mac context
444 * @mb_msg: message sent from SME
445 * @msg_len: Message length
446 * @packet: network buffer for TX
447 * @frame: frame buffer
448 *
449 * This function processes the action frame transmission request and
450 * posts message to WMA.
451 *
452 * Return: NULL
453 */
454static void lim_tx_action_frame(tpAniSirGlobal mac_ctx,
455 tSirMbMsgP2p *mb_msg, uint32_t msg_len, void *packet, uint8_t *frame)
456{
457 uint8_t tx_flag = 0;
458 tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530459 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 uint8_t sme_session_id = 0;
461 uint16_t channel_freq;
462
463 sme_session_id = mb_msg->sessionId;
464 channel_freq = mb_msg->channel_freq;
465 /*
466 * Use BD rate 2 for all P2P related frames. As these frames
467 * need to go at OFDM rates. And BD rate2 we configured at 6Mbps.
468 */
469 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Padma, Santhosh Kumarae6ae242016-10-05 19:45:07 +0530470 mac_ctx->lim.mgmtFrameSessionId = sme_session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800471
472 if ((SIR_MAC_MGMT_PROBE_RSP == fc->subType) ||
473 (mb_msg->noack)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530474 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) msg_len,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800475 TXRX_FRM_802_11_MGMT,
476 ANI_TXDIR_TODS, 7, lim_tx_complete,
477 frame, tx_flag, sme_session_id,
478 channel_freq);
479
480 if (!mb_msg->noack)
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530481 lim_p2p_action_cnf(mac_ctx, packet,
Selvaraj, Sridhar4577a9b2016-09-04 15:17:07 +0530482 (QDF_IS_STATUS_SUCCESS(qdf_status)) ?
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530483 true : false, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 mac_ctx->lim.mgmtFrameSessionId = 0xff;
485 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530486 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487 wma_tx_frameWithTxComplete(mac_ctx, packet,
488 (uint16_t) msg_len,
489 TXRX_FRM_802_11_MGMT,
490 ANI_TXDIR_TODS, 7, lim_tx_complete,
491 frame, lim_p2p_action_cnf, tx_flag,
492 sme_session_id, false,
493 channel_freq);
494
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530495 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496 lim_log(mac_ctx, LOGE,
497 FL("couldn't send action frame"));
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530498 lim_p2p_action_cnf(mac_ctx, packet, false, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800499 mac_ctx->lim.mgmtFrameSessionId = 0xff;
500 } else {
501 mac_ctx->lim.mgmtFrameSessionId = mb_msg->sessionId;
502 lim_log(mac_ctx, LOG2,
503 FL("lim.actionFrameSessionId = %u"),
504 mac_ctx->lim.mgmtFrameSessionId);
505 }
506 }
507
508 return;
509}
510
511/**
512 * lim_send_p2p_action_frame() - Process action frame request
513 * @mac_ctx: Pointer to mac context
514 * @msg: message sent from SME
515 *
516 * This function processes the action frame request sent from the
517 * SME and generates the ACTION frame.
518 *
519 * Return: NULL
520 */
521void lim_send_p2p_action_frame(tpAniSirGlobal mac_ctx,
522 tpSirMsgQ msg)
523{
524 tSirMbMsgP2p *mb_msg = (tSirMbMsgP2p *) msg->bodyptr;
525 uint32_t msg_len;
526 uint8_t *frame;
527 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530528 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529 tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
530 uint8_t noa_len = 0;
531 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + (2 * SIR_P2P_IE_HEADER_LEN)];
532 uint8_t orig_len = 0;
533 uint8_t session_id = 0;
534 uint8_t *p2p_ie = NULL;
535 tpPESession session_entry = NULL;
536 uint8_t *presence_noa_attr = NULL;
537 uint8_t *tmp_p2p_ie = NULL;
538 uint16_t remain_len = 0;
539 uint8_t sme_session_id = 0;
540#ifdef WLAN_FEATURE_11W
541 tpSirMacMgmtHdr mac_hdr;
542 tpSirMacActionFrameHdr action_hdr;
543#endif
544
545 msg_len = mb_msg->msgLen - sizeof(tSirMbMsgP2p);
546 lim_log(mac_ctx, LOG1, FL("sending fc->type=%d fc->subType=%d"),
547 fc->type, fc->subType);
548
549 if ((!mac_ctx->lim.gpLimRemainOnChanReq) && (0 != mb_msg->wait)) {
550 lim_log(mac_ctx, LOGE,
Kaushik, Sushantee3ed032016-08-04 16:40:46 +0530551 FL("RemainOnChannel is not running"));
Padma, Santhosh Kumarae6ae242016-10-05 19:45:07 +0530552 mac_ctx->lim.mgmtFrameSessionId = mb_msg->sessionId;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +0530553 lim_p2p_action_cnf(mac_ctx, NULL, false, NULL);
Padma, Santhosh Kumarae6ae242016-10-05 19:45:07 +0530554 mac_ctx->lim.mgmtFrameSessionId = 0xff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555 return;
556 }
557 sme_session_id = mb_msg->sessionId;
558
559 if ((SIR_MAC_MGMT_FRAME == fc->type) &&
560 (SIR_MAC_MGMT_PROBE_RSP == fc->subType)) {
561 /* get proper offset for Probe RSP */
562 p2p_ie = limGetP2pIEPtr(mac_ctx,
563 (uint8_t *) mb_msg->data +
564 PROBE_RSP_IE_OFFSET,
565 msg_len - PROBE_RSP_IE_OFFSET);
566 while ((NULL != p2p_ie)
567 && (SIR_MAC_MAX_IE_LENGTH == p2p_ie[1])) {
568 remain_len =
569 msg_len - (p2p_ie -
570 (uint8_t *) mb_msg->data);
571 if (remain_len > 2) {
572 tmp_p2p_ie = limGetP2pIEPtr(mac_ctx,
573 p2p_ie + SIR_MAC_MAX_IE_LENGTH + 2,
574 remain_len);
575 }
576 if (tmp_p2p_ie) {
577 p2p_ie = tmp_p2p_ie;
578 tmp_p2p_ie = NULL;
579 } else {
580 break;
581 }
582 } /* end of while */
583 } else if ((SIR_MAC_MGMT_FRAME == fc->type) &&
584 (SIR_MAC_MGMT_ACTION == fc->subType) &&
585 (SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY ==
586 *((uint8_t *) mb_msg->data + ACTION_OFFSET))) {
587 tpSirMacP2PActionFrameHdr action_hdr =
588 (tpSirMacP2PActionFrameHdr) ((uint8_t *)
589 mb_msg->data + ACTION_OFFSET);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530590 if ((!qdf_mem_cmp(action_hdr->Oui, SIR_MAC_P2P_OUI,
591 SIR_MAC_P2P_OUI_SIZE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 (SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP ==
593 action_hdr->OuiSubType)) {
594
595 /* In case of Presence RSP response */
596 p2p_ie = limGetP2pIEPtr(mac_ctx,
597 (uint8_t *)mb_msg->data +
598 ACTION_OFFSET +
599 sizeof(tSirMacP2PActionFrameHdr),
600 (msg_len - ACTION_OFFSET
601 - sizeof(tSirMacP2PActionFrameHdr)));
602 if (NULL != p2p_ie) {
603 /* extract the presence of NoA attribute inside
604 * P2P IE */
605 presence_noa_attr = lim_get_ie_ptr_new(mac_ctx,
606 p2p_ie + SIR_P2P_IE_HEADER_LEN,
607 p2p_ie[1], SIR_P2P_NOA_ATTR, TWO_BYTE);
608 }
609 }
610 }
611
612 if ((SIR_MAC_MGMT_FRAME == fc->type) &&
613 (SIR_MAC_MGMT_PROBE_RSP == fc->subType ||
614 SIR_MAC_MGMT_ACTION == fc->subType) && p2p_ie != NULL) {
615 /* get NoA attribute stream P2P IE */
616 noa_len =
617 lim_get_noa_attr_stream(mac_ctx, noa_stream,
618 session_entry);
619 /* need to append NoA attribute in P2P IE */
620 if (noa_len > 0) {
621 orig_len = p2p_ie[1];
622 /* if Presence Rsp has NoAttr */
623 if (presence_noa_attr) {
624 uint16_t noa_len =
625 presence_noa_attr[1] |
626 (presence_noa_attr[2] << 8);
627 /*One byte for attribute, 2bytes for length */
628 orig_len -= (noa_len + 1 + 2);
629 /* remove those bytes to copy */
630 msg_len -= (noa_len + 1 + 2);
631 /* remove NoA from original Len */
632 p2p_ie[1] = orig_len;
633 }
634 if ((p2p_ie[1] + (uint16_t) noa_len) >
635 SIR_MAC_MAX_IE_LENGTH) {
636 /*
637 * Form the new NoA Byte array in multiple
638 * P2P IEs
639 */
640 noa_len =
641 lim_get_noa_attr_stream_in_mult_p2p_ies
642 (mac_ctx, noa_stream, noa_len,
643 ((p2p_ie[1] + (uint16_t)noa_len)
644 - SIR_MAC_MAX_IE_LENGTH));
645 p2p_ie[1] = SIR_MAC_MAX_IE_LENGTH;
646 } else {
647 /* increment the length of P2P IE */
648 p2p_ie[1] += noa_len;
649 }
650 msg_len += noa_len;
651 lim_log(mac_ctx, LOGE,
652 FL("noa_len=%d orig_len=%d p2p_ie=%p"
653 " msg_len=%d nBytesToCopy=%zu "),
654 noa_len, orig_len, p2p_ie, msg_len,
655 ((p2p_ie + orig_len + 2) -
656 (uint8_t *) mb_msg->data));
657 }
658 }
659
Krunal Soni0acfdcd2016-03-09 12:03:06 -0800660 if (SIR_MAC_MGMT_PROBE_RSP == fc->subType)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661 lim_set_ht_caps(mac_ctx, session_entry,
662 (uint8_t *) mb_msg->data + PROBE_RSP_IE_OFFSET,
663 msg_len - PROBE_RSP_IE_OFFSET);
664
665 /* Ok-- try to allocate some memory: */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530666 qdf_status = cds_packet_alloc((uint16_t) msg_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530668 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669 lim_log(mac_ctx, LOGE,
670 FL("Failed to allocate %d bytes for a Probe Request."),
671 msg_len);
672 return;
673 }
674 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530675 qdf_mem_set(frame, msg_len, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676
677 /*
678 * Add sequence number to action frames
679 * Frames are handed over in .11 format by supplicant already
680 */
681 lim_populate_p2p_mac_header(mac_ctx, (uint8_t *) mb_msg->data);
682
683 if ((noa_len > 0)
684 && (noa_len < (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN))) {
685 /* Add 2 bytes for length and Arribute field */
686 uint32_t nBytesToCopy = ((p2p_ie + orig_len + 2) -
687 (uint8_t *) mb_msg->data);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530688 qdf_mem_copy(frame, mb_msg->data, nBytesToCopy);
689 qdf_mem_copy((frame + nBytesToCopy), noa_stream, noa_len);
690 qdf_mem_copy((frame + nBytesToCopy + noa_len),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800691 mb_msg->data + nBytesToCopy,
692 msg_len - nBytesToCopy - noa_len);
693
694 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530695 qdf_mem_copy(frame, mb_msg->data, msg_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696 }
697
698#ifdef WLAN_FEATURE_11W
Rajeev Kumar03200802016-04-15 13:59:36 -0700699 action_hdr = (tpSirMacActionFrameHdr)
700 (frame + sizeof(tSirMacMgmtHdr));
701 mac_hdr = (tpSirMacMgmtHdr) frame;
702 session_entry = pe_find_session_by_bssid(mac_ctx,
703 (uint8_t *) mb_msg->data + BSSID_OFFSET,
704 &session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800705
706 /*
Rajeev Kumar03200802016-04-15 13:59:36 -0700707 * Check for session corresponding to ADDR2 as supplicant
708 * is filling ADDR2 with BSSID
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709 */
Rajeev Kumar03200802016-04-15 13:59:36 -0700710 if (NULL == session_entry) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800711 session_entry = pe_find_session_by_bssid(mac_ctx,
Rajeev Kumar03200802016-04-15 13:59:36 -0700712 (uint8_t *) mb_msg->data + ADDR2_OFFSET,
713 &session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800714 }
Rajeev Kumar03200802016-04-15 13:59:36 -0700715 /*
716 * Setting Protected bit only for Robust Action Frames
717 * This has to be based on the current Connection with the
718 * station. lim_set_protected_bit API will set the protected
719 * bit if connection is PMF
720 */
721 if (session_entry && (SIR_MAC_MGMT_ACTION == fc->subType) &&
722 session_entry->limRmfEnabled &&
723 (!lim_is_group_addr(mac_hdr->da)) &&
724 lim_is_robust_mgmt_action_frame(action_hdr->category))
725 lim_set_protected_bit(mac_ctx, session_entry,
726 mac_hdr->da, mac_hdr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800727#endif
Rajeev Kumar03200802016-04-15 13:59:36 -0700728
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 lim_tx_action_frame(mac_ctx, mb_msg, msg_len, packet, frame);
730 return;
731}
732
733void lim_abort_remain_on_chan(tpAniSirGlobal pMac, uint8_t sessionId,
734 uint32_t scan_id)
735{
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700736 lim_process_abort_scan_ind(pMac, sessionId, scan_id,
737 ROC_SCAN_REQUESTOR_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738}
739
740/* Power Save Related Functions */
741tSirRetStatus __lim_process_sme_no_a_update(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
742{
743 tpP2pPsConfig pNoA;
744 tpP2pPsParams pMsgNoA;
745 tSirMsgQ msg;
746
747 pNoA = (tpP2pPsConfig) pMsgBuf;
748
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530749 pMsgNoA = qdf_mem_malloc(sizeof(tP2pPsConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750 if (NULL == pMsgNoA) {
751 lim_log(pMac, LOGE,
752 FL("Unable to allocate memory during NoA Update"));
753 return eSIR_MEM_ALLOC_FAILED;
754 }
755
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 pMsgNoA->opp_ps = pNoA->opp_ps;
757 pMsgNoA->ctWindow = pNoA->ctWindow;
758 pMsgNoA->duration = pNoA->duration;
759 pMsgNoA->interval = pNoA->interval;
760 pMsgNoA->count = pNoA->count;
761 pMsgNoA->single_noa_duration = pNoA->single_noa_duration;
762 pMsgNoA->psSelection = pNoA->psSelection;
763 pMsgNoA->sessionId = pNoA->sessionid;
764
765 msg.type = WMA_SET_P2P_GO_NOA_REQ;
766 msg.reserved = 0;
767 msg.bodyptr = pMsgNoA;
768 msg.bodyval = 0;
769
770 if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
771 lim_log(pMac, LOGE, FL("halPostMsgApi failed"));
772 return eSIR_FAILURE;
773 }
774
775 return eSIR_SUCCESS;
776} /*** end __limProcessSmeGoNegReq() ***/
Deepak Dhamdhered97bfb32015-10-11 15:16:18 -0700777