blob: a421c73dd4fe56046773b0e40e75c3f3f5cd6579 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Jeff Johnson295189b2012-06-20 16:38:30 -070026 */
27
28/**===========================================================================
29
30 \file wlan_hdd_softap_tx_rx.c
31
32 \brief Linux HDD Tx/RX APIs
Kiet Lamaa8e15a2014-02-11 23:30:06 -080033 Copyright 2008 (c) Qualcomm, Incorporated.
34 All Rights Reserved.
35 Qualcomm Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070036
37 ==========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070038
39/*---------------------------------------------------------------------------
40 Include files
41 -------------------------------------------------------------------------*/
42#include <linux/semaphore.h>
43#include <wlan_hdd_tx_rx.h>
44#include <wlan_hdd_softap_tx_rx.h>
45#include <wlan_hdd_dp_utils.h>
46#include <wlan_qct_tl.h>
47#include <linux/netdevice.h>
48#include <linux/skbuff.h>
49#include <linux/etherdevice.h>
50//#include <vos_list.h>
51#include <vos_types.h>
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053052#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <aniGlobal.h>
54#include <halTypes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070055#include <net/ieee80211_radiotap.h>
Mihir Shetef3473692014-06-27 15:13:20 +053056#include <linux/ratelimit.h>
57#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
58#include <soc/qcom/subsystem_restart.h>
59#else
60#include <mach/subsystem_restart.h>
61#endif
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053062#include "sapInternal.h"
Mihir Shete5d148f12014-12-16 17:54:49 +053063#include "wlan_hdd_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070064
65/*---------------------------------------------------------------------------
66 Preprocessor definitions and constants
67 -------------------------------------------------------------------------*/
68
69/*---------------------------------------------------------------------------
70 Type declarations
71 -------------------------------------------------------------------------*/
72
73/*---------------------------------------------------------------------------
74 Function definitions and documenation
75 -------------------------------------------------------------------------*/
76#if 0
77static void hdd_softap_dump_sk_buff(struct sk_buff * skb)
78{
c_hpothu6d1d2a32014-03-18 20:17:03 +053079 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head);
80 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data);
81 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail);
82 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end);
83 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
84 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
85 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070086
c_hpothu6d1d2a32014-03-18 20:17:03 +053087 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
Jeff Johnson295189b2012-06-20 16:38:30 -070088 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
89 skb->data[5], skb->data[6], skb->data[7]);
c_hpothu6d1d2a32014-03-18 20:17:03 +053090 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
Jeff Johnson295189b2012-06-20 16:38:30 -070091 skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
92 skb->data[13], skb->data[14], skb->data[15]);
93}
94#endif
Leo Chang64d68bc2013-06-04 15:40:52 -070095
96extern void hdd_set_wlan_suspend_mode(bool suspend);
97
Mihir Shetef3473692014-06-27 15:13:20 +053098#define HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ
99#define HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST 1
100#define HDD_SAP_TX_STALL_SSR_THRESHOLD 5
Mihir Shete327c2ab2014-11-13 15:17:02 +0530101#define HDD_SAP_TX_STALL_RECOVERY_THRESHOLD HDD_SAP_TX_STALL_SSR_THRESHOLD - 2
Mihir Shetef3473692014-06-27 15:13:20 +0530102
103static DEFINE_RATELIMIT_STATE(hdd_softap_tx_timeout_rs, \
104 HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL, \
105 HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST);
106
Leo Chang64d68bc2013-06-04 15:40:52 -0700107/**============================================================================
108 @brief hdd_softap_traffic_monitor_timeout_handler() -
109 SAP/P2P GO traffin monitor timeout handler function
110 If no traffic during programmed time, trigger suspand mode
111
112 @param pUsrData : [in] pointer to hdd context
113 @return : NONE
114 ===========================================================================*/
115void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData )
116{
117 hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData;
118 v_TIME_t currentTS;
119
120 if (NULL == pHddCtx)
121 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530122 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Leo Chang64d68bc2013-06-04 15:40:52 -0700123 "%s: Invalid user data, context", __func__);
124 return;
125 }
126
127 currentTS = vos_timer_get_system_time();
128 if (pHddCtx->cfg_ini->trafficIdleTimeout <
129 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
130 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530131 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530132 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -0700133 hdd_set_wlan_suspend_mode(1);
134 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
135 }
136 else
137 {
138 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
139 pHddCtx->cfg_ini->trafficIdleTimeout);
140 }
141
142 return;
143}
144
Kiet Lambcf38522013-10-26 18:28:27 +0530145VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter )
146{
147
148 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
149 VOS_STATUS status = VOS_STATUS_SUCCESS;
150
151 status = wlan_hdd_validate_context(pHddCtx);
152
153 if (0 != status)
154 {
155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
156 "%s: HDD context is not valid", __func__);
157 return status;
158 }
159
160 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
161 (!pHddCtx->traffic_monitor.isInitialized))
162 {
163 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
164 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
165 VOS_TIMER_TYPE_SW,
166 hdd_softap_traffic_monitor_timeout_handler,
167 pHddCtx);
168 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
169 pHddCtx->traffic_monitor.isInitialized = 1;
170 pHddCtx->traffic_monitor.lastFrameTs = 0;
171 /* Start traffic monitor timer here
172 * If no AP assoc, immediatly go into suspend */
c_hpothu6d1d2a32014-03-18 20:17:03 +0530173 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530174 "%s Start Traffic Monitor Timer", __func__);
175 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
176 pHddCtx->cfg_ini->trafficIdleTimeout);
177 }
178 else
179 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530180 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530181 "%s Traffic Monitor is not Enable in ini file", __func__);
182 }
183 return status;
184}
185
186VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter )
187{
188 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
189 VOS_STATUS status = VOS_STATUS_SUCCESS;
190
191 status = wlan_hdd_validate_context(pHddCtx);
192
Kiet Lamae69d7a2013-11-08 14:38:04 +0530193 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530194 {
195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
196 "%s: HDD context is not valid", __func__);
197 return status;
198 }
199
200 if (pHddCtx->traffic_monitor.isInitialized)
201 {
202 if (VOS_TIMER_STATE_STOPPED !=
203 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
204 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530205 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530206 "%s Stop Traffic Monitor Timer", __func__);
207 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
208 }
c_hpothu6d1d2a32014-03-18 20:17:03 +0530209 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530210 "%s Destroy Traffic Monitor Timer", __func__);
211 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
212 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
213 pHddCtx->traffic_monitor.isInitialized = 0;
214 }
Kiet Lamae69d7a2013-11-08 14:38:04 +0530215 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530216}
217
Jeff Johnson295189b2012-06-20 16:38:30 -0700218/**============================================================================
219 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
220
221 @param pAdapter : [in] pointer to adapter context
222 @return : VOS_STATUS_E_FAILURE if any errors encountered
223 : VOS_STATUS_SUCCESS otherwise
224 ===========================================================================*/
225static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
226{
227 VOS_STATUS status = VOS_STATUS_SUCCESS;
228 v_SINT_t i = -1;
229 v_U8_t STAId = 0;
230 hdd_list_node_t *anchor = NULL;
231 skb_list_node_t *pktNode = NULL;
232 struct sk_buff *skb = NULL;
233
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530234 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
235 ptSapContext pSapCtx = NULL;
236 pSapCtx = VOS_GET_SAP_CB(pVosContext);
237 if(pSapCtx == NULL){
238 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
239 FL("psapCtx is NULL"));
240 return VOS_STATUS_E_FAULT;
241 }
242 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700243 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
244 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530245 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700246 {
247 continue;
248 }
249
250 for (i = 0; i < NUM_TX_QUEUES; i ++)
251 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530252 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700253 while (true)
254 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530255 status = hdd_list_remove_front ( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
Jeff Johnson295189b2012-06-20 16:38:30 -0700256
257 if (VOS_STATUS_E_EMPTY != status)
258 {
259 //If success then we got a valid packet from some AC
260 pktNode = list_entry(anchor, skb_list_node_t, anchor);
261 skb = pktNode->skb;
262 ++pAdapter->stats.tx_dropped;
263 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
264 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
265 kfree_skb(skb);
266 continue;
267 }
268
269 //current list is empty
270 break;
271 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530272 pSapCtx->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
273 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530275 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 }
277
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530278 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
280 return status;
281}
282
283/**============================================================================
284 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
285 transmitting packets. There are 2 versions of this function. One that uses
286 locked queue and other that uses lockless queues. Both have been retained to
287 do some performance testing
288
289 @param skb : [in] pointer to OS packet (sk_buff)
290 @param dev : [in] pointer to Libra network device
291
292 @return : NET_XMIT_DROP if packets are dropped
293 : NET_XMIT_SUCCESS if packet is enqueued succesfully
294 ===========================================================================*/
295int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
296{
297 VOS_STATUS status;
298 WLANTL_ACEnumType ac = WLANTL_AC_BE;
299 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
300 skb_list_node_t *pktNode = NULL;
301 v_SIZE_t pktListSize = 0;
302 v_BOOL_t txSuspended = VOS_FALSE;
303 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
304 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530305 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 vos_list_node_t *anchor = NULL;
307 v_U8_t STAId = WLAN_MAX_STA_COUNT;
308 //Extract the destination address from ethernet frame
309 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
310 int os_status = NETDEV_TX_OK;
Mihir Shetef8f74532014-12-04 11:53:34 +0530311 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700312
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530313 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
314 ptSapContext pSapCtx = NULL;
315 pSapCtx = VOS_GET_SAP_CB(pVosContext);
316 if(pSapCtx == NULL){
317 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
318 FL("psapCtx is NULL"));
319 ++pAdapter->stats.tx_dropped;
320 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
321 kfree_skb(skb);
322 return os_status;
323 }
324
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 pDestMacAddress = (v_MACADDR_t*)skb->data;
326
327 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
328
c_hpothu6d1d2a32014-03-18 20:17:03 +0530329 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700330 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700331
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530332 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
334 {
335 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
336 //ID used for BC/MC traffic. The station id is registered to TL as well.
337 STAId = pHddApCtx->uBCStaId;
338
339 /* Setting priority for broadcast packets which doesn't go to select_queue function */
340 skb->priority = SME_QOS_WMM_UP_BE;
341 skb->queue_mapping = HDD_LINUX_AC_BE;
342
c_hpothu6d1d2a32014-03-18 20:17:03 +0530343 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800344 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346 else
347 {
348 STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
349 if (STAId == HDD_WLAN_INVALID_STA_ID)
350 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530351 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700352 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 ++pAdapter->stats.tx_dropped;
354 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
355 kfree_skb(skb);
356 goto xmit_done;
357 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530358 else if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700359 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530360 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
361 "%s: STA %d is unregistered", __func__, STAId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700362 ++pAdapter->stats.tx_dropped;
363 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
364 kfree_skb(skb);
365 goto xmit_done;
366 }
367
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530368 if ( (WLANTL_STA_CONNECTED != pSapCtx->aStaInfo[STAId].tlSTAState) &&
369 (WLANTL_STA_AUTHENTICATED != pSapCtx->aStaInfo[STAId].tlSTAState) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530371 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700372 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 ++pAdapter->stats.tx_dropped;
374 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
375 kfree_skb(skb);
376 goto xmit_done;
377 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530378 else if(WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[STAId].tlSTAState)
Jeff Johnson295189b2012-06-20 16:38:30 -0700379 {
380 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
381 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530382 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700383 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 ++pAdapter->stats.tx_dropped;
385 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
386 kfree_skb(skb);
387 goto xmit_done;
388 }
389 }
390 }
391
392 //Get TL AC corresponding to Qdisc queue index/AC.
393 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
394 //user priority from IP header, which is already extracted and set from
395 //select_queue call back function
396 up = skb->priority;
397 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
398
c_hpothu6d1d2a32014-03-18 20:17:03 +0530399 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700400 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700401
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530402 if (( NULL != pHddCtx ) &&
403 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530404 {
405 hdd_dump_dhcp_pkt(skb, TX_PATH);
406 }
407
Jeff Johnson295189b2012-06-20 16:38:30 -0700408 // If the memory differentiation mode is enabled, the memory limit of each queue will be
409 // checked. Over-limit packets will be dropped.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530410 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
411 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700412 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
413 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530414 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800415 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530416 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700417 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
418 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530419 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
420 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -0700421 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530422
423 /* If 3/4th of the max queue size is used then enable the flag.
424 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
425 if (WLANTL_AC_BE == ac)
426 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530427 if (pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530428 {
429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
430 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530431 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_TRUE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530432 }
433 else
434 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530435 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530436 }
437 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530438 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700439
440 if (VOS_TRUE == txSuspended)
441 {
442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
443 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700444 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700445 os_status = NETDEV_TX_BUSY;
446 goto xmit_done;
447 }
448
449 //Use the skb->cb field to hold the list node information
450 pktNode = (skb_list_node_t *)&skb->cb;
451
452 //Stick the OS packet inside this node.
453 pktNode->skb = skb;
454
455 //Stick the User Priority inside this node
456 pktNode->userPriority = up;
457
458 INIT_LIST_HEAD(&pktNode->anchor);
459
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530460 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
461 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
462 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700463 if ( !VOS_IS_STATUS_SUCCESS( status ) )
464 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530465 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
466 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700467 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
468 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
469 ++pAdapter->stats.tx_dropped;
470 kfree_skb(skb);
471 goto xmit_done;
472 }
473
474 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
475 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530476 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700477
478 if (1 == pktListSize)
479 {
480 //Let TL know we have a packet to send for this AC
481 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
482
483 if ( !VOS_IS_STATUS_SUCCESS( status ) )
484 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530485 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
486 "%s: Failed to signal TL for AC=%d STAId =%d",
487 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700488
489 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
490 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530491 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
492 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
493 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530494 /* Free the skb only if we are able to remove it from the list.
495 * If we are not able to retrieve it from the list it means that
496 * the skb was pulled by TX Thread and is use so we should not free
497 * it here
498 */
499 if (VOS_IS_STATUS_SUCCESS(status))
500 {
501 pktNode = list_entry(anchor, skb_list_node_t, anchor);
502 skb1 = pktNode->skb;
503 kfree_skb(skb1);
504 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700505 ++pAdapter->stats.tx_dropped;
506 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
507 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700508 goto xmit_done;
509 }
510 }
511 dev->trans_start = jiffies;
512
c_hpothu6d1d2a32014-03-18 20:17:03 +0530513 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
514 "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700515
516xmit_done:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530517 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700518 return os_status;
519}
520
521/**============================================================================
522 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
523
524 @param skb : [in] pointer to packet (sk_buff)
525 @param dev : [in] pointer to Libra network device
526 @param STAId : [in] Station Id of Destination Station
527 @param up : [in] User Priority
528
529 @return : NET_XMIT_DROP if packets are dropped
530 : NET_XMIT_SUCCESS if packet is enqueued succesfully
531 ===========================================================================*/
532VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
533 struct net_device *dev,
534 v_U8_t STAId,
535 v_U8_t up)
536{
537 VOS_STATUS status = VOS_STATUS_SUCCESS;
538 skb_list_node_t *pktNode = NULL;
539 v_SIZE_t pktListSize = 0;
540 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
541 v_U8_t ac;
542 vos_list_node_t *anchor = NULL;
Mihir Shetef8f74532014-12-04 11:53:34 +0530543 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700544
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530545 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
546 ptSapContext pSapCtx = NULL;
547 pSapCtx = VOS_GET_SAP_CB(pVosContext);
548 if(pSapCtx == NULL){
549 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
550 FL("psapCtx is NULL"));
551 kfree_skb(skb);
552 status = VOS_STATUS_E_FAILURE;
553 return status;
554 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700555 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
556
c_hpothu6d1d2a32014-03-18 20:17:03 +0530557 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700558 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700559
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530560 spin_lock_bh( &pSapCtx->staInfo_lock );
561 if ( FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700562 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530563 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530564 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700565 kfree_skb(skb);
566 status = VOS_STATUS_E_FAILURE;
567 goto xmit_end;
568 }
569
570 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530571 if ( !pSapCtx->aStaInfo[STAId].isQosEnabled )
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 up = SME_QOS_WMM_UP_BE;
573
574 ac = hddWmmUpToAcMap[up];
575 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
c_hpothu6d1d2a32014-03-18 20:17:03 +0530576 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700577 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700578
579 skb->queue_mapping = hddLinuxUpToAcMap[up];
580
581 //Use the skb->cb field to hold the list node information
582 pktNode = (skb_list_node_t *)&skb->cb;
583
584 //Stick the OS packet inside this node.
585 pktNode->skb = skb;
586
587 //Stick the User Priority inside this node
588 pktNode->userPriority = up;
589
590 INIT_LIST_HEAD(&pktNode->anchor);
591
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530592 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
593 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
594 if(pSapCtx->aStaInfo[STAId].txSuspended[ac] ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700595 pktListSize >= pAdapter->aTxQueueLimit[ac])
596 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530597 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800598 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700599 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
600 * SUSPEND should be done based on Threshold. RESUME would be
601 * triggered in fetch cbk after recovery.
602 */
603 kfree_skb(skb);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530604 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700605 status = VOS_STATUS_E_FAILURE;
606 goto xmit_end;
607 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530608 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
609 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700610
611 if ( !VOS_IS_STATUS_SUCCESS( status ) )
612 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530613 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
614 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700615 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
616 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
617 ++pAdapter->stats.tx_dropped;
618 kfree_skb(skb);
619 status = VOS_STATUS_E_FAILURE;
620 goto xmit_end;
621 }
622
623 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
624 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
625
626 if (1 == pktListSize)
627 {
628 //Let TL know we have a packet to send for this AC
c_hpothu6d1d2a32014-03-18 20:17:03 +0530629 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
630 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700631
632 if ( !VOS_IS_STATUS_SUCCESS( status ) )
633 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530634 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
635 "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700636 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700637
638 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
639 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530640 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
641 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
642 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530643 /* Free the skb only if we are able to remove it from the list.
644 * If we are not able to retrieve it from the list it means that
645 * the skb was pulled by TX Thread and is use so we should not free
646 * it here
647 */
648 if (VOS_IS_STATUS_SUCCESS(status))
649 {
650 pktNode = list_entry(anchor, skb_list_node_t, anchor);
651 skb1 = pktNode->skb;
652 kfree_skb(skb1);
653 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 ++pAdapter->stats.tx_dropped;
655 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
656 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700657 status = VOS_STATUS_E_FAILURE;
658 goto xmit_end;
659 }
660 }
661
c_hpothu6d1d2a32014-03-18 20:17:03 +0530662 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700663
664xmit_end:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530665 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700666 return status;
667}
668
669/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530670 @brief __hdd_softap_tx_timeout() - Function called by OS if there is any
Jeff Johnson295189b2012-06-20 16:38:30 -0700671 timeout during transmission. Since HDD simply enqueues packet
672 and returns control to OS right away, this would never be invoked
673
674 @param dev : [in] pointer to Libra network device
675 @return : None
676 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530677void __hdd_softap_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700678{
Mihir Shetef3473692014-06-27 15:13:20 +0530679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
680 struct netdev_queue *txq;
681 int i = 0;
682
c_hpothu6d1d2a32014-03-18 20:17:03 +0530683 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700684 "%s: Transmission timeout occurred", __func__);
Mihir Shetef3473692014-06-27 15:13:20 +0530685
686 if ( NULL == pAdapter )
687 {
688 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
689 FL("pAdapter is NULL"));
690 VOS_ASSERT(0);
691 return;
692 }
693
694 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
695
696 for (i = 0; i < 8; i++)
697 {
698 txq = netdev_get_tx_queue(dev, i);
699 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
700 "Queue%d status: %d", i, netif_tx_queue_stopped(txq));
701 }
702
703 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
704 "carrier state: %d", netif_carrier_ok(dev));
705
706 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
707
Mihir Shete327c2ab2014-11-13 15:17:02 +0530708 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
709 HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
710 {
711 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
712 "%s: Request firmware for recovery",__func__);
713 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
714 }
Mihir Shetef3473692014-06-27 15:13:20 +0530715 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
716 HDD_SAP_TX_STALL_SSR_THRESHOLD)
717 {
718 // Driver could not recover, issue SSR
719 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
720 "%s: Cannot recover from Data stall Issue SSR",
721 __func__);
Mihir Shetefd62d9d2014-08-06 15:08:21 +0530722 WLANTL_FatalError();
Mihir Shetef3473692014-06-27 15:13:20 +0530723 return;
724 }
725
726 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
727 * every 5sec. The TL debug spits out a lot of information on the
728 * serial console, if it is called every time *hdd_tx_timeout* is
729 * called then we may get a watchdog bite on the Application
730 * processor, so ratelimit the TL debug logs.
731 */
732 if (__ratelimit(&hdd_softap_tx_timeout_rs))
733 {
734 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +0530735 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetef3473692014-06-27 15:13:20 +0530736 }
737
Jeff Johnson295189b2012-06-20 16:38:30 -0700738}
739
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530740void hdd_softap_tx_timeout(struct net_device *dev)
741{
742 vos_ssr_protect(__func__);
743 __hdd_softap_tx_timeout(dev);
744 vos_ssr_unprotect(__func__);
745 return;
746}
Jeff Johnson295189b2012-06-20 16:38:30 -0700747
748/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530749 @brief __hdd_softap_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700750 device TX/RX statistic
751
752 @param dev : [in] pointer to Libra network device
753
754 @return : pointer to net_device_stats structure
755 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530756struct net_device_stats* __hdd_softap_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700757{
758 hdd_adapter_t* priv = netdev_priv(dev);
759 return &priv->stats;
760}
761
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530762struct net_device_stats* hdd_softap_stats(struct net_device *dev)
763{
764 struct net_device_stats *priv_stats;
765 vos_ssr_protect(__func__);
766 priv_stats = __hdd_softap_stats(dev);
767 vos_ssr_unprotect(__func__);
768
769 return priv_stats;
770}
Jeff Johnson295189b2012-06-20 16:38:30 -0700771
772/**============================================================================
773 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
774 modules in HDD
775
776 @param pAdapter : [in] pointer to adapter context
777 @return : VOS_STATUS_E_FAILURE if any errors encountered
778 : VOS_STATUS_SUCCESS otherwise
779 ===========================================================================*/
780VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
781{
782 VOS_STATUS status = VOS_STATUS_SUCCESS;
783 v_SINT_t i = -1;
784 v_SIZE_t size = 0;
785
786 v_U8_t STAId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530787 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
788 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700789
790 v_U8_t pACWeights[] = {
791 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
792 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
793 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
794 HDD_SOFTAP_VO_WEIGHT_DEFAULT
795 };
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530796 pSapCtx = VOS_GET_SAP_CB(pVosContext);
797 if(pSapCtx == NULL){
798 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
799 FL("psapCtx is NULL"));
800 return VOS_STATUS_E_FAULT;
801 }
802
Leo Chang64d68bc2013-06-04 15:40:52 -0700803
Jeff Johnson295189b2012-06-20 16:38:30 -0700804 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530805 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700806
807 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
808
809 while (++i != NUM_TX_QUEUES)
810 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
811
812 /* Initial HDD buffer control / flow control fields*/
813 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
814
815 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
816 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
817 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
818 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
819
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530820 spin_lock_init( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700821
822 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
823 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530824 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 for (i = 0; i < NUM_TX_QUEUES; i ++)
826 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530827 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700828 }
829 }
830
Yue Ma3ede6052013-08-29 00:33:26 -0700831 /* Update the AC weights suitable for SoftAP mode of operation */
832 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
833
Kiet Lambcf38522013-10-26 18:28:27 +0530834 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700835 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530836 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530837 "%s: failed to start Traffic Monito timer ", __func__ );
838 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700839 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 return status;
841}
842
843/**============================================================================
844 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
845 modules in HDD
846
847 @param pAdapter : [in] pointer to adapter context
848 @return : VOS_STATUS_E_FAILURE if any errors encountered
849 : VOS_STATUS_SUCCESS otherwise
850 ===========================================================================*/
851VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
852{
853 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700854
Kiet Lambcf38522013-10-26 18:28:27 +0530855 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700856 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530857 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530858 "%s: Fail to Stop Traffic Monito timer", __func__ );
859 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700860 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700861
862 status = hdd_softap_flush_tx_queues(pAdapter);
863
864 return status;
865}
866
867/**============================================================================
868 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
869
870 @param pAdapter : [in] pointer to adapter context
871 @param STAId : [in] Station ID to deinit
872 @return : VOS_STATUS_E_FAILURE if any errors encountered
873 : VOS_STATUS_SUCCESS otherwise
874 ===========================================================================*/
875static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
876{
Jeff Johnson295189b2012-06-20 16:38:30 -0700877 v_U8_t i = -1;
878
879 hdd_list_node_t *anchor = NULL;
880
881 skb_list_node_t *pktNode = NULL;
882 struct sk_buff *skb = NULL;
883
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530884 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
885 ptSapContext pSapCtx = NULL;
886 pSapCtx = VOS_GET_SAP_CB(pVosContext);
887 if(pSapCtx == NULL){
888 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
889 FL("psapCtx is NULL"));
890 return VOS_STATUS_E_FAULT;
891 }
892 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700893 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530894 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 }
896
897 for (i = 0; i < NUM_TX_QUEUES; i ++)
898 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530899 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700900 while (true)
901 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530902 if (VOS_STATUS_E_EMPTY !=
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530903 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530904 &anchor))
Jeff Johnson295189b2012-06-20 16:38:30 -0700905 {
906 //If success then we got a valid packet from some AC
907 pktNode = list_entry(anchor, skb_list_node_t, anchor);
908 skb = pktNode->skb;
909 ++pAdapter->stats.tx_dropped;
910 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
911 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
912 kfree_skb(skb);
913 continue;
914 }
915
916 //current list is empty
917 break;
918 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530919 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 }
921
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530922 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700923}
924
925/**============================================================================
926 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
927 modules in HDD
928
929 @param pAdapter : [in] pointer to adapter context
930 @param STAId : [in] Station ID to deinit
931 @param pmacAddrSTA : [in] pointer to the MAC address of the station
932 @return : VOS_STATUS_E_FAILURE if any errors encountered
933 : VOS_STATUS_SUCCESS otherwise
934 ===========================================================================*/
935VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
936{
937 v_U8_t i = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530938 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
939 ptSapContext pSapCtx = NULL;
940 pSapCtx = VOS_GET_SAP_CB(pVosContext);
941 if(pSapCtx == NULL){
942 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
943 FL("psapCtx is NULL"));
944 return VOS_STATUS_E_FAULT;
945 }
946
947 spin_lock_bh( &pSapCtx->staInfo_lock );
948 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700949 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530950 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
951 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530952 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 return VOS_STATUS_E_FAILURE;
954 }
955
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530956 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 for (i = 0; i < NUM_TX_QUEUES; i ++)
958 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530959 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700960 }
961
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530962 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
963 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
964 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700965
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530966 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700967 return VOS_STATUS_SUCCESS;
968}
969
970/**============================================================================
971 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
972 modules in HDD
973
974 @param pAdapter : [in] pointer to adapter context
975 @param STAId : [in] Station ID to deinit
976 @return : VOS_STATUS_E_FAILURE if any errors encountered
977 : VOS_STATUS_SUCCESS otherwise
978 ===========================================================================*/
979VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
980{
981 VOS_STATUS status = VOS_STATUS_SUCCESS;
982 v_U8_t ac;
983 /**Track whether OS TX queue has been disabled.*/
984 v_BOOL_t txSuspended[NUM_TX_QUEUES];
985 v_U8_t tlAC;
986 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700987 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -0700988
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530989 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
990 ptSapContext pSapCtx = NULL;
991 pSapCtx = VOS_GET_SAP_CB(pVosContext);
992 if(pSapCtx == NULL){
993 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
994 FL("psapCtx is NULL"));
995 return VOS_STATUS_E_FAULT;
996 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700997 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
998
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530999 spin_lock_bh( &pSapCtx->staInfo_lock );
1000 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001001 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301002 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001003 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301004 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001005 return VOS_STATUS_E_FAILURE;
1006 }
1007
1008 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1009
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301010 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1011 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 /* if this STA had any of its WMM TX queues suspended, then the
1013 associated queue on the network interface was disabled. check
1014 to see if that is the case, in which case we need to re-enable
1015 the interface queue. but we only do this if the BSS is running
1016 since, if the BSS is stopped, all of the interfaces have been
1017 stopped and should not be re-enabled */
1018
1019 if (BSS_START == pHostapdState->bssState)
1020 {
1021 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1022 {
1023 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301024 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001025 }
1026 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301027 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001028
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001029 /* re-init spin lock, since netdev can still open adapter until
1030 * driver gets unloaded
1031 */
1032 for (i = 0; i < NUM_TX_QUEUES; i ++)
1033 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301034 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001035 HDD_TX_QUEUE_MAX_LEN);
1036 }
1037
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 if (BSS_START == pHostapdState->bssState)
1039 {
1040 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1041 {
1042 if (txSuspended[ac])
1043 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301044 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001045 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 netif_wake_subqueue(pAdapter->dev, ac);
1047 }
1048 }
1049 }
1050
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301051 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 return status;
1053}
1054
1055/**============================================================================
1056 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1057 modules in HDD
1058
1059 @param pAdapter : [in] pointer to adapter context
1060 @return : VOS_STATUS_E_FAILURE if any errors encountered
1061 : VOS_STATUS_SUCCESS otherwise
1062 ===========================================================================*/
1063VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1064{
1065 return hdd_softap_flush_tx_queues(pAdapter);
1066}
1067
1068/**============================================================================
1069 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1070 to indicate that a packet has been transmitted across the bus
1071 succesfully. OS packet resources can be released after this cbk.
1072
1073 @param vosContext : [in] pointer to VOS context
1074 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1075 @param vosStatusIn : [in] status of the transmission
1076
1077 @return : VOS_STATUS_E_FAILURE if any errors encountered
1078 : VOS_STATUS_SUCCESS otherwise
1079 ===========================================================================*/
1080VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1081 vos_pkt_t *pVosPacket,
1082 VOS_STATUS vosStatusIn )
1083{
1084 VOS_STATUS status = VOS_STATUS_SUCCESS;
1085 hdd_adapter_t *pAdapter = NULL;
1086 void* pOsPkt = NULL;
1087
1088 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1089 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301090 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1091 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001092 return VOS_STATUS_E_FAILURE;
1093 }
1094
1095 //Return the skb to the OS
1096 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001097 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001098 {
1099 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301100 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1101 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001102 vos_pkt_return_packet( pVosPacket );
1103 return VOS_STATUS_E_FAILURE;
1104 }
1105
1106 //Get the Adapter context.
1107 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
1108 if(pAdapter == NULL)
1109 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301110 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1111 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 }
1113 else
1114 {
1115 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1116 }
1117
1118 kfree_skb((struct sk_buff *)pOsPkt);
1119
1120 //Return the VOS packet resources.
1121 status = vos_pkt_return_packet( pVosPacket );
1122 if(!VOS_IS_STATUS_SUCCESS( status ))
1123 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301124 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1125 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 }
1127
1128 return status;
1129}
1130
1131
1132/**============================================================================
1133 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1134 fetch a packet for transmission.
1135
1136 @param vosContext : [in] pointer to VOS context
1137 @param staId : [in] Station for which TL is requesting a pkt
1138 @param ac : [in] access category requested by TL
1139 @param pVosPacket : [out] pointer to VOS packet packet pointer
1140 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1141
1142 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1143 : VOS_STATUS_E_FAILURE if any errors encountered
1144 : VOS_STATUS_SUCCESS otherwise
1145 ===========================================================================*/
1146VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1147 v_U8_t *pStaId,
1148 WLANTL_ACEnumType ac,
1149 vos_pkt_t **ppVosPacket,
1150 WLANTL_MetaInfoType *pPktMetaInfo )
1151{
1152 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1153 hdd_adapter_t *pAdapter = NULL;
1154 hdd_list_node_t *anchor = NULL;
1155 skb_list_node_t *pktNode = NULL;
1156 struct sk_buff *skb = NULL;
1157 vos_pkt_t *pVosPacket = NULL;
1158 v_MACADDR_t* pDestMacAddress = NULL;
1159 v_TIME_t timestamp;
1160 v_SIZE_t size = 0;
1161 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1162 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001163 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301164 v_CONTEXT_t pVosContext = NULL;
1165 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 //Sanity check on inputs
1167 if ( ( NULL == vosContext ) ||
1168 ( NULL == pStaId ) ||
1169 ( NULL == ppVosPacket ) ||
1170 ( NULL == pPktMetaInfo ) )
1171 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301172 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1173 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 return VOS_STATUS_E_FAILURE;
1175 }
1176
1177 //Get the HDD context.
1178 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1179 if ( NULL == pHddCtx )
1180 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301181 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1182 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001183 return VOS_STATUS_E_FAILURE;
1184 }
1185
Jeff Johnsonb156c922013-12-05 17:19:46 -08001186 STAId = *pStaId;
1187 if (STAId >= WLAN_MAX_STA_COUNT)
1188 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301189 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001190 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1191 return VOS_STATUS_E_FAILURE;
1192 }
1193
1194 pAdapter = pHddCtx->sta_to_adapter[STAId];
1195 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001196 {
1197 VOS_ASSERT(0);
1198 return VOS_STATUS_E_FAILURE;
1199 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301200 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1201 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1202 if(pSapCtx == NULL){
1203 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1204 FL("psapCtx is NULL"));
1205 return VOS_STATUS_E_FAULT;
1206 }
1207
1208 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001209 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301210 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001211 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1212 return VOS_STATUS_E_FAILURE;
1213 }
1214
Leo Chang64d68bc2013-06-04 15:40:52 -07001215 /* Monitor traffic */
1216 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1217 {
1218 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1219 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1220 {
1221 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1222 /* It was IDLE mode,
1223 * this is new state, then switch mode from suspend to resume */
1224 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1225 {
1226 hdd_set_wlan_suspend_mode(0);
1227 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1228 pHddCtx->cfg_ini->trafficIdleTimeout);
1229 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1230 }
1231 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1232 }
1233 }
1234
Jeff Johnson295189b2012-06-20 16:38:30 -07001235 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1236
Jeff Johnson295189b2012-06-20 16:38:30 -07001237 *ppVosPacket = NULL;
1238
1239 //Make sure the AC being asked for is sane
1240 if( ac > WLANTL_MAX_AC || ac < 0)
1241 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301242 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001243 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001244 return VOS_STATUS_E_FAILURE;
1245 }
1246
1247 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1248
c_hpothu6d1d2a32014-03-18 20:17:03 +05301249 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001250 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001251
1252 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1253 //This simplifies the locking and unlocking of Tx queue
1254 status = vos_pkt_wrap_data_packet( &pVosPacket,
1255 VOS_PKT_TYPE_TX_802_3_DATA,
1256 NULL, //OS Pkt is not being passed
1257 hdd_softap_tx_low_resource_cbk,
1258 pAdapter );
1259
1260 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1261 {
1262 //Remember VOS is in a low resource situation
1263 pAdapter->isVosOutOfResource = VOS_TRUE;
1264 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301265 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001266 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001267 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1268 return VOS_STATUS_E_FAILURE;
1269 }
1270
1271 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1272 as the other branch does.
1273 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301274 spin_lock_bh( &pSapCtx->staInfo_lock );
1275 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1276 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001277
1278 if (0 == size)
1279 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301280 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1281 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 vos_pkt_return_packet(pVosPacket);
1283 return VOS_STATUS_E_EMPTY;
1284 }
1285
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301286 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1287 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1288 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001289
c_hpothu6d1d2a32014-03-18 20:17:03 +05301290 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001291 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001292
1293 if(VOS_STATUS_SUCCESS == status)
1294 {
1295 //If success then we got a valid packet from some AC
1296 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1297 skb = pktNode->skb;
1298 }
1299 else
1300 {
1301 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301302 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001303 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001304 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001305 vos_pkt_return_packet(pVosPacket);
1306 return VOS_STATUS_E_FAILURE;
1307 }
1308
1309 //Attach skb to VOS packet.
1310 status = vos_pkt_set_os_packet( pVosPacket, skb );
1311 if (status != VOS_STATUS_SUCCESS)
1312 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301313 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001314 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001315 vos_pkt_return_packet(pVosPacket);
1316 ++pAdapter->stats.tx_dropped;
1317 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1318 kfree_skb(skb);
1319 return VOS_STATUS_E_FAILURE;
1320 }
1321
1322 //Just being paranoid. To be removed later
1323 if(pVosPacket == NULL)
1324 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301325 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001326 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 ++pAdapter->stats.tx_dropped;
1328 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1329 kfree_skb(skb);
1330 return VOS_STATUS_E_FAILURE;
1331 }
1332
1333 //Return VOS packet to TL;
1334 *ppVosPacket = pVosPacket;
1335
1336 //Fill out the meta information needed by TL
1337 //FIXME This timestamp is really the time stamp of wrap_data_packet
1338 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1339 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1340 if ( 1 < size )
1341 {
1342 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1343 }
1344 else
1345 {
1346 pPktMetaInfo->bMorePackets = 0;
1347 }
1348
1349 pPktMetaInfo->ucIsEapol = 0;
1350
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301351 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 {
1353 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1354 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301355 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001356 "%s: VOS packet is EAPOL packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 pPktMetaInfo->ucIsEapol = 1;
1358 }
1359 }
1360
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301361 if ((NULL != pHddCtx) &&
1362 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001363 {
1364 proto_type = vos_pkt_get_proto_type(skb,
1365 pHddCtx->cfg_ini->gEnableDebugLog);
1366 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1367 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001369 "SAP TX EAPOL");
1370 }
1371 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1372 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001374 "SAP TX DHCP");
1375 }
1376 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001377//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001378 {
1379 pPktMetaInfo->ucUP = pktNode->userPriority;
1380 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1381 }
1382
1383 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1384 //Extract the destination address from ethernet frame
1385 pDestMacAddress = (v_MACADDR_t*)skb->data;
1386
1387 // we need 802.3 to 802.11 frame translation
1388 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1389 pPktMetaInfo->ucDisableFrmXtl = 0;
1390 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1391 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1392
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301393 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1395 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301396 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001397 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301398 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001399 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301400 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1401 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 }
1403
1404 // We're giving the packet to TL so consider it transmitted from
1405 // a statistics perspective. We account for it here instead of
1406 // when the packet is returned for two reasons. First, TL will
1407 // manipulate the skb to the point where the len field is not
1408 // accurate, leading to inaccurate byte counts if we account for
1409 // it later. Second, TL does not provide any feedback as to
1410 // whether or not the packet was successfully sent over the air,
1411 // so the packet counts will be the same regardless of where we
1412 // account for them
1413 pAdapter->stats.tx_bytes += skb->len;
1414 ++pAdapter->stats.tx_packets;
1415 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1416 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301417 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001418
c_hpothu6d1d2a32014-03-18 20:17:03 +05301419 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001420 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001421
1422 return status;
1423}
1424
1425
1426/**============================================================================
1427 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1428 case where VOS packets are not available at the time of the call to get
1429 packets. This callback function is invoked by VOS when packets are
1430 available.
1431
1432 @param pVosPacket : [in] pointer to VOS packet
1433 @param userData : [in] opaque user data that was passed initially
1434
1435 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1436 : VOS_STATUS_SUCCESS otherwise
1437 =============================================================================*/
1438VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1439 v_VOID_t *userData )
1440{
1441 VOS_STATUS status;
1442 v_SINT_t i = 0;
1443 v_SIZE_t size = 0;
1444 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1445 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301446 v_CONTEXT_t pVosContext = NULL;
1447 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 if(pAdapter == NULL)
1449 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301450 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1451 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 return VOS_STATUS_E_FAILURE;
1453 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301454 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1455 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1456 if(pSapCtx == NULL){
1457 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1458 FL("psapCtx is NULL"));
1459 return VOS_STATUS_E_FAULT;
1460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001461 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1462 //situation. Here we will only signal TL that there is a pending data for a STA.
1463 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1464 vos_pkt_return_packet( pVosPacket );
1465
1466 pAdapter->isVosOutOfResource = VOS_FALSE;
1467
1468 // Indicate to TL that there is pending data if a queue is non empty.
1469 // This Code wasnt included in earlier version which resulted in
1470 // Traffic stalling
1471 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1472 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301473 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1474 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001475 {
1476 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1477 {
1478 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301479 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001480 if ( size > 0 )
1481 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301482 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1483 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 (WLANTL_ACEnumType)i );
1485 if( !VOS_IS_STATUS_SUCCESS( status ) )
1486 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301487 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1488 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001489 }
1490 }
1491 }
1492 }
1493 }
1494 return VOS_STATUS_SUCCESS;
1495}
1496
1497
1498/**============================================================================
1499 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1500 TL will call this to notify the HDD when one or more packets were
1501 received for a registered STA.
1502
1503 @param vosContext : [in] pointer to VOS context
1504 @param pVosPacketChain : [in] pointer to VOS packet chain
1505 @param staId : [in] Station Id (Adress 1 Index)
1506 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1507
1508 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1509 : VOS_STATUS_SUCCESS otherwise
1510 ===========================================================================*/
1511VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1512 vos_pkt_t *pVosPacketChain,
1513 v_U8_t staId,
1514 WLANTL_RxMetaInfoType* pRxMetaInfo )
1515{
1516 hdd_adapter_t *pAdapter = NULL;
1517 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1518 int rxstat;
1519 struct sk_buff *skb = NULL;
1520 vos_pkt_t* pVosPacket;
1521 vos_pkt_t* pNextVosPacket;
1522 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001523 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001524
1525 //Sanity check on inputs
1526 if ( ( NULL == vosContext ) ||
1527 ( NULL == pVosPacketChain ) ||
1528 ( NULL == pRxMetaInfo ) )
1529 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301530 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1531 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001532 return VOS_STATUS_E_FAILURE;
1533 }
1534
1535 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1536 if ( NULL == pHddCtx )
1537 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301538 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1539 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001540 return VOS_STATUS_E_FAILURE;
1541 }
1542
1543 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301544 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001545 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301546 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1547 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 VOS_ASSERT(0);
1549 return VOS_STATUS_E_FAILURE;
1550 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001551
1552 /* Monitor traffic */
1553 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1554 {
1555 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1556 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1557 {
1558 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1559 /* It was IDLE mode,
1560 * this is new state, then switch mode from suspend to resume */
1561 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1562 {
1563 hdd_set_wlan_suspend_mode(0);
1564 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1565 pHddCtx->cfg_ini->trafficIdleTimeout);
1566 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1567 }
1568 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1569 }
1570 }
1571
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1573
1574 // walk the chain until all are processed
1575 pVosPacket = pVosPacketChain;
1576 do
1577 {
1578 // get the pointer to the next packet in the chain
1579 // (but don't unlink the packet since we free the entire chain later)
1580 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1581
1582 // both "success" and "empty" are acceptable results
1583 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1584 {
1585 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301586 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1587 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 return VOS_STATUS_E_FAILURE;
1589 }
1590
1591 // Extract the OS packet (skb).
1592 // Tell VOS to detach the OS packet from the VOS packet
1593 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
1594 if(!VOS_IS_STATUS_SUCCESS( status ))
1595 {
1596 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301597 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1598 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 return VOS_STATUS_E_FAILURE;
1600 }
1601
1602 //hdd_softap_dump_sk_buff(skb);
1603
1604 skb->dev = pAdapter->dev;
1605
1606 if(skb->dev == NULL) {
1607
c_hpothu6d1d2a32014-03-18 20:17:03 +05301608 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1609 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001610 return VOS_STATUS_E_FAILURE;
1611 }
1612 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1613 ++pAdapter->stats.rx_packets;
1614 pAdapter->stats.rx_bytes += skb->len;
1615
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001616 if (pHddCtx->cfg_ini->gEnableDebugLog)
1617 {
1618 proto_type = vos_pkt_get_proto_type(skb,
1619 pHddCtx->cfg_ini->gEnableDebugLog);
1620 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1621 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001623 "SAP RX EAPOL");
1624 }
1625 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1626 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001628 "SAP RX DHCP");
1629 }
1630 }
1631
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1633 {
1634 //MC/BC packets. Duplicate a copy of packet
1635 struct sk_buff *pSkbCopy;
1636 hdd_ap_ctx_t *pHddApCtx;
1637
1638 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1639 if (!(pHddApCtx->apDisableIntraBssFwd))
1640 {
1641 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1642 if (pSkbCopy)
1643 {
1644 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1645 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1646 }
1647 }
1648 else
1649 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301650 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001651 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001652 }
1653
1654
1655 } //(WLAN_RX_BCMC_STA_ID == staId)
1656
1657 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1658 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1659 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301660 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001661 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301662 if ((NULL != pHddCtx) &&
1663 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301664 {
1665 hdd_dump_dhcp_pkt(skb, RX_PATH);
1666 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001667
1668 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001669 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001670#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07001671#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07001672 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07001673#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001674#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001675 rxstat = netif_rx_ni(skb);
1676 if (NET_RX_SUCCESS == rxstat)
1677 {
1678 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001679 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 }
1681 else
1682 {
1683 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1684 }
1685 }
1686 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1687 {
1688 kfree_skb(skb);
1689 }
1690 else
1691 {
1692 //loopback traffic
1693 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1694 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1695 }
1696
1697 // now process the next packet in the chain
1698 pVosPacket = pNextVosPacket;
1699
1700 } while (pVosPacket);
1701
1702 //Return the entire VOS packet chain to the resource pool
1703 status = vos_pkt_return_packet( pVosPacketChain );
1704 if(!VOS_IS_STATUS_SUCCESS( status ))
1705 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301706 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1707 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001708 }
1709
1710 pAdapter->dev->last_rx = jiffies;
1711
1712 return status;
1713}
1714
1715VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1716{
1717 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301718 hdd_context_t *pHddCtx;
1719 if (NULL == pAdapter)
1720 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301721 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301722 "%s: pAdapter is NULL", __func__);
1723 return VOS_STATUS_E_INVAL;
1724 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001725
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301726 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1727 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301728 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301729 "%s: Invalid pAdapter magic", __func__);
1730 return VOS_STATUS_E_INVAL;
1731 }
1732
1733 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301734 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001735 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301736 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001737 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1738 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301739 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001740 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001741 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 staId, vosStatus, vosStatus );
1743 }
1744
1745 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1746 if( VOS_STATUS_E_FAILURE == vosStatus )
1747 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301748 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001749 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001750 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001751 staId, vosStatus, vosStatus );
1752 return( vosStatus );
1753 }
1754
1755 pHddCtx->sta_to_adapter[staId] = NULL;
1756
1757 return( vosStatus );
1758}
1759
1760VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1761 v_BOOL_t fAuthRequired,
1762 v_BOOL_t fPrivacyBit,
1763 v_U8_t staId,
1764 v_U8_t ucastSig,
1765 v_U8_t bcastSig,
1766 v_MACADDR_t *pPeerMacAddress,
1767 v_BOOL_t fWmmEnabled )
1768{
1769 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001770 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001771 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1772 hdd_adapter_t *pmonAdapter = NULL;
1773
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301774 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1775 ptSapContext pSapCtx = NULL;
1776 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1777 if(pSapCtx == NULL){
1778 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1779 FL("psapCtx is NULL"));
1780 return VOS_STATUS_E_FAULT;
1781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 //eCsrEncryptionType connectedCipherAlgo;
1783 //v_BOOL_t fConnected;
1784
1785 /*
1786 * Clean up old entry if it is not cleaned up properly
1787 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301788 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301790 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001791 "clean up old entry for STA %d", staId);
1792 hdd_softap_DeregisterSTA( pAdapter, staId );
1793 }
1794
1795 // Get the Station ID from the one saved during the assocation.
1796
1797 staDesc.ucSTAId = staId;
1798
1799
1800 /*Save the pAdapter Pointer for this staId*/
1801 pHddCtx->sta_to_adapter[staId] = pAdapter;
1802
1803 staDesc.wSTAType = WLAN_STA_SOFTAP;
1804
1805 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1806 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1807 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1808
c_hpothu6d1d2a32014-03-18 20:17:03 +05301809 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001810 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301811 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001812 "station mac " MAC_ADDRESS_STR,
1813 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301814 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001815 "BSSIDforIBSS " MAC_ADDRESS_STR,
1816 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301817 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001818 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1819 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001820
1821 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1822
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301824 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 "HDD SOFTAP register TL QoS_enabled=%d",
1826 staDesc.ucQosEnabled );
1827
1828 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1829
1830
Jeff Johnson295189b2012-06-20 16:38:30 -07001831 // For PRIMA UMA frame translation is not enable yet.
1832 staDesc.ucSwFrameTXXlation = 1;
1833 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001834 staDesc.ucAddRmvLLC = 1;
1835
1836 // Initialize signatures and state
1837 staDesc.ucUcastSig = ucastSig;
1838 staDesc.ucBcastSig = bcastSig;
1839 staDesc.ucInitState = fAuthRequired ?
1840 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1841
Prathyushaf5442802012-12-12 13:58:11 -08001842 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1843
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301845 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1846 hdd_softap_rx_packet_cbk,
1847 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001848 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1849
1850 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1851 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301852 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001853 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001854 vosStatus, vosStatus );
1855 return vosStatus;
1856 }
1857
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001858 //Timer value should be in milliseconds
1859 if ( pHddCtx->cfg_ini->dynSplitscan &&
1860 ( VOS_TIMER_STATE_RUNNING !=
1861 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1862 {
1863 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1864 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1865 }
1866
Jeff Johnson295189b2012-06-20 16:38:30 -07001867 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1868 // then go to 'authenticated'. For all other authentication types (those that do
1869 // not require upper layer authentication) we can put TL directly into 'authenticated'
1870 // state.
1871
1872 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301873 pSapCtx->aStaInfo[staId].ucSTAId = staId;
1874 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 if ( !fAuthRequired )
1876 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301877 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1878 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301879 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001880
1881 // Connections that do not need Upper layer auth, transition TL directly
1882 // to 'Authenticated' state.
1883 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1884 WLANTL_STA_AUTHENTICATED );
1885
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301886 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001887 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1888 }
1889 else
1890 {
1891
c_hpothu6d1d2a32014-03-18 20:17:03 +05301892 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301893 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001894
1895 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1896 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301897 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001898
1899 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1900
1901 }
1902 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1903 if(pmonAdapter)
1904 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301905 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
1906 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 netif_carrier_on(pmonAdapter->dev);
1908 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301909 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001910 netif_tx_start_all_queues(pmonAdapter->dev);
1911 }
1912 netif_carrier_on(pAdapter->dev);
1913 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 netif_tx_start_all_queues(pAdapter->dev);
1916
1917 return( vosStatus );
1918}
1919
1920VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1921{
1922 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1923 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1924 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1925
1926
1927 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1928 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1929 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1930
1931 return vosStatus;
1932}
1933
1934VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1935{
1936 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1937}
1938
1939VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1940{
1941 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1942 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301943 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07001944
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301945 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1946 ptSapContext pSapCtx = NULL;
1947 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1948 if(pSapCtx == NULL){
1949 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1950 FL("psapCtx is NULL"));
1951 return VOS_STATUS_E_FAULT;
1952 }
1953
1954 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07001955 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05301956 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07001957 {
1958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1959 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
1960 return VOS_STATUS_E_PERM;
1961 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001962
1963 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
1964
Jeff Johnson43971f52012-07-17 12:26:56 -07001965 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301967 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001968 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 }
1970
1971 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
1972 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301973 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301975 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
1976 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1977 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301978 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001979 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301980 }
1981 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 }
1983
1984 return vosStatus;
1985}
1986
1987VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
1988{
1989 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
1990 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
1991 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001992
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301993 ptSapContext pSapCtx = NULL;
1994 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1995 if(pSapCtx == NULL){
1996 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1997 FL("psapCtx is NULL"));
1998 return VOS_STATUS_E_FAULT;
1999 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302000 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002001 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002002
Jeff Johnson43971f52012-07-17 12:26:56 -07002003 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302005 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002006 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002007 return VOS_STATUS_E_FAILURE;
2008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002009
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302010 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302012 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002013 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002014 return VOS_STATUS_E_FAILURE;
2015 }
2016
2017 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302018 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002019 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002020
Jeff Johnson43971f52012-07-17 12:26:56 -07002021 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302023 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002024 }
2025
c_hpothu6d1d2a32014-03-18 20:17:03 +05302026 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002027 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002028
2029 return vosStatus;
2030}
2031
2032
2033VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2034{
2035 v_U8_t i;
2036
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302037 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2038 ptSapContext pSapCtx = NULL;
2039 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2040 if(pSapCtx == NULL){
2041 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2042 FL("psapCtx is NULL"));
2043 return VOS_STATUS_E_FAULT;
2044 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2046 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302047 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2048 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 {
2050 *staId = i;
2051 return VOS_STATUS_SUCCESS;
2052 }
2053 }
2054
2055 return VOS_STATUS_E_FAILURE;
2056}
2057
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302058VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2059{
2060 v_U8_t i;
2061
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302062 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2063 ptSapContext pSapCtx = NULL;
2064 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2065 if(pSapCtx == NULL){
2066 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2067 FL("psapCtx is NULL"));
2068 return VOS_STATUS_E_FAULT;
2069 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302070 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2071 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302072 if (pSapCtx->aStaInfo[i].isUsed &&
2073 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302074 {
2075 *staId = i;
2076 return VOS_STATUS_SUCCESS;
2077 }
2078 }
2079
2080 return VOS_STATUS_E_FAILURE;
2081}