blob: 6ea3aeec62ef3da80bf093ff1947cc88c94c7b06 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05302 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -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.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
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
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**========================================================================
29
30 \file wlan_hdd_p2p.c
31
32 \brief WLAN Host Device Driver implementation for P2P commands interface
33
Jeff Johnson295189b2012-06-20 16:38:30 -070034
35 ========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070036
37#include <wlan_hdd_includes.h>
38#include <wlan_hdd_hostapd.h>
39#include <net/cfg80211.h>
40#include "sme_Api.h"
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070041#include "sme_QosApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070042#include "wlan_hdd_p2p.h"
43#include "sapApi.h"
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053044#include "wlan_hdd_main.h"
Daram Sudha1f7e0e92013-12-17 07:52:31 +053045#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070046#include <linux/netdevice.h>
47#include <linux/skbuff.h>
48#include <linux/etherdevice.h>
49#include <net/ieee80211_radiotap.h>
Hoonki Lee1090c6a2013-01-16 17:40:54 -080050#ifdef FEATURE_WLAN_TDLS
51#include "wlan_hdd_tdls.h"
52#endif
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053053#include "wlan_hdd_trace.h"
54#include "vos_types.h"
55#include "vos_trace.h"
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +053056#include "vos_sched.h"
57
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -080058//Ms to Micro Sec
59#define MS_TO_MUS(x) ((x)*1000);
Daram Sudha1f7e0e92013-12-17 07:52:31 +053060tANI_U8* hdd_getActionString( tANI_U16 MsgType )
61{
62 switch (MsgType)
63 {
64 CASE_RETURN_STRING(SIR_MAC_ACTION_SPECTRUM_MGMT);
65 CASE_RETURN_STRING(SIR_MAC_ACTION_QOS_MGMT);
66 CASE_RETURN_STRING(SIR_MAC_ACTION_DLP);
67 CASE_RETURN_STRING(SIR_MAC_ACTION_BLKACK);
68 CASE_RETURN_STRING(SIR_MAC_ACTION_PUBLIC_USAGE);
69 CASE_RETURN_STRING(SIR_MAC_ACTION_RRM);
70 CASE_RETURN_STRING(SIR_MAC_ACTION_FAST_BSS_TRNST);
71 CASE_RETURN_STRING(SIR_MAC_ACTION_HT);
72 CASE_RETURN_STRING(SIR_MAC_ACTION_SA_QUERY);
73 CASE_RETURN_STRING(SIR_MAC_ACTION_PROT_DUAL_PUB);
74 CASE_RETURN_STRING(SIR_MAC_ACTION_WNM);
75 CASE_RETURN_STRING(SIR_MAC_ACTION_UNPROT_WNM);
76 CASE_RETURN_STRING(SIR_MAC_ACTION_TDLS);
77 CASE_RETURN_STRING(SIR_MAC_ACITON_MESH);
78 CASE_RETURN_STRING(SIR_MAC_ACTION_MULTIHOP);
79 CASE_RETURN_STRING(SIR_MAC_SELF_PROTECTED);
80 CASE_RETURN_STRING(SIR_MAC_ACTION_WME);
81 CASE_RETURN_STRING(SIR_MAC_ACTION_VHT);
82 default:
83 return ("UNKNOWN");
84 }
85}
86
87
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070088#ifdef WLAN_FEATURE_P2P_DEBUG
89#define MAX_P2P_ACTION_FRAME_TYPE 9
90const char *p2p_action_frame_type[]={"GO Negotiation Request",
91 "GO Negotiation Response",
92 "GO Negotiation Confirmation",
93 "P2P Invitation Request",
94 "P2P Invitation Response",
95 "Device Discoverability Request",
96 "Device Discoverability Response",
97 "Provision Discovery Request",
98 "Provision Discovery Response"};
99
100/* We no need to protect this variable since
101 * there is no chance of race to condition
102 * and also not make any complicating the code
103 * just for debugging log
104 */
105tP2PConnectionStatus globalP2PConnectionStatus = P2P_NOT_ACTIVE;
106
107#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -0800108#define MAX_TDLS_ACTION_FRAME_TYPE 11
109const char *tdls_action_frame_type[] = {"TDLS Setup Request",
110 "TDLS Setup Response",
111 "TDLS Setup Confirm",
112 "TDLS Teardown",
113 "TDLS Peer Traffic Indication",
114 "TDLS Channel Switch Request",
115 "TDLS Channel Switch Response",
116 "TDLS Peer PSM Request",
117 "TDLS Peer PSM Response",
118 "TDLS Peer Traffic Response",
119 "TDLS Discovery Request" };
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -0700120
Jeff Johnson295189b2012-06-20 16:38:30 -0700121extern struct net_device_ops net_ops_struct;
122
123static int hdd_wlan_add_rx_radiotap_hdr( struct sk_buff *skb,
124 int rtap_len, int flag );
125
126static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
127 hdd_cfg80211_state_t* cfgState,
128 tANI_BOOLEAN actionSendSuccess );
129
130static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
Rashmi Ramannac7744532013-10-06 16:49:08 +0530131 tANI_U32 nFrameLength,
Jeff Johnson295189b2012-06-20 16:38:30 -0700132 tANI_U8* pbFrames,
133 tANI_U8 frameType );
vamsi9bd92b72013-12-26 14:11:29 +0530134
135static v_BOOL_t hdd_p2p_is_action_type_rsp( const u8 *buf )
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +0530136{
vamsi9bd92b72013-12-26 14:11:29 +0530137 tActionFrmType actionFrmType;
138 const u8 *ouiPtr;
139
140 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] !=
141 WLAN_HDD_PUBLIC_ACTION_FRAME ) {
142 return VOS_FALSE;
143 }
144
145 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET] !=
146 WLAN_HDD_VENDOR_SPECIFIC_ACTION ) {
147 return VOS_FALSE;
148 }
149
150 ouiPtr = &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET];
151
152 if ( WPA_GET_BE24(ouiPtr) != WLAN_HDD_WFA_OUI ) {
153 return VOS_FALSE;
154 }
155
156 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET] !=
157 WLAN_HDD_WFA_P2P_OUI_TYPE ) {
158 return VOS_FALSE;
159 }
160
Ahmad Kholaife5ec2cd2014-03-19 13:22:04 +0530161 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET];
vamsi9bd92b72013-12-26 14:11:29 +0530162 if ( actionFrmType != WLAN_HDD_INVITATION_REQ &&
163 actionFrmType != WLAN_HDD_GO_NEG_REQ &&
164 actionFrmType != WLAN_HDD_DEV_DIS_REQ &&
165 actionFrmType != WLAN_HDD_PROV_DIS_REQ )
166 return VOS_TRUE;
167 else
168 return VOS_FALSE;
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +0530169}
Jeff Johnson295189b2012-06-20 16:38:30 -0700170
Jeff Johnson295189b2012-06-20 16:38:30 -0700171eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx,
172 eHalStatus status )
173{
174 hdd_adapter_t *pAdapter = (hdd_adapter_t*) pCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
176 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530177 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700178
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530179 if (pHddCtx == NULL)
180 {
181 hddLog(LOGE, "%s: Hdd Context is NULL", __func__);
182 return eHAL_STATUS_FAILURE;
183 }
184 if (pRemainChanCtx == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700185 {
186 hddLog( LOGW,
187 "%s: No Rem on channel pending for which Rsp is received", __func__);
188 return eHAL_STATUS_SUCCESS;
189 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530190
191 mutex_lock(&pHddCtx->roc_lock);
Rashmi Ramannac7744532013-10-06 16:49:08 +0530192 hddLog( VOS_TRACE_LEVEL_INFO,
193 "Received ROC rsp (request type %d, channel %d, cookie %llu",
194 pRemainChanCtx->rem_on_chan_request,
195 pRemainChanCtx->chan.center_freq,
196 pRemainChanCtx->cookie);
Jeff Johnson295189b2012-06-20 16:38:30 -0700197 cfgState->remain_on_chan_ctx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530198 vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer);
199 vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530200 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530201 if ( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
Jeff Johnson295189b2012-06-20 16:38:30 -0700202 {
203 if( cfgState->buf )
204 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530205 hddLog( LOGP,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 "%s: We need to receive yet an ack from one of tx packet",
207 __func__);
208 }
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800209 cfg80211_remain_on_channel_expired(
210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
211 pRemainChanCtx->dev->ieee80211_ptr,
212#else
213 pRemainChanCtx->dev,
214#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700215 pRemainChanCtx->cookie,
216 &pRemainChanCtx->chan,
Yue Maf49ba872013-08-19 12:04:25 -0700217#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
218 pRemainChanCtx->chan_type,
219#endif
220 GFP_KERNEL);
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530221 pAdapter->lastRocTs = vos_timer_get_system_time();
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 }
223
Jeff Johnson295189b2012-06-20 16:38:30 -0700224
225 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
Jeff Johnsone7245742012-09-05 17:12:55 -0700226 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
227 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 )
229 {
230 tANI_U8 sessionId = pAdapter->sessionId;
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800231 if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
232 {
233 sme_DeregisterMgmtFrame(
234 hHal, sessionId,
235 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
236 NULL, 0 );
237 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700238 }
239 else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
240 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
241 )
242 {
243 WLANSAP_DeRegisterMgmtFrame(
244 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
245 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
246 NULL, 0 );
247 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530248 if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL
249 && pRemainChanCtx->action_pkt_buff.frame_length != 0)
250 {
251 vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
252 }
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800253 vos_mem_free( pRemainChanCtx );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800254 pRemainChanCtx = NULL;
Deepthi Gowri3e672f02015-01-30 17:04:08 +0530255 if (eHAL_STATUS_SUCCESS != status)
256 complete(&pAdapter->rem_on_chan_ready_event);
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 complete(&pAdapter->cancel_rem_on_chan_var);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530258 pAdapter->is_roc_inprogress = FALSE;
259 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 return eHAL_STATUS_SUCCESS;
261}
262
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530263VOS_STATUS wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700264{
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530266 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530267 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700268 int status = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530270 if (NULL == pHddCtx)
271 {
272 hddLog(LOGE, "%s: HddCtx is NULL", __func__);
273 return VOS_STATUS_E_FAILURE;
274 }
275
276 mutex_lock(&pHddCtx->roc_lock);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700277 if(cfgState->remain_on_chan_ctx != NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530279 if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(
280 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer))
281 {
282 hddLog(VOS_TRACE_LEVEL_INFO,
283 "Cancel Existing ROC (cookie=%llu)",
284 cfgState->remain_on_chan_ctx->cookie);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700285
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530286 vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
287 }
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530288 /* Wait till remain on channel ready indication before issuing cancel
289 * remain on channel request, otherwise if remain on channel not
290 * received and if the driver issues cancel remain on channel then lim
Jeff Johnson295189b2012-06-20 16:38:30 -0700291 * will be in unknown state.
292 */
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530293 if (pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress != TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 {
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530295 status = wait_for_completion_interruptible_timeout(
296 &pAdapter->rem_on_chan_ready_event,
297 msecs_to_jiffies(WAIT_REM_CHAN_READY));
298 if (0 >= status)
299 {
300 hddLog( LOGE,
301 "%s: timeout waiting for remain on channel"
302 " ready indication %d",
303 __func__, status);
304 pRemainChanCtx->is_pending_roc_cancelled = TRUE;
305 mutex_unlock(&pHddCtx->roc_lock);
306 return VOS_STATUS_E_FAILURE;
307 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700308
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530309 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
310 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
Mahesh A Saptasgar3f692752014-11-17 16:13:35 +0530311 mutex_unlock(&pHddCtx->roc_lock);
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530312
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530313 /* Issue abort remain on chan request to sme.
314 * The remain on channel callback will make sure the remain_on_chan
315 * expired event is sent.
316 */
Deepthi Gowri70498252015-01-20 15:56:45 +0530317 if (( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530318 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ))
319 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530320 if (eHAL_STATUS_SUCCESS !=
321 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
322 pAdapter->sessionId ))
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
325 FL("Failed to Cancel Remain on Channel"));
326 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530327 }
Deepthi Gowri70498252015-01-20 15:56:45 +0530328 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530329 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530330 WLANSAP_CancelRemainOnChannel(
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530331 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
332 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700333
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530334 status = wait_for_completion_interruptible_timeout(
335 &pAdapter->cancel_rem_on_chan_var,
336 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
337 if (0 >= status)
338 {
339 hddLog( LOGE,
340 "%s: timeout waiting for cancel remain on channel"
341 " ready indication %d",
342 __func__, status);
343 }
344 hdd_allow_suspend();
345 }
346 else
347 {
348 hddLog( LOG1,
349 "ROC timer cancellation in progress,"
350 " wait for completion");
351 mutex_unlock(&pHddCtx->roc_lock);
352 status = wait_for_completion_interruptible_timeout(
353 &pAdapter->cancel_rem_on_chan_var,
354 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
355 if (0 >= status)
356 {
357 hddLog( LOGE,
358 "%s:wait on cancel_rem_on_chan_var failed %d",
359 __func__, status);
360 return VOS_STATUS_E_FAILURE;
361 }
362 return VOS_STATUS_SUCCESS;
363 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700364 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530365 else
366 {
367 hddLog(LOG1,
368 "%s: remain_on_chan_ctx is NULL", __func__);
369 mutex_unlock(&pHddCtx->roc_lock);
370 }
371 return VOS_STATUS_SUCCESS;
Jeff Johnson32d95a32012-09-10 13:15:23 -0700372}
373
374int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter)
375{
376 int status = 0;
377 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
378
379 if(WLAN_HDD_P2P_GO != pAdapter->device_mode)
380 {
381 //Cancel Existing Remain On Channel
382 //If no action frame is pending
383 if( cfgState->remain_on_chan_ctx != NULL)
384 {
385 //Check whether Action Frame is pending or not
386 if( cfgState->buf == NULL)
387 {
388 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
389 }
390 else
391 {
Rashmi Ramannac7744532013-10-06 16:49:08 +0530392 hddLog(VOS_TRACE_LEVEL_DEBUG,
393 "Cannot Cancel Existing Remain on Channel");
Jeff Johnson32d95a32012-09-10 13:15:23 -0700394 status = -EBUSY;
395 }
396 }
397 }
398 return status;
399}
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530400void wlan_hdd_remain_on_chan_timeout(void *data)
401{
402 hdd_adapter_t *pAdapter = (hdd_adapter_t *)data;
403 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
404 hdd_cfg80211_state_t *cfgState;
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530405
406 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530407 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530408 hddLog( LOGE, FL("pAdapter is invalid %p !!!"), pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530409 return;
410 }
411 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
412 pRemainChanCtx = cfgState->remain_on_chan_ctx;
413 if (NULL == pRemainChanCtx)
414 {
415 hddLog( LOGE, FL("No Remain on channel is pending"));
416 return;
417 }
418 if ( TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
419 {
420 hddLog( LOGE, FL("Cancellation already in progress"));
421 return;
422 }
423
424 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
425 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
426 hddLog( LOG1,"%s: Cancel Remain on Channel on timeout", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +0530427 if ( ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530428 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
429 )
430 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530431 if (eHAL_STATUS_SUCCESS !=
432 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
433 pAdapter->sessionId ))
434 {
435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
436 FL("Failed to Cancel Remain on Channel"));
437 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530438 }
Deepthi Gowri70498252015-01-20 15:56:45 +0530439 else if ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530440 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530441 WLANSAP_CancelRemainOnChannel(
442 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530443 }
444 hdd_allow_suspend();
445}
Jeff Johnson32d95a32012-09-10 13:15:23 -0700446
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530447static int wlan_hdd_p2p_start_remain_on_channel(
448 hdd_adapter_t *pAdapter)
449{
450 VOS_STATUS status = VOS_STATUS_SUCCESS;
451 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
452 hdd_adapter_t *pAdapter_temp;
453 v_BOOL_t isGoPresent = VOS_FALSE;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530454 hdd_context_t *pHddCtx;
455 hdd_cfg80211_state_t *cfgState;
456 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
457 rem_on_channel_request_type_t request_type;
458 int ret = 0;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530459
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530460 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530461 if (NULL == pAdapter)
462 {
463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
464 "%s: Adapter is NULL",__func__);
465 return -EINVAL;
466 }
467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
468 ret = wlan_hdd_validate_context(pHddCtx);
469 if (0 != ret)
470 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530471 return ret;
472 }
473 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
474 if (NULL == cfgState)
475 {
476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
477 "%s: cfgState is not valid ",__func__);
478 return -EINVAL;
479 }
480 pRemainChanCtx = cfgState->remain_on_chan_ctx;
481 request_type = pRemainChanCtx->rem_on_chan_request;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530482 /* Initialize Remain on chan timer */
483 status = vos_timer_init(&pRemainChanCtx->hdd_remain_on_chan_timer,
484 VOS_TIMER_TYPE_SW,
485 wlan_hdd_remain_on_chan_timeout,
486 pAdapter);
487 if (status != VOS_STATUS_SUCCESS)
488 {
489 hddLog(VOS_TRACE_LEVEL_ERROR,
490 "%s: Not able to initalize remain_on_chan timer", __func__);
491 }
492 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
493 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
494 {
495 pAdapter_temp = pAdapterNode->pAdapter;
496 if (WLAN_HDD_P2P_GO == pAdapter_temp->device_mode)
497 {
498 isGoPresent = VOS_TRUE;
499 }
500 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
501 pAdapterNode = pNext;
502 }
503 hdd_prevent_suspend();
504 //call sme API to start remain on channel.
505 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
506 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
507 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
508 )
509 {
510 tANI_U8 sessionId = pAdapter->sessionId;
511 //call sme API to start remain on channel.
512 if (eHAL_STATUS_SUCCESS != sme_RemainOnChannel(
513 WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId,
514 pRemainChanCtx->chan.hw_value, pRemainChanCtx->duration,
515 wlan_hdd_remain_on_channel_callback, pAdapter,
516 (tANI_U8)(request_type == REMAIN_ON_CHANNEL_REQUEST)? TRUE:FALSE))
517 {
518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
519 FL(" RemainOnChannel returned fail"));
520 cfgState->remain_on_chan_ctx = NULL;
521 vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
522 vos_mem_free (pRemainChanCtx);
523 hdd_allow_suspend();
524 return -EINVAL;
525 }
526
527 if( REMAIN_ON_CHANNEL_REQUEST == request_type)
528 {
529 if( eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame(
530 WLAN_HDD_GET_HAL_CTX(pAdapter),
531 sessionId, (SIR_MAC_MGMT_FRAME << 2) |
532 (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0 ))
533 {
534 hddLog(VOS_TRACE_LEVEL_ERROR, "sme_RegisterMgmtFrame returned fail");
535 }
536 }
537
538 }
539 else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
540 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
541 )
542 {
543 //call sme API to start remain on channel.
544 if (VOS_STATUS_SUCCESS != WLANSAP_RemainOnChannel(
545 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
546 pRemainChanCtx->chan.hw_value, pRemainChanCtx->duration,
547 wlan_hdd_remain_on_channel_callback, pAdapter ))
548
549 {
550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
551 "%s: WLANSAP_RemainOnChannel returned fail", __func__);
552 cfgState->remain_on_chan_ctx = NULL;
553 vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
554 vos_mem_free (pRemainChanCtx);
555 hdd_allow_suspend();
556 return -EINVAL;
557 }
558
559
560 if (VOS_STATUS_SUCCESS != WLANSAP_RegisterMgmtFrame(
561 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
562 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
563 NULL, 0 ))
564 {
565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
566 "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__);
567 WLANSAP_CancelRemainOnChannel(
568 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
569 hdd_allow_suspend();
570 return -EINVAL;
571 }
572
573 }
574
575 pAdapter->is_roc_inprogress = TRUE;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530576 EXIT();
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530577 return 0;
578}
579
580
Jeff Johnson32d95a32012-09-10 13:15:23 -0700581static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy,
582 struct net_device *dev,
583 struct ieee80211_channel *chan,
Yue Maf49ba872013-08-19 12:04:25 -0700584#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson32d95a32012-09-10 13:15:23 -0700585 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -0700586#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -0700587 unsigned int duration, u64 *cookie,
588 rem_on_channel_request_type_t request_type )
589{
590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
591 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
592 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530593 hdd_context_t *pHddCtx = NULL;
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530594 VOS_STATUS checkReadyInd;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530595 hdd_adapter_t *pStaAdapter;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530596 int status = 0;
597
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530598 ENTER();
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530599 if (NULL == pAdapter)
600 {
601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
602 "%s: HDD adapter is Null", __func__);
603 return -ENODEV;
604 }
605
606 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
607 status = wlan_hdd_validate_context(pHddCtx);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530608 if (0 != status)
609 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530610 return status;
611 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530612
Jeff Johnson32d95a32012-09-10 13:15:23 -0700613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
614 __func__,pAdapter->device_mode);
Yue Maf49ba872013-08-19 12:04:25 -0700615#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Rashmi Ramannac7744532013-10-06 16:49:08 +0530616 hddLog(VOS_TRACE_LEVEL_INFO,
617 "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, dur %d,"
618 " request type %d, cookie %llu",
619 chan->hw_value, chan->center_freq, channel_type, duration,
620 request_type, *cookie);
Yue Maf49ba872013-08-19 12:04:25 -0700621#else
Rashmi Ramannac7744532013-10-06 16:49:08 +0530622 hddLog(VOS_TRACE_LEVEL_INFO,
623 "chan(hw_val)0x%x chan(centerfreq) %d, duration %d"
624 " reuest type %d, cookie %llu", chan->hw_value, chan->center_freq,
625 duration, request_type, *cookie );
Yue Maf49ba872013-08-19 12:04:25 -0700626#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -0700627 //Cancel existing remain On Channel if any
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530628 checkReadyInd = wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
629 if (VOS_STATUS_SUCCESS != checkReadyInd)
630 {
631 hddLog( LOGE, FL("Cancel Roc in progress"));
632 return -EBUSY;
633 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700634
Jeff Johnsone7245742012-09-05 17:12:55 -0700635 /* When P2P-GO and if we are trying to unload the driver then
Jeff Johnson295189b2012-06-20 16:38:30 -0700636 * wlan driver is keep on receiving the remain on channel command
Jeff Johnsone7245742012-09-05 17:12:55 -0700637 * and which is resulting in crash. So not allowing any remain on
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 * channel requets when Load/Unload is in progress*/
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530639 if(hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -0700640 {
641 hddLog( LOGE,
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530642 "%s: Connection is in progress", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700643 return -EBUSY;
644 }
645
646 pRemainChanCtx = vos_mem_malloc( sizeof(hdd_remain_on_chan_ctx_t) );
647 if( NULL == pRemainChanCtx )
648 {
649 hddLog(VOS_TRACE_LEVEL_FATAL,
650 "%s: Not able to allocate memory for Channel context",
651 __func__);
652 return -ENOMEM;
653 }
654
655 vos_mem_copy( &pRemainChanCtx->chan, chan,
656 sizeof(struct ieee80211_channel) );
657
Yue Maf49ba872013-08-19 12:04:25 -0700658#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 pRemainChanCtx->chan_type = channel_type;
Yue Maf49ba872013-08-19 12:04:25 -0700660#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 pRemainChanCtx->duration = duration;
662 pRemainChanCtx->dev = dev;
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800663 *cookie = (uintptr_t) pRemainChanCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 pRemainChanCtx->cookie = *cookie;
665 pRemainChanCtx->rem_on_chan_request = request_type;
666 cfgState->remain_on_chan_ctx = pRemainChanCtx;
667 cfgState->current_freq = chan->center_freq;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530668 pRemainChanCtx->action_pkt_buff.freq = 0;
669 pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
670 pRemainChanCtx->action_pkt_buff.frame_length = 0;
671 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = FALSE;
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530672 pRemainChanCtx->is_pending_roc_cancelled = FALSE;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530673
Jeff Johnson295189b2012-06-20 16:38:30 -0700674 INIT_COMPLETION(pAdapter->rem_on_chan_ready_event);
675
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530676 if (REMAIN_ON_CHANNEL_REQUEST == request_type)
Jeff Johnson295189b2012-06-20 16:38:30 -0700677 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530678 pStaAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
679 if((NULL != pStaAdapter)&&
680 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pStaAdapter)))
Sushant Kaushik298a8592014-12-09 17:34:07 +0530681 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530682 if (pAdapter->lastRocTs !=0 &&
683 ((vos_timer_get_system_time() - pAdapter->lastRocTs )
684 < pHddCtx->cfg_ini->gP2PListenDeferInterval))
Rashmi Ramannac7744532013-10-06 16:49:08 +0530685 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530686 if (pRemainChanCtx->duration > HDD_P2P_MAX_ROC_DURATION)
687 pRemainChanCtx->duration = HDD_P2P_MAX_ROC_DURATION;
688 schedule_delayed_work(&pAdapter->roc_work,
689 msecs_to_jiffies(pHddCtx->cfg_ini->gP2PListenDeferInterval));
690 hddLog(VOS_TRACE_LEVEL_INFO, "Defer interval is %hu, pAdapter %p",
691 pHddCtx->cfg_ini->gP2PListenDeferInterval, pAdapter);
692 return 0;
Rashmi Ramannac7744532013-10-06 16:49:08 +0530693 }
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800694 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700695 }
Nirav Shah87cd0cb2013-12-28 21:22:09 +0530696
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530697 status = wlan_hdd_p2p_start_remain_on_channel(pAdapter);
698
699 EXIT();
700 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700701}
702
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530703int __wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
705 struct wireless_dev *wdev,
706#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700707 struct net_device *dev,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800708#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700709 struct ieee80211_channel *chan,
Yue Maf49ba872013-08-19 12:04:25 -0700710#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -0700712#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700713 unsigned int duration, u64 *cookie )
714{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
716 struct net_device *dev = wdev->netdev;
717#endif
Mahesh A Saptasagar74088392015-02-05 17:22:09 +0530718 hdd_adapter_t *pAdapter;
719 hdd_context_t *pHddCtx;
720 int ret = 0;
721
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530722 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +0530723 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
724 if (NULL == pAdapter)
725 {
726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
727 "%s: Adapter is NULL",__func__);
728 return -EINVAL;
729 }
730 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
731 ret = wlan_hdd_validate_context(pHddCtx);
732 if (0 != ret)
733 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +0530734 return ret;
735 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530736
737 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
738 TRACE_CODE_HDD_REMAIN_ON_CHANNEL,
739 pAdapter->sessionId, REMAIN_ON_CHANNEL_REQUEST));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530740 ret = wlan_hdd_request_remain_on_channel(wiphy, dev,
Yue Maf49ba872013-08-19 12:04:25 -0700741 chan,
742#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
743 channel_type,
744#endif
745 duration, cookie,
Jeff Johnson295189b2012-06-20 16:38:30 -0700746 REMAIN_ON_CHANNEL_REQUEST);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530747 EXIT();
748 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700749}
750
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530751int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
753 struct wireless_dev *wdev,
754#else
755 struct net_device *dev,
756#endif
757 struct ieee80211_channel *chan,
758#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
759 enum nl80211_channel_type channel_type,
760#endif
761 unsigned int duration, u64 *cookie )
762{
763 int ret;
764
765 vos_ssr_protect(__func__);
766 ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy,
767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
768 wdev,
769#else
770 dev,
771#endif
772 chan,
773#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
774 channel_type,
775#endif
776 duration, cookie);
777 vos_ssr_unprotect(__func__);
778
779 return ret;
780}
781
782
Jeff Johnson295189b2012-06-20 16:38:30 -0700783void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter )
784{
Kaushik, Sushant26402612014-05-03 16:56:06 +0530785 hdd_cfg80211_state_t *cfgState = NULL;
786 hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530787 VOS_STATUS status;
Kaushik, Sushant26402612014-05-03 16:56:06 +0530788 if (NULL == pAdapter)
789 {
790 hddLog(LOGE, FL("pAdapter is NULL"));
791 return;
792 }
793 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
794 pRemainChanCtx = cfgState->remain_on_chan_ctx;
Deepthi Gowri22d08752015-02-05 15:07:40 +0530795 pAdapter->startRocTs = vos_timer_get_system_time();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530796 hddLog( LOG1, "Ready on chan ind");
Jeff Johnson295189b2012-06-20 16:38:30 -0700797 if( pRemainChanCtx != NULL )
798 {
Kaushik, Sushant78c3efe2014-05-13 10:29:34 +0530799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
800 TRACE_CODE_HDD_REMAINCHANREADYHANDLER,
801 pAdapter->sessionId, pRemainChanCtx->duration));
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530802 //start timer for actual duration
803 status = vos_timer_start(&pRemainChanCtx->hdd_remain_on_chan_timer,
804 (pRemainChanCtx->duration));
805 if (VOS_STATUS_SUCCESS!=status)
806 {
807 hddLog( LOGE, FL("Remain on Channel timer start failed"));
808 }
809 if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request)
Jeff Johnson295189b2012-06-20 16:38:30 -0700810 {
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800811 cfg80211_ready_on_channel(
812#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
813 pAdapter->dev->ieee80211_ptr,
814#else
815 pAdapter->dev,
816#endif
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800817 (uintptr_t)pRemainChanCtx,
Yue Maf49ba872013-08-19 12:04:25 -0700818 &pRemainChanCtx->chan,
819#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
820 pRemainChanCtx->chan_type,
821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 pRemainChanCtx->duration, GFP_KERNEL );
823 }
824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530825 else if( OFF_CHANNEL_ACTION_TX == pRemainChanCtx->rem_on_chan_request)
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 {
827 complete(&pAdapter->offchannel_tx_event);
828 }
829#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530830 // Check for cached action frame
831 if ( pRemainChanCtx->action_pkt_buff.frame_length != 0 )
832 {
833#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
834 cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr,
835 pRemainChanCtx->action_pkt_buff.freq, 0,
836 pRemainChanCtx->action_pkt_buff.frame_ptr,
837 pRemainChanCtx->action_pkt_buff.frame_length,
838 GFP_ATOMIC );
839#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
840 cfg80211_rx_mgmt( pAdapter->dev,
841 pRemainChanCtx->action_pkt_buff.freq, 0,
842 pRemainChanCtx->action_pkt_buff.frame_ptr,
843 pRemainChanCtx->action_pkt_buff.frame_length,
844 GFP_ATOMIC );
845#else
846 cfg80211_rx_mgmt( pAdapter->dev,
847 pRemainChanCtx->action_pkt_buff.freq,
848 pRemainChanCtx->action_pkt_buff.frame_ptr,
849 pRemainChanCtx->action_pkt_buff.frame_length,
850 GFP_ATOMIC );
851#endif //LINUX_VERSION_CODE
852 hddLog( LOGE, "%s: Sent cached action frame to supplicant", __func__);
853 vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
854 pRemainChanCtx->action_pkt_buff.frame_length = 0;
855 pRemainChanCtx->action_pkt_buff.freq = 0;
856 pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
857 }
Rashmi Ramannac7744532013-10-06 16:49:08 +0530858 hddLog( VOS_TRACE_LEVEL_INFO, "Ready on chan ind (cookie=%llu)",
859 pRemainChanCtx->cookie);
Jeff Johnson295189b2012-06-20 16:38:30 -0700860 complete(&pAdapter->rem_on_chan_ready_event);
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530861 if (TRUE == pRemainChanCtx->is_pending_roc_cancelled)
862 {
863 /* since pRemainChanCtx->is_pending_roc_cancelled is
864 * set, it means Cancel Reamain on channel command is
865 * pending because remain on channel event was not
866 * ready when cancel ROC was issued.So issue
867 * cancel ROC now.
868 */
869 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
870 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700871 }
872 else
873 {
874 hddLog( LOGW, "%s: No Pending Remain on channel Request", __func__);
875 }
876 return;
877}
878
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530879int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
881 struct wireless_dev *wdev,
882#else
883 struct net_device *dev,
884#endif
885 u64 cookie )
Jeff Johnson295189b2012-06-20 16:38:30 -0700886{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
888 struct net_device *dev = wdev->netdev;
889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530892 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530893 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
894 int status;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530895 u64 cookie_dummy;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530896
897 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530898 cookie_dummy = cookie << 32;
899 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
900 TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL,
901 pAdapter->sessionId, cookie_dummy));
902 hddLog( LOG1, "Cancel remain on channel req");
Jeff Johnson295189b2012-06-20 16:38:30 -0700903
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530904 status = wlan_hdd_validate_context(pHddCtx);
905
906 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -0700907 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530908 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -0700909 }
Rashmi Ramannac7744532013-10-06 16:49:08 +0530910 hddLog( LOG1, "Cancel remain on channel req (cookie = %llu)", cookie);
911
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 /* FIXME cancel currently running remain on chan.
913 * Need to check cookie and cancel accordingly
914 */
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530915 mutex_lock(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 if( (cfgState->remain_on_chan_ctx == NULL) ||
917 (cfgState->remain_on_chan_ctx->cookie != cookie) )
918 {
919 hddLog( LOGE,
920 "%s: No Remain on channel pending with specified cookie value",
921 __func__);
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530922 mutex_unlock(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 return -EINVAL;
924 }
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530925 if (TRUE != pRemainChanCtx->is_pending_roc_cancelled)
926 {
927 /* wait until remain on channel ready event received
928 * for already issued remain on channel request */
929 status = wait_for_completion_interruptible_timeout(&pAdapter->rem_on_chan_ready_event,
930 msecs_to_jiffies(WAIT_REM_CHAN_READY));
931 if (0 >= status)
932 {
933 hddLog( LOGE,
934 "%s: timeout waiting for remain on channel ready indication %d",
935 __func__, status);
936 pRemainChanCtx->is_pending_roc_cancelled = TRUE;
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530937 mutex_unlock(&pHddCtx->roc_lock);
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530938 return 0;
939
940 }
941 }
942 else
943 {
944 hddLog( LOG1, FL("Cancel ROC event is already pending, "
945 "waiting for ready on channel indication.") );
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530946 mutex_unlock(&pHddCtx->roc_lock);
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530947 return 0;
948 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530949 if (NULL != cfgState->remain_on_chan_ctx)
950 {
951 vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
952 if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress)
953 {
954 hddLog( LOG1,
955 FL("ROC timer cancellation in progress,"
956 " wait for completion"));
957 status = wait_for_completion_interruptible_timeout(
958 &pAdapter->cancel_rem_on_chan_var,
959 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
960 if (0 >= status)
961 {
962 hddLog( LOGE,
963 "%s:wait on cancel_rem_on_chan_var failed %d",
964 __func__, status);
965 }
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530966 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530967 return 0;
968 }
969 else
970 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
971 }
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530972 mutex_unlock(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
974 /* Issue abort remain on chan request to sme.
975 * The remain on channel callback will make sure the remain_on_chan
976 * expired event is sent.
977 */
Deepthi Gowri70498252015-01-20 15:56:45 +0530978 if (( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
979 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ))
Jeff Johnson295189b2012-06-20 16:38:30 -0700980 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530981 tANI_U8 sessionId = pAdapter->sessionId;
Deepthi Gowri70498252015-01-20 15:56:45 +0530982 if (eHAL_STATUS_SUCCESS !=
983 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
984 sessionId ))
985 {
986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
987 FL("Failed to Cancel Remain on Channel"));
988 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 }
Deepthi Gowri70498252015-01-20 15:56:45 +0530990 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -0700991 {
992 WLANSAP_CancelRemainOnChannel(
Deepthi Gowri70498252015-01-20 15:56:45 +0530993 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700994 }
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530995 else
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 {
997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid device_mode = %d",
998 __func__, pAdapter->device_mode);
999 return -EIO;
1000 }
c_hpothu7f63e882013-10-02 19:13:35 +05301001 status = wait_for_completion_interruptible_timeout(&pAdapter->cancel_rem_on_chan_var,
Jeff Johnson295189b2012-06-20 16:38:30 -07001002 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
c_hpothu7f63e882013-10-02 19:13:35 +05301003 if (0 >= status)
1004 {
1005 hddLog( LOGE,
1006 "%s:wait on cancel_rem_on_chan_var failed %d", __func__, status);
1007 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301008 hdd_allow_suspend();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301009
1010 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 return 0;
1012}
1013
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301014int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301016 struct wireless_dev *wdev,
1017#else
1018 struct net_device *dev,
1019#endif
1020 u64 cookie )
1021{
1022 int ret;
1023
1024 vos_ssr_protect(__func__);
1025 ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy,
1026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1027 wdev,
1028#else
1029 dev,
1030#endif
1031 cookie);
1032 vos_ssr_unprotect(__func__);
1033
1034 return ret;
1035}
1036
1037
1038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1039int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001040 struct ieee80211_channel *chan, bool offchan,
Yue Maf49ba872013-08-19 12:04:25 -07001041#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001042 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -07001043 bool channel_type_valid,
1044#endif
1045 unsigned int wait,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001046 const u8 *buf, size_t len, bool no_cck,
1047 bool dont_wait_for_ack, u64 *cookie )
1048#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301049int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 struct ieee80211_channel *chan, bool offchan,
1051 enum nl80211_channel_type channel_type,
1052 bool channel_type_valid, unsigned int wait,
1053 const u8 *buf, size_t len, bool no_cck,
1054 bool dont_wait_for_ack, u64 *cookie )
1055#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301056int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001057 struct ieee80211_channel *chan, bool offchan,
1058 enum nl80211_channel_type channel_type,
1059 bool channel_type_valid, unsigned int wait,
1060 const u8 *buf, size_t len, u64 *cookie )
1061#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301062int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001063 struct ieee80211_channel *chan,
1064 enum nl80211_channel_type channel_type,
1065 bool channel_type_valid,
1066 const u8 *buf, size_t len, u64 *cookie )
1067#endif //LINUX_VERSION_CODE
1068{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001069#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1070 struct net_device *dev = wdev->netdev;
1071#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05301073 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
1074 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
1075 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Jeff Johnsone7245742012-09-05 17:12:55 -07001076 tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
1077 tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
Mukul Sharma1e5d0b72014-07-01 19:22:21 +05301078 tActionFrmType actionFrmType = WLAN_HDD_ACTION_FRM_TYPE_MAX;
Jeff Johnsone7245742012-09-05 17:12:55 -07001079 bool noack = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301080 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07001081
Jeff Johnson295189b2012-06-20 16:38:30 -07001082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1083 hdd_adapter_t *goAdapter;
1084#endif
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05301085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301086 ENTER();
1087 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301088 TRACE_CODE_HDD_ACTION, pAdapter->sessionId,
1089 pAdapter->device_mode ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301090 status = wlan_hdd_validate_context(pHddCtx);
1091
1092 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08001093 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301094 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08001095 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301096
c_hpothu7f63e882013-10-02 19:13:35 +05301097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d",
1098 __func__, pAdapter->device_mode, type);
1099
1100
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001101 if ((type == SIR_MAC_MGMT_FRAME) &&
1102 (subType == SIR_MAC_MGMT_ACTION) &&
1103 (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME))
1104 {
1105 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Kaushik, Sushant731e8942014-09-08 11:59:19 +05301106#ifdef WLAN_FEATURE_P2P_DEBUG
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001107 if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001108 {
1109 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA",
1110 actionFrmType);
1111 }
1112 else
1113 {
1114 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA",
1115 p2p_action_frame_type[actionFrmType]);
1116 if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
1117 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
1118 {
1119 globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
1120 hddLog(LOGE,"[P2P State]Inactive state to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001121 "GO negotiation progress state");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001122 }
1123 else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
1124 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
1125 {
1126 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
1127 hddLog(LOGE,"[P2P State]GO nego progress to GO nego"
1128 " completed state");
1129 }
1130 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001131#endif
Kaushik, Sushant731e8942014-09-08 11:59:19 +05301132 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001133
Jeff Johnsone7245742012-09-05 17:12:55 -07001134#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1135 noack = dont_wait_for_ack;
1136#endif
1137
1138 //If the wait is coming as 0 with off channel set
1139 //then set the wait to 200 ms
1140 if (offchan && !wait)
Deepthi Gowri22d08752015-02-05 15:07:40 +05301141 {
Ganesh Kondabattini7f6049c2015-02-20 20:39:05 +05301142 wait = ACTION_FRAME_DEFAULT_WAIT;
1143 if (pRemainChanCtx)
1144 {
1145 tANI_U32 current_time = vos_timer_get_system_time();
1146 int remaining_roc_time = ((int) pRemainChanCtx->duration -
1147 (current_time - pAdapter->startRocTs));
1148 if ( remaining_roc_time > ACTION_FRAME_DEFAULT_WAIT)
1149 wait = remaining_roc_time;
1150 }
Deepthi Gowri22d08752015-02-05 15:07:40 +05301151 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001152
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 //Call sme API to send out a action frame.
1154 // OR can we send it directly through data path??
1155 // After tx completion send tx status back.
1156 if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) ||
1157 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
1158 )
1159 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001160 if (type == SIR_MAC_MGMT_FRAME)
1161 {
1162 if (subType == SIR_MAC_MGMT_PROBE_RSP)
1163 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301164 /* Drop Probe response recieved from supplicant, as for GO and
Jeff Johnson295189b2012-06-20 16:38:30 -07001165 SAP PE itself sends probe response
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301166 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 goto err_rem_channel;
1168 }
1169 else if ((subType == SIR_MAC_MGMT_DISASSOC) ||
1170 (subType == SIR_MAC_MGMT_DEAUTH))
1171 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001172 /* During EAP failure or P2P Group Remove supplicant
1173 * is sending del_station command to driver. From
1174 * del_station function, Driver will send deauth frame to
1175 * p2p client. No need to send disassoc frame from here.
1176 * so Drop the frame here and send tx indication back to
1177 * supplicant.
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 */
1179 tANI_U8 dstMac[ETH_ALEN] = {0};
1180 memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07001181 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001182 "%s: Deauth/Disassoc received for STA:"
Arif Hussain24bafea2013-11-15 15:10:03 -08001183 MAC_ADDRESS_STR,
Jeff Johnsone7245742012-09-05 17:12:55 -07001184 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08001185 MAC_ADDR_ARRAY(dstMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 goto err_rem_channel;
1187 }
1188 }
1189 }
1190
1191 if( NULL != cfgState->buf )
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08001192 {
1193 if ( !noack )
1194 {
1195 hddLog( LOGE, "(%s):Previous P2P Action frame packet pending",
1196 __func__);
1197 hdd_cleanup_actionframe(pAdapter->pHddCtx, pAdapter);
1198 }
1199 else
1200 {
1201 hddLog( LOGE, "(%s):Pending Action frame packet return EBUSY",
1202 __func__);
1203 return -EBUSY;
1204 }
1205 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001206
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301207 if( subType == SIR_MAC_MGMT_ACTION)
1208 {
1209 hddLog( LOG1, "Action frame tx request : %s",
1210 hdd_getActionString(buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET]));
1211 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001212
1213#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1214 goAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_P2P_GO );
1215
1216 //If GO adapter exists and operating on same frequency
1217 //then we will not request remain on channel
1218 if( goAdapter && ( ieee80211_frequency_to_channel(chan->center_freq)
1219 == goAdapter->sessionCtx.ap.operatingChannel ) )
1220 {
Kaushik, Sushant39bdbe22014-05-23 10:39:15 +05301221 /* if GO exist and is not off channel
1222 * wait time should be zero.
1223 */
1224 wait = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 goto send_frame;
1226 }
1227#endif
1228
1229#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1230 if( offchan && wait)
1231 {
1232 int status;
Agarwal Ashish7875e7c2014-03-11 12:54:57 +05301233 rem_on_channel_request_type_t req_type = OFF_CHANNEL_ACTION_TX;
Jeff Johnson295189b2012-06-20 16:38:30 -07001234 // In case of P2P Client mode if we are already
1235 // on the same channel then send the frame directly
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301236 mutex_lock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301237 if( (cfgState->remain_on_chan_ctx != NULL) &&
1238 (cfgState->current_freq == chan->center_freq)
1239 )
1240 {
1241 if ( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(
1242 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer) )
vamsida0e5ab2013-12-26 14:33:27 +05301243 {
Sushant Kaushik22257d62014-05-20 19:27:07 +05301244 /* Some times FW is taking almost 500 msec for
1245 * full 15 retries, which leads to ROC expiration
1246 * by the time peer gets response from other peer.
1247 * Therefore as part of temporary fix , in host
1248 * ROC time is extended. For frames where we are
1249 * expecting response from peer , its extended by
1250 * 500 msec to make ROC wait time as 1 sec and
1251 * in other cases its extended by 300 msec to make
1252 * total ROC wait as 500 msec.
1253 * TODO: FW needs to fix as why 15 retry is taking
1254 * such long time.
1255 */
1256 if ( actionFrmType == WLAN_HDD_INVITATION_REQ ||
1257 actionFrmType == WLAN_HDD_GO_NEG_REQ ||
1258 actionFrmType == WLAN_HDD_GO_NEG_RESP )
1259 wait = wait + ACTION_FRAME_RSP_WAIT;
1260 else if ( actionFrmType == WLAN_HDD_GO_NEG_CNF ||
1261 actionFrmType == WLAN_HDD_INVITATION_RESP )
1262 wait = wait + ACTION_FRAME_ACK_WAIT;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301263 vos_timer_stop(
1264 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
1265 status = vos_timer_start(
1266 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer,
1267 wait);
1268 if ( status != VOS_STATUS_SUCCESS )
vamsida0e5ab2013-12-26 14:33:27 +05301269 {
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301270 hddLog( LOGE, "Remain on Channel timer start failed");
1271 }
1272
1273 hddLog(VOS_TRACE_LEVEL_INFO,
1274 "action frame: extending the wait time %u",
1275 wait);
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301276 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301277 goto send_frame;
1278 }
1279 else
1280 {
1281 if ( TRUE ==
1282 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
1283 {
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301284 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301285 hddLog(VOS_TRACE_LEVEL_INFO,
1286 "action frame tx: waiting for completion of ROC ");
1287
1288 status = wait_for_completion_interruptible_timeout(
1289 &pAdapter->cancel_rem_on_chan_var,
1290 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
1291 if (0 >= status)
1292 {
1293 hddLog( LOGE,
1294 "%s:wait on cancel_rem_on_chan_var failed %d",
1295 __func__, status);
1296 }
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301297 goto bypass_lock;
vamsida0e5ab2013-12-26 14:33:27 +05301298 }
1299 }
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +05301300 }
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301301 mutex_unlock(&pHddCtx->roc_lock);
1302bypass_lock:
Rashmi Ramannac7744532013-10-06 16:49:08 +05301303 hddLog(VOS_TRACE_LEVEL_INFO,
1304 "action frame: Request ROC for wait time %u", wait);
Jeff Johnson295189b2012-06-20 16:38:30 -07001305 INIT_COMPLETION(pAdapter->offchannel_tx_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 status = wlan_hdd_request_remain_on_channel(wiphy, dev,
Yue Maf49ba872013-08-19 12:04:25 -07001307 chan,
1308#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1309 channel_type,
1310#endif
1311 wait, cookie,
Agarwal Ashish7875e7c2014-03-11 12:54:57 +05301312 req_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001313
1314 if(0 != status)
1315 {
1316 if( (-EBUSY == status) &&
1317 (cfgState->current_freq == chan->center_freq) )
1318 {
1319 goto send_frame;
1320 }
1321 goto err_rem_channel;
1322 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 /* Wait for driver to be ready on the requested channel */
1324 status = wait_for_completion_interruptible_timeout(
1325 &pAdapter->offchannel_tx_event,
1326 msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX));
c_hpothu7f63e882013-10-02 19:13:35 +05301327 if(0 >= status)
Jeff Johnson295189b2012-06-20 16:38:30 -07001328 {
c_hpothu7f63e882013-10-02 19:13:35 +05301329 hddLog( LOGE, "wait on offchannel_tx_event failed %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 goto err_rem_channel;
1331 }
1332 }
1333 else if ( offchan )
1334 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001335 /* Check before sending action frame
1336 whether we already remain on channel */
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 if(NULL == cfgState->remain_on_chan_ctx)
1338 {
1339 goto err_rem_channel;
1340 }
1341 }
1342 send_frame:
1343#endif
1344
Jeff Johnsone7245742012-09-05 17:12:55 -07001345 if(!noack)
1346 {
1347 cfgState->buf = vos_mem_malloc( len ); //buf;
1348 if( cfgState->buf == NULL )
1349 return -ENOMEM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001350
Jeff Johnsone7245742012-09-05 17:12:55 -07001351 cfgState->len = len;
Jeff Johnson295189b2012-06-20 16:38:30 -07001352
Jeff Johnsone7245742012-09-05 17:12:55 -07001353 vos_mem_copy( cfgState->buf, buf, len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001354
1355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsone7245742012-09-05 17:12:55 -07001356 if( cfgState->remain_on_chan_ctx )
1357 {
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301358 mutex_lock(&pHddCtx->roc_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07001359 cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie;
1360 *cookie = cfgState->action_cookie;
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301361 mutex_unlock(&pHddCtx->roc_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07001362 }
1363 else
1364 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001365#endif
Jeff Johnsonf67dca92013-11-08 17:07:40 -08001366 *cookie = (uintptr_t) cfgState->buf;
Jeff Johnsone7245742012-09-05 17:12:55 -07001367 cfgState->action_cookie = *cookie;
Jeff Johnson295189b2012-06-20 16:38:30 -07001368#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsone7245742012-09-05 17:12:55 -07001369 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001370#endif
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301371 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001372
1373 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07001374 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1375 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07001376 )
1377 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001378 tANI_U8 sessionId = pAdapter->sessionId;
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001379
Jeff Johnsone7245742012-09-05 17:12:55 -07001380 if ((type == SIR_MAC_MGMT_FRAME) &&
1381 (subType == SIR_MAC_MGMT_ACTION) &&
1382 (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME))
Jeff Johnson295189b2012-06-20 16:38:30 -07001383 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001384 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Rashmi Ramannac7744532013-10-06 16:49:08 +05301385 hddLog(LOG1, "Tx Action Frame %u.", actionFrmType);
Jeff Johnsone7245742012-09-05 17:12:55 -07001386 if (actionFrmType == WLAN_HDD_PROV_DIS_REQ)
Jeff Johnson295189b2012-06-20 16:38:30 -07001387 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001388 cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING;
Rashmi Ramannac7744532013-10-06 16:49:08 +05301389 hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING.", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001390 }
1391 else if (actionFrmType == WLAN_HDD_GO_NEG_REQ)
1392 {
1393 cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING;
Rashmi Ramannac7744532013-10-06 16:49:08 +05301394 hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING.", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001395 }
1396 }
Abhishek Singh0ebac9c2014-06-25 13:34:12 +05301397
Jeff Johnson295189b2012-06-20 16:38:30 -07001398 if (eHAL_STATUS_SUCCESS !=
1399 sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter),
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301400 sessionId, buf, len, wait, noack))
Jeff Johnson295189b2012-06-20 16:38:30 -07001401 {
1402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1403 "%s: sme_sendAction returned fail", __func__);
1404 goto err;
1405 }
1406 }
1407 else if( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
1408 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
1409 )
1410 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001411 if( VOS_STATUS_SUCCESS !=
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Jeff Johnsone7245742012-09-05 17:12:55 -07001413 buf, len, 0 ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001414 {
1415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1416 "%s: WLANSAP_SendAction returned fail", __func__);
1417 goto err;
1418 }
1419 }
1420
1421 return 0;
1422err:
Jeff Johnsone7245742012-09-05 17:12:55 -07001423 if(!noack)
1424 {
1425 hdd_sendActionCnf( pAdapter, FALSE );
1426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001427 return 0;
1428err_rem_channel:
Jeff Johnsonf67dca92013-11-08 17:07:40 -08001429 *cookie = (uintptr_t)cfgState;
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001430 cfg80211_mgmt_tx_status(
1431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1432 pAdapter->dev->ieee80211_ptr,
1433#else
1434 pAdapter->dev,
1435#endif
1436 *cookie, buf, len, FALSE, GFP_KERNEL );
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301437 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 return 0;
1439}
1440
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1442int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
1443 struct ieee80211_channel *chan, bool offchan,
1444#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1445 enum nl80211_channel_type channel_type,
1446 bool channel_type_valid,
1447#endif
1448 unsigned int wait,
1449 const u8 *buf, size_t len, bool no_cck,
1450 bool dont_wait_for_ack, u64 *cookie )
1451#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1452int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1453 struct ieee80211_channel *chan, bool offchan,
1454 enum nl80211_channel_type channel_type,
1455 bool channel_type_valid, unsigned int wait,
1456 const u8 *buf, size_t len, bool no_cck,
1457 bool dont_wait_for_ack, u64 *cookie )
1458#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1459int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1460 struct ieee80211_channel *chan, bool offchan,
1461 enum nl80211_channel_type channel_type,
1462 bool channel_type_valid, unsigned int wait,
1463 const u8 *buf, size_t len, u64 *cookie )
1464#else
1465int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1466 struct ieee80211_channel *chan,
1467 enum nl80211_channel_type channel_type,
1468 bool channel_type_valid,
1469 const u8 *buf, size_t len, u64 *cookie )
1470#endif //LINUX_VERSION_CODE
1471{
1472 int ret;
1473
1474 vos_ssr_protect(__func__);
1475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1476 ret = __wlan_hdd_mgmt_tx(wiphy, wdev,
1477 chan, offchan,
1478#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1479 channel_type,
1480 channel_type_valid,
1481#endif
1482 wait,
1483 buf, len, no_cck,
1484 dont_wait_for_ack, cookie);
1485#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1486 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
1487 channel_type, channel_type_valid, wait,
1488 buf, len, no_cck,
1489 dont_wait_for_ack, cookie);
1490#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1491 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
1492 channel_type, channel_type_valid, wait,
1493 buf, len, cookie);
1494#else
1495 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, channel_type,
1496 channel_type_valid, buf, len, cookie);
1497#endif //LINUX_VERSION_CODE
1498 vos_ssr_unprotect(__func__);
1499
1500 return ret;
1501}
1502
Jeff Johnson295189b2012-06-20 16:38:30 -07001503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301505int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001506 struct wireless_dev *wdev,
1507 u64 cookie)
1508{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301509 u64 cookie_dummy;
1510 cookie_dummy = cookie << 32;
1511 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1512 TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, NO_SESSION, cookie_dummy));
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001513 return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, wdev, cookie );
1514}
1515#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301516int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07001517 struct net_device *dev,
1518 u64 cookie)
1519{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301520 u64 cookie_dummy;
1521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1522 cookie_dummy = cookie << 32;
1523 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1524 TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT,
1525 pAdapter->sessionId, cookie_dummy));
Jeff Johnson295189b2012-06-20 16:38:30 -07001526 return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, dev, cookie );
1527}
1528#endif
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001529#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001530
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1532#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1533int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1534 struct wireless_dev *wdev,
1535 u64 cookie)
1536{
1537 int ret;
1538
1539 vos_ssr_protect(__func__);
1540 ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie);
1541 vos_ssr_unprotect(__func__);
1542
1543 return ret;
1544}
1545#else
1546int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1547 struct net_device *dev,
1548 u64 cookie)
1549{
1550 int ret;
1551
1552 vos_ssr_protect(__func__);
1553 ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, dev, cookie);
1554 vos_ssr_unprotect(__func__);
1555
1556 return ret;
1557}
1558#endif
1559#endif
1560
Jeff Johnson295189b2012-06-20 16:38:30 -07001561void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess )
1562{
1563 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
1564
Jeff Johnsone7245742012-09-05 17:12:55 -07001565 cfgState->actionFrmState = HDD_IDLE;
1566
Jeff Johnson295189b2012-06-20 16:38:30 -07001567 hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess);
1568 if( NULL == cfgState->buf )
1569 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001570 return;
1571 }
1572
1573 /* If skb is NULL it means this packet was received on CFG80211 interface
1574 * else it was received on Monitor interface */
1575 if( cfgState->skb == NULL )
1576 {
1577 /*
1578 * buf is the same pointer it passed us to send. Since we are sending
1579 * it through control path, we use different buffers.
1580 * In case of mac80211, they just push it to the skb and pass the same
1581 * data while sending tx ack status.
1582 * */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001583 cfg80211_mgmt_tx_status(
1584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1585 pAdapter->dev->ieee80211_ptr,
1586#else
1587 pAdapter->dev,
1588#endif
1589 cfgState->action_cookie,
Jeff Johnson295189b2012-06-20 16:38:30 -07001590 cfgState->buf, cfgState->len, actionSendSuccess, GFP_KERNEL );
1591 vos_mem_free( cfgState->buf );
1592 cfgState->buf = NULL;
1593 }
1594 else
1595 {
1596 hdd_adapter_t* pMonAdapter =
1597 hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR );
1598 if( pMonAdapter == NULL )
1599 {
1600 hddLog( LOGE, "Not able to get Monitor Adapter");
1601 cfgState->skb = NULL;
1602 vos_mem_free( cfgState->buf );
1603 cfgState->buf = NULL;
1604 complete(&pAdapter->tx_action_cnf_event);
1605 return;
1606 }
1607 /* Send TX completion feedback over monitor interface. */
1608 hdd_wlan_tx_complete( pMonAdapter, cfgState, actionSendSuccess );
1609 cfgState->skb = NULL;
1610 vos_mem_free( cfgState->buf );
1611 cfgState->buf = NULL;
1612 /* Look for the next Mgmt packet to TX */
1613 hdd_mon_tx_mgmt_pkt(pAdapter);
1614 }
1615 complete(&pAdapter->tx_action_cnf_event);
1616}
1617
1618/**
1619 * hdd_setP2pNoa
1620 *
1621 *FUNCTION:
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301622 * This function is called from hdd_hostapd_ioctl function when Driver
Jeff Johnson295189b2012-06-20 16:38:30 -07001623 * get P2P_SET_NOA comand from wpa_supplicant using private ioctl
1624 *
1625 *LOGIC:
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301626 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 *
1628 *ASSUMPTIONS:
1629 *
1630 *
1631 *NOTE:
1632 *
1633 * @param dev Pointer to net device structure
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301634 * @param command Pointer to command
Jeff Johnson295189b2012-06-20 16:38:30 -07001635 *
1636 * @return Status
1637 */
1638
1639int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command )
1640{
1641 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1642 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1643 VOS_STATUS status = VOS_STATUS_SUCCESS;
1644 tP2pPsConfig NoA;
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001645 int count, duration, start_time;
Jeff Johnson295189b2012-06-20 16:38:30 -07001646 char *param;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001647 tANI_U8 ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001648
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08001649 param = strnchr(command, strlen(command), ' ');
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 if (param == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301651 {
1652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1653 "%s: strnchr failed to find delimeter",__func__);
1654 return -EINVAL;
1655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 param++;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001657 ret = sscanf(param, "%d %d %d", &count, &start_time, &duration);
1658 if (ret < 3)
1659 {
1660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: P2P_SET GO NoA: fail to read param "
1662 "count=%d duration=%d interval=%d \n",
1663 __func__, count, start_time, duration);
1664 return -EINVAL;
1665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001667 "%s: P2P_SET GO NoA: count=%d duration=%d interval=%d",
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001668 __func__, count, start_time, duration);
1669 duration = MS_TO_MUS(duration);
Jeff Johnson295189b2012-06-20 16:38:30 -07001670 /* PS Selection
1671 * Periodic NoA (2)
1672 * Single NOA (4)
1673 */
1674 NoA.opp_ps = 0;
1675 NoA.ctWindow = 0;
1676 if (count == 1)
1677 {
1678 NoA.duration = 0;
1679 NoA.single_noa_duration = duration;
1680 NoA.psSelection = P2P_POWER_SAVE_TYPE_SINGLE_NOA;
1681 }
1682 else
1683 {
1684 NoA.duration = duration;
1685 NoA.single_noa_duration = 0;
1686 NoA.psSelection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA;
1687 }
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001688 NoA.interval = MS_TO_MUS(100);
Jeff Johnson295189b2012-06-20 16:38:30 -07001689 NoA.count = count;
1690 NoA.sessionid = pAdapter->sessionId;
1691
1692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1693 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1694 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001695 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001696 NoA.ctWindow, NoA.duration, NoA.interval,
1697 NoA.count, NoA.single_noa_duration,
1698 NoA.psSelection);
1699
1700 sme_p2pSetPs(hHal, &NoA);
1701 return status;
1702}
1703
1704/**
1705 * hdd_setP2pOpps
1706 *
1707 *FUNCTION:
1708 * This function is called from hdd_hostapd_ioctl function when Driver
1709 * get P2P_SET_PS comand from wpa_supplicant using private ioctl
1710 *
1711 *LOGIC:
1712 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
1713 *
1714 *ASSUMPTIONS:
1715 *
1716 *
1717 *NOTE:
1718 *
1719 * @param dev Pointer to net device structure
1720 * @param command Pointer to command
1721 *
1722 * @return Status
1723 */
1724
1725int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command )
1726{
1727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1728 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1729 VOS_STATUS status = VOS_STATUS_SUCCESS;
1730 tP2pPsConfig NoA;
1731 char *param;
1732 int legacy_ps, opp_ps, ctwindow;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001733 tANI_U8 ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001734
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08001735 param = strnchr(command, strlen(command), ' ');
Jeff Johnson295189b2012-06-20 16:38:30 -07001736 if (param == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301737 {
1738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1739 "%s: strnchr failed to find delimeter",__func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001740 return -EINVAL;
c_hpothu7f63e882013-10-02 19:13:35 +05301741 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 param++;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001743 ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow);
1744 if (ret < 3)
1745 {
1746 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1747 "%s: P2P_SET GO PS: fail to read param "
1748 " legacy_ps=%d opp_ps=%d ctwindow=%d \n",
1749 __func__, legacy_ps, opp_ps, ctwindow);
1750 return -EINVAL;
1751 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001752 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001753 "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001754 __func__, legacy_ps, opp_ps, ctwindow);
1755
1756 /* PS Selection
1757 * Opportunistic Power Save (1)
1758 */
1759
1760 /* From wpa_cli user need to use separate command to set ctWindow and Opps
1761 * When user want to set ctWindow during that time other parameters
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301762 * values are coming from wpa_supplicant as -1.
1763 * Example : User want to set ctWindow with 30 then wpa_cli command :
1764 * P2P_SET ctwindow 30
1765 * Command Received at hdd_hostapd_ioctl is as below:
Jeff Johnson295189b2012-06-20 16:38:30 -07001766 * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30)
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301767 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 if (ctwindow != -1)
1769 {
1770
1771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001772 "Opportunistic Power Save is %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07001773 (TRUE == pAdapter->ops) ? "Enable" : "Disable" );
1774
1775 if (ctwindow != pAdapter->ctw)
1776 {
1777 pAdapter->ctw = ctwindow;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301778
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 if(pAdapter->ops)
1780 {
1781 NoA.opp_ps = pAdapter->ops;
1782 NoA.ctWindow = pAdapter->ctw;
1783 NoA.duration = 0;
1784 NoA.single_noa_duration = 0;
1785 NoA.interval = 0;
1786 NoA.count = 0;
1787 NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
1788 NoA.sessionid = pAdapter->sessionId;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301789
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1791 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1792 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001793 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 NoA.ctWindow, NoA.duration, NoA.interval,
1795 NoA.count, NoA.single_noa_duration,
1796 NoA.psSelection);
1797
1798 sme_p2pSetPs(hHal, &NoA);
1799 }
1800 return 0;
1801 }
1802 }
1803
1804 if (opp_ps != -1)
1805 {
1806 pAdapter->ops = opp_ps;
1807
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301808 if ((opp_ps != -1) && (pAdapter->ctw))
Jeff Johnson295189b2012-06-20 16:38:30 -07001809 {
1810 NoA.opp_ps = opp_ps;
1811 NoA.ctWindow = pAdapter->ctw;
1812 NoA.duration = 0;
1813 NoA.single_noa_duration = 0;
1814 NoA.interval = 0;
1815 NoA.count = 0;
1816 NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
1817 NoA.sessionid = pAdapter->sessionId;
1818
1819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1820 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1821 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001822 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 NoA.ctWindow, NoA.duration, NoA.interval,
1824 NoA.count, NoA.single_noa_duration,
1825 NoA.psSelection);
1826
1827 sme_p2pSetPs(hHal, &NoA);
1828 }
1829 }
1830 return status;
1831}
1832
1833int hdd_setP2pPs( struct net_device *dev, void *msgData )
1834{
1835 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1836 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1837 VOS_STATUS status = VOS_STATUS_SUCCESS;
1838 tP2pPsConfig NoA;
1839 p2p_app_setP2pPs_t *pappNoA = (p2p_app_setP2pPs_t *) msgData;
1840
1841 NoA.opp_ps = pappNoA->opp_ps;
1842 NoA.ctWindow = pappNoA->ctWindow;
1843 NoA.duration = pappNoA->duration;
1844 NoA.interval = pappNoA->interval;
1845 NoA.count = pappNoA->count;
1846 NoA.single_noa_duration = pappNoA->single_noa_duration;
1847 NoA.psSelection = pappNoA->psSelection;
1848 NoA.sessionid = pAdapter->sessionId;
1849
1850 sme_p2pSetPs(hHal, &NoA);
1851 return status;
1852}
Jeff Johnson295189b2012-06-20 16:38:30 -07001853
1854static tANI_U8 wlan_hdd_get_session_type( enum nl80211_iftype type )
1855{
1856 tANI_U8 sessionType;
1857
1858 switch( type )
1859 {
1860 case NL80211_IFTYPE_AP:
1861 sessionType = WLAN_HDD_SOFTAP;
1862 break;
1863 case NL80211_IFTYPE_P2P_GO:
1864 sessionType = WLAN_HDD_P2P_GO;
1865 break;
1866 case NL80211_IFTYPE_P2P_CLIENT:
1867 sessionType = WLAN_HDD_P2P_CLIENT;
1868 break;
1869 case NL80211_IFTYPE_STATION:
1870 sessionType = WLAN_HDD_INFRA_STATION;
1871 break;
1872 case NL80211_IFTYPE_MONITOR:
1873 sessionType = WLAN_HDD_MONITOR;
1874 break;
1875 default:
1876 sessionType = WLAN_HDD_INFRA_STATION;
1877 break;
1878 }
1879
1880 return sessionType;
1881}
1882
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301884struct wireless_dev* __wlan_hdd_add_virtual_intf(
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001885 struct wiphy *wiphy, const char *name,
1886 enum nl80211_iftype type,
1887 u32 *flags, struct vif_params *params )
1888#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301889struct wireless_dev* __wlan_hdd_add_virtual_intf(
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001890 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1891 u32 *flags, struct vif_params *params )
1892#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301893struct net_device* __wlan_hdd_add_virtual_intf(
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1895 u32 *flags, struct vif_params *params )
1896#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301897int __wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name,
Jeff Johnson295189b2012-06-20 16:38:30 -07001898 enum nl80211_iftype type,
1899 u32 *flags, struct vif_params *params )
1900#endif
1901{
1902 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301903 hdd_adapter_t *pAdapter = NULL;
Rashmi Ramanna8f122ce2014-05-28 22:42:12 +05301904 hdd_scaninfo_t *pScanInfo = NULL;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05301905 int ret = 0;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301906
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 ENTER();
1908
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05301909 ret = wlan_hdd_validate_context(pHddCtx);
1910 if (0 != ret)
1911 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05301912#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1913 return ERR_PTR(-EINVAL);
1914#else
1915 return -EAGAIN;
1916#endif
1917 }
1918
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301919 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1920 TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type));
Agarwal Ashish4cfa1e52014-05-09 20:25:11 +05301921 if (WLAN_HDD_P2P_CLIENT != wlan_hdd_get_session_type(type) &&
1922 WLAN_HDD_INFRA_STATION != wlan_hdd_get_session_type(type) &&
1923 hdd_get_adapter(pHddCtx, wlan_hdd_get_session_type(type)) != NULL)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001924 {
Jeff Johnsond13512a2012-07-17 11:42:19 -07001925 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Interface type %d already exists. Two"
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001926 "interfaces of same type are not supported currently.",__func__, type);
c_hpothu471fc962014-06-24 16:06:53 +05301927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1928 return ERR_PTR(-EINVAL);
1929#else
1930 return -EAGAIN;
1931#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001932 }
1933
Rashmi Ramanna8f122ce2014-05-28 22:42:12 +05301934 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
1935 pScanInfo = &pHddCtx->scan_info;
1936 if ((pScanInfo != NULL) && (pAdapter != NULL) &&
1937 (pHddCtx->scan_info.mScanPending))
1938 {
1939 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
1940 eCSR_SCAN_ABORT_DEFAULT);
1941 hddLog(VOS_TRACE_LEVEL_INFO,
1942 "%s: Abort Scan while adding virtual interface",__func__);
1943 }
1944
1945 pAdapter = NULL;
Kiet Lam04e26912013-10-18 20:13:38 +05301946 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated &&
1947 ((NL80211_IFTYPE_P2P_GO == type) ||
1948 (NL80211_IFTYPE_P2P_CLIENT == type)))
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001950 /* Generate the P2P Interface Address. this address must be
1951 * different from the P2P Device Address.
1952 */
1953 v_MACADDR_t p2pDeviceAddress = pHddCtx->p2pDeviceAddress;
1954 p2pDeviceAddress.bytes[4] ^= 0x80;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301955 pAdapter = hdd_open_adapter( pHddCtx,
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 wlan_hdd_get_session_type(type),
1957 name, p2pDeviceAddress.bytes,
1958 VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 }
1960 else
1961 {
1962 pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type),
1963 name, wlan_hdd_get_intf_addr(pHddCtx), VOS_TRUE );
1964 }
1965
1966 if( NULL == pAdapter)
1967 {
1968 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__);
1969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
c_hpothu471fc962014-06-24 16:06:53 +05301970 return ERR_PTR(-EINVAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001971#else
1972 return -EINVAL;
1973#endif
1974 }
1975 EXIT();
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1977 return pAdapter->dev->ieee80211_ptr;
1978#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 return pAdapter->dev;
1980#else
1981 return 0;
1982#endif
1983}
1984
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301985#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
1986struct wireless_dev* wlan_hdd_add_virtual_intf(
1987 struct wiphy *wiphy, const char *name,
1988 enum nl80211_iftype type,
1989 u32 *flags, struct vif_params *params )
1990#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1991struct wireless_dev* wlan_hdd_add_virtual_intf(
1992 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1993 u32 *flags, struct vif_params *params )
1994#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1995struct net_device* wlan_hdd_add_virtual_intf(
1996 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1997 u32 *flags, struct vif_params *params )
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001998#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301999int wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name,
2000 enum nl80211_iftype type,
2001 u32 *flags, struct vif_params *params )
2002#endif
2003{
2004#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)))
2005 struct wireless_dev* wdev;
2006#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2007 struct net_device* ndev;
2008#else
2009 int ret;
2010#endif
2011 vos_ssr_protect(__func__);
2012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2013 wdev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
2014 vos_ssr_unprotect(__func__);
2015 return wdev;
2016#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2017 ndev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
2018 vos_ssr_unprotect(__func__);
2019 return ndev;
2020#else
2021 ret = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
2022 vos_ssr_unprotect(__func__);
2023 return ret;
2024#endif
2025}
2026
2027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2028int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
2029#else
2030int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002031#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002032{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002033#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2034 struct net_device *dev = wdev->netdev;
2035#endif
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302036 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302038 hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2039 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302040
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302041 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07002042
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302043 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2044 TRACE_CODE_HDD_DEL_VIRTUAL_INTF,
2045 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302046 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2047 __func__,pVirtAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002048
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302049 status = wlan_hdd_validate_context(pHddCtx);
2050
2051 if (0 != status)
2052 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302053 return status;
2054 }
2055
2056 wlan_hdd_release_intf_addr( pHddCtx,
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 pVirtAdapter->macAddressCurrent.bytes );
2058
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05302059 hdd_stop_adapter( pHddCtx, pVirtAdapter, VOS_TRUE);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302060 hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE );
2061 EXIT();
2062 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002063}
2064
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05302065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2066int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
2067#else
2068int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
2069#endif
2070{
2071 int ret;
2072
2073 vos_ssr_protect(__func__);
2074#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2075 ret = __wlan_hdd_del_virtual_intf(wiphy, wdev);
2076#else
2077 ret = __wlan_hdd_del_virtual_intf(wiphy, dev);
2078#endif
2079 vos_ssr_unprotect(__func__);
2080
2081 return ret;
2082}
2083
Jeff Johnson295189b2012-06-20 16:38:30 -07002084void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002085 tANI_U32 nFrameLength,
2086 tANI_U8* pbFrames,
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302087 tANI_U8 frameType )
Jeff Johnson295189b2012-06-20 16:38:30 -07002088{
2089 //Indicate a Frame over Monitor Intf.
2090 int rxstat;
2091 struct sk_buff *skb = NULL;
2092 int needed_headroom = 0;
2093 int flag = HDD_RX_FLAG_IV_STRIPPED | HDD_RX_FLAG_DECRYPTED |
2094 HDD_RX_FLAG_MMIC_STRIPPED;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002095#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002096#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
2097 hdd_context_t* pHddCtx = (hdd_context_t*)(pMonAdapter->pHddCtx);
2098#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002099#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 hddLog( LOG1, FL("Indicate Frame over Monitor Intf"));
2101
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002102 if (NULL == pbFrames)
2103 {
2104 hddLog(LOGE, FL("NULL frame pointer"));
2105 return;
2106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002107
2108 /* room for the radiotap header based on driver features
2109 * 1 Byte for RADIO TAP Flag, 1 Byte padding and 2 Byte for
2110 * RX flags.
2111 * */
2112 needed_headroom = sizeof(struct ieee80211_radiotap_header) + 4;
2113
2114 //alloc skb here
2115 skb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC);
2116 if (unlikely(NULL == skb))
2117 {
2118 hddLog( LOGW, FL("Unable to allocate skb"));
2119 return;
2120 }
2121 skb_reserve(skb, VPKT_SIZE_BUFFER);
2122 if (unlikely(skb_headroom(skb) < nFrameLength))
2123 {
2124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2125 "HDD [%d]: Insufficient headroom, "
2126 "head[%p], data[%p], req[%d]",
2127 __LINE__, skb->head, skb->data, nFrameLength);
2128 kfree_skb(skb);
2129 return ;
2130 }
2131 // actually push the data
2132 memcpy(skb_push(skb, nFrameLength), pbFrames, nFrameLength);
2133 /* prepend radiotap information */
2134 if( 0 != hdd_wlan_add_rx_radiotap_hdr( skb, needed_headroom, flag ) )
2135 {
2136 hddLog( LOGE, FL("Not Able Add Radio Tap"));
2137 //free skb
2138 kfree_skb(skb);
2139 return ;
2140 }
2141
2142 skb_reset_mac_header( skb );
2143 skb->dev = pMonAdapter->dev;
2144 skb->protocol = eth_type_trans( skb, skb->dev );
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002145 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002146#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002147#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07002148 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07002149#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002151 rxstat = netif_rx_ni(skb);
2152 if( NET_RX_SUCCESS == rxstat )
2153 {
2154 hddLog( LOG1, FL("Success"));
2155 }
2156 else
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302157 hddLog( LOGE, FL("Failed %d"), rxstat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002158
2159 return ;
2160}
2161
2162void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter,
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302163 tANI_U32 nFrameLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002164 tANI_U8* pbFrames,
2165 tANI_U8 frameType,
Chilam NG571c65a2013-01-19 12:27:36 +05302166 tANI_U32 rxChan,
2167 tANI_S8 rxRssi )
Jeff Johnson295189b2012-06-20 16:38:30 -07002168{
2169 tANI_U16 freq;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302170 tANI_U16 extend_time;
Jeff Johnsone7245742012-09-05 17:12:55 -07002171 tANI_U8 type = 0;
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002172 tANI_U8 subType = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002173 tActionFrmType actionFrmType;
2174 hdd_cfg80211_state_t *cfgState = NULL;
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302175 hdd_scaninfo_t *pScanInfo = NULL;
Kaushik, Sushant13a287c2014-05-03 12:26:27 +05302176 hdd_context_t *pHddCtx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302177 VOS_STATUS status;
2178 hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002179
Arif Hussain6d2a3322013-11-17 19:50:10 -08002180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Frame Type = %d Frame Length = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002181 __func__, frameType, nFrameLength);
2182
2183 if (NULL == pAdapter)
2184 {
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002185 hddLog(LOGE, FL("pAdapter is NULL"));
2186 return;
2187 }
2188
2189 if (0 == nFrameLength)
2190 {
2191 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
2192 return;
2193 }
2194
2195 if (NULL == pbFrames)
2196 {
2197 hddLog(LOGE, FL("pbFrames is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002198 return;
2199 }
2200
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002201 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
2202 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
2203
2204 /* Get pAdapter from Destination mac address of the frame */
2205 if ((type == SIR_MAC_MGMT_FRAME) &&
2206 (subType != SIR_MAC_MGMT_PROBE_REQ))
2207 {
2208 pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter),
2209 &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]);
2210 if (NULL == pAdapter)
2211 {
2212 /* Under assumtion that we don't receive any action frame
2213 * with BCST as destination we dropping action frame
2214 */
Madan Mohan Koyyalamudi051ff0b2012-12-03 16:55:26 -08002215 hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = "
2216 MAC_ADDRESS_STR ,
2217 MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]));
2218 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d"
Arif Hussain6d2a3322013-11-17 19:50:10 -08002219 " subType = %d",__func__,frameType,nFrameLength,subType);
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002220 return;
2221 }
2222 }
2223
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002224
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 if (NULL == pAdapter->dev)
2226 {
2227 hddLog( LOGE, FL("pAdapter->dev is NULL"));
2228 return;
2229 }
2230
2231 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2232 {
2233 hddLog( LOGE, FL("pAdapter has invalid magic"));
2234 return;
2235 }
2236
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302237 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2238 if (NULL == pHddCtx)
2239 {
2240 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
2241 return;
2242 }
2243
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002244 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
2245 (WLAN_HDD_P2P_GO == pAdapter->device_mode ))
Jeff Johnson295189b2012-06-20 16:38:30 -07002246 {
2247 hdd_adapter_t *pMonAdapter =
2248 hdd_get_mon_adapter( WLAN_HDD_GET_CTX(pAdapter) );
2249
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002250 if (NULL != pMonAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 {
2252 hddLog( LOG1, FL("Indicate Frame over Monitor Interface"));
2253 hdd_sendMgmtFrameOverMonitorIface( pMonAdapter, nFrameLength,
2254 pbFrames, frameType);
2255 return;
2256 }
2257 }
2258
2259 //Channel indicated may be wrong. TODO
2260 //Indicate an action frame.
2261 if( rxChan <= MAX_NO_OF_2_4_CHANNELS )
2262 {
2263 freq = ieee80211_channel_to_frequency( rxChan,
2264 IEEE80211_BAND_2GHZ);
2265 }
2266 else
2267 {
2268 freq = ieee80211_channel_to_frequency( rxChan,
2269 IEEE80211_BAND_5GHZ);
2270 }
2271
Jeff Johnsone7245742012-09-05 17:12:55 -07002272 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302273 pRemainChanCtx = cfgState->remain_on_chan_ctx;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302274
2275 if ((type == SIR_MAC_MGMT_FRAME) &&
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002276 (subType == SIR_MAC_MGMT_ACTION))
Jeff Johnsone7245742012-09-05 17:12:55 -07002277 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002278 if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)
2279 {
2280 // public action frame
2281 if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == SIR_MAC_ACTION_VENDOR_SPECIFIC) &&
Sudhir Sattayappa Kohallic8239802013-02-22 18:46:44 -08002282 vos_mem_compare(&pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE))
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002283 // P2P action frames
2284 {
2285 actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002286 hddLog(LOG1, "Rx Action Frame %u", actionFrmType);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002287#ifdef WLAN_FEATURE_P2P_DEBUG
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002288 if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
2289 {
2290 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] <--- OTA",
2291 actionFrmType);
2292 }
2293 else
2294 {
2295 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s <--- OTA",
2296 p2p_action_frame_type[actionFrmType]);
2297 if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
2298 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
2299 {
2300 globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
2301 hddLog(LOGE,"[P2P State]Inactive state to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002302 "GO negotiation progress state");
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002303 }
2304 else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
2305 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
2306 {
2307 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
Jeff Johnson1250df42012-12-10 14:31:52 -08002308 hddLog(LOGE,"[P2P State]GO negotiation progress to "
2309 "GO negotiation completed state");
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002310 }
2311 else if( (actionFrmType == WLAN_HDD_INVITATION_REQ) &&
2312 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
2313 {
2314 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
2315 hddLog(LOGE,"[P2P State]Inactive state to GO negotiation"
2316 " completed state Autonomous GO formation");
2317 }
2318 }
2319#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302320 if (pRemainChanCtx != NULL && VOS_TIMER_STATE_RUNNING
2321 == vos_timer_getCurrentState(&pRemainChanCtx->hdd_remain_on_chan_timer))
2322 {
2323 if ( actionFrmType == WLAN_HDD_GO_NEG_REQ ||
2324 actionFrmType == WLAN_HDD_GO_NEG_RESP ||
2325 actionFrmType == WLAN_HDD_INVITATION_REQ ||
2326 actionFrmType == WLAN_HDD_DEV_DIS_REQ ||
2327 actionFrmType == WLAN_HDD_PROV_DIS_REQ )
2328 {
2329 hddLog( LOG1, "Extend RoC timer on reception of"
2330 " Action Frame");
2331 if ((actionFrmType == WLAN_HDD_GO_NEG_REQ)
2332 || (actionFrmType == WLAN_HDD_GO_NEG_RESP))
2333 extend_time = 2 * ACTION_FRAME_DEFAULT_WAIT;
2334 else
2335 extend_time = ACTION_FRAME_DEFAULT_WAIT;
2336 if (completion_done(&pAdapter->rem_on_chan_ready_event))
2337 {
2338 vos_timer_stop(
2339 &pRemainChanCtx->hdd_remain_on_chan_timer);
2340 status = vos_timer_start(
2341 &pRemainChanCtx->hdd_remain_on_chan_timer,
2342 extend_time);
2343 if (status != VOS_STATUS_SUCCESS)
2344 {
2345 hddLog( LOGE, "ROC timer start failed");
2346 }
2347 }
2348 else
2349 {
2350 // Buffer Packet
2351 if (pRemainChanCtx->action_pkt_buff.frame_length == 0)
2352 {
2353 pRemainChanCtx->action_pkt_buff.frame_length =
2354 nFrameLength;
2355 pRemainChanCtx->action_pkt_buff.freq = freq;
2356 pRemainChanCtx->action_pkt_buff.frame_ptr
2357 = vos_mem_malloc(nFrameLength);
2358 vos_mem_copy(
2359 pRemainChanCtx->action_pkt_buff.frame_ptr,
2360 pbFrames, nFrameLength);
2361 hddLog( LOGE,"%s:"
2362 "Action Pkt Cached successfully !!!", __func__);
2363 }
2364 else
2365 {
2366 hddLog( LOGE,"%s:"
2367 "Frames are pending. dropping frame !!!",
2368 __func__);
2369 }
2370 return;
2371 }
2372 }
2373 }
2374 if (pRemainChanCtx != NULL &&
2375 VOS_TIMER_STATE_RUNNING != vos_timer_getCurrentState(
2376 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer))
2377 hddLog( LOG1, "%s:"
2378 "Rcvd action frame after timer expired ", __func__);
2379
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302380 if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) &&
2381 (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) ||
2382 ((actionFrmType == WLAN_HDD_GO_NEG_RESP) &&
2383 (cfgState->actionFrmState == HDD_GO_NEG_REQ_ACK_PENDING)))
2384 {
2385 hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ",
2386 __func__);
2387 hdd_sendActionCnf(pAdapter, TRUE);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002388 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002389 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002390#ifdef FEATURE_WLAN_TDLS
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002391 else if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP)
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002392 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002393 u8 *mac = &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6];
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302394 hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] TDLS Discovery Response," MAC_ADDRESS_STR " RSSI[%d] <--- OTA",
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002395 MAC_ADDR_ARRAY(mac),rxRssi);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302396
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002397 wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi);
2398 wlan_hdd_tdls_recv_discovery_resp(pAdapter, mac);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002399 }
2400#endif
2401 }
Kaushik, Sushant507a8612014-10-21 17:00:55 +05302402
2403 pScanInfo = &pHddCtx->scan_info;
2404 if ((pScanInfo != NULL) && (pHddCtx->scan_info.mScanPending))
2405 {
2406 hddLog(LOGE,"Action frame received when Scanning is in"
2407 " progress. Abort Scan.");
2408 hdd_abort_mac_scan(pAdapter->pHddCtx,
2409 pScanInfo->sessionId,
2410 eCSR_SCAN_ABORT_DEFAULT);
2411 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302412
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002413 if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_TDLS_ACTION_FRAME)
2414 {
2415 actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1];
2416 if(actionFrmType >= MAX_TDLS_ACTION_FRAME_TYPE)
2417 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302418 hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] Action type[%d] <--- OTA",
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002419 actionFrmType);
2420 }
2421 else
2422 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302423 hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] %s <--- OTA",
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002424 tdls_action_frame_type[actionFrmType]);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002425 }
2426 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302427
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002428 if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_QOS_ACTION_FRAME)&&
2429 (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_QOS_MAP_CONFIGURE) )
2430 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002431 sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2432 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002433 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002434 }
2435
Jeff Johnson295189b2012-06-20 16:38:30 -07002436 //Indicate Frame Over Normal Interface
2437 hddLog( LOG1, FL("Indicate Frame over NL80211 Interface"));
2438
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2440 cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, 0,
2441 pbFrames, nFrameLength,
2442 GFP_ATOMIC );
2443#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002444 cfg80211_rx_mgmt( pAdapter->dev, freq, 0,
2445 pbFrames, nFrameLength,
2446 GFP_ATOMIC );
2447#else
2448 cfg80211_rx_mgmt( pAdapter->dev, freq,
2449 pbFrames, nFrameLength,
2450 GFP_ATOMIC );
2451#endif //LINUX_VERSION_CODE
2452}
2453
2454/*
2455 * ieee80211_add_rx_radiotap_header - add radiotap header
2456 */
2457static int hdd_wlan_add_rx_radiotap_hdr (
2458 struct sk_buff *skb, int rtap_len, int flag )
2459{
2460 u8 rtap_temp[20] = {0};
2461 struct ieee80211_radiotap_header *rthdr;
2462 unsigned char *pos;
2463 u16 rx_flags = 0;
2464
2465 rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]);
2466
2467 /* radiotap header, set always present flags */
2468 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
2469 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
2470 rthdr->it_len = cpu_to_le16(rtap_len);
2471
2472 pos = (unsigned char *) (rthdr + 1);
2473
2474 /* the order of the following fields is important */
2475
2476 /* IEEE80211_RADIOTAP_FLAGS */
2477 *pos = 0;
2478 pos++;
2479
2480 /* IEEE80211_RADIOTAP_RX_FLAGS: Length 2 Bytes */
2481 /* ensure 2 byte alignment for the 2 byte field as required */
2482 if ((pos - (u8 *)rthdr) & 1)
2483 pos++;
2484 put_unaligned_le16(rx_flags, pos);
2485 pos += 2;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302486
Jeff Johnson295189b2012-06-20 16:38:30 -07002487 // actually push the data
2488 memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len);
2489
2490 return 0;
2491}
2492
2493static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
2494 hdd_cfg80211_state_t* cfgState,
2495 tANI_BOOLEAN actionSendSuccess )
2496{
2497 struct ieee80211_radiotap_header *rthdr;
2498 unsigned char *pos;
2499 struct sk_buff *skb = cfgState->skb;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002500#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002501#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
2502 hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
2503#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002504#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002505
2506 /* 2 Byte for TX flags and 1 Byte for Retry count */
2507 u32 rtHdrLen = sizeof(*rthdr) + 3;
2508
2509 u8 *data;
2510
2511 /* We have to return skb with Data starting with MAC header. We have
2512 * copied SKB data starting with MAC header to cfgState->buf. We will pull
2513 * entire skb->len from skb and then we will push cfgState->buf to skb
2514 * */
2515 if( NULL == skb_pull(skb, skb->len) )
2516 {
2517 hddLog( LOGE, FL("Not Able to Pull %d byte from skb"), skb->len);
2518 kfree_skb(cfgState->skb);
2519 return;
2520 }
2521
2522 data = skb_push( skb, cfgState->len );
2523
2524 if (data == NULL)
2525 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08002526 hddLog( LOGE, FL("Not Able to Push %zu byte to skb"), cfgState->len);
Jeff Johnson295189b2012-06-20 16:38:30 -07002527 kfree_skb( cfgState->skb );
2528 return;
2529 }
2530
2531 memcpy( data, cfgState->buf, cfgState->len );
2532
2533 /* send frame to monitor interfaces now */
2534 if( skb_headroom(skb) < rtHdrLen )
2535 {
2536 hddLog( LOGE, FL("No headroom for rtap header"));
2537 kfree_skb(cfgState->skb);
2538 return;
2539 }
2540
2541 rthdr = (struct ieee80211_radiotap_header*) skb_push( skb, rtHdrLen );
2542
2543 memset( rthdr, 0, rtHdrLen );
2544 rthdr->it_len = cpu_to_le16( rtHdrLen );
2545 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
2546 (1 << IEEE80211_RADIOTAP_DATA_RETRIES)
2547 );
2548
2549 pos = (unsigned char *)( rthdr+1 );
2550
2551 // Fill TX flags
2552 *pos = actionSendSuccess;
2553 pos += 2;
2554
2555 // Fill retry count
2556 *pos = 0;
2557 pos++;
2558
2559 skb_set_mac_header( skb, 0 );
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002560 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002561 skb->pkt_type = PACKET_OTHERHOST;
2562 skb->protocol = htons(ETH_P_802_2);
2563 memset( skb->cb, 0, sizeof( skb->cb ) );
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002564#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002565#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07002566 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07002567#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002569 if (in_interrupt())
2570 netif_rx( skb );
2571 else
2572 netif_rx_ni( skb );
2573
2574 /* Enable Queues which we have disabled earlier */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302575 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05302576 netif_tx_start_all_queues( pAdapter->dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07002577
2578}
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05302579
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302580void __hdd_p2p_roc_work_queue(struct work_struct *work)
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05302581{
2582 hdd_adapter_t *pAdapter = container_of(to_delayed_work(work), hdd_adapter_t, roc_work);
2583 hddLog( VOS_TRACE_LEVEL_INFO, FL("%s: "), __func__);
2584 wlan_hdd_p2p_start_remain_on_channel(pAdapter);
2585 return;
2586}
2587
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302588void hdd_p2p_roc_work_queue(struct work_struct *work)
2589{
2590 vos_ssr_protect(__func__);
2591 __hdd_p2p_roc_work_queue(work);
2592 vos_ssr_unprotect(__func__);
2593 return;
2594}