blob: 9c1e9a663c5d5ba1bc6c0b839c422efcaeda6ec7 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302 * Copyright (c) 2012-2014, 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
34 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
35
36 Qualcomm Confidential and Proprietary.
37
38 ========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070039
40#include <wlan_hdd_includes.h>
41#include <wlan_hdd_hostapd.h>
42#include <net/cfg80211.h>
43#include "sme_Api.h"
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070044#include "sme_QosApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070045#include "wlan_hdd_p2p.h"
46#include "sapApi.h"
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053047#include "wlan_hdd_main.h"
Daram Sudha1f7e0e92013-12-17 07:52:31 +053048#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070049#include <linux/netdevice.h>
50#include <linux/skbuff.h>
51#include <linux/etherdevice.h>
52#include <net/ieee80211_radiotap.h>
Hoonki Lee1090c6a2013-01-16 17:40:54 -080053#ifdef FEATURE_WLAN_TDLS
54#include "wlan_hdd_tdls.h"
55#endif
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053056#include "wlan_hdd_trace.h"
57#include "vos_types.h"
58#include "vos_trace.h"
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +053059#include "vos_sched.h"
60
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -080061//Ms to Micro Sec
62#define MS_TO_MUS(x) ((x)*1000);
Daram Sudha1f7e0e92013-12-17 07:52:31 +053063tANI_U8* hdd_getActionString( tANI_U16 MsgType )
64{
65 switch (MsgType)
66 {
67 CASE_RETURN_STRING(SIR_MAC_ACTION_SPECTRUM_MGMT);
68 CASE_RETURN_STRING(SIR_MAC_ACTION_QOS_MGMT);
69 CASE_RETURN_STRING(SIR_MAC_ACTION_DLP);
70 CASE_RETURN_STRING(SIR_MAC_ACTION_BLKACK);
71 CASE_RETURN_STRING(SIR_MAC_ACTION_PUBLIC_USAGE);
72 CASE_RETURN_STRING(SIR_MAC_ACTION_RRM);
73 CASE_RETURN_STRING(SIR_MAC_ACTION_FAST_BSS_TRNST);
74 CASE_RETURN_STRING(SIR_MAC_ACTION_HT);
75 CASE_RETURN_STRING(SIR_MAC_ACTION_SA_QUERY);
76 CASE_RETURN_STRING(SIR_MAC_ACTION_PROT_DUAL_PUB);
77 CASE_RETURN_STRING(SIR_MAC_ACTION_WNM);
78 CASE_RETURN_STRING(SIR_MAC_ACTION_UNPROT_WNM);
79 CASE_RETURN_STRING(SIR_MAC_ACTION_TDLS);
80 CASE_RETURN_STRING(SIR_MAC_ACITON_MESH);
81 CASE_RETURN_STRING(SIR_MAC_ACTION_MULTIHOP);
82 CASE_RETURN_STRING(SIR_MAC_SELF_PROTECTED);
83 CASE_RETURN_STRING(SIR_MAC_ACTION_WME);
84 CASE_RETURN_STRING(SIR_MAC_ACTION_VHT);
85 default:
86 return ("UNKNOWN");
87 }
88}
89
90
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070091#ifdef WLAN_FEATURE_P2P_DEBUG
92#define MAX_P2P_ACTION_FRAME_TYPE 9
93const char *p2p_action_frame_type[]={"GO Negotiation Request",
94 "GO Negotiation Response",
95 "GO Negotiation Confirmation",
96 "P2P Invitation Request",
97 "P2P Invitation Response",
98 "Device Discoverability Request",
99 "Device Discoverability Response",
100 "Provision Discovery Request",
101 "Provision Discovery Response"};
102
103/* We no need to protect this variable since
104 * there is no chance of race to condition
105 * and also not make any complicating the code
106 * just for debugging log
107 */
108tP2PConnectionStatus globalP2PConnectionStatus = P2P_NOT_ACTIVE;
109
110#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -0800111#ifdef WLAN_FEATURE_TDLS_DEBUG
112#define MAX_TDLS_ACTION_FRAME_TYPE 11
113const char *tdls_action_frame_type[] = {"TDLS Setup Request",
114 "TDLS Setup Response",
115 "TDLS Setup Confirm",
116 "TDLS Teardown",
117 "TDLS Peer Traffic Indication",
118 "TDLS Channel Switch Request",
119 "TDLS Channel Switch Response",
120 "TDLS Peer PSM Request",
121 "TDLS Peer PSM Response",
122 "TDLS Peer Traffic Response",
123 "TDLS Discovery Request" };
124#endif
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -0700125
Jeff Johnson295189b2012-06-20 16:38:30 -0700126extern struct net_device_ops net_ops_struct;
127
128static int hdd_wlan_add_rx_radiotap_hdr( struct sk_buff *skb,
129 int rtap_len, int flag );
130
131static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
132 hdd_cfg80211_state_t* cfgState,
133 tANI_BOOLEAN actionSendSuccess );
134
135static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
Rashmi Ramannac7744532013-10-06 16:49:08 +0530136 tANI_U32 nFrameLength,
Jeff Johnson295189b2012-06-20 16:38:30 -0700137 tANI_U8* pbFrames,
138 tANI_U8 frameType );
vamsi9bd92b72013-12-26 14:11:29 +0530139
140static v_BOOL_t hdd_p2p_is_action_type_rsp( const u8 *buf )
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +0530141{
vamsi9bd92b72013-12-26 14:11:29 +0530142 tActionFrmType actionFrmType;
143 const u8 *ouiPtr;
144
145 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] !=
146 WLAN_HDD_PUBLIC_ACTION_FRAME ) {
147 return VOS_FALSE;
148 }
149
150 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET] !=
151 WLAN_HDD_VENDOR_SPECIFIC_ACTION ) {
152 return VOS_FALSE;
153 }
154
155 ouiPtr = &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET];
156
157 if ( WPA_GET_BE24(ouiPtr) != WLAN_HDD_WFA_OUI ) {
158 return VOS_FALSE;
159 }
160
161 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET] !=
162 WLAN_HDD_WFA_P2P_OUI_TYPE ) {
163 return VOS_FALSE;
164 }
165
Ahmad Kholaife5ec2cd2014-03-19 13:22:04 +0530166 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET];
vamsi9bd92b72013-12-26 14:11:29 +0530167 if ( actionFrmType != WLAN_HDD_INVITATION_REQ &&
168 actionFrmType != WLAN_HDD_GO_NEG_REQ &&
169 actionFrmType != WLAN_HDD_DEV_DIS_REQ &&
170 actionFrmType != WLAN_HDD_PROV_DIS_REQ )
171 return VOS_TRUE;
172 else
173 return VOS_FALSE;
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +0530174}
Jeff Johnson295189b2012-06-20 16:38:30 -0700175
Jeff Johnson295189b2012-06-20 16:38:30 -0700176eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx,
177 eHalStatus status )
178{
179 hdd_adapter_t *pAdapter = (hdd_adapter_t*) pCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700180 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
181 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530182 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700183
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530184 if (pHddCtx == NULL)
185 {
186 hddLog(LOGE, "%s: Hdd Context is NULL", __func__);
187 return eHAL_STATUS_FAILURE;
188 }
189 if (pRemainChanCtx == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700190 {
191 hddLog( LOGW,
192 "%s: No Rem on channel pending for which Rsp is received", __func__);
193 return eHAL_STATUS_SUCCESS;
194 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530195
196 mutex_lock(&pHddCtx->roc_lock);
Rashmi Ramannac7744532013-10-06 16:49:08 +0530197 hddLog( VOS_TRACE_LEVEL_INFO,
198 "Received ROC rsp (request type %d, channel %d, cookie %llu",
199 pRemainChanCtx->rem_on_chan_request,
200 pRemainChanCtx->chan.center_freq,
201 pRemainChanCtx->cookie);
Jeff Johnson295189b2012-06-20 16:38:30 -0700202 cfgState->remain_on_chan_ctx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530203 vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer);
204 vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530205 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530206 if ( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 {
208 if( cfgState->buf )
209 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530210 hddLog( LOGP,
Jeff Johnson295189b2012-06-20 16:38:30 -0700211 "%s: We need to receive yet an ack from one of tx packet",
212 __func__);
213 }
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800214 cfg80211_remain_on_channel_expired(
215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
216 pRemainChanCtx->dev->ieee80211_ptr,
217#else
218 pRemainChanCtx->dev,
219#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700220 pRemainChanCtx->cookie,
221 &pRemainChanCtx->chan,
Yue Maf49ba872013-08-19 12:04:25 -0700222#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
223 pRemainChanCtx->chan_type,
224#endif
225 GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700226 }
227
Jeff Johnson295189b2012-06-20 16:38:30 -0700228
229 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
Jeff Johnsone7245742012-09-05 17:12:55 -0700230 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
231 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 )
233 {
234 tANI_U8 sessionId = pAdapter->sessionId;
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800235 if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
236 {
237 sme_DeregisterMgmtFrame(
238 hHal, sessionId,
239 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
240 NULL, 0 );
241 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700242 }
243 else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
244 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
245 )
246 {
247 WLANSAP_DeRegisterMgmtFrame(
248 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
249 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
250 NULL, 0 );
251 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530252 if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL
253 && pRemainChanCtx->action_pkt_buff.frame_length != 0)
254 {
255 vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
256 }
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800257 vos_mem_free( pRemainChanCtx );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800258 pRemainChanCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700259 complete(&pAdapter->cancel_rem_on_chan_var);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530260 pAdapter->is_roc_inprogress = FALSE;
261 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 return eHAL_STATUS_SUCCESS;
263}
264
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530265VOS_STATUS wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700266{
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530268 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530269 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 int status = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700271
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530272 if (NULL == pHddCtx)
273 {
274 hddLog(LOGE, "%s: HddCtx is NULL", __func__);
275 return VOS_STATUS_E_FAILURE;
276 }
277
278 mutex_lock(&pHddCtx->roc_lock);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700279 if(cfgState->remain_on_chan_ctx != NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 {
Rashmi Ramannac7744532013-10-06 16:49:08 +0530281 hddLog(VOS_TRACE_LEVEL_INFO,
282 "Cancel Existing ROC (cookie=%llu)",
283 cfgState->remain_on_chan_ctx->cookie);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700284
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530285 vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530286
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530287 /* Wait till remain on channel ready indication before issuing cancel
288 * remain on channel request, otherwise if remain on channel not
289 * received and if the driver issues cancel remain on channel then lim
Jeff Johnson295189b2012-06-20 16:38:30 -0700290 * will be in unknown state.
291 */
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530292 if (pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress != TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 {
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530294 status = wait_for_completion_interruptible_timeout(
295 &pAdapter->rem_on_chan_ready_event,
296 msecs_to_jiffies(WAIT_REM_CHAN_READY));
297 if (0 >= status)
298 {
299 hddLog( LOGE,
300 "%s: timeout waiting for remain on channel"
301 " ready indication %d",
302 __func__, status);
303 pRemainChanCtx->is_pending_roc_cancelled = TRUE;
304 mutex_unlock(&pHddCtx->roc_lock);
305 return VOS_STATUS_E_FAILURE;
306 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700307
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530308 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
309 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530310
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530311 /* Issue abort remain on chan request to sme.
312 * The remain on channel callback will make sure the remain_on_chan
313 * expired event is sent.
314 */
315 if (( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
316 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
317 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ))
318 {
319 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 pAdapter->sessionId );
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530321 }
322 else if ( (WLAN_HDD_SOFTAP== pAdapter->device_mode) ||
323 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
324 {
325 WLANSAP_CancelRemainOnChannel(
326 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
327 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700328
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530329 mutex_unlock(&pHddCtx->roc_lock);
330 status = wait_for_completion_interruptible_timeout(
331 &pAdapter->cancel_rem_on_chan_var,
332 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
333 if (0 >= status)
334 {
335 hddLog( LOGE,
336 "%s: timeout waiting for cancel remain on channel"
337 " ready indication %d",
338 __func__, status);
339 }
340 hdd_allow_suspend();
341 }
342 else
343 {
344 hddLog( LOG1,
345 "ROC timer cancellation in progress,"
346 " wait for completion");
347 mutex_unlock(&pHddCtx->roc_lock);
348 status = wait_for_completion_interruptible_timeout(
349 &pAdapter->cancel_rem_on_chan_var,
350 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
351 if (0 >= status)
352 {
353 hddLog( LOGE,
354 "%s:wait on cancel_rem_on_chan_var failed %d",
355 __func__, status);
356 return VOS_STATUS_E_FAILURE;
357 }
358 return VOS_STATUS_SUCCESS;
359 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700360 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530361 else
362 {
363 hddLog(LOG1,
364 "%s: remain_on_chan_ctx is NULL", __func__);
365 mutex_unlock(&pHddCtx->roc_lock);
366 }
367 return VOS_STATUS_SUCCESS;
Jeff Johnson32d95a32012-09-10 13:15:23 -0700368}
369
370int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter)
371{
372 int status = 0;
373 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
374
375 if(WLAN_HDD_P2P_GO != pAdapter->device_mode)
376 {
377 //Cancel Existing Remain On Channel
378 //If no action frame is pending
379 if( cfgState->remain_on_chan_ctx != NULL)
380 {
381 //Check whether Action Frame is pending or not
382 if( cfgState->buf == NULL)
383 {
384 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
385 }
386 else
387 {
Rashmi Ramannac7744532013-10-06 16:49:08 +0530388 hddLog(VOS_TRACE_LEVEL_DEBUG,
389 "Cannot Cancel Existing Remain on Channel");
Jeff Johnson32d95a32012-09-10 13:15:23 -0700390 status = -EBUSY;
391 }
392 }
393 }
394 return status;
395}
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530396void wlan_hdd_remain_on_chan_timeout(void *data)
397{
398 hdd_adapter_t *pAdapter = (hdd_adapter_t *)data;
399 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
400 hdd_cfg80211_state_t *cfgState;
401 if ( NULL == pAdapter )
402 {
403 hddLog( LOGE, FL("pAdapter is NULL !!!"));
404 return;
405 }
406 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
407 pRemainChanCtx = cfgState->remain_on_chan_ctx;
408 if (NULL == pRemainChanCtx)
409 {
410 hddLog( LOGE, FL("No Remain on channel is pending"));
411 return;
412 }
413 if ( TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
414 {
415 hddLog( LOGE, FL("Cancellation already in progress"));
416 return;
417 }
418
419 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
420 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
421 hddLog( LOG1,"%s: Cancel Remain on Channel on timeout", __func__);
422 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
423 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
424 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
425 )
426 {
427 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
428 pAdapter->sessionId );
429 }
430 else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
431 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
432 )
433 {
434 WLANSAP_CancelRemainOnChannel(
435 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
436 }
437 hdd_allow_suspend();
438}
Jeff Johnson32d95a32012-09-10 13:15:23 -0700439
440static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy,
441 struct net_device *dev,
442 struct ieee80211_channel *chan,
Yue Maf49ba872013-08-19 12:04:25 -0700443#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson32d95a32012-09-10 13:15:23 -0700444 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -0700445#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -0700446 unsigned int duration, u64 *cookie,
447 rem_on_channel_request_type_t request_type )
448{
449 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
450 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
451 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530452 VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
453 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
454 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
455 hdd_adapter_t *pAdapter_temp;
456 VOS_STATUS status;
457 v_BOOL_t isGoPresent = VOS_FALSE;
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530458 VOS_STATUS checkReadyInd;
Jeff Johnson32d95a32012-09-10 13:15:23 -0700459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
460 __func__,pAdapter->device_mode);
Yue Maf49ba872013-08-19 12:04:25 -0700461#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Rashmi Ramannac7744532013-10-06 16:49:08 +0530462 hddLog(VOS_TRACE_LEVEL_INFO,
463 "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, dur %d,"
464 " request type %d, cookie %llu",
465 chan->hw_value, chan->center_freq, channel_type, duration,
466 request_type, *cookie);
Yue Maf49ba872013-08-19 12:04:25 -0700467#else
Rashmi Ramannac7744532013-10-06 16:49:08 +0530468 hddLog(VOS_TRACE_LEVEL_INFO,
469 "chan(hw_val)0x%x chan(centerfreq) %d, duration %d"
470 " reuest type %d, cookie %llu", chan->hw_value, chan->center_freq,
471 duration, request_type, *cookie );
Yue Maf49ba872013-08-19 12:04:25 -0700472#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -0700473 //Cancel existing remain On Channel if any
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530474 checkReadyInd = wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
475 if (VOS_STATUS_SUCCESS != checkReadyInd)
476 {
477 hddLog( LOGE, FL("Cancel Roc in progress"));
478 return -EBUSY;
479 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700480
Jeff Johnsone7245742012-09-05 17:12:55 -0700481 /* When P2P-GO and if we are trying to unload the driver then
Jeff Johnson295189b2012-06-20 16:38:30 -0700482 * wlan driver is keep on receiving the remain on channel command
Jeff Johnsone7245742012-09-05 17:12:55 -0700483 * and which is resulting in crash. So not allowing any remain on
Jeff Johnson295189b2012-06-20 16:38:30 -0700484 * channel requets when Load/Unload is in progress*/
Rashmi Ramannab1429032014-04-26 14:59:09 +0530485 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(((hdd_context_t *)pAdapter->pHddCtx))
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +0530486 || hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx, VOS_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -0700487 {
488 hddLog( LOGE,
Rashmi Ramannab1429032014-04-26 14:59:09 +0530489 "%s: Wlan Load/Unload or Connection is in progress", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700490 return -EBUSY;
491 }
492
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -0700493 if (((hdd_context_t*)pAdapter->pHddCtx)->isLogpInProgress)
494 {
495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
496 "%s:LOGP in Progress. Ignore!!!", __func__);
497 return -EAGAIN;
498 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700499 pRemainChanCtx = vos_mem_malloc( sizeof(hdd_remain_on_chan_ctx_t) );
500 if( NULL == pRemainChanCtx )
501 {
502 hddLog(VOS_TRACE_LEVEL_FATAL,
503 "%s: Not able to allocate memory for Channel context",
504 __func__);
505 return -ENOMEM;
506 }
507
508 vos_mem_copy( &pRemainChanCtx->chan, chan,
509 sizeof(struct ieee80211_channel) );
510
Yue Maf49ba872013-08-19 12:04:25 -0700511#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700512 pRemainChanCtx->chan_type = channel_type;
Yue Maf49ba872013-08-19 12:04:25 -0700513#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700514 pRemainChanCtx->duration = duration;
515 pRemainChanCtx->dev = dev;
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800516 *cookie = (uintptr_t) pRemainChanCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700517 pRemainChanCtx->cookie = *cookie;
518 pRemainChanCtx->rem_on_chan_request = request_type;
519 cfgState->remain_on_chan_ctx = pRemainChanCtx;
520 cfgState->current_freq = chan->center_freq;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530521 pRemainChanCtx->action_pkt_buff.freq = 0;
522 pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
523 pRemainChanCtx->action_pkt_buff.frame_length = 0;
524 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = FALSE;
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530525 pRemainChanCtx->is_pending_roc_cancelled = FALSE;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530526 /* Initialize Remain on chan timer */
527 vos_status = vos_timer_init(&pRemainChanCtx->hdd_remain_on_chan_timer,
528 VOS_TIMER_TYPE_SW,
529 wlan_hdd_remain_on_chan_timeout,
530 pAdapter);
531 if (vos_status != VOS_STATUS_SUCCESS)
532 {
533 hddLog(VOS_TRACE_LEVEL_ERROR,
534 "%s: Not able to initalize remain_on_chan timer", __func__);
535 }
536 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
537 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
538 {
539 pAdapter_temp = pAdapterNode->pAdapter;
540 if (WLAN_HDD_P2P_GO == pAdapter_temp->device_mode)
541 {
542 isGoPresent = VOS_TRUE;
543 }
544 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
545 pAdapterNode = pNext;
546 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530547 hdd_prevent_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -0700548 INIT_COMPLETION(pAdapter->rem_on_chan_ready_event);
549
550 //call sme API to start remain on channel.
551 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
Jeff Johnsone7245742012-09-05 17:12:55 -0700552 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
553 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -0700554 )
555 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700556 tANI_U8 sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700557 //call sme API to start remain on channel.
558 sme_RemainOnChannel(
Rashmi Ramannac7744532013-10-06 16:49:08 +0530559 WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId,
560 chan->hw_value, duration,
561 wlan_hdd_remain_on_channel_callback, pAdapter,
562 (tANI_U8)(request_type == REMAIN_ON_CHANNEL_REQUEST)? TRUE:FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700563
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800564 if( REMAIN_ON_CHANNEL_REQUEST == request_type)
565 {
Rashmi Ramannac7744532013-10-06 16:49:08 +0530566 if( eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame(
567 WLAN_HDD_GET_HAL_CTX(pAdapter),
568 sessionId, (SIR_MAC_MGMT_FRAME << 2) |
569 (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0 ))
570 {
571 hddLog(VOS_TRACE_LEVEL_ERROR,
572 "sme_RegisterMgmtFrame returned fail");
573 }
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800574 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
576 }
577 else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
578 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
579 )
580 {
581 //call sme API to start remain on channel.
Jeff Johnson43971f52012-07-17 12:26:56 -0700582 if (VOS_STATUS_SUCCESS != WLANSAP_RemainOnChannel(
Jeff Johnson295189b2012-06-20 16:38:30 -0700583 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
584 chan->hw_value, duration,
585 wlan_hdd_remain_on_channel_callback, pAdapter ))
586
587 {
588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
589 "%s: WLANSAP_RemainOnChannel returned fail", __func__);
590 cfgState->remain_on_chan_ctx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -0700591 vos_mem_free (pRemainChanCtx);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530592 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -0700593 return -EINVAL;
594 }
595
596
Jeff Johnson43971f52012-07-17 12:26:56 -0700597 if (VOS_STATUS_SUCCESS != WLANSAP_RegisterMgmtFrame(
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
599 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
600 NULL, 0 ))
601 {
602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__);
604 WLANSAP_CancelRemainOnChannel(
605 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530606 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -0700607 return -EINVAL;
608 }
609
610 }
Nirav Shah87cd0cb2013-12-28 21:22:09 +0530611
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530612 pAdapter->is_roc_inprogress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700613 return 0;
614
615}
616
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530617int __wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
619 struct wireless_dev *wdev,
620#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700621 struct net_device *dev,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700623 struct ieee80211_channel *chan,
Yue Maf49ba872013-08-19 12:04:25 -0700624#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700625 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -0700626#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700627 unsigned int duration, u64 *cookie )
628{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800629#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
630 struct net_device *dev = wdev->netdev;
631#endif
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530632 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
633
634 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
635 TRACE_CODE_HDD_REMAIN_ON_CHANNEL,
636 pAdapter->sessionId, REMAIN_ON_CHANNEL_REQUEST));
Jeff Johnson295189b2012-06-20 16:38:30 -0700637 return wlan_hdd_request_remain_on_channel(wiphy, dev,
Yue Maf49ba872013-08-19 12:04:25 -0700638 chan,
639#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
640 channel_type,
641#endif
642 duration, cookie,
Jeff Johnson295189b2012-06-20 16:38:30 -0700643 REMAIN_ON_CHANNEL_REQUEST);
644}
645
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530646int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
647#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
648 struct wireless_dev *wdev,
649#else
650 struct net_device *dev,
651#endif
652 struct ieee80211_channel *chan,
653#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
654 enum nl80211_channel_type channel_type,
655#endif
656 unsigned int duration, u64 *cookie )
657{
658 int ret;
659
660 vos_ssr_protect(__func__);
661 ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy,
662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
663 wdev,
664#else
665 dev,
666#endif
667 chan,
668#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
669 channel_type,
670#endif
671 duration, cookie);
672 vos_ssr_unprotect(__func__);
673
674 return ret;
675}
676
677
Jeff Johnson295189b2012-06-20 16:38:30 -0700678void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter )
679{
Kaushik, Sushant26402612014-05-03 16:56:06 +0530680 hdd_cfg80211_state_t *cfgState = NULL;
681 hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530682 VOS_STATUS status;
Kaushik, Sushant26402612014-05-03 16:56:06 +0530683 if (NULL == pAdapter)
684 {
685 hddLog(LOGE, FL("pAdapter is NULL"));
686 return;
687 }
688 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
689 pRemainChanCtx = cfgState->remain_on_chan_ctx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530690 hddLog( LOG1, "Ready on chan ind");
Jeff Johnson295189b2012-06-20 16:38:30 -0700691 if( pRemainChanCtx != NULL )
692 {
Kaushik, Sushant78c3efe2014-05-13 10:29:34 +0530693 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
694 TRACE_CODE_HDD_REMAINCHANREADYHANDLER,
695 pAdapter->sessionId, pRemainChanCtx->duration));
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530696 //start timer for actual duration
697 status = vos_timer_start(&pRemainChanCtx->hdd_remain_on_chan_timer,
698 (pRemainChanCtx->duration));
699 if (VOS_STATUS_SUCCESS!=status)
700 {
701 hddLog( LOGE, FL("Remain on Channel timer start failed"));
702 }
703 if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request)
Jeff Johnson295189b2012-06-20 16:38:30 -0700704 {
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800705 cfg80211_ready_on_channel(
706#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
707 pAdapter->dev->ieee80211_ptr,
708#else
709 pAdapter->dev,
710#endif
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800711 (uintptr_t)pRemainChanCtx,
Yue Maf49ba872013-08-19 12:04:25 -0700712 &pRemainChanCtx->chan,
713#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
714 pRemainChanCtx->chan_type,
715#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700716 pRemainChanCtx->duration, GFP_KERNEL );
717 }
718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530719 else if( OFF_CHANNEL_ACTION_TX == pRemainChanCtx->rem_on_chan_request)
Jeff Johnson295189b2012-06-20 16:38:30 -0700720 {
721 complete(&pAdapter->offchannel_tx_event);
722 }
723#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530724 // Check for cached action frame
725 if ( pRemainChanCtx->action_pkt_buff.frame_length != 0 )
726 {
727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
728 cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr,
729 pRemainChanCtx->action_pkt_buff.freq, 0,
730 pRemainChanCtx->action_pkt_buff.frame_ptr,
731 pRemainChanCtx->action_pkt_buff.frame_length,
732 GFP_ATOMIC );
733#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
734 cfg80211_rx_mgmt( pAdapter->dev,
735 pRemainChanCtx->action_pkt_buff.freq, 0,
736 pRemainChanCtx->action_pkt_buff.frame_ptr,
737 pRemainChanCtx->action_pkt_buff.frame_length,
738 GFP_ATOMIC );
739#else
740 cfg80211_rx_mgmt( pAdapter->dev,
741 pRemainChanCtx->action_pkt_buff.freq,
742 pRemainChanCtx->action_pkt_buff.frame_ptr,
743 pRemainChanCtx->action_pkt_buff.frame_length,
744 GFP_ATOMIC );
745#endif //LINUX_VERSION_CODE
746 hddLog( LOGE, "%s: Sent cached action frame to supplicant", __func__);
747 vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
748 pRemainChanCtx->action_pkt_buff.frame_length = 0;
749 pRemainChanCtx->action_pkt_buff.freq = 0;
750 pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
751 }
Rashmi Ramannac7744532013-10-06 16:49:08 +0530752 hddLog( VOS_TRACE_LEVEL_INFO, "Ready on chan ind (cookie=%llu)",
753 pRemainChanCtx->cookie);
Jeff Johnson295189b2012-06-20 16:38:30 -0700754 complete(&pAdapter->rem_on_chan_ready_event);
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530755 if (TRUE == pRemainChanCtx->is_pending_roc_cancelled)
756 {
757 /* since pRemainChanCtx->is_pending_roc_cancelled is
758 * set, it means Cancel Reamain on channel command is
759 * pending because remain on channel event was not
760 * ready when cancel ROC was issued.So issue
761 * cancel ROC now.
762 */
763 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
764 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700765 }
766 else
767 {
768 hddLog( LOGW, "%s: No Pending Remain on channel Request", __func__);
769 }
770 return;
771}
772
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530773int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
775 struct wireless_dev *wdev,
776#else
777 struct net_device *dev,
778#endif
779 u64 cookie )
Jeff Johnson295189b2012-06-20 16:38:30 -0700780{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
782 struct net_device *dev = wdev->netdev;
783#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530786 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530787 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
788 int status;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530789 u64 cookie_dummy;
790 cookie_dummy = cookie << 32;
791 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
792 TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL,
793 pAdapter->sessionId, cookie_dummy));
794 hddLog( LOG1, "Cancel remain on channel req");
Jeff Johnson295189b2012-06-20 16:38:30 -0700795
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530796 status = wlan_hdd_validate_context(pHddCtx);
797
798 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -0700799 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
801 "%s: HDD context is not valid", __func__);
802 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -0700803 }
Rashmi Ramannac7744532013-10-06 16:49:08 +0530804 hddLog( LOG1, "Cancel remain on channel req (cookie = %llu)", cookie);
805
Jeff Johnson295189b2012-06-20 16:38:30 -0700806 /* FIXME cancel currently running remain on chan.
807 * Need to check cookie and cancel accordingly
808 */
809 if( (cfgState->remain_on_chan_ctx == NULL) ||
810 (cfgState->remain_on_chan_ctx->cookie != cookie) )
811 {
812 hddLog( LOGE,
813 "%s: No Remain on channel pending with specified cookie value",
814 __func__);
815 return -EINVAL;
816 }
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530817 if (TRUE != pRemainChanCtx->is_pending_roc_cancelled)
818 {
819 /* wait until remain on channel ready event received
820 * for already issued remain on channel request */
821 status = wait_for_completion_interruptible_timeout(&pAdapter->rem_on_chan_ready_event,
822 msecs_to_jiffies(WAIT_REM_CHAN_READY));
823 if (0 >= status)
824 {
825 hddLog( LOGE,
826 "%s: timeout waiting for remain on channel ready indication %d",
827 __func__, status);
828 pRemainChanCtx->is_pending_roc_cancelled = TRUE;
829 return 0;
830
831 }
832 }
833 else
834 {
835 hddLog( LOG1, FL("Cancel ROC event is already pending, "
836 "waiting for ready on channel indication.") );
837 return 0;
838 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530839 if (NULL != cfgState->remain_on_chan_ctx)
840 {
841 vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
842 if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress)
843 {
844 hddLog( LOG1,
845 FL("ROC timer cancellation in progress,"
846 " wait for completion"));
847 status = wait_for_completion_interruptible_timeout(
848 &pAdapter->cancel_rem_on_chan_var,
849 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
850 if (0 >= status)
851 {
852 hddLog( LOGE,
853 "%s:wait on cancel_rem_on_chan_var failed %d",
854 __func__, status);
855 }
856 return 0;
857 }
858 else
859 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
860 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700861 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
862 /* Issue abort remain on chan request to sme.
863 * The remain on channel callback will make sure the remain_on_chan
864 * expired event is sent.
865 */
866 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
Jeff Johnsone7245742012-09-05 17:12:55 -0700867 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
868 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -0700869 )
870 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530871 tANI_U8 sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700872 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
873 sessionId );
874 }
875 else if ( (WLAN_HDD_SOFTAP== pAdapter->device_mode) ||
876 (WLAN_HDD_P2P_GO == pAdapter->device_mode)
877 )
878 {
879 WLANSAP_CancelRemainOnChannel(
880 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
881 }
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530882 else
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 {
884 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid device_mode = %d",
885 __func__, pAdapter->device_mode);
886 return -EIO;
887 }
c_hpothu7f63e882013-10-02 19:13:35 +0530888 status = wait_for_completion_interruptible_timeout(&pAdapter->cancel_rem_on_chan_var,
Jeff Johnson295189b2012-06-20 16:38:30 -0700889 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
c_hpothu7f63e882013-10-02 19:13:35 +0530890 if (0 >= status)
891 {
892 hddLog( LOGE,
893 "%s:wait on cancel_rem_on_chan_var failed %d", __func__, status);
894 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530895 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -0700896 return 0;
897}
898
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530899int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530901 struct wireless_dev *wdev,
902#else
903 struct net_device *dev,
904#endif
905 u64 cookie )
906{
907 int ret;
908
909 vos_ssr_protect(__func__);
910 ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy,
911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
912 wdev,
913#else
914 dev,
915#endif
916 cookie);
917 vos_ssr_unprotect(__func__);
918
919 return ret;
920}
921
922
923#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
924int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800925 struct ieee80211_channel *chan, bool offchan,
Yue Maf49ba872013-08-19 12:04:25 -0700926#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800927 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -0700928 bool channel_type_valid,
929#endif
930 unsigned int wait,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800931 const u8 *buf, size_t len, bool no_cck,
932 bool dont_wait_for_ack, u64 *cookie )
933#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530934int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 struct ieee80211_channel *chan, bool offchan,
936 enum nl80211_channel_type channel_type,
937 bool channel_type_valid, unsigned int wait,
938 const u8 *buf, size_t len, bool no_cck,
939 bool dont_wait_for_ack, u64 *cookie )
940#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530941int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 struct ieee80211_channel *chan, bool offchan,
943 enum nl80211_channel_type channel_type,
944 bool channel_type_valid, unsigned int wait,
945 const u8 *buf, size_t len, u64 *cookie )
946#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530947int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 struct ieee80211_channel *chan,
949 enum nl80211_channel_type channel_type,
950 bool channel_type_valid,
951 const u8 *buf, size_t len, u64 *cookie )
952#endif //LINUX_VERSION_CODE
953{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
955 struct net_device *dev = wdev->netdev;
956#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +0530958 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
959 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
960 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Jeff Johnsone7245742012-09-05 17:12:55 -0700961 tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
962 tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
Mukul Sharma1e5d0b72014-07-01 19:22:21 +0530963 tActionFrmType actionFrmType = WLAN_HDD_ACTION_FRM_TYPE_MAX;
Jeff Johnsone7245742012-09-05 17:12:55 -0700964 bool noack = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530965 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -0700966
Jeff Johnson295189b2012-06-20 16:38:30 -0700967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
968 hdd_adapter_t *goAdapter;
969#endif
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +0530970
971 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530972 TRACE_CODE_HDD_ACTION, pAdapter->sessionId,
973 pAdapter->device_mode ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530974 status = wlan_hdd_validate_context(pHddCtx);
975
976 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -0800977 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
979 "%s: HDD context is not valid", __func__);
980 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -0800981 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530982
c_hpothu7f63e882013-10-02 19:13:35 +0530983 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d",
984 __func__, pAdapter->device_mode, type);
985
986
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -0700987 if ((type == SIR_MAC_MGMT_FRAME) &&
988 (subType == SIR_MAC_MGMT_ACTION) &&
989 (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME))
990 {
991 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Kaushik, Sushant731e8942014-09-08 11:59:19 +0530992#ifdef WLAN_FEATURE_P2P_DEBUG
Hoonki Lee1090c6a2013-01-16 17:40:54 -0800993 if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -0700994 {
995 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA",
996 actionFrmType);
997 }
998 else
999 {
1000 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA",
1001 p2p_action_frame_type[actionFrmType]);
1002 if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
1003 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
1004 {
1005 globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
1006 hddLog(LOGE,"[P2P State]Inactive state to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001007 "GO negotiation progress state");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001008 }
1009 else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
1010 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
1011 {
1012 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
1013 hddLog(LOGE,"[P2P State]GO nego progress to GO nego"
1014 " completed state");
1015 }
1016 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001017#endif
Kaushik, Sushant731e8942014-09-08 11:59:19 +05301018 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001019
Jeff Johnsone7245742012-09-05 17:12:55 -07001020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1021 noack = dont_wait_for_ack;
1022#endif
1023
1024 //If the wait is coming as 0 with off channel set
1025 //then set the wait to 200 ms
1026 if (offchan && !wait)
1027 wait = ACTION_FRAME_DEFAULT_WAIT;
1028
Jeff Johnson295189b2012-06-20 16:38:30 -07001029 //Call sme API to send out a action frame.
1030 // OR can we send it directly through data path??
1031 // After tx completion send tx status back.
1032 if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) ||
1033 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
1034 )
1035 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001036 if (type == SIR_MAC_MGMT_FRAME)
1037 {
1038 if (subType == SIR_MAC_MGMT_PROBE_RSP)
1039 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301040 /* Drop Probe response recieved from supplicant, as for GO and
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 SAP PE itself sends probe response
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301042 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 goto err_rem_channel;
1044 }
1045 else if ((subType == SIR_MAC_MGMT_DISASSOC) ||
1046 (subType == SIR_MAC_MGMT_DEAUTH))
1047 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001048 /* During EAP failure or P2P Group Remove supplicant
1049 * is sending del_station command to driver. From
1050 * del_station function, Driver will send deauth frame to
1051 * p2p client. No need to send disassoc frame from here.
1052 * so Drop the frame here and send tx indication back to
1053 * supplicant.
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 */
1055 tANI_U8 dstMac[ETH_ALEN] = {0};
1056 memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07001057 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001058 "%s: Deauth/Disassoc received for STA:"
Arif Hussain24bafea2013-11-15 15:10:03 -08001059 MAC_ADDRESS_STR,
Jeff Johnsone7245742012-09-05 17:12:55 -07001060 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08001061 MAC_ADDR_ARRAY(dstMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001062 goto err_rem_channel;
1063 }
1064 }
1065 }
1066
1067 if( NULL != cfgState->buf )
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08001068 {
1069 if ( !noack )
1070 {
1071 hddLog( LOGE, "(%s):Previous P2P Action frame packet pending",
1072 __func__);
1073 hdd_cleanup_actionframe(pAdapter->pHddCtx, pAdapter);
1074 }
1075 else
1076 {
1077 hddLog( LOGE, "(%s):Pending Action frame packet return EBUSY",
1078 __func__);
1079 return -EBUSY;
1080 }
1081 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001082
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301083 if( subType == SIR_MAC_MGMT_ACTION)
1084 {
1085 hddLog( LOG1, "Action frame tx request : %s",
1086 hdd_getActionString(buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET]));
1087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001088
1089#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1090 goAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_P2P_GO );
1091
1092 //If GO adapter exists and operating on same frequency
1093 //then we will not request remain on channel
1094 if( goAdapter && ( ieee80211_frequency_to_channel(chan->center_freq)
1095 == goAdapter->sessionCtx.ap.operatingChannel ) )
1096 {
Kaushik, Sushant39bdbe22014-05-23 10:39:15 +05301097 /* if GO exist and is not off channel
1098 * wait time should be zero.
1099 */
1100 wait = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 goto send_frame;
1102 }
1103#endif
1104
1105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1106 if( offchan && wait)
1107 {
1108 int status;
Agarwal Ashish7875e7c2014-03-11 12:54:57 +05301109 rem_on_channel_request_type_t req_type = OFF_CHANNEL_ACTION_TX;
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 // In case of P2P Client mode if we are already
1111 // on the same channel then send the frame directly
1112
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301113 if( (cfgState->remain_on_chan_ctx != NULL) &&
1114 (cfgState->current_freq == chan->center_freq)
1115 )
1116 {
1117 if ( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(
1118 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer) )
vamsida0e5ab2013-12-26 14:33:27 +05301119 {
Sushant Kaushik22257d62014-05-20 19:27:07 +05301120 /* Some times FW is taking almost 500 msec for
1121 * full 15 retries, which leads to ROC expiration
1122 * by the time peer gets response from other peer.
1123 * Therefore as part of temporary fix , in host
1124 * ROC time is extended. For frames where we are
1125 * expecting response from peer , its extended by
1126 * 500 msec to make ROC wait time as 1 sec and
1127 * in other cases its extended by 300 msec to make
1128 * total ROC wait as 500 msec.
1129 * TODO: FW needs to fix as why 15 retry is taking
1130 * such long time.
1131 */
1132 if ( actionFrmType == WLAN_HDD_INVITATION_REQ ||
1133 actionFrmType == WLAN_HDD_GO_NEG_REQ ||
1134 actionFrmType == WLAN_HDD_GO_NEG_RESP )
1135 wait = wait + ACTION_FRAME_RSP_WAIT;
1136 else if ( actionFrmType == WLAN_HDD_GO_NEG_CNF ||
1137 actionFrmType == WLAN_HDD_INVITATION_RESP )
1138 wait = wait + ACTION_FRAME_ACK_WAIT;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301139 vos_timer_stop(
1140 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
1141 status = vos_timer_start(
1142 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer,
1143 wait);
1144 if ( status != VOS_STATUS_SUCCESS )
vamsida0e5ab2013-12-26 14:33:27 +05301145 {
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301146 hddLog( LOGE, "Remain on Channel timer start failed");
1147 }
1148
1149 hddLog(VOS_TRACE_LEVEL_INFO,
1150 "action frame: extending the wait time %u",
1151 wait);
1152 goto send_frame;
1153 }
1154 else
1155 {
1156 if ( TRUE ==
1157 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
1158 {
1159 hddLog(VOS_TRACE_LEVEL_INFO,
1160 "action frame tx: waiting for completion of ROC ");
1161
1162 status = wait_for_completion_interruptible_timeout(
1163 &pAdapter->cancel_rem_on_chan_var,
1164 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
1165 if (0 >= status)
1166 {
1167 hddLog( LOGE,
1168 "%s:wait on cancel_rem_on_chan_var failed %d",
1169 __func__, status);
1170 }
vamsida0e5ab2013-12-26 14:33:27 +05301171 }
1172 }
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +05301173 }
Rashmi Ramannac7744532013-10-06 16:49:08 +05301174 hddLog(VOS_TRACE_LEVEL_INFO,
1175 "action frame: Request ROC for wait time %u", wait);
1176
Jeff Johnson295189b2012-06-20 16:38:30 -07001177 INIT_COMPLETION(pAdapter->offchannel_tx_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 status = wlan_hdd_request_remain_on_channel(wiphy, dev,
Yue Maf49ba872013-08-19 12:04:25 -07001179 chan,
1180#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1181 channel_type,
1182#endif
1183 wait, cookie,
Agarwal Ashish7875e7c2014-03-11 12:54:57 +05301184 req_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001185
1186 if(0 != status)
1187 {
1188 if( (-EBUSY == status) &&
1189 (cfgState->current_freq == chan->center_freq) )
1190 {
1191 goto send_frame;
1192 }
1193 goto err_rem_channel;
1194 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001195 /* Wait for driver to be ready on the requested channel */
1196 status = wait_for_completion_interruptible_timeout(
1197 &pAdapter->offchannel_tx_event,
1198 msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX));
c_hpothu7f63e882013-10-02 19:13:35 +05301199 if(0 >= status)
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 {
c_hpothu7f63e882013-10-02 19:13:35 +05301201 hddLog( LOGE, "wait on offchannel_tx_event failed %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001202 goto err_rem_channel;
1203 }
1204 }
1205 else if ( offchan )
1206 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001207 /* Check before sending action frame
1208 whether we already remain on channel */
Jeff Johnson295189b2012-06-20 16:38:30 -07001209 if(NULL == cfgState->remain_on_chan_ctx)
1210 {
1211 goto err_rem_channel;
1212 }
1213 }
1214 send_frame:
1215#endif
1216
Jeff Johnsone7245742012-09-05 17:12:55 -07001217 if(!noack)
1218 {
1219 cfgState->buf = vos_mem_malloc( len ); //buf;
1220 if( cfgState->buf == NULL )
1221 return -ENOMEM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001222
Jeff Johnsone7245742012-09-05 17:12:55 -07001223 cfgState->len = len;
Jeff Johnson295189b2012-06-20 16:38:30 -07001224
Jeff Johnsone7245742012-09-05 17:12:55 -07001225 vos_mem_copy( cfgState->buf, buf, len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001226
1227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsone7245742012-09-05 17:12:55 -07001228 if( cfgState->remain_on_chan_ctx )
1229 {
1230 cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie;
1231 *cookie = cfgState->action_cookie;
1232 }
1233 else
1234 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001235#endif
Jeff Johnsonf67dca92013-11-08 17:07:40 -08001236 *cookie = (uintptr_t) cfgState->buf;
Jeff Johnsone7245742012-09-05 17:12:55 -07001237 cfgState->action_cookie = *cookie;
Jeff Johnson295189b2012-06-20 16:38:30 -07001238#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsone7245742012-09-05 17:12:55 -07001239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001240#endif
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301241 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001242
1243 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07001244 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1245 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07001246 )
1247 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001248 tANI_U8 sessionId = pAdapter->sessionId;
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001249
Jeff Johnsone7245742012-09-05 17:12:55 -07001250 if ((type == SIR_MAC_MGMT_FRAME) &&
1251 (subType == SIR_MAC_MGMT_ACTION) &&
1252 (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME))
Jeff Johnson295189b2012-06-20 16:38:30 -07001253 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001254 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Rashmi Ramannac7744532013-10-06 16:49:08 +05301255 hddLog(LOG1, "Tx Action Frame %u.", actionFrmType);
Jeff Johnsone7245742012-09-05 17:12:55 -07001256 if (actionFrmType == WLAN_HDD_PROV_DIS_REQ)
Jeff Johnson295189b2012-06-20 16:38:30 -07001257 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001258 cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING;
Rashmi Ramannac7744532013-10-06 16:49:08 +05301259 hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING.", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001260 }
1261 else if (actionFrmType == WLAN_HDD_GO_NEG_REQ)
1262 {
1263 cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING;
Rashmi Ramannac7744532013-10-06 16:49:08 +05301264 hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING.", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001265 }
1266 }
Abhishek Singh0ebac9c2014-06-25 13:34:12 +05301267
Jeff Johnson295189b2012-06-20 16:38:30 -07001268 if (eHAL_STATUS_SUCCESS !=
1269 sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter),
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301270 sessionId, buf, len, wait, noack))
Jeff Johnson295189b2012-06-20 16:38:30 -07001271 {
1272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1273 "%s: sme_sendAction returned fail", __func__);
1274 goto err;
1275 }
1276 }
1277 else if( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) ||
1278 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
1279 )
1280 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001281 if( VOS_STATUS_SUCCESS !=
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Jeff Johnsone7245742012-09-05 17:12:55 -07001283 buf, len, 0 ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 {
1285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1286 "%s: WLANSAP_SendAction returned fail", __func__);
1287 goto err;
1288 }
1289 }
1290
1291 return 0;
1292err:
Jeff Johnsone7245742012-09-05 17:12:55 -07001293 if(!noack)
1294 {
1295 hdd_sendActionCnf( pAdapter, FALSE );
1296 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 return 0;
1298err_rem_channel:
Jeff Johnsonf67dca92013-11-08 17:07:40 -08001299 *cookie = (uintptr_t)cfgState;
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001300 cfg80211_mgmt_tx_status(
1301#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1302 pAdapter->dev->ieee80211_ptr,
1303#else
1304 pAdapter->dev,
1305#endif
1306 *cookie, buf, len, FALSE, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07001307 return 0;
1308}
1309
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1311int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
1312 struct ieee80211_channel *chan, bool offchan,
1313#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1314 enum nl80211_channel_type channel_type,
1315 bool channel_type_valid,
1316#endif
1317 unsigned int wait,
1318 const u8 *buf, size_t len, bool no_cck,
1319 bool dont_wait_for_ack, u64 *cookie )
1320#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1321int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1322 struct ieee80211_channel *chan, bool offchan,
1323 enum nl80211_channel_type channel_type,
1324 bool channel_type_valid, unsigned int wait,
1325 const u8 *buf, size_t len, bool no_cck,
1326 bool dont_wait_for_ack, u64 *cookie )
1327#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1328int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1329 struct ieee80211_channel *chan, bool offchan,
1330 enum nl80211_channel_type channel_type,
1331 bool channel_type_valid, unsigned int wait,
1332 const u8 *buf, size_t len, u64 *cookie )
1333#else
1334int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1335 struct ieee80211_channel *chan,
1336 enum nl80211_channel_type channel_type,
1337 bool channel_type_valid,
1338 const u8 *buf, size_t len, u64 *cookie )
1339#endif //LINUX_VERSION_CODE
1340{
1341 int ret;
1342
1343 vos_ssr_protect(__func__);
1344#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1345 ret = __wlan_hdd_mgmt_tx(wiphy, wdev,
1346 chan, offchan,
1347#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1348 channel_type,
1349 channel_type_valid,
1350#endif
1351 wait,
1352 buf, len, no_cck,
1353 dont_wait_for_ack, cookie);
1354#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1355 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
1356 channel_type, channel_type_valid, wait,
1357 buf, len, no_cck,
1358 dont_wait_for_ack, cookie);
1359#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1360 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
1361 channel_type, channel_type_valid, wait,
1362 buf, len, cookie);
1363#else
1364 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, channel_type,
1365 channel_type_valid, buf, len, cookie);
1366#endif //LINUX_VERSION_CODE
1367 vos_ssr_unprotect(__func__);
1368
1369 return ret;
1370}
1371
Jeff Johnson295189b2012-06-20 16:38:30 -07001372#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001373#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301374int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001375 struct wireless_dev *wdev,
1376 u64 cookie)
1377{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301378 u64 cookie_dummy;
1379 cookie_dummy = cookie << 32;
1380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1381 TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, NO_SESSION, cookie_dummy));
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001382 return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, wdev, cookie );
1383}
1384#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301385int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 struct net_device *dev,
1387 u64 cookie)
1388{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301389 u64 cookie_dummy;
1390 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1391 cookie_dummy = cookie << 32;
1392 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1393 TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT,
1394 pAdapter->sessionId, cookie_dummy));
Jeff Johnson295189b2012-06-20 16:38:30 -07001395 return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, dev, cookie );
1396}
1397#endif
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001398#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001399
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301400#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1401#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1402int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1403 struct wireless_dev *wdev,
1404 u64 cookie)
1405{
1406 int ret;
1407
1408 vos_ssr_protect(__func__);
1409 ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie);
1410 vos_ssr_unprotect(__func__);
1411
1412 return ret;
1413}
1414#else
1415int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1416 struct net_device *dev,
1417 u64 cookie)
1418{
1419 int ret;
1420
1421 vos_ssr_protect(__func__);
1422 ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, dev, cookie);
1423 vos_ssr_unprotect(__func__);
1424
1425 return ret;
1426}
1427#endif
1428#endif
1429
Jeff Johnson295189b2012-06-20 16:38:30 -07001430void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess )
1431{
1432 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
1433
Jeff Johnsone7245742012-09-05 17:12:55 -07001434 cfgState->actionFrmState = HDD_IDLE;
1435
Jeff Johnson295189b2012-06-20 16:38:30 -07001436 hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess);
1437 if( NULL == cfgState->buf )
1438 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001439 return;
1440 }
1441
1442 /* If skb is NULL it means this packet was received on CFG80211 interface
1443 * else it was received on Monitor interface */
1444 if( cfgState->skb == NULL )
1445 {
1446 /*
1447 * buf is the same pointer it passed us to send. Since we are sending
1448 * it through control path, we use different buffers.
1449 * In case of mac80211, they just push it to the skb and pass the same
1450 * data while sending tx ack status.
1451 * */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001452 cfg80211_mgmt_tx_status(
1453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1454 pAdapter->dev->ieee80211_ptr,
1455#else
1456 pAdapter->dev,
1457#endif
1458 cfgState->action_cookie,
Jeff Johnson295189b2012-06-20 16:38:30 -07001459 cfgState->buf, cfgState->len, actionSendSuccess, GFP_KERNEL );
1460 vos_mem_free( cfgState->buf );
1461 cfgState->buf = NULL;
1462 }
1463 else
1464 {
1465 hdd_adapter_t* pMonAdapter =
1466 hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR );
1467 if( pMonAdapter == NULL )
1468 {
1469 hddLog( LOGE, "Not able to get Monitor Adapter");
1470 cfgState->skb = NULL;
1471 vos_mem_free( cfgState->buf );
1472 cfgState->buf = NULL;
1473 complete(&pAdapter->tx_action_cnf_event);
1474 return;
1475 }
1476 /* Send TX completion feedback over monitor interface. */
1477 hdd_wlan_tx_complete( pMonAdapter, cfgState, actionSendSuccess );
1478 cfgState->skb = NULL;
1479 vos_mem_free( cfgState->buf );
1480 cfgState->buf = NULL;
1481 /* Look for the next Mgmt packet to TX */
1482 hdd_mon_tx_mgmt_pkt(pAdapter);
1483 }
1484 complete(&pAdapter->tx_action_cnf_event);
1485}
1486
1487/**
1488 * hdd_setP2pNoa
1489 *
1490 *FUNCTION:
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301491 * This function is called from hdd_hostapd_ioctl function when Driver
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 * get P2P_SET_NOA comand from wpa_supplicant using private ioctl
1493 *
1494 *LOGIC:
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301495 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
Jeff Johnson295189b2012-06-20 16:38:30 -07001496 *
1497 *ASSUMPTIONS:
1498 *
1499 *
1500 *NOTE:
1501 *
1502 * @param dev Pointer to net device structure
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301503 * @param command Pointer to command
Jeff Johnson295189b2012-06-20 16:38:30 -07001504 *
1505 * @return Status
1506 */
1507
1508int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command )
1509{
1510 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1511 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1512 VOS_STATUS status = VOS_STATUS_SUCCESS;
1513 tP2pPsConfig NoA;
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001514 int count, duration, start_time;
Jeff Johnson295189b2012-06-20 16:38:30 -07001515 char *param;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001516 tANI_U8 ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001517
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08001518 param = strnchr(command, strlen(command), ' ');
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 if (param == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301520 {
1521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1522 "%s: strnchr failed to find delimeter",__func__);
1523 return -EINVAL;
1524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 param++;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001526 ret = sscanf(param, "%d %d %d", &count, &start_time, &duration);
1527 if (ret < 3)
1528 {
1529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1530 "%s: P2P_SET GO NoA: fail to read param "
1531 "count=%d duration=%d interval=%d \n",
1532 __func__, count, start_time, duration);
1533 return -EINVAL;
1534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001536 "%s: P2P_SET GO NoA: count=%d duration=%d interval=%d",
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001537 __func__, count, start_time, duration);
1538 duration = MS_TO_MUS(duration);
Jeff Johnson295189b2012-06-20 16:38:30 -07001539 /* PS Selection
1540 * Periodic NoA (2)
1541 * Single NOA (4)
1542 */
1543 NoA.opp_ps = 0;
1544 NoA.ctWindow = 0;
1545 if (count == 1)
1546 {
1547 NoA.duration = 0;
1548 NoA.single_noa_duration = duration;
1549 NoA.psSelection = P2P_POWER_SAVE_TYPE_SINGLE_NOA;
1550 }
1551 else
1552 {
1553 NoA.duration = duration;
1554 NoA.single_noa_duration = 0;
1555 NoA.psSelection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA;
1556 }
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001557 NoA.interval = MS_TO_MUS(100);
Jeff Johnson295189b2012-06-20 16:38:30 -07001558 NoA.count = count;
1559 NoA.sessionid = pAdapter->sessionId;
1560
1561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1562 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1563 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001564 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 NoA.ctWindow, NoA.duration, NoA.interval,
1566 NoA.count, NoA.single_noa_duration,
1567 NoA.psSelection);
1568
1569 sme_p2pSetPs(hHal, &NoA);
1570 return status;
1571}
1572
1573/**
1574 * hdd_setP2pOpps
1575 *
1576 *FUNCTION:
1577 * This function is called from hdd_hostapd_ioctl function when Driver
1578 * get P2P_SET_PS comand from wpa_supplicant using private ioctl
1579 *
1580 *LOGIC:
1581 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
1582 *
1583 *ASSUMPTIONS:
1584 *
1585 *
1586 *NOTE:
1587 *
1588 * @param dev Pointer to net device structure
1589 * @param command Pointer to command
1590 *
1591 * @return Status
1592 */
1593
1594int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command )
1595{
1596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1597 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1598 VOS_STATUS status = VOS_STATUS_SUCCESS;
1599 tP2pPsConfig NoA;
1600 char *param;
1601 int legacy_ps, opp_ps, ctwindow;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001602 tANI_U8 ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001603
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08001604 param = strnchr(command, strlen(command), ' ');
Jeff Johnson295189b2012-06-20 16:38:30 -07001605 if (param == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301606 {
1607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1608 "%s: strnchr failed to find delimeter",__func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001609 return -EINVAL;
c_hpothu7f63e882013-10-02 19:13:35 +05301610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 param++;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001612 ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow);
1613 if (ret < 3)
1614 {
1615 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1616 "%s: P2P_SET GO PS: fail to read param "
1617 " legacy_ps=%d opp_ps=%d ctwindow=%d \n",
1618 __func__, legacy_ps, opp_ps, ctwindow);
1619 return -EINVAL;
1620 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001621 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001622 "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001623 __func__, legacy_ps, opp_ps, ctwindow);
1624
1625 /* PS Selection
1626 * Opportunistic Power Save (1)
1627 */
1628
1629 /* From wpa_cli user need to use separate command to set ctWindow and Opps
1630 * When user want to set ctWindow during that time other parameters
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301631 * values are coming from wpa_supplicant as -1.
1632 * Example : User want to set ctWindow with 30 then wpa_cli command :
1633 * P2P_SET ctwindow 30
1634 * Command Received at hdd_hostapd_ioctl is as below:
Jeff Johnson295189b2012-06-20 16:38:30 -07001635 * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30)
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301636 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 if (ctwindow != -1)
1638 {
1639
1640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001641 "Opportunistic Power Save is %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 (TRUE == pAdapter->ops) ? "Enable" : "Disable" );
1643
1644 if (ctwindow != pAdapter->ctw)
1645 {
1646 pAdapter->ctw = ctwindow;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301647
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 if(pAdapter->ops)
1649 {
1650 NoA.opp_ps = pAdapter->ops;
1651 NoA.ctWindow = pAdapter->ctw;
1652 NoA.duration = 0;
1653 NoA.single_noa_duration = 0;
1654 NoA.interval = 0;
1655 NoA.count = 0;
1656 NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
1657 NoA.sessionid = pAdapter->sessionId;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301658
Jeff Johnson295189b2012-06-20 16:38:30 -07001659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1660 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1661 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001662 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 NoA.ctWindow, NoA.duration, NoA.interval,
1664 NoA.count, NoA.single_noa_duration,
1665 NoA.psSelection);
1666
1667 sme_p2pSetPs(hHal, &NoA);
1668 }
1669 return 0;
1670 }
1671 }
1672
1673 if (opp_ps != -1)
1674 {
1675 pAdapter->ops = opp_ps;
1676
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301677 if ((opp_ps != -1) && (pAdapter->ctw))
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 {
1679 NoA.opp_ps = opp_ps;
1680 NoA.ctWindow = pAdapter->ctw;
1681 NoA.duration = 0;
1682 NoA.single_noa_duration = 0;
1683 NoA.interval = 0;
1684 NoA.count = 0;
1685 NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
1686 NoA.sessionid = pAdapter->sessionId;
1687
1688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1689 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1690 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001691 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 NoA.ctWindow, NoA.duration, NoA.interval,
1693 NoA.count, NoA.single_noa_duration,
1694 NoA.psSelection);
1695
1696 sme_p2pSetPs(hHal, &NoA);
1697 }
1698 }
1699 return status;
1700}
1701
1702int hdd_setP2pPs( struct net_device *dev, void *msgData )
1703{
1704 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1705 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1706 VOS_STATUS status = VOS_STATUS_SUCCESS;
1707 tP2pPsConfig NoA;
1708 p2p_app_setP2pPs_t *pappNoA = (p2p_app_setP2pPs_t *) msgData;
1709
1710 NoA.opp_ps = pappNoA->opp_ps;
1711 NoA.ctWindow = pappNoA->ctWindow;
1712 NoA.duration = pappNoA->duration;
1713 NoA.interval = pappNoA->interval;
1714 NoA.count = pappNoA->count;
1715 NoA.single_noa_duration = pappNoA->single_noa_duration;
1716 NoA.psSelection = pappNoA->psSelection;
1717 NoA.sessionid = pAdapter->sessionId;
1718
1719 sme_p2pSetPs(hHal, &NoA);
1720 return status;
1721}
Jeff Johnson295189b2012-06-20 16:38:30 -07001722
1723static tANI_U8 wlan_hdd_get_session_type( enum nl80211_iftype type )
1724{
1725 tANI_U8 sessionType;
1726
1727 switch( type )
1728 {
1729 case NL80211_IFTYPE_AP:
1730 sessionType = WLAN_HDD_SOFTAP;
1731 break;
1732 case NL80211_IFTYPE_P2P_GO:
1733 sessionType = WLAN_HDD_P2P_GO;
1734 break;
1735 case NL80211_IFTYPE_P2P_CLIENT:
1736 sessionType = WLAN_HDD_P2P_CLIENT;
1737 break;
1738 case NL80211_IFTYPE_STATION:
1739 sessionType = WLAN_HDD_INFRA_STATION;
1740 break;
1741 case NL80211_IFTYPE_MONITOR:
1742 sessionType = WLAN_HDD_MONITOR;
1743 break;
1744 default:
1745 sessionType = WLAN_HDD_INFRA_STATION;
1746 break;
1747 }
1748
1749 return sessionType;
1750}
1751
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301753struct wireless_dev* __wlan_hdd_add_virtual_intf(
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001754 struct wiphy *wiphy, const char *name,
1755 enum nl80211_iftype type,
1756 u32 *flags, struct vif_params *params )
1757#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301758struct wireless_dev* __wlan_hdd_add_virtual_intf(
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001759 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1760 u32 *flags, struct vif_params *params )
1761#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301762struct net_device* __wlan_hdd_add_virtual_intf(
Jeff Johnson295189b2012-06-20 16:38:30 -07001763 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1764 u32 *flags, struct vif_params *params )
1765#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301766int __wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name,
Jeff Johnson295189b2012-06-20 16:38:30 -07001767 enum nl80211_iftype type,
1768 u32 *flags, struct vif_params *params )
1769#endif
1770{
1771 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301772 hdd_adapter_t *pAdapter = NULL;
Rashmi Ramanna8f122ce2014-05-28 22:42:12 +05301773 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 ENTER();
1775
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301776 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1777 TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type));
Agarwal Ashish4cfa1e52014-05-09 20:25:11 +05301778 if (WLAN_HDD_P2P_CLIENT != wlan_hdd_get_session_type(type) &&
1779 WLAN_HDD_INFRA_STATION != wlan_hdd_get_session_type(type) &&
1780 hdd_get_adapter(pHddCtx, wlan_hdd_get_session_type(type)) != NULL)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001781 {
Jeff Johnsond13512a2012-07-17 11:42:19 -07001782 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Interface type %d already exists. Two"
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001783 "interfaces of same type are not supported currently.",__func__, type);
c_hpothu471fc962014-06-24 16:06:53 +05301784#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1785 return ERR_PTR(-EINVAL);
1786#else
1787 return -EAGAIN;
1788#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001789 }
1790
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001791 if (pHddCtx->isLogpInProgress)
1792 {
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "%s:LOGP in Progress. Ignore!!!", __func__);
1795#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
c_hpothu471fc962014-06-24 16:06:53 +05301796 return ERR_PTR(-EINVAL);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07001797#else
1798 return -EAGAIN;
1799#endif
1800 }
Rashmi Ramanna8f122ce2014-05-28 22:42:12 +05301801
1802 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
1803 pScanInfo = &pHddCtx->scan_info;
1804 if ((pScanInfo != NULL) && (pAdapter != NULL) &&
1805 (pHddCtx->scan_info.mScanPending))
1806 {
1807 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
1808 eCSR_SCAN_ABORT_DEFAULT);
1809 hddLog(VOS_TRACE_LEVEL_INFO,
1810 "%s: Abort Scan while adding virtual interface",__func__);
1811 }
1812
1813 pAdapter = NULL;
Kiet Lam04e26912013-10-18 20:13:38 +05301814 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated &&
1815 ((NL80211_IFTYPE_P2P_GO == type) ||
1816 (NL80211_IFTYPE_P2P_CLIENT == type)))
Jeff Johnson295189b2012-06-20 16:38:30 -07001817 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001818 /* Generate the P2P Interface Address. this address must be
1819 * different from the P2P Device Address.
1820 */
1821 v_MACADDR_t p2pDeviceAddress = pHddCtx->p2pDeviceAddress;
1822 p2pDeviceAddress.bytes[4] ^= 0x80;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301823 pAdapter = hdd_open_adapter( pHddCtx,
Jeff Johnson295189b2012-06-20 16:38:30 -07001824 wlan_hdd_get_session_type(type),
1825 name, p2pDeviceAddress.bytes,
1826 VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001827 }
1828 else
1829 {
1830 pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type),
1831 name, wlan_hdd_get_intf_addr(pHddCtx), VOS_TRUE );
1832 }
1833
1834 if( NULL == pAdapter)
1835 {
1836 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__);
1837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
c_hpothu471fc962014-06-24 16:06:53 +05301838 return ERR_PTR(-EINVAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001839#else
1840 return -EINVAL;
1841#endif
1842 }
1843 EXIT();
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1845 return pAdapter->dev->ieee80211_ptr;
1846#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07001847 return pAdapter->dev;
1848#else
1849 return 0;
1850#endif
1851}
1852
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
1854struct wireless_dev* wlan_hdd_add_virtual_intf(
1855 struct wiphy *wiphy, const char *name,
1856 enum nl80211_iftype type,
1857 u32 *flags, struct vif_params *params )
1858#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1859struct wireless_dev* wlan_hdd_add_virtual_intf(
1860 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1861 u32 *flags, struct vif_params *params )
1862#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1863struct net_device* wlan_hdd_add_virtual_intf(
1864 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1865 u32 *flags, struct vif_params *params )
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001866#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301867int wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name,
1868 enum nl80211_iftype type,
1869 u32 *flags, struct vif_params *params )
1870#endif
1871{
1872#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)))
1873 struct wireless_dev* wdev;
1874#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1875 struct net_device* ndev;
1876#else
1877 int ret;
1878#endif
1879 vos_ssr_protect(__func__);
1880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1881 wdev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
1882 vos_ssr_unprotect(__func__);
1883 return wdev;
1884#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1885 ndev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
1886 vos_ssr_unprotect(__func__);
1887 return ndev;
1888#else
1889 ret = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
1890 vos_ssr_unprotect(__func__);
1891 return ret;
1892#endif
1893}
1894
1895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1896int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
1897#else
1898int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001899#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001900{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001901#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1902 struct net_device *dev = wdev->netdev;
1903#endif
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301904 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301906 hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1907 int status;
1908 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001909
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301910 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1911 TRACE_CODE_HDD_DEL_VIRTUAL_INTF,
1912 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301913 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
1914 __func__,pVirtAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07001915
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301916 status = wlan_hdd_validate_context(pHddCtx);
1917
1918 if (0 != status)
1919 {
1920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1921 "%s: HDD context is not valid", __func__);
1922 return status;
1923 }
1924
1925 wlan_hdd_release_intf_addr( pHddCtx,
Jeff Johnson295189b2012-06-20 16:38:30 -07001926 pVirtAdapter->macAddressCurrent.bytes );
1927
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05301928 hdd_stop_adapter( pHddCtx, pVirtAdapter, VOS_TRUE);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301929 hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE );
1930 EXIT();
1931 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001932}
1933
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1935int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
1936#else
1937int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
1938#endif
1939{
1940 int ret;
1941
1942 vos_ssr_protect(__func__);
1943#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1944 ret = __wlan_hdd_del_virtual_intf(wiphy, wdev);
1945#else
1946 ret = __wlan_hdd_del_virtual_intf(wiphy, dev);
1947#endif
1948 vos_ssr_unprotect(__func__);
1949
1950 return ret;
1951}
1952
Jeff Johnson295189b2012-06-20 16:38:30 -07001953void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07001954 tANI_U32 nFrameLength,
1955 tANI_U8* pbFrames,
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301956 tANI_U8 frameType )
Jeff Johnson295189b2012-06-20 16:38:30 -07001957{
1958 //Indicate a Frame over Monitor Intf.
1959 int rxstat;
1960 struct sk_buff *skb = NULL;
1961 int needed_headroom = 0;
1962 int flag = HDD_RX_FLAG_IV_STRIPPED | HDD_RX_FLAG_DECRYPTED |
1963 HDD_RX_FLAG_MMIC_STRIPPED;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001964#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07001965#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
1966 hdd_context_t* pHddCtx = (hdd_context_t*)(pMonAdapter->pHddCtx);
1967#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 hddLog( LOG1, FL("Indicate Frame over Monitor Intf"));
1970
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07001971 if (NULL == pbFrames)
1972 {
1973 hddLog(LOGE, FL("NULL frame pointer"));
1974 return;
1975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001976
1977 /* room for the radiotap header based on driver features
1978 * 1 Byte for RADIO TAP Flag, 1 Byte padding and 2 Byte for
1979 * RX flags.
1980 * */
1981 needed_headroom = sizeof(struct ieee80211_radiotap_header) + 4;
1982
1983 //alloc skb here
1984 skb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC);
1985 if (unlikely(NULL == skb))
1986 {
1987 hddLog( LOGW, FL("Unable to allocate skb"));
1988 return;
1989 }
1990 skb_reserve(skb, VPKT_SIZE_BUFFER);
1991 if (unlikely(skb_headroom(skb) < nFrameLength))
1992 {
1993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1994 "HDD [%d]: Insufficient headroom, "
1995 "head[%p], data[%p], req[%d]",
1996 __LINE__, skb->head, skb->data, nFrameLength);
1997 kfree_skb(skb);
1998 return ;
1999 }
2000 // actually push the data
2001 memcpy(skb_push(skb, nFrameLength), pbFrames, nFrameLength);
2002 /* prepend radiotap information */
2003 if( 0 != hdd_wlan_add_rx_radiotap_hdr( skb, needed_headroom, flag ) )
2004 {
2005 hddLog( LOGE, FL("Not Able Add Radio Tap"));
2006 //free skb
2007 kfree_skb(skb);
2008 return ;
2009 }
2010
2011 skb_reset_mac_header( skb );
2012 skb->dev = pMonAdapter->dev;
2013 skb->protocol = eth_type_trans( skb, skb->dev );
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002014 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002015#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002016#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07002017 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07002018#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002019#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 rxstat = netif_rx_ni(skb);
2021 if( NET_RX_SUCCESS == rxstat )
2022 {
2023 hddLog( LOG1, FL("Success"));
2024 }
2025 else
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302026 hddLog( LOGE, FL("Failed %d"), rxstat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002027
2028 return ;
2029}
2030
2031void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter,
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302032 tANI_U32 nFrameLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 tANI_U8* pbFrames,
2034 tANI_U8 frameType,
Chilam NG571c65a2013-01-19 12:27:36 +05302035 tANI_U32 rxChan,
2036 tANI_S8 rxRssi )
Jeff Johnson295189b2012-06-20 16:38:30 -07002037{
2038 tANI_U16 freq;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302039 tANI_U16 extend_time;
Jeff Johnsone7245742012-09-05 17:12:55 -07002040 tANI_U8 type = 0;
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002041 tANI_U8 subType = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002042 tActionFrmType actionFrmType;
2043 hdd_cfg80211_state_t *cfgState = NULL;
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302044 hdd_scaninfo_t *pScanInfo = NULL;
Kaushik, Sushant13a287c2014-05-03 12:26:27 +05302045 hdd_context_t *pHddCtx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302046 VOS_STATUS status;
2047 hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002048
Arif Hussain6d2a3322013-11-17 19:50:10 -08002049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Frame Type = %d Frame Length = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002050 __func__, frameType, nFrameLength);
2051
2052 if (NULL == pAdapter)
2053 {
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002054 hddLog(LOGE, FL("pAdapter is NULL"));
2055 return;
2056 }
2057
2058 if (0 == nFrameLength)
2059 {
2060 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
2061 return;
2062 }
2063
2064 if (NULL == pbFrames)
2065 {
2066 hddLog(LOGE, FL("pbFrames is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 return;
2068 }
2069
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002070 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
2071 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
2072
2073 /* Get pAdapter from Destination mac address of the frame */
2074 if ((type == SIR_MAC_MGMT_FRAME) &&
2075 (subType != SIR_MAC_MGMT_PROBE_REQ))
2076 {
2077 pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter),
2078 &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]);
2079 if (NULL == pAdapter)
2080 {
2081 /* Under assumtion that we don't receive any action frame
2082 * with BCST as destination we dropping action frame
2083 */
Madan Mohan Koyyalamudi051ff0b2012-12-03 16:55:26 -08002084 hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = "
2085 MAC_ADDRESS_STR ,
2086 MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]));
2087 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d"
Arif Hussain6d2a3322013-11-17 19:50:10 -08002088 " subType = %d",__func__,frameType,nFrameLength,subType);
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002089 return;
2090 }
2091 }
2092
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002093
Jeff Johnson295189b2012-06-20 16:38:30 -07002094 if (NULL == pAdapter->dev)
2095 {
2096 hddLog( LOGE, FL("pAdapter->dev is NULL"));
2097 return;
2098 }
2099
2100 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2101 {
2102 hddLog( LOGE, FL("pAdapter has invalid magic"));
2103 return;
2104 }
2105
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2107 if (NULL == pHddCtx)
2108 {
2109 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
2110 return;
2111 }
2112
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002113 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
2114 (WLAN_HDD_P2P_GO == pAdapter->device_mode ))
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 {
2116 hdd_adapter_t *pMonAdapter =
2117 hdd_get_mon_adapter( WLAN_HDD_GET_CTX(pAdapter) );
2118
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002119 if (NULL != pMonAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 {
2121 hddLog( LOG1, FL("Indicate Frame over Monitor Interface"));
2122 hdd_sendMgmtFrameOverMonitorIface( pMonAdapter, nFrameLength,
2123 pbFrames, frameType);
2124 return;
2125 }
2126 }
2127
2128 //Channel indicated may be wrong. TODO
2129 //Indicate an action frame.
2130 if( rxChan <= MAX_NO_OF_2_4_CHANNELS )
2131 {
2132 freq = ieee80211_channel_to_frequency( rxChan,
2133 IEEE80211_BAND_2GHZ);
2134 }
2135 else
2136 {
2137 freq = ieee80211_channel_to_frequency( rxChan,
2138 IEEE80211_BAND_5GHZ);
2139 }
2140
Jeff Johnsone7245742012-09-05 17:12:55 -07002141 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302142 pRemainChanCtx = cfgState->remain_on_chan_ctx;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302143
2144 if ((type == SIR_MAC_MGMT_FRAME) &&
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002145 (subType == SIR_MAC_MGMT_ACTION))
Jeff Johnsone7245742012-09-05 17:12:55 -07002146 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002147 if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)
2148 {
2149 // public action frame
2150 if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == SIR_MAC_ACTION_VENDOR_SPECIFIC) &&
Sudhir Sattayappa Kohallic8239802013-02-22 18:46:44 -08002151 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 -08002152 // P2P action frames
2153 {
2154 actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002155 hddLog(LOG1, "Rx Action Frame %u", actionFrmType);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002156#ifdef WLAN_FEATURE_P2P_DEBUG
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002157 if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
2158 {
2159 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] <--- OTA",
2160 actionFrmType);
2161 }
2162 else
2163 {
2164 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s <--- OTA",
2165 p2p_action_frame_type[actionFrmType]);
2166 if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
2167 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
2168 {
2169 globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
2170 hddLog(LOGE,"[P2P State]Inactive state to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002171 "GO negotiation progress state");
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002172 }
2173 else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
2174 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
2175 {
2176 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
Jeff Johnson1250df42012-12-10 14:31:52 -08002177 hddLog(LOGE,"[P2P State]GO negotiation progress to "
2178 "GO negotiation completed state");
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002179 }
2180 else if( (actionFrmType == WLAN_HDD_INVITATION_REQ) &&
2181 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
2182 {
2183 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
2184 hddLog(LOGE,"[P2P State]Inactive state to GO negotiation"
2185 " completed state Autonomous GO formation");
2186 }
2187 }
2188#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302189 if (pRemainChanCtx != NULL && VOS_TIMER_STATE_RUNNING
2190 == vos_timer_getCurrentState(&pRemainChanCtx->hdd_remain_on_chan_timer))
2191 {
2192 if ( actionFrmType == WLAN_HDD_GO_NEG_REQ ||
2193 actionFrmType == WLAN_HDD_GO_NEG_RESP ||
2194 actionFrmType == WLAN_HDD_INVITATION_REQ ||
2195 actionFrmType == WLAN_HDD_DEV_DIS_REQ ||
2196 actionFrmType == WLAN_HDD_PROV_DIS_REQ )
2197 {
2198 hddLog( LOG1, "Extend RoC timer on reception of"
2199 " Action Frame");
2200 if ((actionFrmType == WLAN_HDD_GO_NEG_REQ)
2201 || (actionFrmType == WLAN_HDD_GO_NEG_RESP))
2202 extend_time = 2 * ACTION_FRAME_DEFAULT_WAIT;
2203 else
2204 extend_time = ACTION_FRAME_DEFAULT_WAIT;
2205 if (completion_done(&pAdapter->rem_on_chan_ready_event))
2206 {
2207 vos_timer_stop(
2208 &pRemainChanCtx->hdd_remain_on_chan_timer);
2209 status = vos_timer_start(
2210 &pRemainChanCtx->hdd_remain_on_chan_timer,
2211 extend_time);
2212 if (status != VOS_STATUS_SUCCESS)
2213 {
2214 hddLog( LOGE, "ROC timer start failed");
2215 }
2216 }
2217 else
2218 {
2219 // Buffer Packet
2220 if (pRemainChanCtx->action_pkt_buff.frame_length == 0)
2221 {
2222 pRemainChanCtx->action_pkt_buff.frame_length =
2223 nFrameLength;
2224 pRemainChanCtx->action_pkt_buff.freq = freq;
2225 pRemainChanCtx->action_pkt_buff.frame_ptr
2226 = vos_mem_malloc(nFrameLength);
2227 vos_mem_copy(
2228 pRemainChanCtx->action_pkt_buff.frame_ptr,
2229 pbFrames, nFrameLength);
2230 hddLog( LOGE,"%s:"
2231 "Action Pkt Cached successfully !!!", __func__);
2232 }
2233 else
2234 {
2235 hddLog( LOGE,"%s:"
2236 "Frames are pending. dropping frame !!!",
2237 __func__);
2238 }
2239 return;
2240 }
2241 }
2242 }
2243 if (pRemainChanCtx != NULL &&
2244 VOS_TIMER_STATE_RUNNING != vos_timer_getCurrentState(
2245 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer))
2246 hddLog( LOG1, "%s:"
2247 "Rcvd action frame after timer expired ", __func__);
2248
2249 if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) ||
2250 (actionFrmType == WLAN_HDD_GO_NEG_REQ) ||
2251 (actionFrmType == WLAN_HDD_INVITATION_REQ) )
2252 {
2253 pScanInfo = &pHddCtx->scan_info;
2254 if((pScanInfo != NULL) && (pHddCtx->scan_info.mScanPending))
2255 {
2256 hddLog(LOGE,"Action frame received when Scanning is in"
2257 " progress. Abort Scan.");
2258 hdd_abort_mac_scan(pAdapter->pHddCtx,
2259 pAdapter->sessionId,
2260 eCSR_SCAN_ABORT_DEFAULT);
2261 }
2262 }
2263 if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) &&
2264 (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) ||
2265 ((actionFrmType == WLAN_HDD_GO_NEG_RESP) &&
2266 (cfgState->actionFrmState == HDD_GO_NEG_REQ_ACK_PENDING)))
2267 {
2268 hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ",
2269 __func__);
2270 hdd_sendActionCnf(pAdapter, TRUE);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002271 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002272 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002273#ifdef FEATURE_WLAN_TDLS
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002274 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 -07002275 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002276 u8 *mac = &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6];
2277#ifdef WLAN_FEATURE_TDLS_DEBUG
2278 hddLog(VOS_TRACE_LEVEL_ERROR,"[TDLS] TDLS Discovery Response," MAC_ADDRESS_STR " RSSI[%d] <--- OTA",
2279 MAC_ADDR_ARRAY(mac),rxRssi);
2280#endif
2281 wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi);
2282 wlan_hdd_tdls_recv_discovery_resp(pAdapter, mac);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002283 }
2284#endif
2285 }
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002286#ifdef WLAN_FEATURE_TDLS_DEBUG
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002287 if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_TDLS_ACTION_FRAME)
2288 {
2289 actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1];
2290 if(actionFrmType >= MAX_TDLS_ACTION_FRAME_TYPE)
2291 {
2292 hddLog(VOS_TRACE_LEVEL_ERROR,"[TDLS] unknown[%d] <--- OTA",
2293 actionFrmType);
2294 }
2295 else
2296 {
2297 hddLog(VOS_TRACE_LEVEL_ERROR,"[TDLS] %s <--- OTA",
2298 tdls_action_frame_type[actionFrmType]);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002299 }
2300 }
2301#endif
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002302 if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_QOS_ACTION_FRAME)&&
2303 (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_QOS_MAP_CONFIGURE) )
2304 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002305 sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2306 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002307 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002308 }
2309
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 //Indicate Frame Over Normal Interface
2311 hddLog( LOG1, FL("Indicate Frame over NL80211 Interface"));
2312
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002313#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2314 cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, 0,
2315 pbFrames, nFrameLength,
2316 GFP_ATOMIC );
2317#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002318 cfg80211_rx_mgmt( pAdapter->dev, freq, 0,
2319 pbFrames, nFrameLength,
2320 GFP_ATOMIC );
2321#else
2322 cfg80211_rx_mgmt( pAdapter->dev, freq,
2323 pbFrames, nFrameLength,
2324 GFP_ATOMIC );
2325#endif //LINUX_VERSION_CODE
2326}
2327
2328/*
2329 * ieee80211_add_rx_radiotap_header - add radiotap header
2330 */
2331static int hdd_wlan_add_rx_radiotap_hdr (
2332 struct sk_buff *skb, int rtap_len, int flag )
2333{
2334 u8 rtap_temp[20] = {0};
2335 struct ieee80211_radiotap_header *rthdr;
2336 unsigned char *pos;
2337 u16 rx_flags = 0;
2338
2339 rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]);
2340
2341 /* radiotap header, set always present flags */
2342 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
2343 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
2344 rthdr->it_len = cpu_to_le16(rtap_len);
2345
2346 pos = (unsigned char *) (rthdr + 1);
2347
2348 /* the order of the following fields is important */
2349
2350 /* IEEE80211_RADIOTAP_FLAGS */
2351 *pos = 0;
2352 pos++;
2353
2354 /* IEEE80211_RADIOTAP_RX_FLAGS: Length 2 Bytes */
2355 /* ensure 2 byte alignment for the 2 byte field as required */
2356 if ((pos - (u8 *)rthdr) & 1)
2357 pos++;
2358 put_unaligned_le16(rx_flags, pos);
2359 pos += 2;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302360
Jeff Johnson295189b2012-06-20 16:38:30 -07002361 // actually push the data
2362 memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len);
2363
2364 return 0;
2365}
2366
2367static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
2368 hdd_cfg80211_state_t* cfgState,
2369 tANI_BOOLEAN actionSendSuccess )
2370{
2371 struct ieee80211_radiotap_header *rthdr;
2372 unsigned char *pos;
2373 struct sk_buff *skb = cfgState->skb;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002374#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002375#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
2376 hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
2377#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002378#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002379
2380 /* 2 Byte for TX flags and 1 Byte for Retry count */
2381 u32 rtHdrLen = sizeof(*rthdr) + 3;
2382
2383 u8 *data;
2384
2385 /* We have to return skb with Data starting with MAC header. We have
2386 * copied SKB data starting with MAC header to cfgState->buf. We will pull
2387 * entire skb->len from skb and then we will push cfgState->buf to skb
2388 * */
2389 if( NULL == skb_pull(skb, skb->len) )
2390 {
2391 hddLog( LOGE, FL("Not Able to Pull %d byte from skb"), skb->len);
2392 kfree_skb(cfgState->skb);
2393 return;
2394 }
2395
2396 data = skb_push( skb, cfgState->len );
2397
2398 if (data == NULL)
2399 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08002400 hddLog( LOGE, FL("Not Able to Push %zu byte to skb"), cfgState->len);
Jeff Johnson295189b2012-06-20 16:38:30 -07002401 kfree_skb( cfgState->skb );
2402 return;
2403 }
2404
2405 memcpy( data, cfgState->buf, cfgState->len );
2406
2407 /* send frame to monitor interfaces now */
2408 if( skb_headroom(skb) < rtHdrLen )
2409 {
2410 hddLog( LOGE, FL("No headroom for rtap header"));
2411 kfree_skb(cfgState->skb);
2412 return;
2413 }
2414
2415 rthdr = (struct ieee80211_radiotap_header*) skb_push( skb, rtHdrLen );
2416
2417 memset( rthdr, 0, rtHdrLen );
2418 rthdr->it_len = cpu_to_le16( rtHdrLen );
2419 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
2420 (1 << IEEE80211_RADIOTAP_DATA_RETRIES)
2421 );
2422
2423 pos = (unsigned char *)( rthdr+1 );
2424
2425 // Fill TX flags
2426 *pos = actionSendSuccess;
2427 pos += 2;
2428
2429 // Fill retry count
2430 *pos = 0;
2431 pos++;
2432
2433 skb_set_mac_header( skb, 0 );
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002434 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 skb->pkt_type = PACKET_OTHERHOST;
2436 skb->protocol = htons(ETH_P_802_2);
2437 memset( skb->cb, 0, sizeof( skb->cb ) );
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002438#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002439#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07002440 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07002441#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002442#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002443 if (in_interrupt())
2444 netif_rx( skb );
2445 else
2446 netif_rx_ni( skb );
2447
2448 /* Enable Queues which we have disabled earlier */
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05302449 netif_tx_start_all_queues( pAdapter->dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07002450
2451}
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05302452