blob: 113c140fa8a108b49f75692aeb7cebcde51e46cf [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumantha Reddy Pothula07050f52015-02-24 11:36:12 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
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
Jeff Johnson295189b2012-06-20 16:38:30 -070033
34 ==========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070035
36/*---------------------------------------------------------------------------
37 Include files
38 -------------------------------------------------------------------------*/
39#include <linux/semaphore.h>
40#include <wlan_hdd_tx_rx.h>
41#include <wlan_hdd_softap_tx_rx.h>
42#include <wlan_hdd_dp_utils.h>
43#include <wlan_qct_tl.h>
44#include <linux/netdevice.h>
45#include <linux/skbuff.h>
46#include <linux/etherdevice.h>
47//#include <vos_list.h>
48#include <vos_types.h>
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053049#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070050#include <aniGlobal.h>
51#include <halTypes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070052#include <net/ieee80211_radiotap.h>
Mihir Shetef3473692014-06-27 15:13:20 +053053#include <linux/ratelimit.h>
54#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
55#include <soc/qcom/subsystem_restart.h>
56#else
57#include <mach/subsystem_restart.h>
58#endif
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053059#include "sapInternal.h"
Mihir Shete5d148f12014-12-16 17:54:49 +053060#include "wlan_hdd_trace.h"
Sushant Kaushika8073312015-05-04 17:33:52 +053061#include "vos_diag_core_event.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062/*---------------------------------------------------------------------------
63 Preprocessor definitions and constants
64 -------------------------------------------------------------------------*/
65
66/*---------------------------------------------------------------------------
67 Type declarations
68 -------------------------------------------------------------------------*/
69
70/*---------------------------------------------------------------------------
71 Function definitions and documenation
72 -------------------------------------------------------------------------*/
73#if 0
74static void hdd_softap_dump_sk_buff(struct sk_buff * skb)
75{
c_hpothu6d1d2a32014-03-18 20:17:03 +053076 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head);
77 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data);
78 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail);
79 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end);
80 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
81 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
82 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 -070083
c_hpothu6d1d2a32014-03-18 20:17:03 +053084 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 -070085 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
86 skb->data[5], skb->data[6], skb->data[7]);
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[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
89 skb->data[13], skb->data[14], skb->data[15]);
90}
91#endif
Leo Chang64d68bc2013-06-04 15:40:52 -070092
93extern void hdd_set_wlan_suspend_mode(bool suspend);
94
Mihir Shetef3473692014-06-27 15:13:20 +053095#define HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ
96#define HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST 1
97#define HDD_SAP_TX_STALL_SSR_THRESHOLD 5
Mihir Shete327c2ab2014-11-13 15:17:02 +053098#define HDD_SAP_TX_STALL_RECOVERY_THRESHOLD HDD_SAP_TX_STALL_SSR_THRESHOLD - 2
Mihir Shetef3473692014-06-27 15:13:20 +053099
100static DEFINE_RATELIMIT_STATE(hdd_softap_tx_timeout_rs, \
101 HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL, \
102 HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST);
103
Leo Chang64d68bc2013-06-04 15:40:52 -0700104/**============================================================================
105 @brief hdd_softap_traffic_monitor_timeout_handler() -
106 SAP/P2P GO traffin monitor timeout handler function
107 If no traffic during programmed time, trigger suspand mode
108
109 @param pUsrData : [in] pointer to hdd context
110 @return : NONE
111 ===========================================================================*/
112void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData )
113{
114 hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData;
115 v_TIME_t currentTS;
116
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530117 ENTER();
118 if (0 != (wlan_hdd_validate_context(pHddCtx)))
Leo Chang64d68bc2013-06-04 15:40:52 -0700119 {
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530120 return;
Leo Chang64d68bc2013-06-04 15:40:52 -0700121 }
122
123 currentTS = vos_timer_get_system_time();
124 if (pHddCtx->cfg_ini->trafficIdleTimeout <
125 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
126 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530127 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530128 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -0700129 hdd_set_wlan_suspend_mode(1);
130 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
131 }
132 else
133 {
134 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
135 pHddCtx->cfg_ini->trafficIdleTimeout);
136 }
137
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530138 EXIT();
Leo Chang64d68bc2013-06-04 15:40:52 -0700139 return;
140}
141
Kiet Lambcf38522013-10-26 18:28:27 +0530142VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter )
143{
144
145 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
146 VOS_STATUS status = VOS_STATUS_SUCCESS;
147
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530148 ENTER();
Kiet Lambcf38522013-10-26 18:28:27 +0530149 status = wlan_hdd_validate_context(pHddCtx);
Kiet Lambcf38522013-10-26 18:28:27 +0530150 if (0 != status)
151 {
Kiet Lambcf38522013-10-26 18:28:27 +0530152 return status;
153 }
154
155 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
156 (!pHddCtx->traffic_monitor.isInitialized))
157 {
158 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
159 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
160 VOS_TIMER_TYPE_SW,
161 hdd_softap_traffic_monitor_timeout_handler,
162 pHddCtx);
163 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
164 pHddCtx->traffic_monitor.isInitialized = 1;
165 pHddCtx->traffic_monitor.lastFrameTs = 0;
166 /* Start traffic monitor timer here
167 * If no AP assoc, immediatly go into suspend */
c_hpothu6d1d2a32014-03-18 20:17:03 +0530168 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530169 "%s Start Traffic Monitor Timer", __func__);
170 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
171 pHddCtx->cfg_ini->trafficIdleTimeout);
172 }
173 else
174 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530175 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530176 "%s Traffic Monitor is not Enable in ini file", __func__);
177 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530178
179 EXIT();
Kiet Lambcf38522013-10-26 18:28:27 +0530180 return status;
181}
182
183VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter )
184{
185 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
186 VOS_STATUS status = VOS_STATUS_SUCCESS;
187
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530188 ENTER();
Kiet Lambcf38522013-10-26 18:28:27 +0530189 status = wlan_hdd_validate_context(pHddCtx);
Kiet Lamae69d7a2013-11-08 14:38:04 +0530190 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530191 {
Kiet Lambcf38522013-10-26 18:28:27 +0530192 return status;
193 }
194
195 if (pHddCtx->traffic_monitor.isInitialized)
196 {
197 if (VOS_TIMER_STATE_STOPPED !=
198 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
199 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530200 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530201 "%s Stop Traffic Monitor Timer", __func__);
202 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
203 }
c_hpothu6d1d2a32014-03-18 20:17:03 +0530204 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530205 "%s Destroy Traffic Monitor Timer", __func__);
206 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
207 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
208 pHddCtx->traffic_monitor.isInitialized = 0;
209 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530210 EXIT();
Kiet Lamae69d7a2013-11-08 14:38:04 +0530211 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530212}
213
Jeff Johnson295189b2012-06-20 16:38:30 -0700214/**============================================================================
215 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
216
217 @param pAdapter : [in] pointer to adapter context
218 @return : VOS_STATUS_E_FAILURE if any errors encountered
219 : VOS_STATUS_SUCCESS otherwise
220 ===========================================================================*/
221static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
222{
223 VOS_STATUS status = VOS_STATUS_SUCCESS;
224 v_SINT_t i = -1;
225 v_U8_t STAId = 0;
226 hdd_list_node_t *anchor = NULL;
227 skb_list_node_t *pktNode = NULL;
228 struct sk_buff *skb = NULL;
229
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530230 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
231 ptSapContext pSapCtx = NULL;
232 pSapCtx = VOS_GET_SAP_CB(pVosContext);
233 if(pSapCtx == NULL){
234 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
235 FL("psapCtx is NULL"));
236 return VOS_STATUS_E_FAULT;
237 }
238 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
240 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530241 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700242 {
243 continue;
244 }
245
246 for (i = 0; i < NUM_TX_QUEUES; i ++)
247 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530248 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700249 while (true)
250 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530251 status = hdd_list_remove_front ( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
Jeff Johnson295189b2012-06-20 16:38:30 -0700252
253 if (VOS_STATUS_E_EMPTY != status)
254 {
255 //If success then we got a valid packet from some AC
256 pktNode = list_entry(anchor, skb_list_node_t, anchor);
257 skb = pktNode->skb;
258 ++pAdapter->stats.tx_dropped;
259 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
260 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
261 kfree_skb(skb);
262 continue;
263 }
264
265 //current list is empty
266 break;
267 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530268 pSapCtx->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
269 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530271 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 }
273
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530274 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700275
276 return status;
277}
278
279/**============================================================================
280 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
281 transmitting packets. There are 2 versions of this function. One that uses
282 locked queue and other that uses lockless queues. Both have been retained to
283 do some performance testing
284
285 @param skb : [in] pointer to OS packet (sk_buff)
286 @param dev : [in] pointer to Libra network device
287
288 @return : NET_XMIT_DROP if packets are dropped
289 : NET_XMIT_SUCCESS if packet is enqueued succesfully
290 ===========================================================================*/
291int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
292{
293 VOS_STATUS status;
294 WLANTL_ACEnumType ac = WLANTL_AC_BE;
295 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
296 skb_list_node_t *pktNode = NULL;
297 v_SIZE_t pktListSize = 0;
298 v_BOOL_t txSuspended = VOS_FALSE;
299 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
300 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530301 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302 vos_list_node_t *anchor = NULL;
303 v_U8_t STAId = WLAN_MAX_STA_COUNT;
304 //Extract the destination address from ethernet frame
305 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
306 int os_status = NETDEV_TX_OK;
Mihir Shetef8f74532014-12-04 11:53:34 +0530307 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700308
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530309 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
310 ptSapContext pSapCtx = NULL;
311 pSapCtx = VOS_GET_SAP_CB(pVosContext);
312 if(pSapCtx == NULL){
313 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
314 FL("psapCtx is NULL"));
315 ++pAdapter->stats.tx_dropped;
316 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
317 kfree_skb(skb);
318 return os_status;
319 }
320
Ratheesh S Pe8f00c62015-08-20 13:03:01 +0530321 if (pHddCtx == NULL)
322 {
323 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
324 FL("pHddCtx is NULL"));
325 goto xmit_done;
326 }
327
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 pDestMacAddress = (v_MACADDR_t*)skb->data;
329
330 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
331
c_hpothu6d1d2a32014-03-18 20:17:03 +0530332 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700333 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530335 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
337 {
338 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
339 //ID used for BC/MC traffic. The station id is registered to TL as well.
340 STAId = pHddApCtx->uBCStaId;
341
342 /* Setting priority for broadcast packets which doesn't go to select_queue function */
343 skb->priority = SME_QOS_WMM_UP_BE;
344 skb->queue_mapping = HDD_LINUX_AC_BE;
345
c_hpothu6d1d2a32014-03-18 20:17:03 +0530346 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800347 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700348 }
349 else
350 {
Nirav Shah7e3c8132015-06-22 23:51:42 +0530351 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 if (STAId == HDD_WLAN_INVALID_STA_ID)
353 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530354 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700355 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 ++pAdapter->stats.tx_dropped;
357 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
358 kfree_skb(skb);
359 goto xmit_done;
360 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530361 else if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700362 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530363 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
364 "%s: STA %d is unregistered", __func__, STAId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 ++pAdapter->stats.tx_dropped;
366 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
367 kfree_skb(skb);
368 goto xmit_done;
369 }
370
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530371 if ( (WLANTL_STA_CONNECTED != pSapCtx->aStaInfo[STAId].tlSTAState) &&
372 (WLANTL_STA_AUTHENTICATED != pSapCtx->aStaInfo[STAId].tlSTAState) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530374 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700375 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 ++pAdapter->stats.tx_dropped;
377 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
378 kfree_skb(skb);
379 goto xmit_done;
380 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530381 else if(WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[STAId].tlSTAState)
Jeff Johnson295189b2012-06-20 16:38:30 -0700382 {
383 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
384 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530385 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700386 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 ++pAdapter->stats.tx_dropped;
388 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
389 kfree_skb(skb);
390 goto xmit_done;
391 }
392 }
393 }
394
395 //Get TL AC corresponding to Qdisc queue index/AC.
396 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
397 //user priority from IP header, which is already extracted and set from
398 //select_queue call back function
399 up = skb->priority;
400 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
401
c_hpothu6d1d2a32014-03-18 20:17:03 +0530402 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700403 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700404
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530405 if (( NULL != pHddCtx ) &&
406 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530407 {
408 hdd_dump_dhcp_pkt(skb, TX_PATH);
409 }
410
Jeff Johnson295189b2012-06-20 16:38:30 -0700411 // If the memory differentiation mode is enabled, the memory limit of each queue will be
412 // checked. Over-limit packets will be dropped.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530413 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
414 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700415 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
416 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530417 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800418 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Bhargav Shah7f03b812015-08-21 11:17:32 +0530419 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured;
420 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530421 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700422 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
423 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530424 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
425 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -0700426 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530427
428 /* If 3/4th of the max queue size is used then enable the flag.
429 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
430 if (WLANTL_AC_BE == ac)
431 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530432 if (pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530433 {
Sushant Kaushik40bcd6e2015-09-18 12:09:54 +0530434 if (!(pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count % 0x40))
435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530436 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
Sushant Kaushik40bcd6e2015-09-18 12:09:54 +0530437 pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count++;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530438 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_TRUE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530439 }
440 else
441 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530442 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530443 }
444 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530445 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700446
447 if (VOS_TRUE == txSuspended)
448 {
449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
450 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700451 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700452 os_status = NETDEV_TX_BUSY;
453 goto xmit_done;
454 }
455
456 //Use the skb->cb field to hold the list node information
457 pktNode = (skb_list_node_t *)&skb->cb;
458
459 //Stick the OS packet inside this node.
460 pktNode->skb = skb;
461
462 //Stick the User Priority inside this node
463 pktNode->userPriority = up;
464
465 INIT_LIST_HEAD(&pktNode->anchor);
466
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530467 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
468 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
469 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700470 if ( !VOS_IS_STATUS_SUCCESS( status ) )
471 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530472 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
473 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700474 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
475 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
476 ++pAdapter->stats.tx_dropped;
477 kfree_skb(skb);
478 goto xmit_done;
479 }
480
481 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
482 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530483 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700484
485 if (1 == pktListSize)
486 {
487 //Let TL know we have a packet to send for this AC
488 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
489
490 if ( !VOS_IS_STATUS_SUCCESS( status ) )
491 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530492 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
493 "%s: Failed to signal TL for AC=%d STAId =%d",
494 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700495
496 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
497 //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 +0530498 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
499 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
500 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530501 /* Free the skb only if we are able to remove it from the list.
502 * If we are not able to retrieve it from the list it means that
503 * the skb was pulled by TX Thread and is use so we should not free
504 * it here
505 */
506 if (VOS_IS_STATUS_SUCCESS(status))
507 {
508 pktNode = list_entry(anchor, skb_list_node_t, anchor);
509 skb1 = pktNode->skb;
510 kfree_skb(skb1);
511 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700512 ++pAdapter->stats.tx_dropped;
513 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
514 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700515 goto xmit_done;
516 }
517 }
518 dev->trans_start = jiffies;
519
c_hpothu6d1d2a32014-03-18 20:17:03 +0530520 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
521 "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700522
523xmit_done:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530524 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700525 return os_status;
526}
527
528/**============================================================================
529 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
530
531 @param skb : [in] pointer to packet (sk_buff)
532 @param dev : [in] pointer to Libra network device
533 @param STAId : [in] Station Id of Destination Station
534 @param up : [in] User Priority
535
536 @return : NET_XMIT_DROP if packets are dropped
537 : NET_XMIT_SUCCESS if packet is enqueued succesfully
538 ===========================================================================*/
539VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
540 struct net_device *dev,
541 v_U8_t STAId,
542 v_U8_t up)
543{
544 VOS_STATUS status = VOS_STATUS_SUCCESS;
545 skb_list_node_t *pktNode = NULL;
546 v_SIZE_t pktListSize = 0;
547 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
548 v_U8_t ac;
549 vos_list_node_t *anchor = NULL;
Mihir Shetef8f74532014-12-04 11:53:34 +0530550 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530552 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
553 ptSapContext pSapCtx = NULL;
554 pSapCtx = VOS_GET_SAP_CB(pVosContext);
555 if(pSapCtx == NULL){
556 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
557 FL("psapCtx is NULL"));
558 kfree_skb(skb);
559 status = VOS_STATUS_E_FAILURE;
560 return status;
561 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700562 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
563
c_hpothu6d1d2a32014-03-18 20:17:03 +0530564 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700565 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530567 spin_lock_bh( &pSapCtx->staInfo_lock );
568 if ( FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700569 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530570 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530571 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 kfree_skb(skb);
573 status = VOS_STATUS_E_FAILURE;
574 goto xmit_end;
575 }
576
577 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530578 if ( !pSapCtx->aStaInfo[STAId].isQosEnabled )
Jeff Johnson295189b2012-06-20 16:38:30 -0700579 up = SME_QOS_WMM_UP_BE;
580
581 ac = hddWmmUpToAcMap[up];
582 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
c_hpothu6d1d2a32014-03-18 20:17:03 +0530583 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700584 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700585
586 skb->queue_mapping = hddLinuxUpToAcMap[up];
587
588 //Use the skb->cb field to hold the list node information
589 pktNode = (skb_list_node_t *)&skb->cb;
590
591 //Stick the OS packet inside this node.
592 pktNode->skb = skb;
593
594 //Stick the User Priority inside this node
595 pktNode->userPriority = up;
596
597 INIT_LIST_HEAD(&pktNode->anchor);
598
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530599 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
600 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
601 if(pSapCtx->aStaInfo[STAId].txSuspended[ac] ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 pktListSize >= pAdapter->aTxQueueLimit[ac])
603 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530604 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800605 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700606 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
607 * SUSPEND should be done based on Threshold. RESUME would be
608 * triggered in fetch cbk after recovery.
609 */
610 kfree_skb(skb);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530611 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700612 status = VOS_STATUS_E_FAILURE;
613 goto xmit_end;
614 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530615 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
616 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700617
618 if ( !VOS_IS_STATUS_SUCCESS( status ) )
619 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530620 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
621 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
623 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
624 ++pAdapter->stats.tx_dropped;
625 kfree_skb(skb);
626 status = VOS_STATUS_E_FAILURE;
627 goto xmit_end;
628 }
629
630 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
631 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
632
633 if (1 == pktListSize)
634 {
635 //Let TL know we have a packet to send for this AC
c_hpothu6d1d2a32014-03-18 20:17:03 +0530636 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
637 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700638
639 if ( !VOS_IS_STATUS_SUCCESS( status ) )
640 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530641 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
642 "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700643 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700644
645 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
646 //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 +0530647 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
648 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
649 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530650 /* Free the skb only if we are able to remove it from the list.
651 * If we are not able to retrieve it from the list it means that
652 * the skb was pulled by TX Thread and is use so we should not free
653 * it here
654 */
655 if (VOS_IS_STATUS_SUCCESS(status))
656 {
657 pktNode = list_entry(anchor, skb_list_node_t, anchor);
658 skb1 = pktNode->skb;
659 kfree_skb(skb1);
660 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 ++pAdapter->stats.tx_dropped;
662 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
663 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 status = VOS_STATUS_E_FAILURE;
665 goto xmit_end;
666 }
667 }
668
c_hpothu6d1d2a32014-03-18 20:17:03 +0530669 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700670
671xmit_end:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530672 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700673 return status;
674}
675
676/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530677 @brief __hdd_softap_tx_timeout() - Function called by OS if there is any
Jeff Johnson295189b2012-06-20 16:38:30 -0700678 timeout during transmission. Since HDD simply enqueues packet
679 and returns control to OS right away, this would never be invoked
680
681 @param dev : [in] pointer to Libra network device
682 @return : None
683 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530684void __hdd_softap_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700685{
Mihir Shetef3473692014-06-27 15:13:20 +0530686 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
687 struct netdev_queue *txq;
688 int i = 0;
Mukul Sharma4b322632015-02-28 20:21:43 +0530689 int status = 0;
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530690 hdd_context_t *pHddCtx;
Mihir Shetef3473692014-06-27 15:13:20 +0530691
c_hpothu6d1d2a32014-03-18 20:17:03 +0530692 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700693 "%s: Transmission timeout occurred", __func__);
Mihir Shetef3473692014-06-27 15:13:20 +0530694
695 if ( NULL == pAdapter )
696 {
697 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
698 FL("pAdapter is NULL"));
699 VOS_ASSERT(0);
700 return;
701 }
702
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mukul Sharma4b322632015-02-28 20:21:43 +0530704 status = wlan_hdd_validate_context(pHddCtx);
705 if (status != 0)
706 {
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530707 return;
708 }
709
Mihir Shetef3473692014-06-27 15:13:20 +0530710 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
711
712 for (i = 0; i < 8; i++)
713 {
714 txq = netdev_get_tx_queue(dev, i);
715 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
716 "Queue%d status: %d", i, netif_tx_queue_stopped(txq));
717 }
718
719 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
720 "carrier state: %d", netif_carrier_ok(dev));
721
722 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
723
Mihir Shete327c2ab2014-11-13 15:17:02 +0530724 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
725 HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
726 {
727 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
728 "%s: Request firmware for recovery",__func__);
729 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
730 }
Mihir Shetef3473692014-06-27 15:13:20 +0530731 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
732 HDD_SAP_TX_STALL_SSR_THRESHOLD)
733 {
734 // Driver could not recover, issue SSR
735 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
736 "%s: Cannot recover from Data stall Issue SSR",
737 __func__);
Mihir Shetefd62d9d2014-08-06 15:08:21 +0530738 WLANTL_FatalError();
Mihir Shetef3473692014-06-27 15:13:20 +0530739 return;
740 }
741
742 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
743 * every 5sec. The TL debug spits out a lot of information on the
744 * serial console, if it is called every time *hdd_tx_timeout* is
745 * called then we may get a watchdog bite on the Application
746 * processor, so ratelimit the TL debug logs.
747 */
748 if (__ratelimit(&hdd_softap_tx_timeout_rs))
749 {
750 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +0530751 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetef3473692014-06-27 15:13:20 +0530752 }
753
Jeff Johnson295189b2012-06-20 16:38:30 -0700754}
755
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530756void hdd_softap_tx_timeout(struct net_device *dev)
757{
758 vos_ssr_protect(__func__);
759 __hdd_softap_tx_timeout(dev);
760 vos_ssr_unprotect(__func__);
761 return;
762}
Jeff Johnson295189b2012-06-20 16:38:30 -0700763
764/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530765 @brief __hdd_softap_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700766 device TX/RX statistic
767
768 @param dev : [in] pointer to Libra network device
769
770 @return : pointer to net_device_stats structure
771 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530772struct net_device_stats* __hdd_softap_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700773{
774 hdd_adapter_t* priv = netdev_priv(dev);
775 return &priv->stats;
776}
777
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530778struct net_device_stats* hdd_softap_stats(struct net_device *dev)
779{
780 struct net_device_stats *priv_stats;
781 vos_ssr_protect(__func__);
782 priv_stats = __hdd_softap_stats(dev);
783 vos_ssr_unprotect(__func__);
784
785 return priv_stats;
786}
Jeff Johnson295189b2012-06-20 16:38:30 -0700787
788/**============================================================================
789 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
790 modules in HDD
791
792 @param pAdapter : [in] pointer to adapter context
793 @return : VOS_STATUS_E_FAILURE if any errors encountered
794 : VOS_STATUS_SUCCESS otherwise
795 ===========================================================================*/
796VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
797{
798 VOS_STATUS status = VOS_STATUS_SUCCESS;
799 v_SINT_t i = -1;
800 v_SIZE_t size = 0;
801
802 v_U8_t STAId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530803 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
804 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700805
806 v_U8_t pACWeights[] = {
807 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
808 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
809 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
810 HDD_SOFTAP_VO_WEIGHT_DEFAULT
811 };
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530812 pSapCtx = VOS_GET_SAP_CB(pVosContext);
813 if(pSapCtx == NULL){
814 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
815 FL("psapCtx is NULL"));
816 return VOS_STATUS_E_FAULT;
817 }
818
Leo Chang64d68bc2013-06-04 15:40:52 -0700819
Jeff Johnson295189b2012-06-20 16:38:30 -0700820 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530821 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700822
823 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
824
825 while (++i != NUM_TX_QUEUES)
826 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
827
828 /* Initial HDD buffer control / flow control fields*/
829 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
830
831 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
832 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
833 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
834 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
835
Jeff Johnson295189b2012-06-20 16:38:30 -0700836 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
837 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530838 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 for (i = 0; i < NUM_TX_QUEUES; i ++)
840 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530841 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700842 }
843 }
844
Yue Ma3ede6052013-08-29 00:33:26 -0700845 /* Update the AC weights suitable for SoftAP mode of operation */
846 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
847
Kiet Lambcf38522013-10-26 18:28:27 +0530848 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700849 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530850 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530851 "%s: failed to start Traffic Monito timer ", __func__ );
852 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700853 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700854 return status;
855}
856
857/**============================================================================
858 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
859 modules in HDD
860
861 @param pAdapter : [in] pointer to adapter context
862 @return : VOS_STATUS_E_FAILURE if any errors encountered
863 : VOS_STATUS_SUCCESS otherwise
864 ===========================================================================*/
865VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
866{
867 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700868
Kiet Lambcf38522013-10-26 18:28:27 +0530869 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700870 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530871 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530872 "%s: Fail to Stop Traffic Monito timer", __func__ );
873 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700874 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700875
876 status = hdd_softap_flush_tx_queues(pAdapter);
877
878 return status;
879}
880
881/**============================================================================
882 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
883
884 @param pAdapter : [in] pointer to adapter context
885 @param STAId : [in] Station ID to deinit
886 @return : VOS_STATUS_E_FAILURE if any errors encountered
887 : VOS_STATUS_SUCCESS otherwise
888 ===========================================================================*/
889static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
890{
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 v_U8_t i = -1;
892
893 hdd_list_node_t *anchor = NULL;
894
895 skb_list_node_t *pktNode = NULL;
896 struct sk_buff *skb = NULL;
897
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530898 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
899 ptSapContext pSapCtx = NULL;
900 pSapCtx = VOS_GET_SAP_CB(pVosContext);
901 if(pSapCtx == NULL){
902 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
903 FL("psapCtx is NULL"));
904 return VOS_STATUS_E_FAULT;
905 }
906 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700907 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530908 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700909 }
910
911 for (i = 0; i < NUM_TX_QUEUES; i ++)
912 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530913 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700914 while (true)
915 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530916 if (VOS_STATUS_E_EMPTY !=
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530917 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530918 &anchor))
Jeff Johnson295189b2012-06-20 16:38:30 -0700919 {
920 //If success then we got a valid packet from some AC
921 pktNode = list_entry(anchor, skb_list_node_t, anchor);
922 skb = pktNode->skb;
923 ++pAdapter->stats.tx_dropped;
924 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
925 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
926 kfree_skb(skb);
927 continue;
928 }
929
930 //current list is empty
931 break;
932 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530933 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 }
935
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530936 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700937}
938
939/**============================================================================
940 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
941 modules in HDD
942
943 @param pAdapter : [in] pointer to adapter context
944 @param STAId : [in] Station ID to deinit
945 @param pmacAddrSTA : [in] pointer to the MAC address of the station
946 @return : VOS_STATUS_E_FAILURE if any errors encountered
947 : VOS_STATUS_SUCCESS otherwise
948 ===========================================================================*/
949VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
950{
951 v_U8_t i = 0;
Nirav Shah7e3c8132015-06-22 23:51:42 +0530952 VOS_STATUS status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530953 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
954 ptSapContext pSapCtx = NULL;
Nirav Shah7e3c8132015-06-22 23:51:42 +0530955
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530956 pSapCtx = VOS_GET_SAP_CB(pVosContext);
957 if(pSapCtx == NULL){
958 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
959 FL("psapCtx is NULL"));
960 return VOS_STATUS_E_FAULT;
961 }
962
963 spin_lock_bh( &pSapCtx->staInfo_lock );
964 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530966 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
967 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530968 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700969 return VOS_STATUS_E_FAILURE;
970 }
971
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530972 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 for (i = 0; i < NUM_TX_QUEUES; i ++)
974 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530975 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700976 }
977
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530978 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
979 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
980 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700981
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530982 spin_unlock_bh( &pSapCtx->staInfo_lock );
Nirav Shah7e3c8132015-06-22 23:51:42 +0530983
984 status = hdd_sta_id_hash_add_entry(pAdapter, STAId, pmacAddrSTA);
985 if (status != VOS_STATUS_SUCCESS) {
986 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
987 FL("Not able to add staid hash %d"), STAId);
988 return VOS_STATUS_E_FAILURE;
989 }
990
991 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
992 FL("New station added sta_id %d mac:"
993 MAC_ADDRESS_STR), STAId,
994 MAC_ADDR_ARRAY(pmacAddrSTA->bytes));
995
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 return VOS_STATUS_SUCCESS;
997}
998
999/**============================================================================
1000 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
1001 modules in HDD
1002
1003 @param pAdapter : [in] pointer to adapter context
1004 @param STAId : [in] Station ID to deinit
1005 @return : VOS_STATUS_E_FAILURE if any errors encountered
1006 : VOS_STATUS_SUCCESS otherwise
1007 ===========================================================================*/
1008VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
1009{
1010 VOS_STATUS status = VOS_STATUS_SUCCESS;
1011 v_U8_t ac;
1012 /**Track whether OS TX queue has been disabled.*/
1013 v_BOOL_t txSuspended[NUM_TX_QUEUES];
1014 v_U8_t tlAC;
1015 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001016 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -07001017
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301018 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1019 ptSapContext pSapCtx = NULL;
1020 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1021 if(pSapCtx == NULL){
1022 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1023 FL("psapCtx is NULL"));
1024 return VOS_STATUS_E_FAULT;
1025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001026 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1027
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301028 spin_lock_bh( &pSapCtx->staInfo_lock );
1029 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001030 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301031 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001032 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301033 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 return VOS_STATUS_E_FAILURE;
1035 }
1036
1037 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1038
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301039 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1040 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301041
1042 status = hdd_sta_id_hash_remove_entry(pAdapter,
1043 STAId, &pSapCtx->aStaInfo[STAId].macAddrSTA);
1044 if (status != VOS_STATUS_SUCCESS) {
1045 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1046 FL("Not able to remove staid hash %d"), STAId);
1047 return VOS_STATUS_E_FAILURE;
1048 }
1049
1050 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1051 FL("station removed sta_id %d mac:"
1052 MAC_ADDRESS_STR), STAId,
1053 MAC_ADDR_ARRAY(pSapCtx->aStaInfo[STAId].macAddrSTA.bytes));
1054
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 /* if this STA had any of its WMM TX queues suspended, then the
1056 associated queue on the network interface was disabled. check
1057 to see if that is the case, in which case we need to re-enable
1058 the interface queue. but we only do this if the BSS is running
1059 since, if the BSS is stopped, all of the interfaces have been
1060 stopped and should not be re-enabled */
1061
1062 if (BSS_START == pHostapdState->bssState)
1063 {
1064 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1065 {
1066 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301067 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001068 }
1069 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301070 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001071
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001072 /* re-init spin lock, since netdev can still open adapter until
1073 * driver gets unloaded
1074 */
1075 for (i = 0; i < NUM_TX_QUEUES; i ++)
1076 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301077 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001078 HDD_TX_QUEUE_MAX_LEN);
1079 }
1080
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 if (BSS_START == pHostapdState->bssState)
1082 {
1083 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1084 {
1085 if (txSuspended[ac])
1086 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301087 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001088 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001089 netif_wake_subqueue(pAdapter->dev, ac);
1090 }
1091 }
1092 }
1093
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301094 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001095 return status;
1096}
1097
1098/**============================================================================
1099 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1100 modules in HDD
1101
1102 @param pAdapter : [in] pointer to adapter context
1103 @return : VOS_STATUS_E_FAILURE if any errors encountered
1104 : VOS_STATUS_SUCCESS otherwise
1105 ===========================================================================*/
1106VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1107{
1108 return hdd_softap_flush_tx_queues(pAdapter);
1109}
1110
1111/**============================================================================
1112 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1113 to indicate that a packet has been transmitted across the bus
1114 succesfully. OS packet resources can be released after this cbk.
1115
1116 @param vosContext : [in] pointer to VOS context
1117 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1118 @param vosStatusIn : [in] status of the transmission
1119
1120 @return : VOS_STATUS_E_FAILURE if any errors encountered
1121 : VOS_STATUS_SUCCESS otherwise
1122 ===========================================================================*/
1123VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1124 vos_pkt_t *pVosPacket,
1125 VOS_STATUS vosStatusIn )
1126{
1127 VOS_STATUS status = VOS_STATUS_SUCCESS;
1128 hdd_adapter_t *pAdapter = NULL;
1129 void* pOsPkt = NULL;
1130
1131 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1132 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301133 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1134 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 return VOS_STATUS_E_FAILURE;
1136 }
1137
1138 //Return the skb to the OS
1139 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001140 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 {
1142 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301143 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1144 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001145 vos_pkt_return_packet( pVosPacket );
1146 return VOS_STATUS_E_FAILURE;
1147 }
1148
1149 //Get the Adapter context.
1150 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301151 if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301153 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301154 "%s: HDD adapter context is invalid", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 }
1156 else
1157 {
1158 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1159 }
1160
1161 kfree_skb((struct sk_buff *)pOsPkt);
1162
1163 //Return the VOS packet resources.
1164 status = vos_pkt_return_packet( pVosPacket );
1165 if(!VOS_IS_STATUS_SUCCESS( status ))
1166 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301167 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1168 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001169 }
1170
1171 return status;
1172}
1173
1174
1175/**============================================================================
1176 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1177 fetch a packet for transmission.
1178
1179 @param vosContext : [in] pointer to VOS context
1180 @param staId : [in] Station for which TL is requesting a pkt
1181 @param ac : [in] access category requested by TL
1182 @param pVosPacket : [out] pointer to VOS packet packet pointer
1183 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1184
1185 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1186 : VOS_STATUS_E_FAILURE if any errors encountered
1187 : VOS_STATUS_SUCCESS otherwise
1188 ===========================================================================*/
1189VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1190 v_U8_t *pStaId,
1191 WLANTL_ACEnumType ac,
1192 vos_pkt_t **ppVosPacket,
1193 WLANTL_MetaInfoType *pPktMetaInfo )
1194{
1195 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1196 hdd_adapter_t *pAdapter = NULL;
1197 hdd_list_node_t *anchor = NULL;
1198 skb_list_node_t *pktNode = NULL;
1199 struct sk_buff *skb = NULL;
1200 vos_pkt_t *pVosPacket = NULL;
1201 v_MACADDR_t* pDestMacAddress = NULL;
1202 v_TIME_t timestamp;
1203 v_SIZE_t size = 0;
1204 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1205 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001206 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301207 v_CONTEXT_t pVosContext = NULL;
1208 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001209 //Sanity check on inputs
1210 if ( ( NULL == vosContext ) ||
1211 ( NULL == pStaId ) ||
1212 ( NULL == ppVosPacket ) ||
1213 ( NULL == pPktMetaInfo ) )
1214 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301215 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1216 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 return VOS_STATUS_E_FAILURE;
1218 }
1219
1220 //Get the HDD context.
1221 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1222 if ( NULL == pHddCtx )
1223 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301224 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1225 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001226 return VOS_STATUS_E_FAILURE;
1227 }
1228
Jeff Johnsonb156c922013-12-05 17:19:46 -08001229 STAId = *pStaId;
1230 if (STAId >= WLAN_MAX_STA_COUNT)
1231 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301232 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001233 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1234 return VOS_STATUS_E_FAILURE;
1235 }
1236
1237 pAdapter = pHddCtx->sta_to_adapter[STAId];
1238 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 {
1240 VOS_ASSERT(0);
1241 return VOS_STATUS_E_FAILURE;
1242 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301243 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1244 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1245 if(pSapCtx == NULL){
1246 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1247 FL("psapCtx is NULL"));
1248 return VOS_STATUS_E_FAULT;
1249 }
1250
1251 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001252 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301253 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001254 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1255 return VOS_STATUS_E_FAILURE;
1256 }
1257
Leo Chang64d68bc2013-06-04 15:40:52 -07001258 /* Monitor traffic */
1259 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1260 {
1261 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1262 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1263 {
1264 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1265 /* It was IDLE mode,
1266 * this is new state, then switch mode from suspend to resume */
1267 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1268 {
1269 hdd_set_wlan_suspend_mode(0);
1270 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1271 pHddCtx->cfg_ini->trafficIdleTimeout);
1272 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1273 }
1274 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1275 }
1276 }
1277
Jeff Johnson295189b2012-06-20 16:38:30 -07001278 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1279
Jeff Johnson295189b2012-06-20 16:38:30 -07001280 *ppVosPacket = NULL;
1281
1282 //Make sure the AC being asked for is sane
1283 if( ac > WLANTL_MAX_AC || ac < 0)
1284 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301285 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001286 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001287 return VOS_STATUS_E_FAILURE;
1288 }
1289
1290 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1291
c_hpothu6d1d2a32014-03-18 20:17:03 +05301292 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001293 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001294
1295 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1296 //This simplifies the locking and unlocking of Tx queue
1297 status = vos_pkt_wrap_data_packet( &pVosPacket,
1298 VOS_PKT_TYPE_TX_802_3_DATA,
1299 NULL, //OS Pkt is not being passed
1300 hdd_softap_tx_low_resource_cbk,
1301 pAdapter );
1302
1303 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1304 {
1305 //Remember VOS is in a low resource situation
1306 pAdapter->isVosOutOfResource = VOS_TRUE;
1307 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301308 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001309 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001310 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1311 return VOS_STATUS_E_FAILURE;
1312 }
1313
1314 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1315 as the other branch does.
1316 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301317 spin_lock_bh( &pSapCtx->staInfo_lock );
1318 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1319 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001320
1321 if (0 == size)
1322 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301323 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1324 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001325 vos_pkt_return_packet(pVosPacket);
1326 return VOS_STATUS_E_EMPTY;
1327 }
1328
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301329 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1330 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1331 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001332
c_hpothu6d1d2a32014-03-18 20:17:03 +05301333 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001334 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001335
1336 if(VOS_STATUS_SUCCESS == status)
1337 {
1338 //If success then we got a valid packet from some AC
1339 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1340 skb = pktNode->skb;
1341 }
1342 else
1343 {
1344 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301345 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001346 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001347 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 vos_pkt_return_packet(pVosPacket);
1349 return VOS_STATUS_E_FAILURE;
1350 }
1351
1352 //Attach skb to VOS packet.
1353 status = vos_pkt_set_os_packet( pVosPacket, skb );
1354 if (status != VOS_STATUS_SUCCESS)
1355 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301356 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001357 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 vos_pkt_return_packet(pVosPacket);
1359 ++pAdapter->stats.tx_dropped;
1360 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1361 kfree_skb(skb);
1362 return VOS_STATUS_E_FAILURE;
1363 }
1364
1365 //Just being paranoid. To be removed later
1366 if(pVosPacket == NULL)
1367 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301368 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001369 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001370 ++pAdapter->stats.tx_dropped;
1371 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1372 kfree_skb(skb);
1373 return VOS_STATUS_E_FAILURE;
1374 }
1375
1376 //Return VOS packet to TL;
1377 *ppVosPacket = pVosPacket;
1378
1379 //Fill out the meta information needed by TL
1380 //FIXME This timestamp is really the time stamp of wrap_data_packet
1381 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1382 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1383 if ( 1 < size )
1384 {
1385 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1386 }
1387 else
1388 {
1389 pPktMetaInfo->bMorePackets = 0;
1390 }
1391
1392 pPktMetaInfo->ucIsEapol = 0;
1393
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301394 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001395 {
1396 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1397 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001398 pPktMetaInfo->ucIsEapol = 1;
Sushant Kaushika8073312015-05-04 17:33:52 +05301399 wlan_hdd_log_eapol(skb,
1400 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
Jeff Johnson295189b2012-06-20 16:38:30 -07001401 }
1402 }
Sushant Kaushika8073312015-05-04 17:33:52 +05301403
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301404 if ((NULL != pHddCtx) &&
1405 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001406 {
1407 proto_type = vos_pkt_get_proto_type(skb,
1408 pHddCtx->cfg_ini->gEnableDebugLog);
1409 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1410 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001412 "SAP TX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001413 }
1414 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1415 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001417 "SAP TX DHCP");
1418 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301419 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1420 {
1421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1422 "SAP TX ARP");
1423 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001425//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301427 pPktMetaInfo->ac = ac;
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 pPktMetaInfo->ucUP = pktNode->userPriority;
1429 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1430 }
1431
1432 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1433 //Extract the destination address from ethernet frame
1434 pDestMacAddress = (v_MACADDR_t*)skb->data;
1435
1436 // we need 802.3 to 802.11 frame translation
1437 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1438 pPktMetaInfo->ucDisableFrmXtl = 0;
1439 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1440 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1441
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301442 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1444 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301445 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001446 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301447 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301449 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1450 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001451 }
1452
1453 // We're giving the packet to TL so consider it transmitted from
1454 // a statistics perspective. We account for it here instead of
1455 // when the packet is returned for two reasons. First, TL will
1456 // manipulate the skb to the point where the len field is not
1457 // accurate, leading to inaccurate byte counts if we account for
1458 // it later. Second, TL does not provide any feedback as to
1459 // whether or not the packet was successfully sent over the air,
1460 // so the packet counts will be the same regardless of where we
1461 // account for them
1462 pAdapter->stats.tx_bytes += skb->len;
1463 ++pAdapter->stats.tx_packets;
1464 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1465 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301466 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001467
c_hpothu6d1d2a32014-03-18 20:17:03 +05301468 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001469 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001470
1471 return status;
1472}
1473
1474
1475/**============================================================================
1476 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1477 case where VOS packets are not available at the time of the call to get
1478 packets. This callback function is invoked by VOS when packets are
1479 available.
1480
1481 @param pVosPacket : [in] pointer to VOS packet
1482 @param userData : [in] opaque user data that was passed initially
1483
1484 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1485 : VOS_STATUS_SUCCESS otherwise
1486 =============================================================================*/
1487VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1488 v_VOID_t *userData )
1489{
1490 VOS_STATUS status;
1491 v_SINT_t i = 0;
1492 v_SIZE_t size = 0;
1493 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1494 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301495 v_CONTEXT_t pVosContext = NULL;
1496 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301497
1498 if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07001499 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301500 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1501 FL("Invalid adapter %p"), pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001502 return VOS_STATUS_E_FAILURE;
1503 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301504 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1505 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1506 if(pSapCtx == NULL){
1507 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1508 FL("psapCtx is NULL"));
1509 return VOS_STATUS_E_FAULT;
1510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001511 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1512 //situation. Here we will only signal TL that there is a pending data for a STA.
1513 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1514 vos_pkt_return_packet( pVosPacket );
1515
1516 pAdapter->isVosOutOfResource = VOS_FALSE;
1517
1518 // Indicate to TL that there is pending data if a queue is non empty.
1519 // This Code wasnt included in earlier version which resulted in
1520 // Traffic stalling
1521 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1522 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301523 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1524 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 {
1526 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1527 {
1528 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301529 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001530 if ( size > 0 )
1531 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301532 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1533 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001534 (WLANTL_ACEnumType)i );
1535 if( !VOS_IS_STATUS_SUCCESS( status ) )
1536 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301537 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1538 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001539 }
1540 }
1541 }
1542 }
1543 }
1544 return VOS_STATUS_SUCCESS;
1545}
1546
1547
1548/**============================================================================
1549 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1550 TL will call this to notify the HDD when one or more packets were
1551 received for a registered STA.
1552
1553 @param vosContext : [in] pointer to VOS context
1554 @param pVosPacketChain : [in] pointer to VOS packet chain
1555 @param staId : [in] Station Id (Adress 1 Index)
1556 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1557
1558 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1559 : VOS_STATUS_SUCCESS otherwise
1560 ===========================================================================*/
1561VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1562 vos_pkt_t *pVosPacketChain,
1563 v_U8_t staId,
1564 WLANTL_RxMetaInfoType* pRxMetaInfo )
1565{
1566 hdd_adapter_t *pAdapter = NULL;
1567 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1568 int rxstat;
1569 struct sk_buff *skb = NULL;
1570 vos_pkt_t* pVosPacket;
1571 vos_pkt_t* pNextVosPacket;
1572 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001573 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001574
1575 //Sanity check on inputs
1576 if ( ( NULL == vosContext ) ||
1577 ( NULL == pVosPacketChain ) ||
1578 ( NULL == pRxMetaInfo ) )
1579 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301580 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1581 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 return VOS_STATUS_E_FAILURE;
1583 }
1584
1585 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1586 if ( NULL == pHddCtx )
1587 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301588 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1589 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001590 return VOS_STATUS_E_FAILURE;
1591 }
1592
1593 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301594 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001595 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301596 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1597 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001598 VOS_ASSERT(0);
1599 return VOS_STATUS_E_FAILURE;
1600 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001601
1602 /* Monitor traffic */
1603 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1604 {
1605 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1606 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1607 {
1608 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1609 /* It was IDLE mode,
1610 * this is new state, then switch mode from suspend to resume */
1611 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1612 {
1613 hdd_set_wlan_suspend_mode(0);
1614 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1615 pHddCtx->cfg_ini->trafficIdleTimeout);
1616 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1617 }
1618 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1619 }
1620 }
1621
Jeff Johnson295189b2012-06-20 16:38:30 -07001622 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1623
1624 // walk the chain until all are processed
1625 pVosPacket = pVosPacketChain;
1626 do
1627 {
1628 // get the pointer to the next packet in the chain
1629 // (but don't unlink the packet since we free the entire chain later)
1630 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1631
1632 // both "success" and "empty" are acceptable results
1633 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1634 {
1635 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301636 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1637 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001638 return VOS_STATUS_E_FAILURE;
1639 }
1640
1641 // Extract the OS packet (skb).
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301642 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001643 if(!VOS_IS_STATUS_SUCCESS( status ))
1644 {
1645 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301646 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1647 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 return VOS_STATUS_E_FAILURE;
1649 }
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301650
1651 if (TRUE == hdd_IsEAPOLPacket(pVosPacket))
1652 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
1653
1654 pVosPacket->pSkb = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001655 //hdd_softap_dump_sk_buff(skb);
1656
1657 skb->dev = pAdapter->dev;
1658
1659 if(skb->dev == NULL) {
1660
c_hpothu6d1d2a32014-03-18 20:17:03 +05301661 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1662 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 return VOS_STATUS_E_FAILURE;
1664 }
1665 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1666 ++pAdapter->stats.rx_packets;
1667 pAdapter->stats.rx_bytes += skb->len;
1668
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001669 if (pHddCtx->cfg_ini->gEnableDebugLog)
1670 {
1671 proto_type = vos_pkt_get_proto_type(skb,
1672 pHddCtx->cfg_ini->gEnableDebugLog);
1673 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1674 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001676 "SAP RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001677 }
1678 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1679 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001681 "SAP RX DHCP");
1682 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301683 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1684 {
1685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1686 "SAP RX ARP");
1687 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001688 }
1689
Jeff Johnson295189b2012-06-20 16:38:30 -07001690 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1691 {
1692 //MC/BC packets. Duplicate a copy of packet
1693 struct sk_buff *pSkbCopy;
1694 hdd_ap_ctx_t *pHddApCtx;
1695
1696 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1697 if (!(pHddApCtx->apDisableIntraBssFwd))
1698 {
1699 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1700 if (pSkbCopy)
1701 {
1702 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1703 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1704 }
1705 }
1706 else
1707 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301708 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001709 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001710 }
1711
1712
1713 } //(WLAN_RX_BCMC_STA_ID == staId)
1714
1715 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1716 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1717 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301718 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001719 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301720 if ((NULL != pHddCtx) &&
1721 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301722 {
1723 hdd_dump_dhcp_pkt(skb, RX_PATH);
1724 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001725
1726 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001727 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnsone7245742012-09-05 17:12:55 -07001728#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301729 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
1730 HDD_WAKE_LOCK_DURATION,
1731 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
1732
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001733#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001734 rxstat = netif_rx_ni(skb);
1735 if (NET_RX_SUCCESS == rxstat)
1736 {
1737 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001738 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 }
1740 else
1741 {
1742 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1743 }
1744 }
1745 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1746 {
1747 kfree_skb(skb);
1748 }
1749 else
1750 {
1751 //loopback traffic
1752 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1753 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1754 }
1755
1756 // now process the next packet in the chain
1757 pVosPacket = pNextVosPacket;
1758
1759 } while (pVosPacket);
1760
1761 //Return the entire VOS packet chain to the resource pool
1762 status = vos_pkt_return_packet( pVosPacketChain );
1763 if(!VOS_IS_STATUS_SUCCESS( status ))
1764 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301765 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1766 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001767 }
1768
1769 pAdapter->dev->last_rx = jiffies;
1770
1771 return status;
1772}
1773
1774VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1775{
1776 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301777 hdd_context_t *pHddCtx;
1778 if (NULL == pAdapter)
1779 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301780 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301781 "%s: pAdapter is NULL", __func__);
1782 return VOS_STATUS_E_INVAL;
1783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001784
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301785 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1786 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301787 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301788 "%s: Invalid pAdapter magic", __func__);
1789 return VOS_STATUS_E_INVAL;
1790 }
1791
1792 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301793 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301795 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1797 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301798 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001799 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001800 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001801 staId, vosStatus, vosStatus );
1802 }
1803
1804 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1805 if( VOS_STATUS_E_FAILURE == vosStatus )
1806 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301807 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001809 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001810 staId, vosStatus, vosStatus );
1811 return( vosStatus );
1812 }
1813
1814 pHddCtx->sta_to_adapter[staId] = NULL;
1815
1816 return( vosStatus );
1817}
1818
1819VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1820 v_BOOL_t fAuthRequired,
1821 v_BOOL_t fPrivacyBit,
1822 v_U8_t staId,
1823 v_U8_t ucastSig,
1824 v_U8_t bcastSig,
1825 v_MACADDR_t *pPeerMacAddress,
1826 v_BOOL_t fWmmEnabled )
1827{
1828 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001829 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1831 hdd_adapter_t *pmonAdapter = NULL;
1832
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301833 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1834 ptSapContext pSapCtx = NULL;
1835 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1836 if(pSapCtx == NULL){
1837 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1838 FL("psapCtx is NULL"));
1839 return VOS_STATUS_E_FAULT;
1840 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 //eCsrEncryptionType connectedCipherAlgo;
1842 //v_BOOL_t fConnected;
1843
1844 /*
1845 * Clean up old entry if it is not cleaned up properly
1846 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301847 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001848 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301849 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001850 "clean up old entry for STA %d", staId);
1851 hdd_softap_DeregisterSTA( pAdapter, staId );
1852 }
1853
1854 // Get the Station ID from the one saved during the assocation.
1855
1856 staDesc.ucSTAId = staId;
1857
1858
1859 /*Save the pAdapter Pointer for this staId*/
1860 pHddCtx->sta_to_adapter[staId] = pAdapter;
1861
1862 staDesc.wSTAType = WLAN_STA_SOFTAP;
1863
1864 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1865 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1866 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1867
c_hpothu6d1d2a32014-03-18 20:17:03 +05301868 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001869 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301870 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001871 "station mac " MAC_ADDRESS_STR,
1872 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301873 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001874 "BSSIDforIBSS " MAC_ADDRESS_STR,
1875 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301876 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001877 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1878 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001879
1880 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1881
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301883 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001884 "HDD SOFTAP register TL QoS_enabled=%d",
1885 staDesc.ucQosEnabled );
1886
1887 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1888
1889
Jeff Johnson295189b2012-06-20 16:38:30 -07001890 // For PRIMA UMA frame translation is not enable yet.
1891 staDesc.ucSwFrameTXXlation = 1;
1892 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001893 staDesc.ucAddRmvLLC = 1;
1894
1895 // Initialize signatures and state
1896 staDesc.ucUcastSig = ucastSig;
1897 staDesc.ucBcastSig = bcastSig;
1898 staDesc.ucInitState = fAuthRequired ?
1899 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1900
Prathyushaf5442802012-12-12 13:58:11 -08001901 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1902
Jeff Johnson295189b2012-06-20 16:38:30 -07001903 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301904 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1905 hdd_softap_rx_packet_cbk,
1906 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1908
1909 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1910 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301911 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001912 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 vosStatus, vosStatus );
1914 return vosStatus;
1915 }
1916
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001917 //Timer value should be in milliseconds
1918 if ( pHddCtx->cfg_ini->dynSplitscan &&
1919 ( VOS_TIMER_STATE_RUNNING !=
1920 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1921 {
1922 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1923 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1924 }
1925
Jeff Johnson295189b2012-06-20 16:38:30 -07001926 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1927 // then go to 'authenticated'. For all other authentication types (those that do
1928 // not require upper layer authentication) we can put TL directly into 'authenticated'
1929 // state.
1930
1931 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301932 pSapCtx->aStaInfo[staId].ucSTAId = staId;
1933 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001934 if ( !fAuthRequired )
1935 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301936 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1937 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301938 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001939
1940 // Connections that do not need Upper layer auth, transition TL directly
1941 // to 'Authenticated' state.
1942 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1943 WLANTL_STA_AUTHENTICATED );
1944
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301945 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1947 }
1948 else
1949 {
1950
c_hpothu6d1d2a32014-03-18 20:17:03 +05301951 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301952 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001953
1954 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1955 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301956 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001957
1958 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1959
1960 }
1961 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1962 if(pmonAdapter)
1963 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301964 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
1965 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 netif_carrier_on(pmonAdapter->dev);
1967 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301968 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 netif_tx_start_all_queues(pmonAdapter->dev);
1970 }
1971 netif_carrier_on(pAdapter->dev);
1972 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301973 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 netif_tx_start_all_queues(pAdapter->dev);
1975
1976 return( vosStatus );
1977}
1978
1979VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1980{
1981 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1982 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1983 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1984
1985
1986 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1987 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1988 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1989
1990 return vosStatus;
1991}
1992
1993VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1994{
1995 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1996}
1997
1998VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1999{
2000 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2001 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302002 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07002003
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302004 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2005 ptSapContext pSapCtx = NULL;
2006 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2007 if(pSapCtx == NULL){
2008 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2009 FL("psapCtx is NULL"));
2010 return VOS_STATUS_E_FAULT;
2011 }
2012
2013 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07002014 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05302015 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07002016 {
2017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2018 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
2019 return VOS_STATUS_E_PERM;
2020 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002021
2022 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
2023
Jeff Johnson43971f52012-07-17 12:26:56 -07002024 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002025 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302026 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002027 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002028 }
2029
2030 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2031 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302032 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302034 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
2035 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2036 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302037 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002038 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302039 }
2040 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 }
2042
2043 return vosStatus;
2044}
2045
2046VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
2047{
2048 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
2049 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2050 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002051
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302052 ptSapContext pSapCtx = NULL;
2053 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2054 if(pSapCtx == NULL){
2055 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2056 FL("psapCtx is NULL"));
2057 return VOS_STATUS_E_FAULT;
2058 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302059 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002060 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002061
Jeff Johnson43971f52012-07-17 12:26:56 -07002062 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302064 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002065 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 return VOS_STATUS_E_FAILURE;
2067 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002068
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302069 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302071 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002072 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002073 return VOS_STATUS_E_FAILURE;
2074 }
2075
2076 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302077 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002078 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002079
Jeff Johnson43971f52012-07-17 12:26:56 -07002080 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302082 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 }
2084
c_hpothu6d1d2a32014-03-18 20:17:03 +05302085 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002086 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002087
2088 return vosStatus;
2089}
2090
2091
2092VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2093{
2094 v_U8_t i;
2095
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302096 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2097 ptSapContext pSapCtx = NULL;
2098 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2099 if(pSapCtx == NULL){
2100 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2101 FL("psapCtx is NULL"));
2102 return VOS_STATUS_E_FAULT;
2103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2105 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302106 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2107 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 {
2109 *staId = i;
2110 return VOS_STATUS_SUCCESS;
2111 }
2112 }
2113
2114 return VOS_STATUS_E_FAILURE;
2115}
2116
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302117VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2118{
2119 v_U8_t i;
2120
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302121 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2122 ptSapContext pSapCtx = NULL;
2123 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2124 if(pSapCtx == NULL){
2125 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2126 FL("psapCtx is NULL"));
2127 return VOS_STATUS_E_FAULT;
2128 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302129 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2130 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302131 if (pSapCtx->aStaInfo[i].isUsed &&
2132 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302133 {
2134 *staId = i;
2135 return VOS_STATUS_SUCCESS;
2136 }
2137 }
2138
2139 return VOS_STATUS_E_FAILURE;
2140}