blob: bfd1171b674ce55e89cc355617a4a0ffed993f42 [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;
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530682 hdd_context_t *pHddCtx;
Mihir Shetef3473692014-06-27 15:13:20 +0530683
c_hpothu6d1d2a32014-03-18 20:17:03 +0530684 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700685 "%s: Transmission timeout occurred", __func__);
Mihir Shetef3473692014-06-27 15:13:20 +0530686
687 if ( NULL == pAdapter )
688 {
689 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
690 FL("pAdapter is NULL"));
691 VOS_ASSERT(0);
692 return;
693 }
694
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530695 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
696 if (pHddCtx->isLogpInProgress) {
697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
698 "%s:LOGP in Progress. Ignore!!!",__func__);
699 return;
700 }
701
Mihir Shetef3473692014-06-27 15:13:20 +0530702 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
703
704 for (i = 0; i < 8; i++)
705 {
706 txq = netdev_get_tx_queue(dev, i);
707 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
708 "Queue%d status: %d", i, netif_tx_queue_stopped(txq));
709 }
710
711 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
712 "carrier state: %d", netif_carrier_ok(dev));
713
714 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
715
Mihir Shete327c2ab2014-11-13 15:17:02 +0530716 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
717 HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
718 {
719 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
720 "%s: Request firmware for recovery",__func__);
721 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
722 }
Mihir Shetef3473692014-06-27 15:13:20 +0530723 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
724 HDD_SAP_TX_STALL_SSR_THRESHOLD)
725 {
726 // Driver could not recover, issue SSR
727 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
728 "%s: Cannot recover from Data stall Issue SSR",
729 __func__);
Mihir Shetefd62d9d2014-08-06 15:08:21 +0530730 WLANTL_FatalError();
Mihir Shetef3473692014-06-27 15:13:20 +0530731 return;
732 }
733
734 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
735 * every 5sec. The TL debug spits out a lot of information on the
736 * serial console, if it is called every time *hdd_tx_timeout* is
737 * called then we may get a watchdog bite on the Application
738 * processor, so ratelimit the TL debug logs.
739 */
740 if (__ratelimit(&hdd_softap_tx_timeout_rs))
741 {
742 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +0530743 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetef3473692014-06-27 15:13:20 +0530744 }
745
Jeff Johnson295189b2012-06-20 16:38:30 -0700746}
747
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530748void hdd_softap_tx_timeout(struct net_device *dev)
749{
750 vos_ssr_protect(__func__);
751 __hdd_softap_tx_timeout(dev);
752 vos_ssr_unprotect(__func__);
753 return;
754}
Jeff Johnson295189b2012-06-20 16:38:30 -0700755
756/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530757 @brief __hdd_softap_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700758 device TX/RX statistic
759
760 @param dev : [in] pointer to Libra network device
761
762 @return : pointer to net_device_stats structure
763 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530764struct net_device_stats* __hdd_softap_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700765{
766 hdd_adapter_t* priv = netdev_priv(dev);
767 return &priv->stats;
768}
769
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530770struct net_device_stats* hdd_softap_stats(struct net_device *dev)
771{
772 struct net_device_stats *priv_stats;
773 vos_ssr_protect(__func__);
774 priv_stats = __hdd_softap_stats(dev);
775 vos_ssr_unprotect(__func__);
776
777 return priv_stats;
778}
Jeff Johnson295189b2012-06-20 16:38:30 -0700779
780/**============================================================================
781 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
782 modules in HDD
783
784 @param pAdapter : [in] pointer to adapter context
785 @return : VOS_STATUS_E_FAILURE if any errors encountered
786 : VOS_STATUS_SUCCESS otherwise
787 ===========================================================================*/
788VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
789{
790 VOS_STATUS status = VOS_STATUS_SUCCESS;
791 v_SINT_t i = -1;
792 v_SIZE_t size = 0;
793
794 v_U8_t STAId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530795 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
796 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700797
798 v_U8_t pACWeights[] = {
799 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
800 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
801 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
802 HDD_SOFTAP_VO_WEIGHT_DEFAULT
803 };
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530804 pSapCtx = VOS_GET_SAP_CB(pVosContext);
805 if(pSapCtx == NULL){
806 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
807 FL("psapCtx is NULL"));
808 return VOS_STATUS_E_FAULT;
809 }
810
Leo Chang64d68bc2013-06-04 15:40:52 -0700811
Jeff Johnson295189b2012-06-20 16:38:30 -0700812 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530813 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700814
815 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
816
817 while (++i != NUM_TX_QUEUES)
818 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
819
820 /* Initial HDD buffer control / flow control fields*/
821 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
822
823 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
824 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
825 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
826 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
827
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530828 spin_lock_init( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700829
830 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
831 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530832 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700833 for (i = 0; i < NUM_TX_QUEUES; i ++)
834 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530835 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700836 }
837 }
838
Yue Ma3ede6052013-08-29 00:33:26 -0700839 /* Update the AC weights suitable for SoftAP mode of operation */
840 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
841
Kiet Lambcf38522013-10-26 18:28:27 +0530842 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700843 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530844 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530845 "%s: failed to start Traffic Monito timer ", __func__ );
846 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700847 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 return status;
849}
850
851/**============================================================================
852 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
853 modules in HDD
854
855 @param pAdapter : [in] pointer to adapter context
856 @return : VOS_STATUS_E_FAILURE if any errors encountered
857 : VOS_STATUS_SUCCESS otherwise
858 ===========================================================================*/
859VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
860{
861 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700862
Kiet Lambcf38522013-10-26 18:28:27 +0530863 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700864 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530865 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530866 "%s: Fail to Stop Traffic Monito timer", __func__ );
867 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700868 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700869
870 status = hdd_softap_flush_tx_queues(pAdapter);
871
872 return status;
873}
874
875/**============================================================================
876 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
877
878 @param pAdapter : [in] pointer to adapter context
879 @param STAId : [in] Station ID to deinit
880 @return : VOS_STATUS_E_FAILURE if any errors encountered
881 : VOS_STATUS_SUCCESS otherwise
882 ===========================================================================*/
883static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
884{
Jeff Johnson295189b2012-06-20 16:38:30 -0700885 v_U8_t i = -1;
886
887 hdd_list_node_t *anchor = NULL;
888
889 skb_list_node_t *pktNode = NULL;
890 struct sk_buff *skb = NULL;
891
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530892 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
893 ptSapContext pSapCtx = NULL;
894 pSapCtx = VOS_GET_SAP_CB(pVosContext);
895 if(pSapCtx == NULL){
896 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
897 FL("psapCtx is NULL"));
898 return VOS_STATUS_E_FAULT;
899 }
900 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530902 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700903 }
904
905 for (i = 0; i < NUM_TX_QUEUES; i ++)
906 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530907 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700908 while (true)
909 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530910 if (VOS_STATUS_E_EMPTY !=
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530911 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530912 &anchor))
Jeff Johnson295189b2012-06-20 16:38:30 -0700913 {
914 //If success then we got a valid packet from some AC
915 pktNode = list_entry(anchor, skb_list_node_t, anchor);
916 skb = pktNode->skb;
917 ++pAdapter->stats.tx_dropped;
918 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
919 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
920 kfree_skb(skb);
921 continue;
922 }
923
924 //current list is empty
925 break;
926 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530927 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700928 }
929
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530930 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700931}
932
933/**============================================================================
934 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
935 modules in HDD
936
937 @param pAdapter : [in] pointer to adapter context
938 @param STAId : [in] Station ID to deinit
939 @param pmacAddrSTA : [in] pointer to the MAC address of the station
940 @return : VOS_STATUS_E_FAILURE if any errors encountered
941 : VOS_STATUS_SUCCESS otherwise
942 ===========================================================================*/
943VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
944{
945 v_U8_t i = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530946 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
947 ptSapContext pSapCtx = NULL;
948 pSapCtx = VOS_GET_SAP_CB(pVosContext);
949 if(pSapCtx == NULL){
950 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
951 FL("psapCtx is NULL"));
952 return VOS_STATUS_E_FAULT;
953 }
954
955 spin_lock_bh( &pSapCtx->staInfo_lock );
956 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530958 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
959 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530960 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700961 return VOS_STATUS_E_FAILURE;
962 }
963
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530964 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 for (i = 0; i < NUM_TX_QUEUES; i ++)
966 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530967 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700968 }
969
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530970 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
971 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
972 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700973
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530974 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700975 return VOS_STATUS_SUCCESS;
976}
977
978/**============================================================================
979 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
980 modules in HDD
981
982 @param pAdapter : [in] pointer to adapter context
983 @param STAId : [in] Station ID to deinit
984 @return : VOS_STATUS_E_FAILURE if any errors encountered
985 : VOS_STATUS_SUCCESS otherwise
986 ===========================================================================*/
987VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
988{
989 VOS_STATUS status = VOS_STATUS_SUCCESS;
990 v_U8_t ac;
991 /**Track whether OS TX queue has been disabled.*/
992 v_BOOL_t txSuspended[NUM_TX_QUEUES];
993 v_U8_t tlAC;
994 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700995 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -0700996
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530997 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
998 ptSapContext pSapCtx = NULL;
999 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1000 if(pSapCtx == NULL){
1001 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1002 FL("psapCtx is NULL"));
1003 return VOS_STATUS_E_FAULT;
1004 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001005 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1006
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301007 spin_lock_bh( &pSapCtx->staInfo_lock );
1008 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001009 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301010 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001011 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301012 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001013 return VOS_STATUS_E_FAILURE;
1014 }
1015
1016 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1017
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301018 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1019 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001020 /* if this STA had any of its WMM TX queues suspended, then the
1021 associated queue on the network interface was disabled. check
1022 to see if that is the case, in which case we need to re-enable
1023 the interface queue. but we only do this if the BSS is running
1024 since, if the BSS is stopped, all of the interfaces have been
1025 stopped and should not be re-enabled */
1026
1027 if (BSS_START == pHostapdState->bssState)
1028 {
1029 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1030 {
1031 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301032 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001033 }
1034 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301035 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001036
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001037 /* re-init spin lock, since netdev can still open adapter until
1038 * driver gets unloaded
1039 */
1040 for (i = 0; i < NUM_TX_QUEUES; i ++)
1041 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301042 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001043 HDD_TX_QUEUE_MAX_LEN);
1044 }
1045
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 if (BSS_START == pHostapdState->bssState)
1047 {
1048 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1049 {
1050 if (txSuspended[ac])
1051 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301052 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001053 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 netif_wake_subqueue(pAdapter->dev, ac);
1055 }
1056 }
1057 }
1058
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301059 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001060 return status;
1061}
1062
1063/**============================================================================
1064 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1065 modules in HDD
1066
1067 @param pAdapter : [in] pointer to adapter context
1068 @return : VOS_STATUS_E_FAILURE if any errors encountered
1069 : VOS_STATUS_SUCCESS otherwise
1070 ===========================================================================*/
1071VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1072{
1073 return hdd_softap_flush_tx_queues(pAdapter);
1074}
1075
1076/**============================================================================
1077 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1078 to indicate that a packet has been transmitted across the bus
1079 succesfully. OS packet resources can be released after this cbk.
1080
1081 @param vosContext : [in] pointer to VOS context
1082 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1083 @param vosStatusIn : [in] status of the transmission
1084
1085 @return : VOS_STATUS_E_FAILURE if any errors encountered
1086 : VOS_STATUS_SUCCESS otherwise
1087 ===========================================================================*/
1088VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1089 vos_pkt_t *pVosPacket,
1090 VOS_STATUS vosStatusIn )
1091{
1092 VOS_STATUS status = VOS_STATUS_SUCCESS;
1093 hdd_adapter_t *pAdapter = NULL;
1094 void* pOsPkt = NULL;
1095
1096 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1097 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301098 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1099 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 return VOS_STATUS_E_FAILURE;
1101 }
1102
1103 //Return the skb to the OS
1104 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001105 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001106 {
1107 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301108 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1109 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 vos_pkt_return_packet( pVosPacket );
1111 return VOS_STATUS_E_FAILURE;
1112 }
1113
1114 //Get the Adapter context.
1115 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
1116 if(pAdapter == NULL)
1117 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301118 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1119 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 }
1121 else
1122 {
1123 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1124 }
1125
1126 kfree_skb((struct sk_buff *)pOsPkt);
1127
1128 //Return the VOS packet resources.
1129 status = vos_pkt_return_packet( pVosPacket );
1130 if(!VOS_IS_STATUS_SUCCESS( status ))
1131 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301132 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1133 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 }
1135
1136 return status;
1137}
1138
1139
1140/**============================================================================
1141 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1142 fetch a packet for transmission.
1143
1144 @param vosContext : [in] pointer to VOS context
1145 @param staId : [in] Station for which TL is requesting a pkt
1146 @param ac : [in] access category requested by TL
1147 @param pVosPacket : [out] pointer to VOS packet packet pointer
1148 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1149
1150 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1151 : VOS_STATUS_E_FAILURE if any errors encountered
1152 : VOS_STATUS_SUCCESS otherwise
1153 ===========================================================================*/
1154VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1155 v_U8_t *pStaId,
1156 WLANTL_ACEnumType ac,
1157 vos_pkt_t **ppVosPacket,
1158 WLANTL_MetaInfoType *pPktMetaInfo )
1159{
1160 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1161 hdd_adapter_t *pAdapter = NULL;
1162 hdd_list_node_t *anchor = NULL;
1163 skb_list_node_t *pktNode = NULL;
1164 struct sk_buff *skb = NULL;
1165 vos_pkt_t *pVosPacket = NULL;
1166 v_MACADDR_t* pDestMacAddress = NULL;
1167 v_TIME_t timestamp;
1168 v_SIZE_t size = 0;
1169 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1170 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001171 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301172 v_CONTEXT_t pVosContext = NULL;
1173 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 //Sanity check on inputs
1175 if ( ( NULL == vosContext ) ||
1176 ( NULL == pStaId ) ||
1177 ( NULL == ppVosPacket ) ||
1178 ( NULL == pPktMetaInfo ) )
1179 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301180 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1181 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001182 return VOS_STATUS_E_FAILURE;
1183 }
1184
1185 //Get the HDD context.
1186 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1187 if ( NULL == pHddCtx )
1188 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301189 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1190 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001191 return VOS_STATUS_E_FAILURE;
1192 }
1193
Jeff Johnsonb156c922013-12-05 17:19:46 -08001194 STAId = *pStaId;
1195 if (STAId >= WLAN_MAX_STA_COUNT)
1196 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301197 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001198 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1199 return VOS_STATUS_E_FAILURE;
1200 }
1201
1202 pAdapter = pHddCtx->sta_to_adapter[STAId];
1203 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001204 {
1205 VOS_ASSERT(0);
1206 return VOS_STATUS_E_FAILURE;
1207 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301208 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1209 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1210 if(pSapCtx == NULL){
1211 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1212 FL("psapCtx is NULL"));
1213 return VOS_STATUS_E_FAULT;
1214 }
1215
1216 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001217 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301218 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001219 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1220 return VOS_STATUS_E_FAILURE;
1221 }
1222
Leo Chang64d68bc2013-06-04 15:40:52 -07001223 /* Monitor traffic */
1224 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1225 {
1226 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1227 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1228 {
1229 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1230 /* It was IDLE mode,
1231 * this is new state, then switch mode from suspend to resume */
1232 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1233 {
1234 hdd_set_wlan_suspend_mode(0);
1235 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1236 pHddCtx->cfg_ini->trafficIdleTimeout);
1237 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1238 }
1239 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1240 }
1241 }
1242
Jeff Johnson295189b2012-06-20 16:38:30 -07001243 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1244
Jeff Johnson295189b2012-06-20 16:38:30 -07001245 *ppVosPacket = NULL;
1246
1247 //Make sure the AC being asked for is sane
1248 if( ac > WLANTL_MAX_AC || ac < 0)
1249 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301250 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001251 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001252 return VOS_STATUS_E_FAILURE;
1253 }
1254
1255 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1256
c_hpothu6d1d2a32014-03-18 20:17:03 +05301257 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001258 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001259
1260 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1261 //This simplifies the locking and unlocking of Tx queue
1262 status = vos_pkt_wrap_data_packet( &pVosPacket,
1263 VOS_PKT_TYPE_TX_802_3_DATA,
1264 NULL, //OS Pkt is not being passed
1265 hdd_softap_tx_low_resource_cbk,
1266 pAdapter );
1267
1268 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1269 {
1270 //Remember VOS is in a low resource situation
1271 pAdapter->isVosOutOfResource = VOS_TRUE;
1272 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301273 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001274 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001275 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1276 return VOS_STATUS_E_FAILURE;
1277 }
1278
1279 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1280 as the other branch does.
1281 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301282 spin_lock_bh( &pSapCtx->staInfo_lock );
1283 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1284 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001285
1286 if (0 == size)
1287 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301288 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1289 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001290 vos_pkt_return_packet(pVosPacket);
1291 return VOS_STATUS_E_EMPTY;
1292 }
1293
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301294 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1295 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1296 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001297
c_hpothu6d1d2a32014-03-18 20:17:03 +05301298 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001299 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001300
1301 if(VOS_STATUS_SUCCESS == status)
1302 {
1303 //If success then we got a valid packet from some AC
1304 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1305 skb = pktNode->skb;
1306 }
1307 else
1308 {
1309 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301310 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001311 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001312 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001313 vos_pkt_return_packet(pVosPacket);
1314 return VOS_STATUS_E_FAILURE;
1315 }
1316
1317 //Attach skb to VOS packet.
1318 status = vos_pkt_set_os_packet( pVosPacket, skb );
1319 if (status != VOS_STATUS_SUCCESS)
1320 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301321 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001322 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 vos_pkt_return_packet(pVosPacket);
1324 ++pAdapter->stats.tx_dropped;
1325 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1326 kfree_skb(skb);
1327 return VOS_STATUS_E_FAILURE;
1328 }
1329
1330 //Just being paranoid. To be removed later
1331 if(pVosPacket == NULL)
1332 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301333 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001334 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001335 ++pAdapter->stats.tx_dropped;
1336 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1337 kfree_skb(skb);
1338 return VOS_STATUS_E_FAILURE;
1339 }
1340
1341 //Return VOS packet to TL;
1342 *ppVosPacket = pVosPacket;
1343
1344 //Fill out the meta information needed by TL
1345 //FIXME This timestamp is really the time stamp of wrap_data_packet
1346 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1347 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1348 if ( 1 < size )
1349 {
1350 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1351 }
1352 else
1353 {
1354 pPktMetaInfo->bMorePackets = 0;
1355 }
1356
1357 pPktMetaInfo->ucIsEapol = 0;
1358
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301359 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 {
1361 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1362 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301363 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001364 "%s: VOS packet is EAPOL packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001365 pPktMetaInfo->ucIsEapol = 1;
1366 }
1367 }
1368
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301369 if ((NULL != pHddCtx) &&
1370 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001371 {
1372 proto_type = vos_pkt_get_proto_type(skb,
1373 pHddCtx->cfg_ini->gEnableDebugLog);
1374 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1375 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001377 "SAP TX EAPOL");
1378 }
1379 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1380 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001382 "SAP TX DHCP");
1383 }
1384 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001385//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 {
1387 pPktMetaInfo->ucUP = pktNode->userPriority;
1388 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1389 }
1390
1391 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1392 //Extract the destination address from ethernet frame
1393 pDestMacAddress = (v_MACADDR_t*)skb->data;
1394
1395 // we need 802.3 to 802.11 frame translation
1396 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1397 pPktMetaInfo->ucDisableFrmXtl = 0;
1398 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1399 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1400
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301401 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001402 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1403 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301404 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001405 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301406 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301408 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1409 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001410 }
1411
1412 // We're giving the packet to TL so consider it transmitted from
1413 // a statistics perspective. We account for it here instead of
1414 // when the packet is returned for two reasons. First, TL will
1415 // manipulate the skb to the point where the len field is not
1416 // accurate, leading to inaccurate byte counts if we account for
1417 // it later. Second, TL does not provide any feedback as to
1418 // whether or not the packet was successfully sent over the air,
1419 // so the packet counts will be the same regardless of where we
1420 // account for them
1421 pAdapter->stats.tx_bytes += skb->len;
1422 ++pAdapter->stats.tx_packets;
1423 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1424 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301425 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001426
c_hpothu6d1d2a32014-03-18 20:17:03 +05301427 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001428 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001429
1430 return status;
1431}
1432
1433
1434/**============================================================================
1435 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1436 case where VOS packets are not available at the time of the call to get
1437 packets. This callback function is invoked by VOS when packets are
1438 available.
1439
1440 @param pVosPacket : [in] pointer to VOS packet
1441 @param userData : [in] opaque user data that was passed initially
1442
1443 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1444 : VOS_STATUS_SUCCESS otherwise
1445 =============================================================================*/
1446VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1447 v_VOID_t *userData )
1448{
1449 VOS_STATUS status;
1450 v_SINT_t i = 0;
1451 v_SIZE_t size = 0;
1452 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1453 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301454 v_CONTEXT_t pVosContext = NULL;
1455 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001456 if(pAdapter == NULL)
1457 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301458 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1459 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 return VOS_STATUS_E_FAILURE;
1461 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301462 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1463 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1464 if(pSapCtx == NULL){
1465 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1466 FL("psapCtx is NULL"));
1467 return VOS_STATUS_E_FAULT;
1468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001469 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1470 //situation. Here we will only signal TL that there is a pending data for a STA.
1471 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1472 vos_pkt_return_packet( pVosPacket );
1473
1474 pAdapter->isVosOutOfResource = VOS_FALSE;
1475
1476 // Indicate to TL that there is pending data if a queue is non empty.
1477 // This Code wasnt included in earlier version which resulted in
1478 // Traffic stalling
1479 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1480 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301481 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1482 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001483 {
1484 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1485 {
1486 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301487 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001488 if ( size > 0 )
1489 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301490 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1491 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 (WLANTL_ACEnumType)i );
1493 if( !VOS_IS_STATUS_SUCCESS( status ) )
1494 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301495 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1496 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001497 }
1498 }
1499 }
1500 }
1501 }
1502 return VOS_STATUS_SUCCESS;
1503}
1504
1505
1506/**============================================================================
1507 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1508 TL will call this to notify the HDD when one or more packets were
1509 received for a registered STA.
1510
1511 @param vosContext : [in] pointer to VOS context
1512 @param pVosPacketChain : [in] pointer to VOS packet chain
1513 @param staId : [in] Station Id (Adress 1 Index)
1514 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1515
1516 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1517 : VOS_STATUS_SUCCESS otherwise
1518 ===========================================================================*/
1519VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1520 vos_pkt_t *pVosPacketChain,
1521 v_U8_t staId,
1522 WLANTL_RxMetaInfoType* pRxMetaInfo )
1523{
1524 hdd_adapter_t *pAdapter = NULL;
1525 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1526 int rxstat;
1527 struct sk_buff *skb = NULL;
1528 vos_pkt_t* pVosPacket;
1529 vos_pkt_t* pNextVosPacket;
1530 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001531 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001532
1533 //Sanity check on inputs
1534 if ( ( NULL == vosContext ) ||
1535 ( NULL == pVosPacketChain ) ||
1536 ( NULL == pRxMetaInfo ) )
1537 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301538 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1539 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001540 return VOS_STATUS_E_FAILURE;
1541 }
1542
1543 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1544 if ( NULL == pHddCtx )
1545 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301546 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1547 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001548 return VOS_STATUS_E_FAILURE;
1549 }
1550
1551 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301552 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001553 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301554 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1555 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001556 VOS_ASSERT(0);
1557 return VOS_STATUS_E_FAILURE;
1558 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001559
1560 /* Monitor traffic */
1561 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1562 {
1563 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1564 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1565 {
1566 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1567 /* It was IDLE mode,
1568 * this is new state, then switch mode from suspend to resume */
1569 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1570 {
1571 hdd_set_wlan_suspend_mode(0);
1572 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1573 pHddCtx->cfg_ini->trafficIdleTimeout);
1574 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1575 }
1576 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1577 }
1578 }
1579
Jeff Johnson295189b2012-06-20 16:38:30 -07001580 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1581
1582 // walk the chain until all are processed
1583 pVosPacket = pVosPacketChain;
1584 do
1585 {
1586 // get the pointer to the next packet in the chain
1587 // (but don't unlink the packet since we free the entire chain later)
1588 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1589
1590 // both "success" and "empty" are acceptable results
1591 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1592 {
1593 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301594 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1595 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001596 return VOS_STATUS_E_FAILURE;
1597 }
1598
1599 // Extract the OS packet (skb).
1600 // Tell VOS to detach the OS packet from the VOS packet
1601 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
1602 if(!VOS_IS_STATUS_SUCCESS( status ))
1603 {
1604 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301605 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1606 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 return VOS_STATUS_E_FAILURE;
1608 }
1609
1610 //hdd_softap_dump_sk_buff(skb);
1611
1612 skb->dev = pAdapter->dev;
1613
1614 if(skb->dev == NULL) {
1615
c_hpothu6d1d2a32014-03-18 20:17:03 +05301616 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1617 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001618 return VOS_STATUS_E_FAILURE;
1619 }
1620 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1621 ++pAdapter->stats.rx_packets;
1622 pAdapter->stats.rx_bytes += skb->len;
1623
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001624 if (pHddCtx->cfg_ini->gEnableDebugLog)
1625 {
1626 proto_type = vos_pkt_get_proto_type(skb,
1627 pHddCtx->cfg_ini->gEnableDebugLog);
1628 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1629 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001631 "SAP RX EAPOL");
1632 }
1633 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1634 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001636 "SAP RX DHCP");
1637 }
1638 }
1639
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1641 {
1642 //MC/BC packets. Duplicate a copy of packet
1643 struct sk_buff *pSkbCopy;
1644 hdd_ap_ctx_t *pHddApCtx;
1645
1646 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1647 if (!(pHddApCtx->apDisableIntraBssFwd))
1648 {
1649 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1650 if (pSkbCopy)
1651 {
1652 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1653 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1654 }
1655 }
1656 else
1657 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301658 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001659 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001660 }
1661
1662
1663 } //(WLAN_RX_BCMC_STA_ID == staId)
1664
1665 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1666 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1667 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301668 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001669 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301670 if ((NULL != pHddCtx) &&
1671 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301672 {
1673 hdd_dump_dhcp_pkt(skb, RX_PATH);
1674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001675
1676 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001677 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001678#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07001679#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07001680 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07001681#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001682#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001683 rxstat = netif_rx_ni(skb);
1684 if (NET_RX_SUCCESS == rxstat)
1685 {
1686 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001687 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001688 }
1689 else
1690 {
1691 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1692 }
1693 }
1694 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1695 {
1696 kfree_skb(skb);
1697 }
1698 else
1699 {
1700 //loopback traffic
1701 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1702 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1703 }
1704
1705 // now process the next packet in the chain
1706 pVosPacket = pNextVosPacket;
1707
1708 } while (pVosPacket);
1709
1710 //Return the entire VOS packet chain to the resource pool
1711 status = vos_pkt_return_packet( pVosPacketChain );
1712 if(!VOS_IS_STATUS_SUCCESS( status ))
1713 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301714 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1715 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 }
1717
1718 pAdapter->dev->last_rx = jiffies;
1719
1720 return status;
1721}
1722
1723VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1724{
1725 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301726 hdd_context_t *pHddCtx;
1727 if (NULL == pAdapter)
1728 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301729 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301730 "%s: pAdapter is NULL", __func__);
1731 return VOS_STATUS_E_INVAL;
1732 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001733
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301734 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1735 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301736 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301737 "%s: Invalid pAdapter magic", __func__);
1738 return VOS_STATUS_E_INVAL;
1739 }
1740
1741 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301742 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001743 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301744 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001745 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1746 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301747 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001749 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001750 staId, vosStatus, vosStatus );
1751 }
1752
1753 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1754 if( VOS_STATUS_E_FAILURE == vosStatus )
1755 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301756 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001757 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001758 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001759 staId, vosStatus, vosStatus );
1760 return( vosStatus );
1761 }
1762
1763 pHddCtx->sta_to_adapter[staId] = NULL;
1764
1765 return( vosStatus );
1766}
1767
1768VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1769 v_BOOL_t fAuthRequired,
1770 v_BOOL_t fPrivacyBit,
1771 v_U8_t staId,
1772 v_U8_t ucastSig,
1773 v_U8_t bcastSig,
1774 v_MACADDR_t *pPeerMacAddress,
1775 v_BOOL_t fWmmEnabled )
1776{
1777 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001778 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1780 hdd_adapter_t *pmonAdapter = NULL;
1781
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301782 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1783 ptSapContext pSapCtx = NULL;
1784 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1785 if(pSapCtx == NULL){
1786 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1787 FL("psapCtx is NULL"));
1788 return VOS_STATUS_E_FAULT;
1789 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 //eCsrEncryptionType connectedCipherAlgo;
1791 //v_BOOL_t fConnected;
1792
1793 /*
1794 * Clean up old entry if it is not cleaned up properly
1795 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301796 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301798 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001799 "clean up old entry for STA %d", staId);
1800 hdd_softap_DeregisterSTA( pAdapter, staId );
1801 }
1802
1803 // Get the Station ID from the one saved during the assocation.
1804
1805 staDesc.ucSTAId = staId;
1806
1807
1808 /*Save the pAdapter Pointer for this staId*/
1809 pHddCtx->sta_to_adapter[staId] = pAdapter;
1810
1811 staDesc.wSTAType = WLAN_STA_SOFTAP;
1812
1813 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1814 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1815 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1816
c_hpothu6d1d2a32014-03-18 20:17:03 +05301817 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001818 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301819 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001820 "station mac " MAC_ADDRESS_STR,
1821 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301822 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001823 "BSSIDforIBSS " MAC_ADDRESS_STR,
1824 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301825 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001826 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1827 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001828
1829 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1830
Jeff Johnson295189b2012-06-20 16:38:30 -07001831 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301832 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001833 "HDD SOFTAP register TL QoS_enabled=%d",
1834 staDesc.ucQosEnabled );
1835
1836 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1837
1838
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 // For PRIMA UMA frame translation is not enable yet.
1840 staDesc.ucSwFrameTXXlation = 1;
1841 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001842 staDesc.ucAddRmvLLC = 1;
1843
1844 // Initialize signatures and state
1845 staDesc.ucUcastSig = ucastSig;
1846 staDesc.ucBcastSig = bcastSig;
1847 staDesc.ucInitState = fAuthRequired ?
1848 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1849
Prathyushaf5442802012-12-12 13:58:11 -08001850 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1851
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301853 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1854 hdd_softap_rx_packet_cbk,
1855 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001856 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1857
1858 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1859 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301860 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001861 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001862 vosStatus, vosStatus );
1863 return vosStatus;
1864 }
1865
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001866 //Timer value should be in milliseconds
1867 if ( pHddCtx->cfg_ini->dynSplitscan &&
1868 ( VOS_TIMER_STATE_RUNNING !=
1869 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1870 {
1871 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1872 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1873 }
1874
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1876 // then go to 'authenticated'. For all other authentication types (those that do
1877 // not require upper layer authentication) we can put TL directly into 'authenticated'
1878 // state.
1879
1880 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301881 pSapCtx->aStaInfo[staId].ucSTAId = staId;
1882 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001883 if ( !fAuthRequired )
1884 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301885 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1886 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301887 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001888
1889 // Connections that do not need Upper layer auth, transition TL directly
1890 // to 'Authenticated' state.
1891 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1892 WLANTL_STA_AUTHENTICATED );
1893
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301894 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001895 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1896 }
1897 else
1898 {
1899
c_hpothu6d1d2a32014-03-18 20:17:03 +05301900 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301901 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001902
1903 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1904 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301905 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001906
1907 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1908
1909 }
1910 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1911 if(pmonAdapter)
1912 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301913 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
1914 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 netif_carrier_on(pmonAdapter->dev);
1916 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301917 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001918 netif_tx_start_all_queues(pmonAdapter->dev);
1919 }
1920 netif_carrier_on(pAdapter->dev);
1921 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301922 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 netif_tx_start_all_queues(pAdapter->dev);
1924
1925 return( vosStatus );
1926}
1927
1928VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1929{
1930 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1931 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1932 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1933
1934
1935 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1936 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1937 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1938
1939 return vosStatus;
1940}
1941
1942VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1943{
1944 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1945}
1946
1947VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1948{
1949 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1950 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301951 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07001952
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301953 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1954 ptSapContext pSapCtx = NULL;
1955 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1956 if(pSapCtx == NULL){
1957 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1958 FL("psapCtx is NULL"));
1959 return VOS_STATUS_E_FAULT;
1960 }
1961
1962 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07001963 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05301964 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07001965 {
1966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1967 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
1968 return VOS_STATUS_E_PERM;
1969 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001970
1971 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
1972
Jeff Johnson43971f52012-07-17 12:26:56 -07001973 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301975 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001976 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 }
1978
1979 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
1980 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301981 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301983 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
1984 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1985 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301986 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001987 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301988 }
1989 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 }
1991
1992 return vosStatus;
1993}
1994
1995VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
1996{
1997 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
1998 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
1999 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002000
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302001 ptSapContext pSapCtx = NULL;
2002 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2003 if(pSapCtx == NULL){
2004 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2005 FL("psapCtx is NULL"));
2006 return VOS_STATUS_E_FAULT;
2007 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302008 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002009 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002010
Jeff Johnson43971f52012-07-17 12:26:56 -07002011 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302013 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002014 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 return VOS_STATUS_E_FAILURE;
2016 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002017
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302018 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302020 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002021 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 return VOS_STATUS_E_FAILURE;
2023 }
2024
2025 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302026 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002027 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002028
Jeff Johnson43971f52012-07-17 12:26:56 -07002029 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302031 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002032 }
2033
c_hpothu6d1d2a32014-03-18 20:17:03 +05302034 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002035 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002036
2037 return vosStatus;
2038}
2039
2040
2041VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2042{
2043 v_U8_t i;
2044
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302045 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2046 ptSapContext pSapCtx = NULL;
2047 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2048 if(pSapCtx == NULL){
2049 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2050 FL("psapCtx is NULL"));
2051 return VOS_STATUS_E_FAULT;
2052 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2054 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302055 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2056 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 {
2058 *staId = i;
2059 return VOS_STATUS_SUCCESS;
2060 }
2061 }
2062
2063 return VOS_STATUS_E_FAILURE;
2064}
2065
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302066VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2067{
2068 v_U8_t i;
2069
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302070 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2071 ptSapContext pSapCtx = NULL;
2072 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2073 if(pSapCtx == NULL){
2074 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2075 FL("psapCtx is NULL"));
2076 return VOS_STATUS_E_FAULT;
2077 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302078 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2079 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302080 if (pSapCtx->aStaInfo[i].isUsed &&
2081 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302082 {
2083 *staId = i;
2084 return VOS_STATUS_SUCCESS;
2085 }
2086 }
2087
2088 return VOS_STATUS_E_FAILURE;
2089}