blob: 8203248769713c7b571b0dca3845be830699abf4 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05302 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**========================================================================
29
30 \file wlan_hdd_p2p.c
31
32 \brief WLAN Host Device Driver implementation for P2P commands interface
33
Jeff Johnson295189b2012-06-20 16:38:30 -070034
35 ========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070036
37#include <wlan_hdd_includes.h>
38#include <wlan_hdd_hostapd.h>
39#include <net/cfg80211.h>
40#include "sme_Api.h"
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -070041#include "sme_QosApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070042#include "wlan_hdd_p2p.h"
43#include "sapApi.h"
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053044#include "wlan_hdd_main.h"
Daram Sudha1f7e0e92013-12-17 07:52:31 +053045#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070046#include <linux/netdevice.h>
47#include <linux/skbuff.h>
48#include <linux/etherdevice.h>
49#include <net/ieee80211_radiotap.h>
Hoonki Lee1090c6a2013-01-16 17:40:54 -080050#ifdef FEATURE_WLAN_TDLS
51#include "wlan_hdd_tdls.h"
52#endif
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053053#include "wlan_hdd_trace.h"
54#include "vos_types.h"
55#include "vos_trace.h"
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +053056#include "vos_sched.h"
57
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -080058//Ms to Micro Sec
59#define MS_TO_MUS(x) ((x)*1000);
Daram Sudha1f7e0e92013-12-17 07:52:31 +053060tANI_U8* hdd_getActionString( tANI_U16 MsgType )
61{
62 switch (MsgType)
63 {
64 CASE_RETURN_STRING(SIR_MAC_ACTION_SPECTRUM_MGMT);
65 CASE_RETURN_STRING(SIR_MAC_ACTION_QOS_MGMT);
66 CASE_RETURN_STRING(SIR_MAC_ACTION_DLP);
67 CASE_RETURN_STRING(SIR_MAC_ACTION_BLKACK);
68 CASE_RETURN_STRING(SIR_MAC_ACTION_PUBLIC_USAGE);
69 CASE_RETURN_STRING(SIR_MAC_ACTION_RRM);
70 CASE_RETURN_STRING(SIR_MAC_ACTION_FAST_BSS_TRNST);
71 CASE_RETURN_STRING(SIR_MAC_ACTION_HT);
72 CASE_RETURN_STRING(SIR_MAC_ACTION_SA_QUERY);
73 CASE_RETURN_STRING(SIR_MAC_ACTION_PROT_DUAL_PUB);
74 CASE_RETURN_STRING(SIR_MAC_ACTION_WNM);
75 CASE_RETURN_STRING(SIR_MAC_ACTION_UNPROT_WNM);
76 CASE_RETURN_STRING(SIR_MAC_ACTION_TDLS);
77 CASE_RETURN_STRING(SIR_MAC_ACITON_MESH);
78 CASE_RETURN_STRING(SIR_MAC_ACTION_MULTIHOP);
79 CASE_RETURN_STRING(SIR_MAC_SELF_PROTECTED);
80 CASE_RETURN_STRING(SIR_MAC_ACTION_WME);
81 CASE_RETURN_STRING(SIR_MAC_ACTION_VHT);
82 default:
83 return ("UNKNOWN");
84 }
85}
86
87
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070088#ifdef WLAN_FEATURE_P2P_DEBUG
89#define MAX_P2P_ACTION_FRAME_TYPE 9
90const char *p2p_action_frame_type[]={"GO Negotiation Request",
91 "GO Negotiation Response",
92 "GO Negotiation Confirmation",
93 "P2P Invitation Request",
94 "P2P Invitation Response",
95 "Device Discoverability Request",
96 "Device Discoverability Response",
97 "Provision Discovery Request",
98 "Provision Discovery Response"};
99
100/* We no need to protect this variable since
101 * there is no chance of race to condition
102 * and also not make any complicating the code
103 * just for debugging log
104 */
105tP2PConnectionStatus globalP2PConnectionStatus = P2P_NOT_ACTIVE;
106
107#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -0800108#define MAX_TDLS_ACTION_FRAME_TYPE 11
109const char *tdls_action_frame_type[] = {"TDLS Setup Request",
110 "TDLS Setup Response",
111 "TDLS Setup Confirm",
112 "TDLS Teardown",
113 "TDLS Peer Traffic Indication",
114 "TDLS Channel Switch Request",
115 "TDLS Channel Switch Response",
116 "TDLS Peer PSM Request",
117 "TDLS Peer PSM Response",
118 "TDLS Peer Traffic Response",
119 "TDLS Discovery Request" };
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -0700120
Jeff Johnson295189b2012-06-20 16:38:30 -0700121extern struct net_device_ops net_ops_struct;
122
123static int hdd_wlan_add_rx_radiotap_hdr( struct sk_buff *skb,
124 int rtap_len, int flag );
125
126static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
127 hdd_cfg80211_state_t* cfgState,
128 tANI_BOOLEAN actionSendSuccess );
129
130static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
Rashmi Ramannac7744532013-10-06 16:49:08 +0530131 tANI_U32 nFrameLength,
Jeff Johnson295189b2012-06-20 16:38:30 -0700132 tANI_U8* pbFrames,
133 tANI_U8 frameType );
vamsi9bd92b72013-12-26 14:11:29 +0530134
135static v_BOOL_t hdd_p2p_is_action_type_rsp( const u8 *buf )
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +0530136{
vamsi9bd92b72013-12-26 14:11:29 +0530137 tActionFrmType actionFrmType;
138 const u8 *ouiPtr;
139
140 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] !=
141 WLAN_HDD_PUBLIC_ACTION_FRAME ) {
142 return VOS_FALSE;
143 }
144
145 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET] !=
146 WLAN_HDD_VENDOR_SPECIFIC_ACTION ) {
147 return VOS_FALSE;
148 }
149
150 ouiPtr = &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET];
151
152 if ( WPA_GET_BE24(ouiPtr) != WLAN_HDD_WFA_OUI ) {
153 return VOS_FALSE;
154 }
155
156 if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET] !=
157 WLAN_HDD_WFA_P2P_OUI_TYPE ) {
158 return VOS_FALSE;
159 }
160
Ahmad Kholaife5ec2cd2014-03-19 13:22:04 +0530161 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET];
vamsi9bd92b72013-12-26 14:11:29 +0530162 if ( actionFrmType != WLAN_HDD_INVITATION_REQ &&
163 actionFrmType != WLAN_HDD_GO_NEG_REQ &&
164 actionFrmType != WLAN_HDD_DEV_DIS_REQ &&
165 actionFrmType != WLAN_HDD_PROV_DIS_REQ )
166 return VOS_TRUE;
167 else
168 return VOS_FALSE;
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +0530169}
Jeff Johnson295189b2012-06-20 16:38:30 -0700170
Jeff Johnson295189b2012-06-20 16:38:30 -0700171eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx,
172 eHalStatus status )
173{
174 hdd_adapter_t *pAdapter = (hdd_adapter_t*) pCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
176 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530177 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700178
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530179 if (pHddCtx == NULL)
180 {
181 hddLog(LOGE, "%s: Hdd Context is NULL", __func__);
182 return eHAL_STATUS_FAILURE;
183 }
184 if (pRemainChanCtx == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700185 {
186 hddLog( LOGW,
187 "%s: No Rem on channel pending for which Rsp is received", __func__);
188 return eHAL_STATUS_SUCCESS;
189 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530190
191 mutex_lock(&pHddCtx->roc_lock);
Rashmi Ramannac7744532013-10-06 16:49:08 +0530192 hddLog( VOS_TRACE_LEVEL_INFO,
193 "Received ROC rsp (request type %d, channel %d, cookie %llu",
194 pRemainChanCtx->rem_on_chan_request,
195 pRemainChanCtx->chan.center_freq,
196 pRemainChanCtx->cookie);
Jeff Johnson295189b2012-06-20 16:38:30 -0700197 cfgState->remain_on_chan_ctx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530198 vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer);
199 vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530200 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530201 if ( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
Jeff Johnson295189b2012-06-20 16:38:30 -0700202 {
203 if( cfgState->buf )
204 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530205 hddLog( LOGP,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 "%s: We need to receive yet an ack from one of tx packet",
207 __func__);
208 }
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800209 cfg80211_remain_on_channel_expired(
210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
211 pRemainChanCtx->dev->ieee80211_ptr,
212#else
213 pRemainChanCtx->dev,
214#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700215 pRemainChanCtx->cookie,
216 &pRemainChanCtx->chan,
Yue Maf49ba872013-08-19 12:04:25 -0700217#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
218 pRemainChanCtx->chan_type,
219#endif
220 GFP_KERNEL);
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530221 pAdapter->lastRocTs = vos_timer_get_system_time();
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 }
223
Jeff Johnson295189b2012-06-20 16:38:30 -0700224
225 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
Jeff Johnsone7245742012-09-05 17:12:55 -0700226 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
227 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 )
229 {
230 tANI_U8 sessionId = pAdapter->sessionId;
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800231 if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request )
232 {
233 sme_DeregisterMgmtFrame(
234 hHal, sessionId,
235 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
236 NULL, 0 );
237 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700238 }
Abhishek Singh36b7c532015-03-13 15:50:54 +0530239 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -0700240 {
241 WLANSAP_DeRegisterMgmtFrame(
242 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
243 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
244 NULL, 0 );
245 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530246 if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL
247 && pRemainChanCtx->action_pkt_buff.frame_length != 0)
248 {
249 vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
250 }
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800251 vos_mem_free( pRemainChanCtx );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800252 pRemainChanCtx = NULL;
Deepthi Gowri3e672f02015-01-30 17:04:08 +0530253 if (eHAL_STATUS_SUCCESS != status)
254 complete(&pAdapter->rem_on_chan_ready_event);
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 complete(&pAdapter->cancel_rem_on_chan_var);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530256 pAdapter->is_roc_inprogress = FALSE;
257 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 return eHAL_STATUS_SUCCESS;
259}
260
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530261VOS_STATUS wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700262{
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530264 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530265 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 int status = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530268 if (NULL == pHddCtx)
269 {
270 hddLog(LOGE, "%s: HddCtx is NULL", __func__);
271 return VOS_STATUS_E_FAILURE;
272 }
273
274 mutex_lock(&pHddCtx->roc_lock);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700275 if(cfgState->remain_on_chan_ctx != NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530277 if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(
278 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer))
279 {
280 hddLog(VOS_TRACE_LEVEL_INFO,
281 "Cancel Existing ROC (cookie=%llu)",
282 cfgState->remain_on_chan_ctx->cookie);
Jeff Johnson32d95a32012-09-10 13:15:23 -0700283
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530284 vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
285 }
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530286 /* Wait till remain on channel ready indication before issuing cancel
287 * remain on channel request, otherwise if remain on channel not
288 * received and if the driver issues cancel remain on channel then lim
Jeff Johnson295189b2012-06-20 16:38:30 -0700289 * will be in unknown state.
290 */
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530291 if (pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress != TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700292 {
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530293 status = wait_for_completion_interruptible_timeout(
294 &pAdapter->rem_on_chan_ready_event,
295 msecs_to_jiffies(WAIT_REM_CHAN_READY));
296 if (0 >= status)
297 {
298 hddLog( LOGE,
299 "%s: timeout waiting for remain on channel"
300 " ready indication %d",
301 __func__, status);
302 pRemainChanCtx->is_pending_roc_cancelled = TRUE;
303 mutex_unlock(&pHddCtx->roc_lock);
304 return VOS_STATUS_E_FAILURE;
305 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700306
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530307 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
308 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
Mahesh A Saptasgar3f692752014-11-17 16:13:35 +0530309 mutex_unlock(&pHddCtx->roc_lock);
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 */
Abhishek Singh36b7c532015-03-13 15:50:54 +0530315 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
316 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
317 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ))
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530318 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530319 if (eHAL_STATUS_SUCCESS !=
320 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
321 pAdapter->sessionId ))
322 {
323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
324 FL("Failed to Cancel Remain on Channel"));
325 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530326 }
Deepthi Gowri70498252015-01-20 15:56:45 +0530327 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530328 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530329 WLANSAP_CancelRemainOnChannel(
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530330 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
331 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700332
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530333 status = wait_for_completion_interruptible_timeout(
334 &pAdapter->cancel_rem_on_chan_var,
335 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
336 if (0 >= status)
337 {
338 hddLog( LOGE,
339 "%s: timeout waiting for cancel remain on channel"
340 " ready indication %d",
341 __func__, status);
342 }
343 hdd_allow_suspend();
344 }
345 else
346 {
347 hddLog( LOG1,
348 "ROC timer cancellation in progress,"
349 " wait for completion");
350 mutex_unlock(&pHddCtx->roc_lock);
351 status = wait_for_completion_interruptible_timeout(
352 &pAdapter->cancel_rem_on_chan_var,
353 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
354 if (0 >= status)
355 {
356 hddLog( LOGE,
357 "%s:wait on cancel_rem_on_chan_var failed %d",
358 __func__, status);
359 return VOS_STATUS_E_FAILURE;
360 }
361 return VOS_STATUS_SUCCESS;
362 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 }
Mahesh A Saptasagar60627942014-10-13 13:55:14 +0530364 else
365 {
366 hddLog(LOG1,
367 "%s: remain_on_chan_ctx is NULL", __func__);
368 mutex_unlock(&pHddCtx->roc_lock);
369 }
370 return VOS_STATUS_SUCCESS;
Jeff Johnson32d95a32012-09-10 13:15:23 -0700371}
372
373int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter)
374{
375 int status = 0;
376 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
377
378 if(WLAN_HDD_P2P_GO != pAdapter->device_mode)
379 {
380 //Cancel Existing Remain On Channel
381 //If no action frame is pending
382 if( cfgState->remain_on_chan_ctx != NULL)
383 {
384 //Check whether Action Frame is pending or not
385 if( cfgState->buf == NULL)
386 {
387 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
388 }
389 else
390 {
Rashmi Ramannac7744532013-10-06 16:49:08 +0530391 hddLog(VOS_TRACE_LEVEL_DEBUG,
392 "Cannot Cancel Existing Remain on Channel");
Jeff Johnson32d95a32012-09-10 13:15:23 -0700393 status = -EBUSY;
394 }
395 }
396 }
397 return status;
398}
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530399void wlan_hdd_remain_on_chan_timeout(void *data)
400{
401 hdd_adapter_t *pAdapter = (hdd_adapter_t *)data;
402 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
403 hdd_cfg80211_state_t *cfgState;
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530404
405 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530406 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +0530407 hddLog( LOGE, FL("pAdapter is invalid %p !!!"), pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530408 return;
409 }
410 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
411 pRemainChanCtx = cfgState->remain_on_chan_ctx;
412 if (NULL == pRemainChanCtx)
413 {
414 hddLog( LOGE, FL("No Remain on channel is pending"));
415 return;
416 }
417 if ( TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
418 {
419 hddLog( LOGE, FL("Cancellation already in progress"));
420 return;
421 }
422
423 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
424 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
425 hddLog( LOG1,"%s: Cancel Remain on Channel on timeout", __func__);
Abhishek Singh36b7c532015-03-13 15:50:54 +0530426 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
427 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530428 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
429 )
430 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530431 if (eHAL_STATUS_SUCCESS !=
432 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
433 pAdapter->sessionId ))
434 {
435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
436 FL("Failed to Cancel Remain on Channel"));
437 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530438 }
Abhishek Singh36b7c532015-03-13 15:50:54 +0530439 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530440 {
Deepthi Gowri70498252015-01-20 15:56:45 +0530441 WLANSAP_CancelRemainOnChannel(
442 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530443 }
444 hdd_allow_suspend();
445}
Jeff Johnson32d95a32012-09-10 13:15:23 -0700446
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530447static int wlan_hdd_p2p_start_remain_on_channel(
448 hdd_adapter_t *pAdapter)
449{
450 VOS_STATUS status = VOS_STATUS_SUCCESS;
451 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
452 hdd_adapter_t *pAdapter_temp;
453 v_BOOL_t isGoPresent = VOS_FALSE;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530454 hdd_context_t *pHddCtx;
455 hdd_cfg80211_state_t *cfgState;
456 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
457 rem_on_channel_request_type_t request_type;
458 int ret = 0;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530459
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530460 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530461 if (NULL == pAdapter)
462 {
463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
464 "%s: Adapter is NULL",__func__);
465 return -EINVAL;
466 }
467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
468 ret = wlan_hdd_validate_context(pHddCtx);
469 if (0 != ret)
470 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530471 return ret;
472 }
473 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
474 if (NULL == cfgState)
475 {
476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
477 "%s: cfgState is not valid ",__func__);
478 return -EINVAL;
479 }
480 pRemainChanCtx = cfgState->remain_on_chan_ctx;
481 request_type = pRemainChanCtx->rem_on_chan_request;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530482 /* Initialize Remain on chan timer */
483 status = vos_timer_init(&pRemainChanCtx->hdd_remain_on_chan_timer,
484 VOS_TIMER_TYPE_SW,
485 wlan_hdd_remain_on_chan_timeout,
486 pAdapter);
487 if (status != VOS_STATUS_SUCCESS)
488 {
489 hddLog(VOS_TRACE_LEVEL_ERROR,
Ganesh Kondabattini02795ae2015-02-02 17:45:19 +0530490 FL("Not able to initalize remain_on_chan timer"));
491 cfgState->remain_on_chan_ctx = NULL;
492 vos_mem_free(pRemainChanCtx);
493 return -EINVAL;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530494 }
Ganesh Kondabattini02795ae2015-02-02 17:45:19 +0530495
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530496 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
497 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
498 {
499 pAdapter_temp = pAdapterNode->pAdapter;
500 if (WLAN_HDD_P2P_GO == pAdapter_temp->device_mode)
501 {
502 isGoPresent = VOS_TRUE;
503 }
504 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
505 pAdapterNode = pNext;
506 }
507 hdd_prevent_suspend();
508 //call sme API to start remain on channel.
509 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
510 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
511 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
512 )
513 {
514 tANI_U8 sessionId = pAdapter->sessionId;
515 //call sme API to start remain on channel.
516 if (eHAL_STATUS_SUCCESS != sme_RemainOnChannel(
517 WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId,
518 pRemainChanCtx->chan.hw_value, pRemainChanCtx->duration,
519 wlan_hdd_remain_on_channel_callback, pAdapter,
520 (tANI_U8)(request_type == REMAIN_ON_CHANNEL_REQUEST)? TRUE:FALSE))
521 {
522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
523 FL(" RemainOnChannel returned fail"));
524 cfgState->remain_on_chan_ctx = NULL;
525 vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
526 vos_mem_free (pRemainChanCtx);
527 hdd_allow_suspend();
528 return -EINVAL;
529 }
530
531 if( REMAIN_ON_CHANNEL_REQUEST == request_type)
532 {
533 if( eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame(
534 WLAN_HDD_GET_HAL_CTX(pAdapter),
535 sessionId, (SIR_MAC_MGMT_FRAME << 2) |
536 (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0 ))
537 {
538 hddLog(VOS_TRACE_LEVEL_ERROR, "sme_RegisterMgmtFrame returned fail");
539 }
540 }
541
542 }
Abhishek Singh36b7c532015-03-13 15:50:54 +0530543 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530544 {
545 //call sme API to start remain on channel.
546 if (VOS_STATUS_SUCCESS != WLANSAP_RemainOnChannel(
547 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
548 pRemainChanCtx->chan.hw_value, pRemainChanCtx->duration,
549 wlan_hdd_remain_on_channel_callback, pAdapter ))
550
551 {
552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
553 "%s: WLANSAP_RemainOnChannel returned fail", __func__);
554 cfgState->remain_on_chan_ctx = NULL;
555 vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer);
556 vos_mem_free (pRemainChanCtx);
557 hdd_allow_suspend();
558 return -EINVAL;
559 }
560
561
562 if (VOS_STATUS_SUCCESS != WLANSAP_RegisterMgmtFrame(
563 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
564 (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
565 NULL, 0 ))
566 {
567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
568 "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__);
569 WLANSAP_CancelRemainOnChannel(
570 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
571 hdd_allow_suspend();
572 return -EINVAL;
573 }
574
575 }
576
577 pAdapter->is_roc_inprogress = TRUE;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530578 EXIT();
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530579 return 0;
580}
581
582
Jeff Johnson32d95a32012-09-10 13:15:23 -0700583static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy,
584 struct net_device *dev,
585 struct ieee80211_channel *chan,
Yue Maf49ba872013-08-19 12:04:25 -0700586#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson32d95a32012-09-10 13:15:23 -0700587 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -0700588#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -0700589 unsigned int duration, u64 *cookie,
590 rem_on_channel_request_type_t request_type )
591{
592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
593 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
594 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530595 hdd_context_t *pHddCtx = NULL;
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530596 VOS_STATUS checkReadyInd;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530597 hdd_adapter_t *pStaAdapter;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530598 int status = 0;
599
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530600 ENTER();
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530601 if (NULL == pAdapter)
602 {
603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
604 "%s: HDD adapter is Null", __func__);
605 return -ENODEV;
606 }
607
608 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
609 status = wlan_hdd_validate_context(pHddCtx);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530610 if (0 != status)
611 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530612 return status;
613 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530614
Jeff Johnson32d95a32012-09-10 13:15:23 -0700615 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
616 __func__,pAdapter->device_mode);
Yue Maf49ba872013-08-19 12:04:25 -0700617#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Rashmi Ramannac7744532013-10-06 16:49:08 +0530618 hddLog(VOS_TRACE_LEVEL_INFO,
619 "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, dur %d,"
620 " request type %d, cookie %llu",
621 chan->hw_value, chan->center_freq, channel_type, duration,
622 request_type, *cookie);
Yue Maf49ba872013-08-19 12:04:25 -0700623#else
Rashmi Ramannac7744532013-10-06 16:49:08 +0530624 hddLog(VOS_TRACE_LEVEL_INFO,
625 "chan(hw_val)0x%x chan(centerfreq) %d, duration %d"
626 " reuest type %d, cookie %llu", chan->hw_value, chan->center_freq,
627 duration, request_type, *cookie );
Yue Maf49ba872013-08-19 12:04:25 -0700628#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -0700629 //Cancel existing remain On Channel if any
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530630 checkReadyInd = wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
631 if (VOS_STATUS_SUCCESS != checkReadyInd)
632 {
633 hddLog( LOGE, FL("Cancel Roc in progress"));
634 return -EBUSY;
635 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700636
Jeff Johnsone7245742012-09-05 17:12:55 -0700637 /* When P2P-GO and if we are trying to unload the driver then
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 * wlan driver is keep on receiving the remain on channel command
Jeff Johnsone7245742012-09-05 17:12:55 -0700639 * and which is resulting in crash. So not allowing any remain on
Jeff Johnson295189b2012-06-20 16:38:30 -0700640 * channel requets when Load/Unload is in progress*/
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530641 if(hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -0700642 {
643 hddLog( LOGE,
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +0530644 "%s: Connection is in progress", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700645 return -EBUSY;
646 }
647
648 pRemainChanCtx = vos_mem_malloc( sizeof(hdd_remain_on_chan_ctx_t) );
649 if( NULL == pRemainChanCtx )
650 {
651 hddLog(VOS_TRACE_LEVEL_FATAL,
652 "%s: Not able to allocate memory for Channel context",
653 __func__);
654 return -ENOMEM;
655 }
656
Ganesh Kondabattini8ae1a072015-02-02 17:49:50 +0530657 vos_mem_zero(pRemainChanCtx, sizeof (hdd_remain_on_chan_ctx_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 vos_mem_copy( &pRemainChanCtx->chan, chan,
659 sizeof(struct ieee80211_channel) );
660
Yue Maf49ba872013-08-19 12:04:25 -0700661#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700662 pRemainChanCtx->chan_type = channel_type;
Yue Maf49ba872013-08-19 12:04:25 -0700663#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 pRemainChanCtx->duration = duration;
665 pRemainChanCtx->dev = dev;
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800666 *cookie = (uintptr_t) pRemainChanCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700667 pRemainChanCtx->cookie = *cookie;
668 pRemainChanCtx->rem_on_chan_request = request_type;
669 cfgState->remain_on_chan_ctx = pRemainChanCtx;
670 cfgState->current_freq = chan->center_freq;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530671 pRemainChanCtx->action_pkt_buff.freq = 0;
672 pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
673 pRemainChanCtx->action_pkt_buff.frame_length = 0;
674 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = FALSE;
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530675 pRemainChanCtx->is_pending_roc_cancelled = FALSE;
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530676
Jeff Johnson295189b2012-06-20 16:38:30 -0700677 INIT_COMPLETION(pAdapter->rem_on_chan_ready_event);
678
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530679 if (REMAIN_ON_CHANNEL_REQUEST == request_type)
Jeff Johnson295189b2012-06-20 16:38:30 -0700680 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530681 pStaAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
682 if((NULL != pStaAdapter)&&
683 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pStaAdapter)))
Sushant Kaushik298a8592014-12-09 17:34:07 +0530684 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530685 if (pAdapter->lastRocTs !=0 &&
686 ((vos_timer_get_system_time() - pAdapter->lastRocTs )
687 < pHddCtx->cfg_ini->gP2PListenDeferInterval))
Rashmi Ramannac7744532013-10-06 16:49:08 +0530688 {
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +0530689 if (pRemainChanCtx->duration > HDD_P2P_MAX_ROC_DURATION)
690 pRemainChanCtx->duration = HDD_P2P_MAX_ROC_DURATION;
691 schedule_delayed_work(&pAdapter->roc_work,
692 msecs_to_jiffies(pHddCtx->cfg_ini->gP2PListenDeferInterval));
693 hddLog(VOS_TRACE_LEVEL_INFO, "Defer interval is %hu, pAdapter %p",
694 pHddCtx->cfg_ini->gP2PListenDeferInterval, pAdapter);
695 return 0;
Rashmi Ramannac7744532013-10-06 16:49:08 +0530696 }
Madan Mohan Koyyalamudi35885912012-11-30 15:05:42 -0800697 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700698 }
Nirav Shah87cd0cb2013-12-28 21:22:09 +0530699
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530700 status = wlan_hdd_p2p_start_remain_on_channel(pAdapter);
701
702 EXIT();
703 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700704}
705
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530706int __wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
708 struct wireless_dev *wdev,
709#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 struct net_device *dev,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700712 struct ieee80211_channel *chan,
Yue Maf49ba872013-08-19 12:04:25 -0700713#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700714 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -0700715#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700716 unsigned int duration, u64 *cookie )
717{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
719 struct net_device *dev = wdev->netdev;
720#endif
Mahesh A Saptasagar74088392015-02-05 17:22:09 +0530721 hdd_adapter_t *pAdapter;
722 hdd_context_t *pHddCtx;
723 int ret = 0;
724
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530725 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +0530726 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
727 if (NULL == pAdapter)
728 {
729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
730 "%s: Adapter is NULL",__func__);
731 return -EINVAL;
732 }
733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
734 ret = wlan_hdd_validate_context(pHddCtx);
735 if (0 != ret)
736 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +0530737 return ret;
738 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530739
740 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
741 TRACE_CODE_HDD_REMAIN_ON_CHANNEL,
742 pAdapter->sessionId, REMAIN_ON_CHANNEL_REQUEST));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530743 ret = wlan_hdd_request_remain_on_channel(wiphy, dev,
Yue Maf49ba872013-08-19 12:04:25 -0700744 chan,
745#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
746 channel_type,
747#endif
748 duration, cookie,
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 REMAIN_ON_CHANNEL_REQUEST);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530750 EXIT();
751 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -0700752}
753
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530754int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy,
755#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
756 struct wireless_dev *wdev,
757#else
758 struct net_device *dev,
759#endif
760 struct ieee80211_channel *chan,
761#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
762 enum nl80211_channel_type channel_type,
763#endif
764 unsigned int duration, u64 *cookie )
765{
766 int ret;
767
768 vos_ssr_protect(__func__);
769 ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy,
770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
771 wdev,
772#else
773 dev,
774#endif
775 chan,
776#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
777 channel_type,
778#endif
779 duration, cookie);
780 vos_ssr_unprotect(__func__);
781
782 return ret;
783}
784
785
Jeff Johnson295189b2012-06-20 16:38:30 -0700786void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter )
787{
Kaushik, Sushant26402612014-05-03 16:56:06 +0530788 hdd_cfg80211_state_t *cfgState = NULL;
789 hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530790 VOS_STATUS status;
Kaushik, Sushant26402612014-05-03 16:56:06 +0530791 if (NULL == pAdapter)
792 {
793 hddLog(LOGE, FL("pAdapter is NULL"));
794 return;
795 }
796 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
797 pRemainChanCtx = cfgState->remain_on_chan_ctx;
Deepthi Gowri22d08752015-02-05 15:07:40 +0530798 pAdapter->startRocTs = vos_timer_get_system_time();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530799 hddLog( LOG1, "Ready on chan ind");
Jeff Johnson295189b2012-06-20 16:38:30 -0700800 if( pRemainChanCtx != NULL )
801 {
Kaushik, Sushant78c3efe2014-05-13 10:29:34 +0530802 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
803 TRACE_CODE_HDD_REMAINCHANREADYHANDLER,
804 pAdapter->sessionId, pRemainChanCtx->duration));
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530805 //start timer for actual duration
806 status = vos_timer_start(&pRemainChanCtx->hdd_remain_on_chan_timer,
807 (pRemainChanCtx->duration));
808 if (VOS_STATUS_SUCCESS!=status)
809 {
810 hddLog( LOGE, FL("Remain on Channel timer start failed"));
811 }
812 if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request)
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 {
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800814 cfg80211_ready_on_channel(
815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
816 pAdapter->dev->ieee80211_ptr,
817#else
818 pAdapter->dev,
819#endif
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800820 (uintptr_t)pRemainChanCtx,
Yue Maf49ba872013-08-19 12:04:25 -0700821 &pRemainChanCtx->chan,
822#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
823 pRemainChanCtx->chan_type,
824#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 pRemainChanCtx->duration, GFP_KERNEL );
826 }
827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530828 else if( OFF_CHANNEL_ACTION_TX == pRemainChanCtx->rem_on_chan_request)
Jeff Johnson295189b2012-06-20 16:38:30 -0700829 {
830 complete(&pAdapter->offchannel_tx_event);
831 }
832#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530833 // Check for cached action frame
834 if ( pRemainChanCtx->action_pkt_buff.frame_length != 0 )
835 {
836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
837 cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr,
838 pRemainChanCtx->action_pkt_buff.freq, 0,
839 pRemainChanCtx->action_pkt_buff.frame_ptr,
840 pRemainChanCtx->action_pkt_buff.frame_length,
841 GFP_ATOMIC );
842#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
843 cfg80211_rx_mgmt( pAdapter->dev,
844 pRemainChanCtx->action_pkt_buff.freq, 0,
845 pRemainChanCtx->action_pkt_buff.frame_ptr,
846 pRemainChanCtx->action_pkt_buff.frame_length,
847 GFP_ATOMIC );
848#else
849 cfg80211_rx_mgmt( pAdapter->dev,
850 pRemainChanCtx->action_pkt_buff.freq,
851 pRemainChanCtx->action_pkt_buff.frame_ptr,
852 pRemainChanCtx->action_pkt_buff.frame_length,
853 GFP_ATOMIC );
854#endif //LINUX_VERSION_CODE
855 hddLog( LOGE, "%s: Sent cached action frame to supplicant", __func__);
856 vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
857 pRemainChanCtx->action_pkt_buff.frame_length = 0;
858 pRemainChanCtx->action_pkt_buff.freq = 0;
859 pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
860 }
Rashmi Ramannac7744532013-10-06 16:49:08 +0530861 hddLog( VOS_TRACE_LEVEL_INFO, "Ready on chan ind (cookie=%llu)",
862 pRemainChanCtx->cookie);
Jeff Johnson295189b2012-06-20 16:38:30 -0700863 complete(&pAdapter->rem_on_chan_ready_event);
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530864 if (TRUE == pRemainChanCtx->is_pending_roc_cancelled)
865 {
866 /* since pRemainChanCtx->is_pending_roc_cancelled is
867 * set, it means Cancel Reamain on channel command is
868 * pending because remain on channel event was not
869 * ready when cancel ROC was issued.So issue
870 * cancel ROC now.
871 */
872 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
873 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 }
875 else
876 {
877 hddLog( LOGW, "%s: No Pending Remain on channel Request", __func__);
878 }
879 return;
880}
881
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +0530882int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
884 struct wireless_dev *wdev,
885#else
886 struct net_device *dev,
887#endif
888 u64 cookie )
Jeff Johnson295189b2012-06-20 16:38:30 -0700889{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -0800890#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
891 struct net_device *dev = wdev->netdev;
892#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700893 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700894 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530895 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530896 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
897 int status;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530898 u64 cookie_dummy;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530899
900 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530901 cookie_dummy = cookie << 32;
902 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
903 TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL,
904 pAdapter->sessionId, cookie_dummy));
905 hddLog( LOG1, "Cancel remain on channel req");
Jeff Johnson295189b2012-06-20 16:38:30 -0700906
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530907 status = wlan_hdd_validate_context(pHddCtx);
908
909 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -0700910 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530911 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -0700912 }
Rashmi Ramannac7744532013-10-06 16:49:08 +0530913 hddLog( LOG1, "Cancel remain on channel req (cookie = %llu)", cookie);
914
Jeff Johnson295189b2012-06-20 16:38:30 -0700915 /* FIXME cancel currently running remain on chan.
916 * Need to check cookie and cancel accordingly
917 */
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530918 mutex_lock(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700919 if( (cfgState->remain_on_chan_ctx == NULL) ||
920 (cfgState->remain_on_chan_ctx->cookie != cookie) )
921 {
922 hddLog( LOGE,
923 "%s: No Remain on channel pending with specified cookie value",
924 __func__);
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530925 mutex_unlock(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700926 return -EINVAL;
927 }
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530928 if (TRUE != pRemainChanCtx->is_pending_roc_cancelled)
929 {
930 /* wait until remain on channel ready event received
931 * for already issued remain on channel request */
932 status = wait_for_completion_interruptible_timeout(&pAdapter->rem_on_chan_ready_event,
933 msecs_to_jiffies(WAIT_REM_CHAN_READY));
934 if (0 >= status)
935 {
936 hddLog( LOGE,
937 "%s: timeout waiting for remain on channel ready indication %d",
938 __func__, status);
939 pRemainChanCtx->is_pending_roc_cancelled = TRUE;
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530940 mutex_unlock(&pHddCtx->roc_lock);
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530941 return 0;
942
943 }
944 }
945 else
946 {
947 hddLog( LOG1, FL("Cancel ROC event is already pending, "
948 "waiting for ready on channel indication.") );
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530949 mutex_unlock(&pHddCtx->roc_lock);
Sushant Kaushik5ad9b7b2014-05-21 21:09:43 +0530950 return 0;
951 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530952 if (NULL != cfgState->remain_on_chan_ctx)
953 {
954 vos_timer_stop(&cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
955 if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress)
956 {
957 hddLog( LOG1,
958 FL("ROC timer cancellation in progress,"
959 " wait for completion"));
960 status = wait_for_completion_interruptible_timeout(
961 &pAdapter->cancel_rem_on_chan_var,
962 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
963 if (0 >= status)
964 {
965 hddLog( LOGE,
966 "%s:wait on cancel_rem_on_chan_var failed %d",
967 __func__, status);
968 }
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530969 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530970 return 0;
971 }
972 else
973 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE;
974 }
Deepthi Gowri8f3c88f2014-12-22 14:38:14 +0530975 mutex_unlock(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700976 INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var);
977 /* Issue abort remain on chan request to sme.
978 * The remain on channel callback will make sure the remain_on_chan
979 * expired event is sent.
980 */
Abhishek Singh36b7c532015-03-13 15:50:54 +0530981 if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) ||
982 ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) ||
Deepthi Gowri70498252015-01-20 15:56:45 +0530983 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ))
Jeff Johnson295189b2012-06-20 16:38:30 -0700984 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530985 tANI_U8 sessionId = pAdapter->sessionId;
Deepthi Gowri70498252015-01-20 15:56:45 +0530986 if (eHAL_STATUS_SUCCESS !=
987 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ),
988 sessionId ))
989 {
990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
991 FL("Failed to Cancel Remain on Channel"));
992 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 }
Deepthi Gowri70498252015-01-20 15:56:45 +0530994 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 {
996 WLANSAP_CancelRemainOnChannel(
Deepthi Gowri70498252015-01-20 15:56:45 +0530997 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -0700998 }
Daram Sudha1f7e0e92013-12-17 07:52:31 +0530999 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 {
1001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid device_mode = %d",
1002 __func__, pAdapter->device_mode);
1003 return -EIO;
1004 }
c_hpothu7f63e882013-10-02 19:13:35 +05301005 status = wait_for_completion_interruptible_timeout(&pAdapter->cancel_rem_on_chan_var,
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
c_hpothu7f63e882013-10-02 19:13:35 +05301007 if (0 >= status)
1008 {
1009 hddLog( LOGE,
1010 "%s:wait on cancel_rem_on_chan_var failed %d", __func__, status);
1011 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301012 hdd_allow_suspend();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301013
1014 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 return 0;
1016}
1017
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301018int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301020 struct wireless_dev *wdev,
1021#else
1022 struct net_device *dev,
1023#endif
1024 u64 cookie )
1025{
1026 int ret;
1027
1028 vos_ssr_protect(__func__);
1029 ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy,
1030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1031 wdev,
1032#else
1033 dev,
1034#endif
1035 cookie);
1036 vos_ssr_unprotect(__func__);
1037
1038 return ret;
1039}
1040
1041
1042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1043int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001044 struct ieee80211_channel *chan, bool offchan,
Yue Maf49ba872013-08-19 12:04:25 -07001045#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001046 enum nl80211_channel_type channel_type,
Yue Maf49ba872013-08-19 12:04:25 -07001047 bool channel_type_valid,
1048#endif
1049 unsigned int wait,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001050 const u8 *buf, size_t len, bool no_cck,
1051 bool dont_wait_for_ack, u64 *cookie )
1052#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301053int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 struct ieee80211_channel *chan, bool offchan,
1055 enum nl80211_channel_type channel_type,
1056 bool channel_type_valid, unsigned int wait,
1057 const u8 *buf, size_t len, bool no_cck,
1058 bool dont_wait_for_ack, u64 *cookie )
1059#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301060int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001061 struct ieee80211_channel *chan, bool offchan,
1062 enum nl80211_channel_type channel_type,
1063 bool channel_type_valid, unsigned int wait,
1064 const u8 *buf, size_t len, u64 *cookie )
1065#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301066int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 struct ieee80211_channel *chan,
1068 enum nl80211_channel_type channel_type,
1069 bool channel_type_valid,
1070 const u8 *buf, size_t len, u64 *cookie )
1071#endif //LINUX_VERSION_CODE
1072{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1074 struct net_device *dev = wdev->netdev;
1075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001076 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05301077 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
1078 hdd_remain_on_chan_ctx_t *pRemainChanCtx = cfgState->remain_on_chan_ctx;
1079 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Jeff Johnsone7245742012-09-05 17:12:55 -07001080 tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
1081 tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
Mukul Sharma1e5d0b72014-07-01 19:22:21 +05301082 tActionFrmType actionFrmType = WLAN_HDD_ACTION_FRM_TYPE_MAX;
Jeff Johnsone7245742012-09-05 17:12:55 -07001083 bool noack = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301084 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07001085
Jeff Johnson295189b2012-06-20 16:38:30 -07001086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1087 hdd_adapter_t *goAdapter;
1088#endif
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05301089
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301090 ENTER();
1091 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301092 TRACE_CODE_HDD_ACTION, pAdapter->sessionId,
1093 pAdapter->device_mode ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301094 status = wlan_hdd_validate_context(pHddCtx);
1095
1096 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08001097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301098 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08001099 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301100
c_hpothu7f63e882013-10-02 19:13:35 +05301101 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d",
1102 __func__, pAdapter->device_mode, type);
1103
1104
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001105 if ((type == SIR_MAC_MGMT_FRAME) &&
1106 (subType == SIR_MAC_MGMT_ACTION) &&
1107 (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME))
1108 {
1109 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Kaushik, Sushant731e8942014-09-08 11:59:19 +05301110#ifdef WLAN_FEATURE_P2P_DEBUG
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001111 if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001112 {
1113 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA",
1114 actionFrmType);
1115 }
1116 else
1117 {
1118 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA",
1119 p2p_action_frame_type[actionFrmType]);
1120 if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
1121 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
1122 {
1123 globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
1124 hddLog(LOGE,"[P2P State]Inactive state to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001125 "GO negotiation progress state");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001126 }
1127 else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
1128 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
1129 {
1130 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
1131 hddLog(LOGE,"[P2P State]GO nego progress to GO nego"
1132 " completed state");
1133 }
1134 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001135#endif
Kaushik, Sushant731e8942014-09-08 11:59:19 +05301136 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001137
Jeff Johnsone7245742012-09-05 17:12:55 -07001138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1139 noack = dont_wait_for_ack;
1140#endif
1141
1142 //If the wait is coming as 0 with off channel set
1143 //then set the wait to 200 ms
1144 if (offchan && !wait)
Deepthi Gowri22d08752015-02-05 15:07:40 +05301145 {
Ganesh Kondabattini7f6049c2015-02-20 20:39:05 +05301146 wait = ACTION_FRAME_DEFAULT_WAIT;
1147 if (pRemainChanCtx)
1148 {
1149 tANI_U32 current_time = vos_timer_get_system_time();
1150 int remaining_roc_time = ((int) pRemainChanCtx->duration -
1151 (current_time - pAdapter->startRocTs));
1152 if ( remaining_roc_time > ACTION_FRAME_DEFAULT_WAIT)
1153 wait = remaining_roc_time;
1154 }
Deepthi Gowri22d08752015-02-05 15:07:40 +05301155 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001156
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 //Call sme API to send out a action frame.
1158 // OR can we send it directly through data path??
1159 // After tx completion send tx status back.
1160 if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) ||
1161 ( WLAN_HDD_P2P_GO == pAdapter->device_mode )
1162 )
1163 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001164 if (type == SIR_MAC_MGMT_FRAME)
1165 {
1166 if (subType == SIR_MAC_MGMT_PROBE_RSP)
1167 {
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301168 /* Drop Probe response recieved from supplicant, as for GO and
Jeff Johnson295189b2012-06-20 16:38:30 -07001169 SAP PE itself sends probe response
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301170 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001171 goto err_rem_channel;
1172 }
1173 else if ((subType == SIR_MAC_MGMT_DISASSOC) ||
1174 (subType == SIR_MAC_MGMT_DEAUTH))
1175 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001176 /* During EAP failure or P2P Group Remove supplicant
1177 * is sending del_station command to driver. From
1178 * del_station function, Driver will send deauth frame to
1179 * p2p client. No need to send disassoc frame from here.
1180 * so Drop the frame here and send tx indication back to
1181 * supplicant.
Jeff Johnson295189b2012-06-20 16:38:30 -07001182 */
1183 tANI_U8 dstMac[ETH_ALEN] = {0};
1184 memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07001185 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 "%s: Deauth/Disassoc received for STA:"
Arif Hussain24bafea2013-11-15 15:10:03 -08001187 MAC_ADDRESS_STR,
Jeff Johnsone7245742012-09-05 17:12:55 -07001188 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08001189 MAC_ADDR_ARRAY(dstMac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 goto err_rem_channel;
1191 }
1192 }
1193 }
1194
1195 if( NULL != cfgState->buf )
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08001196 {
1197 if ( !noack )
1198 {
1199 hddLog( LOGE, "(%s):Previous P2P Action frame packet pending",
1200 __func__);
1201 hdd_cleanup_actionframe(pAdapter->pHddCtx, pAdapter);
1202 }
1203 else
1204 {
1205 hddLog( LOGE, "(%s):Pending Action frame packet return EBUSY",
1206 __func__);
1207 return -EBUSY;
1208 }
1209 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001210
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301211 if( subType == SIR_MAC_MGMT_ACTION)
1212 {
1213 hddLog( LOG1, "Action frame tx request : %s",
1214 hdd_getActionString(buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET]));
1215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001216
1217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1218 goAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_P2P_GO );
1219
1220 //If GO adapter exists and operating on same frequency
1221 //then we will not request remain on channel
1222 if( goAdapter && ( ieee80211_frequency_to_channel(chan->center_freq)
1223 == goAdapter->sessionCtx.ap.operatingChannel ) )
1224 {
Kaushik, Sushant39bdbe22014-05-23 10:39:15 +05301225 /* if GO exist and is not off channel
1226 * wait time should be zero.
1227 */
1228 wait = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 goto send_frame;
1230 }
1231#endif
1232
1233#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1234 if( offchan && wait)
1235 {
1236 int status;
Agarwal Ashish7875e7c2014-03-11 12:54:57 +05301237 rem_on_channel_request_type_t req_type = OFF_CHANNEL_ACTION_TX;
Jeff Johnson295189b2012-06-20 16:38:30 -07001238 // In case of P2P Client mode if we are already
1239 // on the same channel then send the frame directly
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301240 mutex_lock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301241 if( (cfgState->remain_on_chan_ctx != NULL) &&
1242 (cfgState->current_freq == chan->center_freq)
1243 )
1244 {
1245 if ( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(
1246 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer) )
vamsida0e5ab2013-12-26 14:33:27 +05301247 {
Sushant Kaushik22257d62014-05-20 19:27:07 +05301248 /* Some times FW is taking almost 500 msec for
1249 * full 15 retries, which leads to ROC expiration
1250 * by the time peer gets response from other peer.
1251 * Therefore as part of temporary fix , in host
1252 * ROC time is extended. For frames where we are
1253 * expecting response from peer , its extended by
1254 * 500 msec to make ROC wait time as 1 sec and
1255 * in other cases its extended by 300 msec to make
1256 * total ROC wait as 500 msec.
1257 * TODO: FW needs to fix as why 15 retry is taking
1258 * such long time.
1259 */
1260 if ( actionFrmType == WLAN_HDD_INVITATION_REQ ||
1261 actionFrmType == WLAN_HDD_GO_NEG_REQ ||
1262 actionFrmType == WLAN_HDD_GO_NEG_RESP )
1263 wait = wait + ACTION_FRAME_RSP_WAIT;
1264 else if ( actionFrmType == WLAN_HDD_GO_NEG_CNF ||
1265 actionFrmType == WLAN_HDD_INVITATION_RESP )
1266 wait = wait + ACTION_FRAME_ACK_WAIT;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301267 vos_timer_stop(
1268 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer);
1269 status = vos_timer_start(
1270 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer,
1271 wait);
1272 if ( status != VOS_STATUS_SUCCESS )
vamsida0e5ab2013-12-26 14:33:27 +05301273 {
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301274 hddLog( LOGE, "Remain on Channel timer start failed");
1275 }
1276
1277 hddLog(VOS_TRACE_LEVEL_INFO,
1278 "action frame: extending the wait time %u",
1279 wait);
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301280 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301281 goto send_frame;
1282 }
1283 else
1284 {
1285 if ( TRUE ==
1286 pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
1287 {
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301288 mutex_unlock(&pHddCtx->roc_lock);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301289 hddLog(VOS_TRACE_LEVEL_INFO,
1290 "action frame tx: waiting for completion of ROC ");
1291
1292 status = wait_for_completion_interruptible_timeout(
1293 &pAdapter->cancel_rem_on_chan_var,
1294 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
1295 if (0 >= status)
1296 {
1297 hddLog( LOGE,
1298 "%s:wait on cancel_rem_on_chan_var failed %d",
1299 __func__, status);
1300 }
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301301 goto bypass_lock;
vamsida0e5ab2013-12-26 14:33:27 +05301302 }
1303 }
Edhar, Mahesh Kumar9b223db2013-11-28 11:30:01 +05301304 }
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301305 mutex_unlock(&pHddCtx->roc_lock);
1306bypass_lock:
Rashmi Ramannac7744532013-10-06 16:49:08 +05301307 hddLog(VOS_TRACE_LEVEL_INFO,
1308 "action frame: Request ROC for wait time %u", wait);
Jeff Johnson295189b2012-06-20 16:38:30 -07001309 INIT_COMPLETION(pAdapter->offchannel_tx_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07001310 status = wlan_hdd_request_remain_on_channel(wiphy, dev,
Yue Maf49ba872013-08-19 12:04:25 -07001311 chan,
1312#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1313 channel_type,
1314#endif
1315 wait, cookie,
Agarwal Ashish7875e7c2014-03-11 12:54:57 +05301316 req_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001317
1318 if(0 != status)
1319 {
1320 if( (-EBUSY == status) &&
1321 (cfgState->current_freq == chan->center_freq) )
1322 {
1323 goto send_frame;
1324 }
1325 goto err_rem_channel;
1326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 /* Wait for driver to be ready on the requested channel */
1328 status = wait_for_completion_interruptible_timeout(
1329 &pAdapter->offchannel_tx_event,
1330 msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX));
c_hpothu7f63e882013-10-02 19:13:35 +05301331 if(0 >= status)
Jeff Johnson295189b2012-06-20 16:38:30 -07001332 {
c_hpothu7f63e882013-10-02 19:13:35 +05301333 hddLog( LOGE, "wait on offchannel_tx_event failed %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07001334 goto err_rem_channel;
1335 }
1336 }
1337 else if ( offchan )
1338 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001339 /* Check before sending action frame
1340 whether we already remain on channel */
Jeff Johnson295189b2012-06-20 16:38:30 -07001341 if(NULL == cfgState->remain_on_chan_ctx)
1342 {
1343 goto err_rem_channel;
1344 }
1345 }
1346 send_frame:
1347#endif
1348
Jeff Johnsone7245742012-09-05 17:12:55 -07001349 if(!noack)
1350 {
1351 cfgState->buf = vos_mem_malloc( len ); //buf;
1352 if( cfgState->buf == NULL )
1353 return -ENOMEM;
Jeff Johnson295189b2012-06-20 16:38:30 -07001354
Jeff Johnsone7245742012-09-05 17:12:55 -07001355 cfgState->len = len;
Jeff Johnson295189b2012-06-20 16:38:30 -07001356
Jeff Johnsone7245742012-09-05 17:12:55 -07001357 vos_mem_copy( cfgState->buf, buf, len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001358
1359#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsone7245742012-09-05 17:12:55 -07001360 if( cfgState->remain_on_chan_ctx )
1361 {
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301362 mutex_lock(&pHddCtx->roc_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07001363 cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie;
1364 *cookie = cfgState->action_cookie;
Mahesh A Saptasagar5c032042015-01-08 14:56:33 +05301365 mutex_unlock(&pHddCtx->roc_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07001366 }
1367 else
1368 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001369#endif
Jeff Johnsonf67dca92013-11-08 17:07:40 -08001370 *cookie = (uintptr_t) cfgState->buf;
Jeff Johnsone7245742012-09-05 17:12:55 -07001371 cfgState->action_cookie = *cookie;
Jeff Johnson295189b2012-06-20 16:38:30 -07001372#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsone7245742012-09-05 17:12:55 -07001373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001374#endif
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001376
1377 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07001378 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1379 ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07001380 )
1381 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001382 tANI_U8 sessionId = pAdapter->sessionId;
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001383
Jeff Johnsone7245742012-09-05 17:12:55 -07001384 if ((type == SIR_MAC_MGMT_FRAME) &&
1385 (subType == SIR_MAC_MGMT_ACTION) &&
1386 (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME))
Jeff Johnson295189b2012-06-20 16:38:30 -07001387 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001388 actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Rashmi Ramannac7744532013-10-06 16:49:08 +05301389 hddLog(LOG1, "Tx Action Frame %u.", actionFrmType);
Jeff Johnsone7245742012-09-05 17:12:55 -07001390 if (actionFrmType == WLAN_HDD_PROV_DIS_REQ)
Jeff Johnson295189b2012-06-20 16:38:30 -07001391 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001392 cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING;
Rashmi Ramannac7744532013-10-06 16:49:08 +05301393 hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING.", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07001394 }
1395 else if (actionFrmType == WLAN_HDD_GO_NEG_REQ)
1396 {
1397 cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING;
Rashmi Ramannac7744532013-10-06 16:49:08 +05301398 hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING.", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001399 }
1400 }
Abhishek Singh0ebac9c2014-06-25 13:34:12 +05301401
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 if (eHAL_STATUS_SUCCESS !=
1403 sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter),
Kaushik, Sushant7005e372014-04-08 11:36:54 +05301404 sessionId, buf, len, wait, noack))
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 {
1406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1407 "%s: sme_sendAction returned fail", __func__);
1408 goto err;
1409 }
1410 }
Abhishek Singh36b7c532015-03-13 15:50:54 +05301411 else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001413 if( VOS_STATUS_SUCCESS !=
Jeff Johnson295189b2012-06-20 16:38:30 -07001414 WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Jeff Johnsone7245742012-09-05 17:12:55 -07001415 buf, len, 0 ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001416 {
1417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1418 "%s: WLANSAP_SendAction returned fail", __func__);
1419 goto err;
1420 }
1421 }
1422
1423 return 0;
1424err:
Jeff Johnsone7245742012-09-05 17:12:55 -07001425 if(!noack)
1426 {
1427 hdd_sendActionCnf( pAdapter, FALSE );
1428 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 return 0;
1430err_rem_channel:
Jeff Johnsonf67dca92013-11-08 17:07:40 -08001431 *cookie = (uintptr_t)cfgState;
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001432 cfg80211_mgmt_tx_status(
1433#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1434 pAdapter->dev->ieee80211_ptr,
1435#else
1436 pAdapter->dev,
1437#endif
1438 *cookie, buf, len, FALSE, GFP_KERNEL );
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301439 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 return 0;
1441}
1442
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301443#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1444int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev,
1445 struct ieee80211_channel *chan, bool offchan,
1446#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1447 enum nl80211_channel_type channel_type,
1448 bool channel_type_valid,
1449#endif
1450 unsigned int wait,
1451 const u8 *buf, size_t len, bool no_cck,
1452 bool dont_wait_for_ack, u64 *cookie )
1453#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1454int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1455 struct ieee80211_channel *chan, bool offchan,
1456 enum nl80211_channel_type channel_type,
1457 bool channel_type_valid, unsigned int wait,
1458 const u8 *buf, size_t len, bool no_cck,
1459 bool dont_wait_for_ack, u64 *cookie )
1460#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1461int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1462 struct ieee80211_channel *chan, bool offchan,
1463 enum nl80211_channel_type channel_type,
1464 bool channel_type_valid, unsigned int wait,
1465 const u8 *buf, size_t len, u64 *cookie )
1466#else
1467int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev,
1468 struct ieee80211_channel *chan,
1469 enum nl80211_channel_type channel_type,
1470 bool channel_type_valid,
1471 const u8 *buf, size_t len, u64 *cookie )
1472#endif //LINUX_VERSION_CODE
1473{
1474 int ret;
1475
1476 vos_ssr_protect(__func__);
1477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1478 ret = __wlan_hdd_mgmt_tx(wiphy, wdev,
1479 chan, offchan,
1480#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
1481 channel_type,
1482 channel_type_valid,
1483#endif
1484 wait,
1485 buf, len, no_cck,
1486 dont_wait_for_ack, cookie);
1487#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
1488 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
1489 channel_type, channel_type_valid, wait,
1490 buf, len, no_cck,
1491 dont_wait_for_ack, cookie);
1492#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1493 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
1494 channel_type, channel_type_valid, wait,
1495 buf, len, cookie);
1496#else
1497 ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, channel_type,
1498 channel_type_valid, buf, len, cookie);
1499#endif //LINUX_VERSION_CODE
1500 vos_ssr_unprotect(__func__);
1501
1502 return ret;
1503}
1504
Jeff Johnson295189b2012-06-20 16:38:30 -07001505#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301507int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001508 struct wireless_dev *wdev,
1509 u64 cookie)
1510{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301511 u64 cookie_dummy;
1512 cookie_dummy = cookie << 32;
1513 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1514 TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, NO_SESSION, cookie_dummy));
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001515 return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, wdev, cookie );
1516}
1517#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301518int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 struct net_device *dev,
1520 u64 cookie)
1521{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301522 u64 cookie_dummy;
1523 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1524 cookie_dummy = cookie << 32;
1525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1526 TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT,
1527 pAdapter->sessionId, cookie_dummy));
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, dev, cookie );
1529}
1530#endif
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001531#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001532
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1535int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1536 struct wireless_dev *wdev,
1537 u64 cookie)
1538{
1539 int ret;
1540
1541 vos_ssr_protect(__func__);
1542 ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie);
1543 vos_ssr_unprotect(__func__);
1544
1545 return ret;
1546}
1547#else
1548int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1549 struct net_device *dev,
1550 u64 cookie)
1551{
1552 int ret;
1553
1554 vos_ssr_protect(__func__);
1555 ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, dev, cookie);
1556 vos_ssr_unprotect(__func__);
1557
1558 return ret;
1559}
1560#endif
1561#endif
1562
Jeff Johnson295189b2012-06-20 16:38:30 -07001563void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess )
1564{
1565 hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
1566
Jeff Johnsone7245742012-09-05 17:12:55 -07001567 cfgState->actionFrmState = HDD_IDLE;
1568
Jeff Johnson295189b2012-06-20 16:38:30 -07001569 hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess);
1570 if( NULL == cfgState->buf )
1571 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 return;
1573 }
1574
1575 /* If skb is NULL it means this packet was received on CFG80211 interface
1576 * else it was received on Monitor interface */
1577 if( cfgState->skb == NULL )
1578 {
1579 /*
1580 * buf is the same pointer it passed us to send. Since we are sending
1581 * it through control path, we use different buffers.
1582 * In case of mac80211, they just push it to the skb and pass the same
1583 * data while sending tx ack status.
1584 * */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001585 cfg80211_mgmt_tx_status(
1586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1587 pAdapter->dev->ieee80211_ptr,
1588#else
1589 pAdapter->dev,
1590#endif
1591 cfgState->action_cookie,
Jeff Johnson295189b2012-06-20 16:38:30 -07001592 cfgState->buf, cfgState->len, actionSendSuccess, GFP_KERNEL );
1593 vos_mem_free( cfgState->buf );
1594 cfgState->buf = NULL;
1595 }
1596 else
1597 {
1598 hdd_adapter_t* pMonAdapter =
1599 hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR );
1600 if( pMonAdapter == NULL )
1601 {
1602 hddLog( LOGE, "Not able to get Monitor Adapter");
1603 cfgState->skb = NULL;
1604 vos_mem_free( cfgState->buf );
1605 cfgState->buf = NULL;
1606 complete(&pAdapter->tx_action_cnf_event);
1607 return;
1608 }
1609 /* Send TX completion feedback over monitor interface. */
1610 hdd_wlan_tx_complete( pMonAdapter, cfgState, actionSendSuccess );
1611 cfgState->skb = NULL;
1612 vos_mem_free( cfgState->buf );
1613 cfgState->buf = NULL;
1614 /* Look for the next Mgmt packet to TX */
1615 hdd_mon_tx_mgmt_pkt(pAdapter);
1616 }
1617 complete(&pAdapter->tx_action_cnf_event);
1618}
1619
1620/**
1621 * hdd_setP2pNoa
1622 *
1623 *FUNCTION:
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301624 * This function is called from hdd_hostapd_ioctl function when Driver
Jeff Johnson295189b2012-06-20 16:38:30 -07001625 * get P2P_SET_NOA comand from wpa_supplicant using private ioctl
1626 *
1627 *LOGIC:
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301628 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
Jeff Johnson295189b2012-06-20 16:38:30 -07001629 *
1630 *ASSUMPTIONS:
1631 *
1632 *
1633 *NOTE:
1634 *
1635 * @param dev Pointer to net device structure
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301636 * @param command Pointer to command
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 *
1638 * @return Status
1639 */
1640
1641int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command )
1642{
1643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1644 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1645 VOS_STATUS status = VOS_STATUS_SUCCESS;
1646 tP2pPsConfig NoA;
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001647 int count, duration, start_time;
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 char *param;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001649 tANI_U8 ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001650
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08001651 param = strnchr(command, strlen(command), ' ');
Jeff Johnson295189b2012-06-20 16:38:30 -07001652 if (param == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301653 {
1654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1655 "%s: strnchr failed to find delimeter",__func__);
1656 return -EINVAL;
1657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001658 param++;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001659 ret = sscanf(param, "%d %d %d", &count, &start_time, &duration);
1660 if (ret < 3)
1661 {
1662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1663 "%s: P2P_SET GO NoA: fail to read param "
1664 "count=%d duration=%d interval=%d \n",
1665 __func__, count, start_time, duration);
1666 return -EINVAL;
1667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001669 "%s: P2P_SET GO NoA: count=%d duration=%d interval=%d",
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001670 __func__, count, start_time, duration);
1671 duration = MS_TO_MUS(duration);
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 /* PS Selection
1673 * Periodic NoA (2)
1674 * Single NOA (4)
1675 */
1676 NoA.opp_ps = 0;
1677 NoA.ctWindow = 0;
1678 if (count == 1)
1679 {
1680 NoA.duration = 0;
1681 NoA.single_noa_duration = duration;
1682 NoA.psSelection = P2P_POWER_SAVE_TYPE_SINGLE_NOA;
1683 }
1684 else
1685 {
1686 NoA.duration = duration;
1687 NoA.single_noa_duration = 0;
1688 NoA.psSelection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA;
1689 }
Madan Mohan Koyyalamudi4b63eee2012-11-06 18:47:56 -08001690 NoA.interval = MS_TO_MUS(100);
Jeff Johnson295189b2012-06-20 16:38:30 -07001691 NoA.count = count;
1692 NoA.sessionid = pAdapter->sessionId;
1693
1694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1695 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1696 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001697 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 NoA.ctWindow, NoA.duration, NoA.interval,
1699 NoA.count, NoA.single_noa_duration,
1700 NoA.psSelection);
1701
1702 sme_p2pSetPs(hHal, &NoA);
1703 return status;
1704}
1705
1706/**
1707 * hdd_setP2pOpps
1708 *
1709 *FUNCTION:
1710 * This function is called from hdd_hostapd_ioctl function when Driver
1711 * get P2P_SET_PS comand from wpa_supplicant using private ioctl
1712 *
1713 *LOGIC:
1714 * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer
1715 *
1716 *ASSUMPTIONS:
1717 *
1718 *
1719 *NOTE:
1720 *
1721 * @param dev Pointer to net device structure
1722 * @param command Pointer to command
1723 *
1724 * @return Status
1725 */
1726
1727int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command )
1728{
1729 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1730 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1731 VOS_STATUS status = VOS_STATUS_SUCCESS;
1732 tP2pPsConfig NoA;
1733 char *param;
1734 int legacy_ps, opp_ps, ctwindow;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001735 tANI_U8 ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001736
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08001737 param = strnchr(command, strlen(command), ' ');
Jeff Johnson295189b2012-06-20 16:38:30 -07001738 if (param == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301739 {
1740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1741 "%s: strnchr failed to find delimeter",__func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08001742 return -EINVAL;
c_hpothu7f63e882013-10-02 19:13:35 +05301743 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001744 param++;
kalikinkar dhara19d77182013-11-12 14:29:46 -08001745 ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow);
1746 if (ret < 3)
1747 {
1748 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1749 "%s: P2P_SET GO PS: fail to read param "
1750 " legacy_ps=%d opp_ps=%d ctwindow=%d \n",
1751 __func__, legacy_ps, opp_ps, ctwindow);
1752 return -EINVAL;
1753 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001754 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001755 "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001756 __func__, legacy_ps, opp_ps, ctwindow);
1757
1758 /* PS Selection
1759 * Opportunistic Power Save (1)
1760 */
1761
1762 /* From wpa_cli user need to use separate command to set ctWindow and Opps
1763 * When user want to set ctWindow during that time other parameters
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301764 * values are coming from wpa_supplicant as -1.
1765 * Example : User want to set ctWindow with 30 then wpa_cli command :
1766 * P2P_SET ctwindow 30
1767 * Command Received at hdd_hostapd_ioctl is as below:
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30)
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301769 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001770 if (ctwindow != -1)
1771 {
1772
1773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001774 "Opportunistic Power Save is %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07001775 (TRUE == pAdapter->ops) ? "Enable" : "Disable" );
1776
1777 if (ctwindow != pAdapter->ctw)
1778 {
1779 pAdapter->ctw = ctwindow;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301780
Jeff Johnson295189b2012-06-20 16:38:30 -07001781 if(pAdapter->ops)
1782 {
1783 NoA.opp_ps = pAdapter->ops;
1784 NoA.ctWindow = pAdapter->ctw;
1785 NoA.duration = 0;
1786 NoA.single_noa_duration = 0;
1787 NoA.interval = 0;
1788 NoA.count = 0;
1789 NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
1790 NoA.sessionid = pAdapter->sessionId;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301791
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1793 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1794 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001795 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 NoA.ctWindow, NoA.duration, NoA.interval,
1797 NoA.count, NoA.single_noa_duration,
1798 NoA.psSelection);
1799
1800 sme_p2pSetPs(hHal, &NoA);
1801 }
1802 return 0;
1803 }
1804 }
1805
1806 if (opp_ps != -1)
1807 {
1808 pAdapter->ops = opp_ps;
1809
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301810 if ((opp_ps != -1) && (pAdapter->ctw))
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 {
1812 NoA.opp_ps = opp_ps;
1813 NoA.ctWindow = pAdapter->ctw;
1814 NoA.duration = 0;
1815 NoA.single_noa_duration = 0;
1816 NoA.interval = 0;
1817 NoA.count = 0;
1818 NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
1819 NoA.sessionid = pAdapter->sessionId;
1820
1821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1822 "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
1823 "interval %d count %d single noa duration %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001824 "PsSelection %x", __func__, NoA.opp_ps,
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 NoA.ctWindow, NoA.duration, NoA.interval,
1826 NoA.count, NoA.single_noa_duration,
1827 NoA.psSelection);
1828
1829 sme_p2pSetPs(hHal, &NoA);
1830 }
1831 }
1832 return status;
1833}
1834
1835int hdd_setP2pPs( struct net_device *dev, void *msgData )
1836{
1837 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1838 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1839 VOS_STATUS status = VOS_STATUS_SUCCESS;
1840 tP2pPsConfig NoA;
1841 p2p_app_setP2pPs_t *pappNoA = (p2p_app_setP2pPs_t *) msgData;
1842
1843 NoA.opp_ps = pappNoA->opp_ps;
1844 NoA.ctWindow = pappNoA->ctWindow;
1845 NoA.duration = pappNoA->duration;
1846 NoA.interval = pappNoA->interval;
1847 NoA.count = pappNoA->count;
1848 NoA.single_noa_duration = pappNoA->single_noa_duration;
1849 NoA.psSelection = pappNoA->psSelection;
1850 NoA.sessionid = pAdapter->sessionId;
1851
1852 sme_p2pSetPs(hHal, &NoA);
1853 return status;
1854}
Jeff Johnson295189b2012-06-20 16:38:30 -07001855
1856static tANI_U8 wlan_hdd_get_session_type( enum nl80211_iftype type )
1857{
1858 tANI_U8 sessionType;
1859
1860 switch( type )
1861 {
1862 case NL80211_IFTYPE_AP:
1863 sessionType = WLAN_HDD_SOFTAP;
1864 break;
1865 case NL80211_IFTYPE_P2P_GO:
1866 sessionType = WLAN_HDD_P2P_GO;
1867 break;
1868 case NL80211_IFTYPE_P2P_CLIENT:
1869 sessionType = WLAN_HDD_P2P_CLIENT;
1870 break;
1871 case NL80211_IFTYPE_STATION:
1872 sessionType = WLAN_HDD_INFRA_STATION;
1873 break;
1874 case NL80211_IFTYPE_MONITOR:
1875 sessionType = WLAN_HDD_MONITOR;
1876 break;
1877 default:
1878 sessionType = WLAN_HDD_INFRA_STATION;
1879 break;
1880 }
1881
1882 return sessionType;
1883}
1884
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001885#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301886struct wireless_dev* __wlan_hdd_add_virtual_intf(
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001887 struct wiphy *wiphy, const char *name,
1888 enum nl80211_iftype type,
1889 u32 *flags, struct vif_params *params )
1890#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301891struct wireless_dev* __wlan_hdd_add_virtual_intf(
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001892 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1893 u32 *flags, struct vif_params *params )
1894#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301895struct net_device* __wlan_hdd_add_virtual_intf(
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1897 u32 *flags, struct vif_params *params )
1898#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301899int __wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name,
Jeff Johnson295189b2012-06-20 16:38:30 -07001900 enum nl80211_iftype type,
1901 u32 *flags, struct vif_params *params )
1902#endif
1903{
1904 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301905 hdd_adapter_t *pAdapter = NULL;
Rashmi Ramanna8f122ce2014-05-28 22:42:12 +05301906 hdd_scaninfo_t *pScanInfo = NULL;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05301907 int ret = 0;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301908
Jeff Johnson295189b2012-06-20 16:38:30 -07001909 ENTER();
1910
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05301911 ret = wlan_hdd_validate_context(pHddCtx);
1912 if (0 != ret)
1913 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05301914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1915 return ERR_PTR(-EINVAL);
1916#else
1917 return -EAGAIN;
1918#endif
1919 }
1920
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301921 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1922 TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type));
Agarwal Ashish4cfa1e52014-05-09 20:25:11 +05301923 if (WLAN_HDD_P2P_CLIENT != wlan_hdd_get_session_type(type) &&
1924 WLAN_HDD_INFRA_STATION != wlan_hdd_get_session_type(type) &&
1925 hdd_get_adapter(pHddCtx, wlan_hdd_get_session_type(type)) != NULL)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001926 {
Jeff Johnsond13512a2012-07-17 11:42:19 -07001927 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Interface type %d already exists. Two"
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001928 "interfaces of same type are not supported currently.",__func__, type);
c_hpothu471fc962014-06-24 16:06:53 +05301929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1930 return ERR_PTR(-EINVAL);
1931#else
1932 return -EAGAIN;
1933#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001934 }
1935
Rashmi Ramanna8f122ce2014-05-28 22:42:12 +05301936 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
1937 pScanInfo = &pHddCtx->scan_info;
1938 if ((pScanInfo != NULL) && (pAdapter != NULL) &&
1939 (pHddCtx->scan_info.mScanPending))
1940 {
1941 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
1942 eCSR_SCAN_ABORT_DEFAULT);
1943 hddLog(VOS_TRACE_LEVEL_INFO,
1944 "%s: Abort Scan while adding virtual interface",__func__);
1945 }
1946
1947 pAdapter = NULL;
Kiet Lam04e26912013-10-18 20:13:38 +05301948 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated &&
1949 ((NL80211_IFTYPE_P2P_GO == type) ||
1950 (NL80211_IFTYPE_P2P_CLIENT == type)))
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001952 /* Generate the P2P Interface Address. this address must be
1953 * different from the P2P Device Address.
1954 */
1955 v_MACADDR_t p2pDeviceAddress = pHddCtx->p2pDeviceAddress;
1956 p2pDeviceAddress.bytes[4] ^= 0x80;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05301957 pAdapter = hdd_open_adapter( pHddCtx,
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 wlan_hdd_get_session_type(type),
1959 name, p2pDeviceAddress.bytes,
1960 VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001961 }
1962 else
1963 {
1964 pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type),
1965 name, wlan_hdd_get_intf_addr(pHddCtx), VOS_TRUE );
1966 }
1967
1968 if( NULL == pAdapter)
1969 {
1970 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__);
1971#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
c_hpothu471fc962014-06-24 16:06:53 +05301972 return ERR_PTR(-EINVAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001973#else
1974 return -EINVAL;
1975#endif
1976 }
1977 EXIT();
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08001978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1979 return pAdapter->dev->ieee80211_ptr;
1980#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 return pAdapter->dev;
1982#else
1983 return 0;
1984#endif
1985}
1986
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05301987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
1988struct wireless_dev* wlan_hdd_add_virtual_intf(
1989 struct wiphy *wiphy, const char *name,
1990 enum nl80211_iftype type,
1991 u32 *flags, struct vif_params *params )
1992#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1993struct wireless_dev* wlan_hdd_add_virtual_intf(
1994 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1995 u32 *flags, struct vif_params *params )
1996#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
1997struct net_device* wlan_hdd_add_virtual_intf(
1998 struct wiphy *wiphy, char *name, enum nl80211_iftype type,
1999 u32 *flags, struct vif_params *params )
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002000#else
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05302001int wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name,
2002 enum nl80211_iftype type,
2003 u32 *flags, struct vif_params *params )
2004#endif
2005{
2006#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)))
2007 struct wireless_dev* wdev;
2008#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2009 struct net_device* ndev;
2010#else
2011 int ret;
2012#endif
2013 vos_ssr_protect(__func__);
2014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2015 wdev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
2016 vos_ssr_unprotect(__func__);
2017 return wdev;
2018#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
2019 ndev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
2020 vos_ssr_unprotect(__func__);
2021 return ndev;
2022#else
2023 ret = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
2024 vos_ssr_unprotect(__func__);
2025 return ret;
2026#endif
2027}
2028
2029#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2030int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
2031#else
2032int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002033#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002034{
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002035#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2036 struct net_device *dev = wdev->netdev;
2037#endif
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302038 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302040 hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2041 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302042
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302043 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07002044
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302045 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2046 TRACE_CODE_HDD_DEL_VIRTUAL_INTF,
2047 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2049 __func__,pVirtAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002050
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302051 status = wlan_hdd_validate_context(pHddCtx);
2052
2053 if (0 != status)
2054 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302055 return status;
2056 }
2057
2058 wlan_hdd_release_intf_addr( pHddCtx,
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 pVirtAdapter->macAddressCurrent.bytes );
2060
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05302061 hdd_stop_adapter( pHddCtx, pVirtAdapter, VOS_TRUE);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302062 hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE );
2063 EXIT();
2064 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002065}
2066
Mahesh A Saptasagar65570ad2014-06-23 21:05:38 +05302067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2068int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev )
2069#else
2070int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev )
2071#endif
2072{
2073 int ret;
2074
2075 vos_ssr_protect(__func__);
2076#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2077 ret = __wlan_hdd_del_virtual_intf(wiphy, wdev);
2078#else
2079 ret = __wlan_hdd_del_virtual_intf(wiphy, dev);
2080#endif
2081 vos_ssr_unprotect(__func__);
2082
2083 return ret;
2084}
2085
Jeff Johnson295189b2012-06-20 16:38:30 -07002086void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter,
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002087 tANI_U32 nFrameLength,
2088 tANI_U8* pbFrames,
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302089 tANI_U8 frameType )
Jeff Johnson295189b2012-06-20 16:38:30 -07002090{
2091 //Indicate a Frame over Monitor Intf.
2092 int rxstat;
2093 struct sk_buff *skb = NULL;
2094 int needed_headroom = 0;
2095 int flag = HDD_RX_FLAG_IV_STRIPPED | HDD_RX_FLAG_DECRYPTED |
2096 HDD_RX_FLAG_MMIC_STRIPPED;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002097#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002098#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
2099 hdd_context_t* pHddCtx = (hdd_context_t*)(pMonAdapter->pHddCtx);
2100#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002101#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002102 hddLog( LOG1, FL("Indicate Frame over Monitor Intf"));
2103
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002104 if (NULL == pbFrames)
2105 {
2106 hddLog(LOGE, FL("NULL frame pointer"));
2107 return;
2108 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002109
2110 /* room for the radiotap header based on driver features
2111 * 1 Byte for RADIO TAP Flag, 1 Byte padding and 2 Byte for
2112 * RX flags.
2113 * */
2114 needed_headroom = sizeof(struct ieee80211_radiotap_header) + 4;
2115
2116 //alloc skb here
2117 skb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC);
2118 if (unlikely(NULL == skb))
2119 {
2120 hddLog( LOGW, FL("Unable to allocate skb"));
2121 return;
2122 }
2123 skb_reserve(skb, VPKT_SIZE_BUFFER);
2124 if (unlikely(skb_headroom(skb) < nFrameLength))
2125 {
2126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2127 "HDD [%d]: Insufficient headroom, "
2128 "head[%p], data[%p], req[%d]",
2129 __LINE__, skb->head, skb->data, nFrameLength);
2130 kfree_skb(skb);
2131 return ;
2132 }
2133 // actually push the data
2134 memcpy(skb_push(skb, nFrameLength), pbFrames, nFrameLength);
2135 /* prepend radiotap information */
2136 if( 0 != hdd_wlan_add_rx_radiotap_hdr( skb, needed_headroom, flag ) )
2137 {
2138 hddLog( LOGE, FL("Not Able Add Radio Tap"));
2139 //free skb
2140 kfree_skb(skb);
2141 return ;
2142 }
2143
2144 skb_reset_mac_header( skb );
2145 skb->dev = pMonAdapter->dev;
2146 skb->protocol = eth_type_trans( skb, skb->dev );
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002147 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002148#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002149#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07002150 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07002151#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002152#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 rxstat = netif_rx_ni(skb);
2154 if( NET_RX_SUCCESS == rxstat )
2155 {
2156 hddLog( LOG1, FL("Success"));
2157 }
2158 else
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302159 hddLog( LOGE, FL("Failed %d"), rxstat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002160
2161 return ;
2162}
2163
2164void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter,
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302165 tANI_U32 nFrameLength,
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 tANI_U8* pbFrames,
2167 tANI_U8 frameType,
Chilam NG571c65a2013-01-19 12:27:36 +05302168 tANI_U32 rxChan,
2169 tANI_S8 rxRssi )
Jeff Johnson295189b2012-06-20 16:38:30 -07002170{
2171 tANI_U16 freq;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302172 tANI_U16 extend_time;
Jeff Johnsone7245742012-09-05 17:12:55 -07002173 tANI_U8 type = 0;
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002174 tANI_U8 subType = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002175 tActionFrmType actionFrmType;
2176 hdd_cfg80211_state_t *cfgState = NULL;
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302177 hdd_scaninfo_t *pScanInfo = NULL;
Kaushik, Sushant13a287c2014-05-03 12:26:27 +05302178 hdd_context_t *pHddCtx = NULL;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302179 VOS_STATUS status;
2180 hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002181
Arif Hussain6d2a3322013-11-17 19:50:10 -08002182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Frame Type = %d Frame Length = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002183 __func__, frameType, nFrameLength);
2184
2185 if (NULL == pAdapter)
2186 {
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002187 hddLog(LOGE, FL("pAdapter is NULL"));
2188 return;
2189 }
2190
2191 if (0 == nFrameLength)
2192 {
2193 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
2194 return;
2195 }
2196
2197 if (NULL == pbFrames)
2198 {
2199 hddLog(LOGE, FL("pbFrames is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 return;
2201 }
2202
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002203 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
2204 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
2205
2206 /* Get pAdapter from Destination mac address of the frame */
2207 if ((type == SIR_MAC_MGMT_FRAME) &&
2208 (subType != SIR_MAC_MGMT_PROBE_REQ))
2209 {
2210 pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter),
2211 &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]);
2212 if (NULL == pAdapter)
2213 {
2214 /* Under assumtion that we don't receive any action frame
2215 * with BCST as destination we dropping action frame
2216 */
Madan Mohan Koyyalamudi051ff0b2012-12-03 16:55:26 -08002217 hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = "
2218 MAC_ADDRESS_STR ,
2219 MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]));
2220 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d"
Arif Hussain6d2a3322013-11-17 19:50:10 -08002221 " subType = %d",__func__,frameType,nFrameLength,subType);
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07002222 return;
2223 }
2224 }
2225
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002226
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 if (NULL == pAdapter->dev)
2228 {
2229 hddLog( LOGE, FL("pAdapter->dev is NULL"));
2230 return;
2231 }
2232
2233 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2234 {
2235 hddLog( LOGE, FL("pAdapter has invalid magic"));
2236 return;
2237 }
2238
Rashmi Ramannadae90e02013-12-30 21:49:48 +05302239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2240 if (NULL == pHddCtx)
2241 {
2242 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
2243 return;
2244 }
2245
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002246 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
2247 (WLAN_HDD_P2P_GO == pAdapter->device_mode ))
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 {
2249 hdd_adapter_t *pMonAdapter =
2250 hdd_get_mon_adapter( WLAN_HDD_GET_CTX(pAdapter) );
2251
Jeff Johnsonc9ca3732013-03-27 11:31:03 -07002252 if (NULL != pMonAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 {
2254 hddLog( LOG1, FL("Indicate Frame over Monitor Interface"));
2255 hdd_sendMgmtFrameOverMonitorIface( pMonAdapter, nFrameLength,
2256 pbFrames, frameType);
2257 return;
2258 }
2259 }
2260
2261 //Channel indicated may be wrong. TODO
2262 //Indicate an action frame.
2263 if( rxChan <= MAX_NO_OF_2_4_CHANNELS )
2264 {
2265 freq = ieee80211_channel_to_frequency( rxChan,
2266 IEEE80211_BAND_2GHZ);
2267 }
2268 else
2269 {
2270 freq = ieee80211_channel_to_frequency( rxChan,
2271 IEEE80211_BAND_5GHZ);
2272 }
2273
Jeff Johnsone7245742012-09-05 17:12:55 -07002274 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302275 pRemainChanCtx = cfgState->remain_on_chan_ctx;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302276
2277 if ((type == SIR_MAC_MGMT_FRAME) &&
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002278 (subType == SIR_MAC_MGMT_ACTION))
Jeff Johnsone7245742012-09-05 17:12:55 -07002279 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002280 if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)
2281 {
2282 // public action frame
2283 if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == SIR_MAC_ACTION_VENDOR_SPECIFIC) &&
Sudhir Sattayappa Kohallic8239802013-02-22 18:46:44 -08002284 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 -08002285 // P2P action frames
2286 {
2287 actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002288 hddLog(LOG1, "Rx Action Frame %u", actionFrmType);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002289#ifdef WLAN_FEATURE_P2P_DEBUG
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002290 if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE)
2291 {
2292 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] <--- OTA",
2293 actionFrmType);
2294 }
2295 else
2296 {
2297 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s <--- OTA",
2298 p2p_action_frame_type[actionFrmType]);
2299 if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) &&
2300 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
2301 {
2302 globalP2PConnectionStatus = P2P_GO_NEG_PROCESS;
2303 hddLog(LOGE,"[P2P State]Inactive state to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002304 "GO negotiation progress state");
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002305 }
2306 else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) &&
2307 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) )
2308 {
2309 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
Jeff Johnson1250df42012-12-10 14:31:52 -08002310 hddLog(LOGE,"[P2P State]GO negotiation progress to "
2311 "GO negotiation completed state");
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002312 }
2313 else if( (actionFrmType == WLAN_HDD_INVITATION_REQ) &&
2314 (globalP2PConnectionStatus == P2P_NOT_ACTIVE) )
2315 {
2316 globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED;
2317 hddLog(LOGE,"[P2P State]Inactive state to GO negotiation"
2318 " completed state Autonomous GO formation");
2319 }
2320 }
2321#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302322 if (pRemainChanCtx != NULL && VOS_TIMER_STATE_RUNNING
2323 == vos_timer_getCurrentState(&pRemainChanCtx->hdd_remain_on_chan_timer))
2324 {
2325 if ( actionFrmType == WLAN_HDD_GO_NEG_REQ ||
2326 actionFrmType == WLAN_HDD_GO_NEG_RESP ||
2327 actionFrmType == WLAN_HDD_INVITATION_REQ ||
2328 actionFrmType == WLAN_HDD_DEV_DIS_REQ ||
2329 actionFrmType == WLAN_HDD_PROV_DIS_REQ )
2330 {
2331 hddLog( LOG1, "Extend RoC timer on reception of"
2332 " Action Frame");
2333 if ((actionFrmType == WLAN_HDD_GO_NEG_REQ)
2334 || (actionFrmType == WLAN_HDD_GO_NEG_RESP))
2335 extend_time = 2 * ACTION_FRAME_DEFAULT_WAIT;
2336 else
2337 extend_time = ACTION_FRAME_DEFAULT_WAIT;
2338 if (completion_done(&pAdapter->rem_on_chan_ready_event))
2339 {
2340 vos_timer_stop(
2341 &pRemainChanCtx->hdd_remain_on_chan_timer);
2342 status = vos_timer_start(
2343 &pRemainChanCtx->hdd_remain_on_chan_timer,
2344 extend_time);
2345 if (status != VOS_STATUS_SUCCESS)
2346 {
2347 hddLog( LOGE, "ROC timer start failed");
2348 }
2349 }
2350 else
2351 {
2352 // Buffer Packet
2353 if (pRemainChanCtx->action_pkt_buff.frame_length == 0)
2354 {
2355 pRemainChanCtx->action_pkt_buff.frame_length =
2356 nFrameLength;
2357 pRemainChanCtx->action_pkt_buff.freq = freq;
2358 pRemainChanCtx->action_pkt_buff.frame_ptr
2359 = vos_mem_malloc(nFrameLength);
2360 vos_mem_copy(
2361 pRemainChanCtx->action_pkt_buff.frame_ptr,
2362 pbFrames, nFrameLength);
2363 hddLog( LOGE,"%s:"
2364 "Action Pkt Cached successfully !!!", __func__);
2365 }
2366 else
2367 {
2368 hddLog( LOGE,"%s:"
2369 "Frames are pending. dropping frame !!!",
2370 __func__);
2371 }
2372 return;
2373 }
2374 }
2375 }
2376 if (pRemainChanCtx != NULL &&
2377 VOS_TIMER_STATE_RUNNING != vos_timer_getCurrentState(
2378 &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer))
2379 hddLog( LOG1, "%s:"
2380 "Rcvd action frame after timer expired ", __func__);
2381
Kaushik, Sushant7005e372014-04-08 11:36:54 +05302382 if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) &&
2383 (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) ||
2384 ((actionFrmType == WLAN_HDD_GO_NEG_RESP) &&
2385 (cfgState->actionFrmState == HDD_GO_NEG_REQ_ACK_PENDING)))
2386 {
2387 hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ",
2388 __func__);
2389 hdd_sendActionCnf(pAdapter, TRUE);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002390 }
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002391 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002392#ifdef FEATURE_WLAN_TDLS
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002393 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 -07002394 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002395 u8 *mac = &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6];
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302396 hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] TDLS Discovery Response," MAC_ADDRESS_STR " RSSI[%d] <--- OTA",
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002397 MAC_ADDR_ARRAY(mac),rxRssi);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302398
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002399 wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi);
2400 wlan_hdd_tdls_recv_discovery_resp(pAdapter, mac);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002401 }
2402#endif
2403 }
Kaushik, Sushant507a8612014-10-21 17:00:55 +05302404
2405 pScanInfo = &pHddCtx->scan_info;
2406 if ((pScanInfo != NULL) && (pHddCtx->scan_info.mScanPending))
2407 {
2408 hddLog(LOGE,"Action frame received when Scanning is in"
2409 " progress. Abort Scan.");
2410 hdd_abort_mac_scan(pAdapter->pHddCtx,
2411 pScanInfo->sessionId,
2412 eCSR_SCAN_ABORT_DEFAULT);
2413 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302414
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002415 if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_TDLS_ACTION_FRAME)
2416 {
2417 actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1];
2418 if(actionFrmType >= MAX_TDLS_ACTION_FRAME_TYPE)
2419 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302420 hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] Action type[%d] <--- OTA",
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002421 actionFrmType);
2422 }
2423 else
2424 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302425 hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] %s <--- OTA",
Hoonki Lee1090c6a2013-01-16 17:40:54 -08002426 tdls_action_frame_type[actionFrmType]);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002427 }
2428 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05302429
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002430 if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_QOS_ACTION_FRAME)&&
2431 (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_QOS_MAP_CONFIGURE) )
2432 {
Kumar Anand82c009f2014-05-29 00:29:42 -07002433 sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
2434 pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07002435 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002436 }
2437
Jeff Johnson295189b2012-06-20 16:38:30 -07002438 //Indicate Frame Over Normal Interface
2439 hddLog( LOG1, FL("Indicate Frame over NL80211 Interface"));
2440
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08002441#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2442 cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, 0,
2443 pbFrames, nFrameLength,
2444 GFP_ATOMIC );
2445#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002446 cfg80211_rx_mgmt( pAdapter->dev, freq, 0,
2447 pbFrames, nFrameLength,
2448 GFP_ATOMIC );
2449#else
2450 cfg80211_rx_mgmt( pAdapter->dev, freq,
2451 pbFrames, nFrameLength,
2452 GFP_ATOMIC );
2453#endif //LINUX_VERSION_CODE
2454}
2455
2456/*
2457 * ieee80211_add_rx_radiotap_header - add radiotap header
2458 */
2459static int hdd_wlan_add_rx_radiotap_hdr (
2460 struct sk_buff *skb, int rtap_len, int flag )
2461{
2462 u8 rtap_temp[20] = {0};
2463 struct ieee80211_radiotap_header *rthdr;
2464 unsigned char *pos;
2465 u16 rx_flags = 0;
2466
2467 rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]);
2468
2469 /* radiotap header, set always present flags */
2470 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
2471 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
2472 rthdr->it_len = cpu_to_le16(rtap_len);
2473
2474 pos = (unsigned char *) (rthdr + 1);
2475
2476 /* the order of the following fields is important */
2477
2478 /* IEEE80211_RADIOTAP_FLAGS */
2479 *pos = 0;
2480 pos++;
2481
2482 /* IEEE80211_RADIOTAP_RX_FLAGS: Length 2 Bytes */
2483 /* ensure 2 byte alignment for the 2 byte field as required */
2484 if ((pos - (u8 *)rthdr) & 1)
2485 pos++;
2486 put_unaligned_le16(rx_flags, pos);
2487 pos += 2;
Daram Sudha1f7e0e92013-12-17 07:52:31 +05302488
Jeff Johnson295189b2012-06-20 16:38:30 -07002489 // actually push the data
2490 memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len);
2491
2492 return 0;
2493}
2494
2495static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter,
2496 hdd_cfg80211_state_t* cfgState,
2497 tANI_BOOLEAN actionSendSuccess )
2498{
2499 struct ieee80211_radiotap_header *rthdr;
2500 unsigned char *pos;
2501 struct sk_buff *skb = cfgState->skb;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002502#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002503#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
2504 hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
2505#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002507
2508 /* 2 Byte for TX flags and 1 Byte for Retry count */
2509 u32 rtHdrLen = sizeof(*rthdr) + 3;
2510
2511 u8 *data;
2512
2513 /* We have to return skb with Data starting with MAC header. We have
2514 * copied SKB data starting with MAC header to cfgState->buf. We will pull
2515 * entire skb->len from skb and then we will push cfgState->buf to skb
2516 * */
2517 if( NULL == skb_pull(skb, skb->len) )
2518 {
2519 hddLog( LOGE, FL("Not Able to Pull %d byte from skb"), skb->len);
2520 kfree_skb(cfgState->skb);
2521 return;
2522 }
2523
2524 data = skb_push( skb, cfgState->len );
2525
2526 if (data == NULL)
2527 {
Jeff Johnson59a121e2013-11-30 09:46:08 -08002528 hddLog( LOGE, FL("Not Able to Push %zu byte to skb"), cfgState->len);
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 kfree_skb( cfgState->skb );
2530 return;
2531 }
2532
2533 memcpy( data, cfgState->buf, cfgState->len );
2534
2535 /* send frame to monitor interfaces now */
2536 if( skb_headroom(skb) < rtHdrLen )
2537 {
2538 hddLog( LOGE, FL("No headroom for rtap header"));
2539 kfree_skb(cfgState->skb);
2540 return;
2541 }
2542
2543 rthdr = (struct ieee80211_radiotap_header*) skb_push( skb, rtHdrLen );
2544
2545 memset( rthdr, 0, rtHdrLen );
2546 rthdr->it_len = cpu_to_le16( rtHdrLen );
2547 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
2548 (1 << IEEE80211_RADIOTAP_DATA_RETRIES)
2549 );
2550
2551 pos = (unsigned char *)( rthdr+1 );
2552
2553 // Fill TX flags
2554 *pos = actionSendSuccess;
2555 pos += 2;
2556
2557 // Fill retry count
2558 *pos = 0;
2559 pos++;
2560
2561 skb_set_mac_header( skb, 0 );
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002562 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002563 skb->pkt_type = PACKET_OTHERHOST;
2564 skb->protocol = htons(ETH_P_802_2);
2565 memset( skb->cb, 0, sizeof( skb->cb ) );
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002566#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07002567#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07002568 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07002569#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002570#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002571 if (in_interrupt())
2572 netif_rx( skb );
2573 else
2574 netif_rx_ni( skb );
2575
2576 /* Enable Queues which we have disabled earlier */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05302578 netif_tx_start_all_queues( pAdapter->dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07002579
2580}
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05302581
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302582void __hdd_p2p_roc_work_queue(struct work_struct *work)
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05302583{
2584 hdd_adapter_t *pAdapter = container_of(to_delayed_work(work), hdd_adapter_t, roc_work);
2585 hddLog( VOS_TRACE_LEVEL_INFO, FL("%s: "), __func__);
2586 wlan_hdd_p2p_start_remain_on_channel(pAdapter);
2587 return;
2588}
2589
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302590void hdd_p2p_roc_work_queue(struct work_struct *work)
2591{
2592 vos_ssr_protect(__func__);
2593 __hdd_p2p_roc_work_queue(work);
2594 vos_ssr_unprotect(__func__);
2595 return;
2596}