blob: 3bcf17fc9e4d65ebb03890dd18782490edc261e1 [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
Abhishek Singh837adf22015-10-01 17:37:37 +053099#define HDD_SAP_TX_STALL_FATAL_EVENT_THRESHOLD 2
100
Mihir Shetef3473692014-06-27 15:13:20 +0530101
102static DEFINE_RATELIMIT_STATE(hdd_softap_tx_timeout_rs, \
103 HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL, \
104 HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST);
105
Leo Chang64d68bc2013-06-04 15:40:52 -0700106/**============================================================================
107 @brief hdd_softap_traffic_monitor_timeout_handler() -
108 SAP/P2P GO traffin monitor timeout handler function
109 If no traffic during programmed time, trigger suspand mode
110
111 @param pUsrData : [in] pointer to hdd context
112 @return : NONE
113 ===========================================================================*/
114void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData )
115{
116 hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData;
117 v_TIME_t currentTS;
118
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530119 ENTER();
120 if (0 != (wlan_hdd_validate_context(pHddCtx)))
Leo Chang64d68bc2013-06-04 15:40:52 -0700121 {
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530122 return;
Leo Chang64d68bc2013-06-04 15:40:52 -0700123 }
124
125 currentTS = vos_timer_get_system_time();
126 if (pHddCtx->cfg_ini->trafficIdleTimeout <
127 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
128 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530129 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530130 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -0700131 hdd_set_wlan_suspend_mode(1);
132 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
133 }
134 else
135 {
136 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
137 pHddCtx->cfg_ini->trafficIdleTimeout);
138 }
139
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530140 EXIT();
Leo Chang64d68bc2013-06-04 15:40:52 -0700141 return;
142}
143
Kiet Lambcf38522013-10-26 18:28:27 +0530144VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter )
145{
146
147 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
148 VOS_STATUS status = VOS_STATUS_SUCCESS;
149
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530150 ENTER();
Kiet Lambcf38522013-10-26 18:28:27 +0530151 status = wlan_hdd_validate_context(pHddCtx);
Kiet Lambcf38522013-10-26 18:28:27 +0530152 if (0 != status)
153 {
Kiet Lambcf38522013-10-26 18:28:27 +0530154 return status;
155 }
156
157 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
158 (!pHddCtx->traffic_monitor.isInitialized))
159 {
160 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
161 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
162 VOS_TIMER_TYPE_SW,
163 hdd_softap_traffic_monitor_timeout_handler,
164 pHddCtx);
165 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
166 pHddCtx->traffic_monitor.isInitialized = 1;
167 pHddCtx->traffic_monitor.lastFrameTs = 0;
168 /* Start traffic monitor timer here
169 * If no AP assoc, immediatly go into suspend */
c_hpothu6d1d2a32014-03-18 20:17:03 +0530170 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530171 "%s Start Traffic Monitor Timer", __func__);
172 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
173 pHddCtx->cfg_ini->trafficIdleTimeout);
174 }
175 else
176 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530177 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530178 "%s Traffic Monitor is not Enable in ini file", __func__);
179 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530180
181 EXIT();
Kiet Lambcf38522013-10-26 18:28:27 +0530182 return status;
183}
184
185VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter )
186{
187 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
188 VOS_STATUS status = VOS_STATUS_SUCCESS;
189
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530190 ENTER();
Kiet Lambcf38522013-10-26 18:28:27 +0530191 status = wlan_hdd_validate_context(pHddCtx);
Kiet Lamae69d7a2013-11-08 14:38:04 +0530192 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530193 {
Kiet Lambcf38522013-10-26 18:28:27 +0530194 return status;
195 }
196
197 if (pHddCtx->traffic_monitor.isInitialized)
198 {
199 if (VOS_TIMER_STATE_STOPPED !=
200 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
201 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530202 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530203 "%s Stop Traffic Monitor Timer", __func__);
204 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
205 }
c_hpothu6d1d2a32014-03-18 20:17:03 +0530206 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530207 "%s Destroy Traffic Monitor Timer", __func__);
208 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
209 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
210 pHddCtx->traffic_monitor.isInitialized = 0;
211 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530212 EXIT();
Kiet Lamae69d7a2013-11-08 14:38:04 +0530213 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530214}
215
Jeff Johnson295189b2012-06-20 16:38:30 -0700216/**============================================================================
217 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
218
219 @param pAdapter : [in] pointer to adapter context
220 @return : VOS_STATUS_E_FAILURE if any errors encountered
221 : VOS_STATUS_SUCCESS otherwise
222 ===========================================================================*/
223static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
224{
225 VOS_STATUS status = VOS_STATUS_SUCCESS;
226 v_SINT_t i = -1;
227 v_U8_t STAId = 0;
228 hdd_list_node_t *anchor = NULL;
229 skb_list_node_t *pktNode = NULL;
230 struct sk_buff *skb = NULL;
231
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530232 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
233 ptSapContext pSapCtx = NULL;
234 pSapCtx = VOS_GET_SAP_CB(pVosContext);
235 if(pSapCtx == NULL){
236 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
237 FL("psapCtx is NULL"));
238 return VOS_STATUS_E_FAULT;
239 }
240 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700241 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
242 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530243 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 {
245 continue;
246 }
247
248 for (i = 0; i < NUM_TX_QUEUES; i ++)
249 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530250 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700251 while (true)
252 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530253 status = hdd_list_remove_front ( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
Jeff Johnson295189b2012-06-20 16:38:30 -0700254
255 if (VOS_STATUS_E_EMPTY != status)
256 {
257 //If success then we got a valid packet from some AC
258 pktNode = list_entry(anchor, skb_list_node_t, anchor);
259 skb = pktNode->skb;
260 ++pAdapter->stats.tx_dropped;
261 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
262 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
263 kfree_skb(skb);
264 continue;
265 }
266
267 //current list is empty
268 break;
269 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530270 pSapCtx->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
271 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530273 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 }
275
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530276 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278 return status;
279}
280
281/**============================================================================
282 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
283 transmitting packets. There are 2 versions of this function. One that uses
284 locked queue and other that uses lockless queues. Both have been retained to
285 do some performance testing
286
287 @param skb : [in] pointer to OS packet (sk_buff)
288 @param dev : [in] pointer to Libra network device
289
290 @return : NET_XMIT_DROP if packets are dropped
291 : NET_XMIT_SUCCESS if packet is enqueued succesfully
292 ===========================================================================*/
293int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
294{
295 VOS_STATUS status;
296 WLANTL_ACEnumType ac = WLANTL_AC_BE;
297 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
298 skb_list_node_t *pktNode = NULL;
299 v_SIZE_t pktListSize = 0;
300 v_BOOL_t txSuspended = VOS_FALSE;
301 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
302 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530303 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 vos_list_node_t *anchor = NULL;
305 v_U8_t STAId = WLAN_MAX_STA_COUNT;
306 //Extract the destination address from ethernet frame
307 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
308 int os_status = NETDEV_TX_OK;
Mihir Shetef8f74532014-12-04 11:53:34 +0530309 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700310
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530311 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
312 ptSapContext pSapCtx = NULL;
313 pSapCtx = VOS_GET_SAP_CB(pVosContext);
314 if(pSapCtx == NULL){
315 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
316 FL("psapCtx is NULL"));
317 ++pAdapter->stats.tx_dropped;
318 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
319 kfree_skb(skb);
320 return os_status;
321 }
322
Ratheesh S Pe8f00c62015-08-20 13:03:01 +0530323 if (pHddCtx == NULL)
324 {
325 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
326 FL("pHddCtx is NULL"));
327 goto xmit_done;
328 }
329
Jeff Johnson295189b2012-06-20 16:38:30 -0700330 pDestMacAddress = (v_MACADDR_t*)skb->data;
331
332 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
333
c_hpothu6d1d2a32014-03-18 20:17:03 +0530334 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700335 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700336
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530337 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
339 {
340 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
341 //ID used for BC/MC traffic. The station id is registered to TL as well.
342 STAId = pHddApCtx->uBCStaId;
343
344 /* Setting priority for broadcast packets which doesn't go to select_queue function */
345 skb->priority = SME_QOS_WMM_UP_BE;
346 skb->queue_mapping = HDD_LINUX_AC_BE;
347
c_hpothu6d1d2a32014-03-18 20:17:03 +0530348 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800349 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 }
351 else
352 {
Nirav Shah7e3c8132015-06-22 23:51:42 +0530353 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700354 if (STAId == HDD_WLAN_INVALID_STA_ID)
355 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530356 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700357 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 ++pAdapter->stats.tx_dropped;
359 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
360 kfree_skb(skb);
361 goto xmit_done;
362 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530363 else if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700364 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530365 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
366 "%s: STA %d is unregistered", __func__, STAId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700367 ++pAdapter->stats.tx_dropped;
368 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
369 kfree_skb(skb);
370 goto xmit_done;
371 }
372
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530373 if ( (WLANTL_STA_CONNECTED != pSapCtx->aStaInfo[STAId].tlSTAState) &&
374 (WLANTL_STA_AUTHENTICATED != pSapCtx->aStaInfo[STAId].tlSTAState) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700375 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530376 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700377 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 ++pAdapter->stats.tx_dropped;
379 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
380 kfree_skb(skb);
381 goto xmit_done;
382 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530383 else if(WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[STAId].tlSTAState)
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 {
385 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
386 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530387 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700388 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 ++pAdapter->stats.tx_dropped;
390 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
391 kfree_skb(skb);
392 goto xmit_done;
393 }
394 }
395 }
396
397 //Get TL AC corresponding to Qdisc queue index/AC.
398 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
399 //user priority from IP header, which is already extracted and set from
400 //select_queue call back function
401 up = skb->priority;
402 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
403
c_hpothu6d1d2a32014-03-18 20:17:03 +0530404 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700405 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700406
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530407 if (( NULL != pHddCtx ) &&
408 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530409 {
410 hdd_dump_dhcp_pkt(skb, TX_PATH);
411 }
412
Jeff Johnson295189b2012-06-20 16:38:30 -0700413 // If the memory differentiation mode is enabled, the memory limit of each queue will be
414 // checked. Over-limit packets will be dropped.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530415 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
416 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700417 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
418 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530419 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800420 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Bhargav Shah7f03b812015-08-21 11:17:32 +0530421 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured;
422 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530423 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700424 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
425 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530426 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
427 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -0700428 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530429
430 /* If 3/4th of the max queue size is used then enable the flag.
431 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
432 if (WLANTL_AC_BE == ac)
433 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530434 if (pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530435 {
Sushant Kaushik40bcd6e2015-09-18 12:09:54 +0530436 if (!(pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count % 0x40))
437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530438 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
Sushant Kaushik40bcd6e2015-09-18 12:09:54 +0530439 pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count++;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530440 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_TRUE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530441 }
442 else
443 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530444 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530445 }
446 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530447 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700448
449 if (VOS_TRUE == txSuspended)
450 {
451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
452 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700453 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700454 os_status = NETDEV_TX_BUSY;
455 goto xmit_done;
456 }
457
458 //Use the skb->cb field to hold the list node information
459 pktNode = (skb_list_node_t *)&skb->cb;
460
461 //Stick the OS packet inside this node.
462 pktNode->skb = skb;
463
464 //Stick the User Priority inside this node
465 pktNode->userPriority = up;
466
467 INIT_LIST_HEAD(&pktNode->anchor);
468
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530469 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
470 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
471 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700472 if ( !VOS_IS_STATUS_SUCCESS( status ) )
473 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530474 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
475 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700476 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
477 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
478 ++pAdapter->stats.tx_dropped;
479 kfree_skb(skb);
480 goto xmit_done;
481 }
482
483 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
484 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530485 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700486
487 if (1 == pktListSize)
488 {
489 //Let TL know we have a packet to send for this AC
490 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
491
492 if ( !VOS_IS_STATUS_SUCCESS( status ) )
493 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530494 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
495 "%s: Failed to signal TL for AC=%d STAId =%d",
496 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700497
498 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
499 //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 +0530500 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
501 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
502 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530503 /* Free the skb only if we are able to remove it from the list.
504 * If we are not able to retrieve it from the list it means that
505 * the skb was pulled by TX Thread and is use so we should not free
506 * it here
507 */
508 if (VOS_IS_STATUS_SUCCESS(status))
509 {
510 pktNode = list_entry(anchor, skb_list_node_t, anchor);
511 skb1 = pktNode->skb;
512 kfree_skb(skb1);
513 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700514 ++pAdapter->stats.tx_dropped;
515 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
516 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700517 goto xmit_done;
518 }
519 }
520 dev->trans_start = jiffies;
521
c_hpothu6d1d2a32014-03-18 20:17:03 +0530522 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
523 "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700524
525xmit_done:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530526 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700527 return os_status;
528}
529
530/**============================================================================
531 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
532
533 @param skb : [in] pointer to packet (sk_buff)
534 @param dev : [in] pointer to Libra network device
535 @param STAId : [in] Station Id of Destination Station
536 @param up : [in] User Priority
537
538 @return : NET_XMIT_DROP if packets are dropped
539 : NET_XMIT_SUCCESS if packet is enqueued succesfully
540 ===========================================================================*/
541VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
542 struct net_device *dev,
543 v_U8_t STAId,
544 v_U8_t up)
545{
546 VOS_STATUS status = VOS_STATUS_SUCCESS;
547 skb_list_node_t *pktNode = NULL;
548 v_SIZE_t pktListSize = 0;
549 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
550 v_U8_t ac;
551 vos_list_node_t *anchor = NULL;
Mihir Shetef8f74532014-12-04 11:53:34 +0530552 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700553
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530554 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
555 ptSapContext pSapCtx = NULL;
556 pSapCtx = VOS_GET_SAP_CB(pVosContext);
557 if(pSapCtx == NULL){
558 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
559 FL("psapCtx is NULL"));
560 kfree_skb(skb);
561 status = VOS_STATUS_E_FAILURE;
562 return status;
563 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700564 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
565
c_hpothu6d1d2a32014-03-18 20:17:03 +0530566 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700567 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700568
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530569 spin_lock_bh( &pSapCtx->staInfo_lock );
570 if ( FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700571 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530572 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530573 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700574 kfree_skb(skb);
575 status = VOS_STATUS_E_FAILURE;
576 goto xmit_end;
577 }
578
579 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530580 if ( !pSapCtx->aStaInfo[STAId].isQosEnabled )
Jeff Johnson295189b2012-06-20 16:38:30 -0700581 up = SME_QOS_WMM_UP_BE;
582
583 ac = hddWmmUpToAcMap[up];
584 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
c_hpothu6d1d2a32014-03-18 20:17:03 +0530585 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700586 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700587
588 skb->queue_mapping = hddLinuxUpToAcMap[up];
589
590 //Use the skb->cb field to hold the list node information
591 pktNode = (skb_list_node_t *)&skb->cb;
592
593 //Stick the OS packet inside this node.
594 pktNode->skb = skb;
595
596 //Stick the User Priority inside this node
597 pktNode->userPriority = up;
598
599 INIT_LIST_HEAD(&pktNode->anchor);
600
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530601 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
602 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
603 if(pSapCtx->aStaInfo[STAId].txSuspended[ac] ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700604 pktListSize >= pAdapter->aTxQueueLimit[ac])
605 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530606 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800607 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700608 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
609 * SUSPEND should be done based on Threshold. RESUME would be
610 * triggered in fetch cbk after recovery.
611 */
612 kfree_skb(skb);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530613 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700614 status = VOS_STATUS_E_FAILURE;
615 goto xmit_end;
616 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530617 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
618 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700619
620 if ( !VOS_IS_STATUS_SUCCESS( status ) )
621 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530622 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
623 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700624 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
625 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
626 ++pAdapter->stats.tx_dropped;
627 kfree_skb(skb);
628 status = VOS_STATUS_E_FAILURE;
629 goto xmit_end;
630 }
631
632 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
633 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
634
635 if (1 == pktListSize)
636 {
637 //Let TL know we have a packet to send for this AC
c_hpothu6d1d2a32014-03-18 20:17:03 +0530638 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
639 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700640
641 if ( !VOS_IS_STATUS_SUCCESS( status ) )
642 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530643 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
644 "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700645 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700646
647 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
648 //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 +0530649 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
650 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
651 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530652 /* Free the skb only if we are able to remove it from the list.
653 * If we are not able to retrieve it from the list it means that
654 * the skb was pulled by TX Thread and is use so we should not free
655 * it here
656 */
657 if (VOS_IS_STATUS_SUCCESS(status))
658 {
659 pktNode = list_entry(anchor, skb_list_node_t, anchor);
660 skb1 = pktNode->skb;
661 kfree_skb(skb1);
662 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700663 ++pAdapter->stats.tx_dropped;
664 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
665 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700666 status = VOS_STATUS_E_FAILURE;
667 goto xmit_end;
668 }
669 }
670
c_hpothu6d1d2a32014-03-18 20:17:03 +0530671 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700672
673xmit_end:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530674 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700675 return status;
676}
677
678/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530679 @brief __hdd_softap_tx_timeout() - Function called by OS if there is any
Jeff Johnson295189b2012-06-20 16:38:30 -0700680 timeout during transmission. Since HDD simply enqueues packet
681 and returns control to OS right away, this would never be invoked
682
683 @param dev : [in] pointer to Libra network device
684 @return : None
685 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530686void __hdd_softap_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700687{
Mihir Shetef3473692014-06-27 15:13:20 +0530688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
689 struct netdev_queue *txq;
690 int i = 0;
Mukul Sharma4b322632015-02-28 20:21:43 +0530691 int status = 0;
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530692 hdd_context_t *pHddCtx;
Mihir Shetef3473692014-06-27 15:13:20 +0530693
c_hpothu6d1d2a32014-03-18 20:17:03 +0530694 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700695 "%s: Transmission timeout occurred", __func__);
Mihir Shetef3473692014-06-27 15:13:20 +0530696
697 if ( NULL == pAdapter )
698 {
699 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
700 FL("pAdapter is NULL"));
701 VOS_ASSERT(0);
702 return;
703 }
704
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530705 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mukul Sharma4b322632015-02-28 20:21:43 +0530706 status = wlan_hdd_validate_context(pHddCtx);
707 if (status != 0)
708 {
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530709 return;
710 }
711
Mihir Shetef3473692014-06-27 15:13:20 +0530712 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
713
mukul sharma2cdb8ea2015-10-01 14:53:38 +0530714 for (i = 0; i < NUM_TX_QUEUES; i++)
Mihir Shetef3473692014-06-27 15:13:20 +0530715 {
716 txq = netdev_get_tx_queue(dev, i);
717 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
718 "Queue%d status: %d", i, netif_tx_queue_stopped(txq));
719 }
720
721 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
mukul sharma2cdb8ea2015-10-01 14:53:38 +0530722 "carrier state: %d", netif_carrier_ok(dev));
Mihir Shetef3473692014-06-27 15:13:20 +0530723
724 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
725
Mihir Shete327c2ab2014-11-13 15:17:02 +0530726 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
727 HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
728 {
729 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
730 "%s: Request firmware for recovery",__func__);
731 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
732 }
Mihir Shetef3473692014-06-27 15:13:20 +0530733 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
734 HDD_SAP_TX_STALL_SSR_THRESHOLD)
735 {
736 // Driver could not recover, issue SSR
737 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
738 "%s: Cannot recover from Data stall Issue SSR",
739 __func__);
Mihir Shetefd62d9d2014-08-06 15:08:21 +0530740 WLANTL_FatalError();
Mukul Sharma987bef02015-11-16 20:04:54 +0530741 // reset count after issuing the SSR
742 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Mihir Shetef3473692014-06-27 15:13:20 +0530743 return;
744 }
745
746 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
747 * every 5sec. The TL debug spits out a lot of information on the
748 * serial console, if it is called every time *hdd_tx_timeout* is
749 * called then we may get a watchdog bite on the Application
750 * processor, so ratelimit the TL debug logs.
751 */
752 if (__ratelimit(&hdd_softap_tx_timeout_rs))
753 {
754 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +0530755 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetef3473692014-06-27 15:13:20 +0530756 }
Abhishek Singh837adf22015-10-01 17:37:37 +0530757 /* Call fatal event if data stall is for
758 * HDD_TX_STALL_FATAL_EVENT_THRESHOLD times
759 */
760 if (HDD_SAP_TX_STALL_FATAL_EVENT_THRESHOLD ==
761 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount)
762 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
763 WLAN_LOG_INDICATOR_HOST_DRIVER,
764 WLAN_LOG_REASON_DATA_STALL,
765 FALSE, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700766}
767
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530768void hdd_softap_tx_timeout(struct net_device *dev)
769{
770 vos_ssr_protect(__func__);
771 __hdd_softap_tx_timeout(dev);
772 vos_ssr_unprotect(__func__);
773 return;
774}
Jeff Johnson295189b2012-06-20 16:38:30 -0700775
776/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530777 @brief __hdd_softap_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700778 device TX/RX statistic
779
780 @param dev : [in] pointer to Libra network device
781
782 @return : pointer to net_device_stats structure
783 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530784struct net_device_stats* __hdd_softap_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700785{
786 hdd_adapter_t* priv = netdev_priv(dev);
787 return &priv->stats;
788}
789
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530790struct net_device_stats* hdd_softap_stats(struct net_device *dev)
791{
792 struct net_device_stats *priv_stats;
793 vos_ssr_protect(__func__);
794 priv_stats = __hdd_softap_stats(dev);
795 vos_ssr_unprotect(__func__);
796
797 return priv_stats;
798}
Jeff Johnson295189b2012-06-20 16:38:30 -0700799
800/**============================================================================
801 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
802 modules in HDD
803
804 @param pAdapter : [in] pointer to adapter context
805 @return : VOS_STATUS_E_FAILURE if any errors encountered
806 : VOS_STATUS_SUCCESS otherwise
807 ===========================================================================*/
808VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
809{
810 VOS_STATUS status = VOS_STATUS_SUCCESS;
811 v_SINT_t i = -1;
812 v_SIZE_t size = 0;
813
814 v_U8_t STAId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530815 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
816 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700817
818 v_U8_t pACWeights[] = {
819 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
820 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
821 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
822 HDD_SOFTAP_VO_WEIGHT_DEFAULT
823 };
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530824 pSapCtx = VOS_GET_SAP_CB(pVosContext);
825 if(pSapCtx == NULL){
826 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
827 FL("psapCtx is NULL"));
828 return VOS_STATUS_E_FAULT;
829 }
830
Leo Chang64d68bc2013-06-04 15:40:52 -0700831
Jeff Johnson295189b2012-06-20 16:38:30 -0700832 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530833 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700834
835 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
836
837 while (++i != NUM_TX_QUEUES)
838 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
839
840 /* Initial HDD buffer control / flow control fields*/
841 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
842
843 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
844 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
845 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
846 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
847
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
849 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530850 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700851 for (i = 0; i < NUM_TX_QUEUES; i ++)
852 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530853 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700854 }
855 }
856
Yue Ma3ede6052013-08-29 00:33:26 -0700857 /* Update the AC weights suitable for SoftAP mode of operation */
858 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
859
Kiet Lambcf38522013-10-26 18:28:27 +0530860 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700861 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530862 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530863 "%s: failed to start Traffic Monito timer ", __func__ );
864 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700865 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 return status;
867}
868
869/**============================================================================
870 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
871 modules in HDD
872
873 @param pAdapter : [in] pointer to adapter context
874 @return : VOS_STATUS_E_FAILURE if any errors encountered
875 : VOS_STATUS_SUCCESS otherwise
876 ===========================================================================*/
877VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
878{
879 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700880
Kiet Lambcf38522013-10-26 18:28:27 +0530881 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700882 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530883 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530884 "%s: Fail to Stop Traffic Monito timer", __func__ );
885 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700886 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700887
888 status = hdd_softap_flush_tx_queues(pAdapter);
889
890 return status;
891}
892
893/**============================================================================
894 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
895
896 @param pAdapter : [in] pointer to adapter context
897 @param STAId : [in] Station ID to deinit
898 @return : VOS_STATUS_E_FAILURE if any errors encountered
899 : VOS_STATUS_SUCCESS otherwise
900 ===========================================================================*/
901static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
902{
Jeff Johnson295189b2012-06-20 16:38:30 -0700903 v_U8_t i = -1;
904
905 hdd_list_node_t *anchor = NULL;
906
907 skb_list_node_t *pktNode = NULL;
908 struct sk_buff *skb = NULL;
909
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530910 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
911 ptSapContext pSapCtx = NULL;
912 pSapCtx = VOS_GET_SAP_CB(pVosContext);
913 if(pSapCtx == NULL){
914 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
915 FL("psapCtx is NULL"));
916 return VOS_STATUS_E_FAULT;
917 }
918 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700919 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530920 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700921 }
922
923 for (i = 0; i < NUM_TX_QUEUES; i ++)
924 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530925 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700926 while (true)
927 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530928 if (VOS_STATUS_E_EMPTY !=
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530929 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530930 &anchor))
Jeff Johnson295189b2012-06-20 16:38:30 -0700931 {
932 //If success then we got a valid packet from some AC
933 pktNode = list_entry(anchor, skb_list_node_t, anchor);
934 skb = pktNode->skb;
935 ++pAdapter->stats.tx_dropped;
936 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
937 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
938 kfree_skb(skb);
939 continue;
940 }
941
942 //current list is empty
943 break;
944 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530945 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700946 }
947
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530948 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700949}
950
951/**============================================================================
952 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
953 modules in HDD
954
955 @param pAdapter : [in] pointer to adapter context
956 @param STAId : [in] Station ID to deinit
957 @param pmacAddrSTA : [in] pointer to the MAC address of the station
958 @return : VOS_STATUS_E_FAILURE if any errors encountered
959 : VOS_STATUS_SUCCESS otherwise
960 ===========================================================================*/
961VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
962{
963 v_U8_t i = 0;
Nirav Shah7e3c8132015-06-22 23:51:42 +0530964 VOS_STATUS status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530965 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
966 ptSapContext pSapCtx = NULL;
Nirav Shah7e3c8132015-06-22 23:51:42 +0530967
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530968 pSapCtx = VOS_GET_SAP_CB(pVosContext);
969 if(pSapCtx == NULL){
970 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
971 FL("psapCtx is NULL"));
972 return VOS_STATUS_E_FAULT;
973 }
974
975 spin_lock_bh( &pSapCtx->staInfo_lock );
976 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700977 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530978 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
979 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530980 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 return VOS_STATUS_E_FAILURE;
982 }
983
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530984 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 for (i = 0; i < NUM_TX_QUEUES; i ++)
986 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530987 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700988 }
989
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530990 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
991 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
992 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700993
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530994 spin_unlock_bh( &pSapCtx->staInfo_lock );
Nirav Shah7e3c8132015-06-22 23:51:42 +0530995
996 status = hdd_sta_id_hash_add_entry(pAdapter, STAId, pmacAddrSTA);
997 if (status != VOS_STATUS_SUCCESS) {
998 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
999 FL("Not able to add staid hash %d"), STAId);
1000 return VOS_STATUS_E_FAILURE;
1001 }
1002
1003 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1004 FL("New station added sta_id %d mac:"
1005 MAC_ADDRESS_STR), STAId,
1006 MAC_ADDR_ARRAY(pmacAddrSTA->bytes));
1007
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 return VOS_STATUS_SUCCESS;
1009}
1010
1011/**============================================================================
1012 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
1013 modules in HDD
1014
1015 @param pAdapter : [in] pointer to adapter context
1016 @param STAId : [in] Station ID to deinit
1017 @return : VOS_STATUS_E_FAILURE if any errors encountered
1018 : VOS_STATUS_SUCCESS otherwise
1019 ===========================================================================*/
1020VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
1021{
1022 VOS_STATUS status = VOS_STATUS_SUCCESS;
1023 v_U8_t ac;
1024 /**Track whether OS TX queue has been disabled.*/
1025 v_BOOL_t txSuspended[NUM_TX_QUEUES];
1026 v_U8_t tlAC;
1027 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001028 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -07001029
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301030 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1031 ptSapContext pSapCtx = NULL;
1032 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1033 if(pSapCtx == NULL){
1034 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1035 FL("psapCtx is NULL"));
1036 return VOS_STATUS_E_FAULT;
1037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1039
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301040 spin_lock_bh( &pSapCtx->staInfo_lock );
1041 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301043 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001044 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301045 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 return VOS_STATUS_E_FAILURE;
1047 }
1048
1049 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1050
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301051 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1052 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301053
1054 status = hdd_sta_id_hash_remove_entry(pAdapter,
1055 STAId, &pSapCtx->aStaInfo[STAId].macAddrSTA);
1056 if (status != VOS_STATUS_SUCCESS) {
1057 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1058 FL("Not able to remove staid hash %d"), STAId);
1059 return VOS_STATUS_E_FAILURE;
1060 }
1061
1062 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1063 FL("station removed sta_id %d mac:"
1064 MAC_ADDRESS_STR), STAId,
1065 MAC_ADDR_ARRAY(pSapCtx->aStaInfo[STAId].macAddrSTA.bytes));
1066
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 /* if this STA had any of its WMM TX queues suspended, then the
1068 associated queue on the network interface was disabled. check
1069 to see if that is the case, in which case we need to re-enable
1070 the interface queue. but we only do this if the BSS is running
1071 since, if the BSS is stopped, all of the interfaces have been
1072 stopped and should not be re-enabled */
1073
1074 if (BSS_START == pHostapdState->bssState)
1075 {
1076 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1077 {
1078 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301079 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001080 }
1081 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301082 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001083
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001084 /* re-init spin lock, since netdev can still open adapter until
1085 * driver gets unloaded
1086 */
1087 for (i = 0; i < NUM_TX_QUEUES; i ++)
1088 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301089 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001090 HDD_TX_QUEUE_MAX_LEN);
1091 }
1092
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 if (BSS_START == pHostapdState->bssState)
1094 {
1095 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1096 {
1097 if (txSuspended[ac])
1098 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301099 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001100 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 netif_wake_subqueue(pAdapter->dev, ac);
1102 }
1103 }
1104 }
1105
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301106 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 return status;
1108}
1109
1110/**============================================================================
1111 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1112 modules in HDD
1113
1114 @param pAdapter : [in] pointer to adapter context
1115 @return : VOS_STATUS_E_FAILURE if any errors encountered
1116 : VOS_STATUS_SUCCESS otherwise
1117 ===========================================================================*/
1118VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1119{
1120 return hdd_softap_flush_tx_queues(pAdapter);
1121}
1122
1123/**============================================================================
1124 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1125 to indicate that a packet has been transmitted across the bus
1126 succesfully. OS packet resources can be released after this cbk.
1127
1128 @param vosContext : [in] pointer to VOS context
1129 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1130 @param vosStatusIn : [in] status of the transmission
1131
1132 @return : VOS_STATUS_E_FAILURE if any errors encountered
1133 : VOS_STATUS_SUCCESS otherwise
1134 ===========================================================================*/
1135VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1136 vos_pkt_t *pVosPacket,
1137 VOS_STATUS vosStatusIn )
1138{
1139 VOS_STATUS status = VOS_STATUS_SUCCESS;
1140 hdd_adapter_t *pAdapter = NULL;
1141 void* pOsPkt = NULL;
1142
1143 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1144 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301145 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1146 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001147 return VOS_STATUS_E_FAILURE;
1148 }
1149
1150 //Return the skb to the OS
1151 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001152 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 {
1154 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301155 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1156 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 vos_pkt_return_packet( pVosPacket );
1158 return VOS_STATUS_E_FAILURE;
1159 }
1160
1161 //Get the Adapter context.
1162 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301163 if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001164 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301165 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301166 "%s: HDD adapter context is invalid", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 }
1168 else
1169 {
1170 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1171 }
1172
1173 kfree_skb((struct sk_buff *)pOsPkt);
1174
1175 //Return the VOS packet resources.
1176 status = vos_pkt_return_packet( pVosPacket );
1177 if(!VOS_IS_STATUS_SUCCESS( status ))
1178 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301179 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1180 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 }
1182
1183 return status;
1184}
1185
1186
1187/**============================================================================
1188 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1189 fetch a packet for transmission.
1190
1191 @param vosContext : [in] pointer to VOS context
1192 @param staId : [in] Station for which TL is requesting a pkt
1193 @param ac : [in] access category requested by TL
1194 @param pVosPacket : [out] pointer to VOS packet packet pointer
1195 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1196
1197 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1198 : VOS_STATUS_E_FAILURE if any errors encountered
1199 : VOS_STATUS_SUCCESS otherwise
1200 ===========================================================================*/
1201VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1202 v_U8_t *pStaId,
1203 WLANTL_ACEnumType ac,
1204 vos_pkt_t **ppVosPacket,
1205 WLANTL_MetaInfoType *pPktMetaInfo )
1206{
1207 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1208 hdd_adapter_t *pAdapter = NULL;
1209 hdd_list_node_t *anchor = NULL;
1210 skb_list_node_t *pktNode = NULL;
1211 struct sk_buff *skb = NULL;
1212 vos_pkt_t *pVosPacket = NULL;
1213 v_MACADDR_t* pDestMacAddress = NULL;
1214 v_TIME_t timestamp;
1215 v_SIZE_t size = 0;
1216 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1217 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001218 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301219 v_CONTEXT_t pVosContext = NULL;
1220 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 //Sanity check on inputs
1222 if ( ( NULL == vosContext ) ||
1223 ( NULL == pStaId ) ||
1224 ( NULL == ppVosPacket ) ||
1225 ( NULL == pPktMetaInfo ) )
1226 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301227 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1228 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 return VOS_STATUS_E_FAILURE;
1230 }
1231
1232 //Get the HDD context.
1233 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1234 if ( NULL == pHddCtx )
1235 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301236 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1237 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001238 return VOS_STATUS_E_FAILURE;
1239 }
1240
Jeff Johnsonb156c922013-12-05 17:19:46 -08001241 STAId = *pStaId;
1242 if (STAId >= WLAN_MAX_STA_COUNT)
1243 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301244 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001245 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1246 return VOS_STATUS_E_FAILURE;
1247 }
1248
1249 pAdapter = pHddCtx->sta_to_adapter[STAId];
1250 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001251 {
1252 VOS_ASSERT(0);
1253 return VOS_STATUS_E_FAILURE;
1254 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301255 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1256 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1257 if(pSapCtx == NULL){
1258 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1259 FL("psapCtx is NULL"));
1260 return VOS_STATUS_E_FAULT;
1261 }
1262
1263 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001264 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301265 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001266 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1267 return VOS_STATUS_E_FAILURE;
1268 }
1269
Leo Chang64d68bc2013-06-04 15:40:52 -07001270 /* Monitor traffic */
1271 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1272 {
1273 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1274 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1275 {
1276 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1277 /* It was IDLE mode,
1278 * this is new state, then switch mode from suspend to resume */
1279 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1280 {
1281 hdd_set_wlan_suspend_mode(0);
1282 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1283 pHddCtx->cfg_ini->trafficIdleTimeout);
1284 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1285 }
1286 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1287 }
1288 }
1289
Jeff Johnson295189b2012-06-20 16:38:30 -07001290 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1291
Jeff Johnson295189b2012-06-20 16:38:30 -07001292 *ppVosPacket = NULL;
1293
1294 //Make sure the AC being asked for is sane
1295 if( ac > WLANTL_MAX_AC || ac < 0)
1296 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301297 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001298 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001299 return VOS_STATUS_E_FAILURE;
1300 }
1301
1302 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1303
c_hpothu6d1d2a32014-03-18 20:17:03 +05301304 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001305 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001306
1307 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1308 //This simplifies the locking and unlocking of Tx queue
1309 status = vos_pkt_wrap_data_packet( &pVosPacket,
1310 VOS_PKT_TYPE_TX_802_3_DATA,
1311 NULL, //OS Pkt is not being passed
1312 hdd_softap_tx_low_resource_cbk,
1313 pAdapter );
1314
1315 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1316 {
1317 //Remember VOS is in a low resource situation
1318 pAdapter->isVosOutOfResource = VOS_TRUE;
1319 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301320 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001321 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1323 return VOS_STATUS_E_FAILURE;
1324 }
1325
1326 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1327 as the other branch does.
1328 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301329 spin_lock_bh( &pSapCtx->staInfo_lock );
1330 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1331 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001332
1333 if (0 == size)
1334 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301335 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1336 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 vos_pkt_return_packet(pVosPacket);
1338 return VOS_STATUS_E_EMPTY;
1339 }
1340
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301341 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1342 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1343 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001344
c_hpothu6d1d2a32014-03-18 20:17:03 +05301345 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001346 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001347
1348 if(VOS_STATUS_SUCCESS == status)
1349 {
1350 //If success then we got a valid packet from some AC
1351 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1352 skb = pktNode->skb;
1353 }
1354 else
1355 {
1356 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301357 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001359 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 vos_pkt_return_packet(pVosPacket);
1361 return VOS_STATUS_E_FAILURE;
1362 }
1363
1364 //Attach skb to VOS packet.
1365 status = vos_pkt_set_os_packet( pVosPacket, skb );
1366 if (status != VOS_STATUS_SUCCESS)
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: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001370 vos_pkt_return_packet(pVosPacket);
1371 ++pAdapter->stats.tx_dropped;
1372 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1373 kfree_skb(skb);
1374 return VOS_STATUS_E_FAILURE;
1375 }
1376
1377 //Just being paranoid. To be removed later
1378 if(pVosPacket == NULL)
1379 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301380 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001381 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001382 ++pAdapter->stats.tx_dropped;
1383 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1384 kfree_skb(skb);
1385 return VOS_STATUS_E_FAILURE;
1386 }
1387
1388 //Return VOS packet to TL;
1389 *ppVosPacket = pVosPacket;
1390
1391 //Fill out the meta information needed by TL
1392 //FIXME This timestamp is really the time stamp of wrap_data_packet
1393 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1394 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1395 if ( 1 < size )
1396 {
1397 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1398 }
1399 else
1400 {
1401 pPktMetaInfo->bMorePackets = 0;
1402 }
1403
1404 pPktMetaInfo->ucIsEapol = 0;
1405
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301406 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 {
1408 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1409 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001410 pPktMetaInfo->ucIsEapol = 1;
Sushant Kaushika8073312015-05-04 17:33:52 +05301411 wlan_hdd_log_eapol(skb,
1412 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
Jeff Johnson295189b2012-06-20 16:38:30 -07001413 }
1414 }
Sushant Kaushika8073312015-05-04 17:33:52 +05301415
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301416 if ((NULL != pHddCtx) &&
1417 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001418 {
1419 proto_type = vos_pkt_get_proto_type(skb,
1420 pHddCtx->cfg_ini->gEnableDebugLog);
1421 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1422 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001424 "SAP TX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001425 }
1426 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1427 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001429 "SAP TX DHCP");
1430 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301431 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1432 {
1433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1434 "SAP TX ARP");
1435 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001436 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001437//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301439 pPktMetaInfo->ac = ac;
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 pPktMetaInfo->ucUP = pktNode->userPriority;
1441 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1442 }
1443
1444 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1445 //Extract the destination address from ethernet frame
1446 pDestMacAddress = (v_MACADDR_t*)skb->data;
1447
1448 // we need 802.3 to 802.11 frame translation
1449 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1450 pPktMetaInfo->ucDisableFrmXtl = 0;
1451 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1452 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1453
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301454 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001455 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1456 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301457 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001458 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301459 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301461 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1462 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 }
1464
1465 // We're giving the packet to TL so consider it transmitted from
1466 // a statistics perspective. We account for it here instead of
1467 // when the packet is returned for two reasons. First, TL will
1468 // manipulate the skb to the point where the len field is not
1469 // accurate, leading to inaccurate byte counts if we account for
1470 // it later. Second, TL does not provide any feedback as to
1471 // whether or not the packet was successfully sent over the air,
1472 // so the packet counts will be the same regardless of where we
1473 // account for them
1474 pAdapter->stats.tx_bytes += skb->len;
1475 ++pAdapter->stats.tx_packets;
1476 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1477 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301478 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001479
c_hpothu6d1d2a32014-03-18 20:17:03 +05301480 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001481 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001482
1483 return status;
1484}
1485
1486
1487/**============================================================================
1488 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1489 case where VOS packets are not available at the time of the call to get
1490 packets. This callback function is invoked by VOS when packets are
1491 available.
1492
1493 @param pVosPacket : [in] pointer to VOS packet
1494 @param userData : [in] opaque user data that was passed initially
1495
1496 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1497 : VOS_STATUS_SUCCESS otherwise
1498 =============================================================================*/
1499VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1500 v_VOID_t *userData )
1501{
1502 VOS_STATUS status;
1503 v_SINT_t i = 0;
1504 v_SIZE_t size = 0;
1505 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1506 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301507 v_CONTEXT_t pVosContext = NULL;
1508 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301509
1510 if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07001511 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301512 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1513 FL("Invalid adapter %p"), pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001514 return VOS_STATUS_E_FAILURE;
1515 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301516 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1517 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1518 if(pSapCtx == NULL){
1519 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1520 FL("psapCtx is NULL"));
1521 return VOS_STATUS_E_FAULT;
1522 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1524 //situation. Here we will only signal TL that there is a pending data for a STA.
1525 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1526 vos_pkt_return_packet( pVosPacket );
1527
1528 pAdapter->isVosOutOfResource = VOS_FALSE;
1529
1530 // Indicate to TL that there is pending data if a queue is non empty.
1531 // This Code wasnt included in earlier version which resulted in
1532 // Traffic stalling
1533 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1534 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301535 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1536 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001537 {
1538 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1539 {
1540 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301541 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001542 if ( size > 0 )
1543 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301544 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1545 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 (WLANTL_ACEnumType)i );
1547 if( !VOS_IS_STATUS_SUCCESS( status ) )
1548 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301549 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1550 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001551 }
1552 }
1553 }
1554 }
1555 }
1556 return VOS_STATUS_SUCCESS;
1557}
1558
1559
1560/**============================================================================
1561 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1562 TL will call this to notify the HDD when one or more packets were
1563 received for a registered STA.
1564
1565 @param vosContext : [in] pointer to VOS context
1566 @param pVosPacketChain : [in] pointer to VOS packet chain
1567 @param staId : [in] Station Id (Adress 1 Index)
1568 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1569
1570 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1571 : VOS_STATUS_SUCCESS otherwise
1572 ===========================================================================*/
1573VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1574 vos_pkt_t *pVosPacketChain,
1575 v_U8_t staId,
1576 WLANTL_RxMetaInfoType* pRxMetaInfo )
1577{
1578 hdd_adapter_t *pAdapter = NULL;
1579 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1580 int rxstat;
1581 struct sk_buff *skb = NULL;
1582 vos_pkt_t* pVosPacket;
1583 vos_pkt_t* pNextVosPacket;
1584 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001585 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001586
1587 //Sanity check on inputs
1588 if ( ( NULL == vosContext ) ||
1589 ( NULL == pVosPacketChain ) ||
1590 ( NULL == pRxMetaInfo ) )
1591 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301592 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1593 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001594 return VOS_STATUS_E_FAILURE;
1595 }
1596
1597 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1598 if ( NULL == pHddCtx )
1599 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301600 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1601 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 return VOS_STATUS_E_FAILURE;
1603 }
1604
1605 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301606 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301608 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1609 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001610 VOS_ASSERT(0);
1611 return VOS_STATUS_E_FAILURE;
1612 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001613
1614 /* Monitor traffic */
1615 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1616 {
1617 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1618 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1619 {
1620 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1621 /* It was IDLE mode,
1622 * this is new state, then switch mode from suspend to resume */
1623 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1624 {
1625 hdd_set_wlan_suspend_mode(0);
1626 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1627 pHddCtx->cfg_ini->trafficIdleTimeout);
1628 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1629 }
1630 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1631 }
1632 }
1633
Jeff Johnson295189b2012-06-20 16:38:30 -07001634 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1635
1636 // walk the chain until all are processed
1637 pVosPacket = pVosPacketChain;
1638 do
1639 {
1640 // get the pointer to the next packet in the chain
1641 // (but don't unlink the packet since we free the entire chain later)
1642 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1643
1644 // both "success" and "empty" are acceptable results
1645 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1646 {
1647 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301648 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1649 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 return VOS_STATUS_E_FAILURE;
1651 }
1652
1653 // Extract the OS packet (skb).
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301654 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001655 if(!VOS_IS_STATUS_SUCCESS( status ))
1656 {
1657 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301658 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1659 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001660 return VOS_STATUS_E_FAILURE;
1661 }
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301662
1663 if (TRUE == hdd_IsEAPOLPacket(pVosPacket))
1664 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
1665
1666 pVosPacket->pSkb = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 //hdd_softap_dump_sk_buff(skb);
1668
1669 skb->dev = pAdapter->dev;
1670
1671 if(skb->dev == NULL) {
1672
c_hpothu6d1d2a32014-03-18 20:17:03 +05301673 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1674 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001675 return VOS_STATUS_E_FAILURE;
1676 }
1677 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1678 ++pAdapter->stats.rx_packets;
1679 pAdapter->stats.rx_bytes += skb->len;
1680
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001681 if (pHddCtx->cfg_ini->gEnableDebugLog)
1682 {
1683 proto_type = vos_pkt_get_proto_type(skb,
1684 pHddCtx->cfg_ini->gEnableDebugLog);
1685 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1686 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001688 "SAP RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001689 }
1690 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1691 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001693 "SAP RX DHCP");
1694 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301695 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1696 {
1697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1698 "SAP RX ARP");
1699 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001700 }
1701
Jeff Johnson295189b2012-06-20 16:38:30 -07001702 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1703 {
1704 //MC/BC packets. Duplicate a copy of packet
1705 struct sk_buff *pSkbCopy;
1706 hdd_ap_ctx_t *pHddApCtx;
1707
1708 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1709 if (!(pHddApCtx->apDisableIntraBssFwd))
1710 {
1711 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1712 if (pSkbCopy)
1713 {
1714 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1715 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1716 }
1717 }
1718 else
1719 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301720 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001721 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001722 }
1723
1724
1725 } //(WLAN_RX_BCMC_STA_ID == staId)
1726
1727 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1728 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1729 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301730 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001731 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301732 if ((NULL != pHddCtx) &&
1733 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301734 {
1735 hdd_dump_dhcp_pkt(skb, RX_PATH);
1736 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001737
1738 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001739 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnsone7245742012-09-05 17:12:55 -07001740#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301741 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
1742 HDD_WAKE_LOCK_DURATION,
1743 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
1744
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001745#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001746 rxstat = netif_rx_ni(skb);
1747 if (NET_RX_SUCCESS == rxstat)
1748 {
1749 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001750 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001751 }
1752 else
1753 {
1754 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1755 }
1756 }
1757 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1758 {
1759 kfree_skb(skb);
1760 }
1761 else
1762 {
1763 //loopback traffic
1764 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1765 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1766 }
1767
1768 // now process the next packet in the chain
1769 pVosPacket = pNextVosPacket;
1770
1771 } while (pVosPacket);
1772
1773 //Return the entire VOS packet chain to the resource pool
1774 status = vos_pkt_return_packet( pVosPacketChain );
1775 if(!VOS_IS_STATUS_SUCCESS( status ))
1776 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301777 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1778 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 }
1780
1781 pAdapter->dev->last_rx = jiffies;
1782
1783 return status;
1784}
1785
1786VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1787{
1788 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301789 hdd_context_t *pHddCtx;
1790 if (NULL == pAdapter)
1791 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301792 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301793 "%s: pAdapter is NULL", __func__);
1794 return VOS_STATUS_E_INVAL;
1795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001796
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301797 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1798 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301799 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301800 "%s: Invalid pAdapter magic", __func__);
1801 return VOS_STATUS_E_INVAL;
1802 }
1803
1804 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301805 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001806 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301807 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1809 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301810 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001812 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 staId, vosStatus, vosStatus );
1814 }
1815
1816 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1817 if( VOS_STATUS_E_FAILURE == vosStatus )
1818 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301819 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001820 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001821 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001822 staId, vosStatus, vosStatus );
1823 return( vosStatus );
1824 }
1825
1826 pHddCtx->sta_to_adapter[staId] = NULL;
1827
1828 return( vosStatus );
1829}
1830
1831VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1832 v_BOOL_t fAuthRequired,
1833 v_BOOL_t fPrivacyBit,
1834 v_U8_t staId,
1835 v_U8_t ucastSig,
1836 v_U8_t bcastSig,
1837 v_MACADDR_t *pPeerMacAddress,
1838 v_BOOL_t fWmmEnabled )
1839{
1840 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001841 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001842 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1843 hdd_adapter_t *pmonAdapter = NULL;
1844
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301845 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1846 ptSapContext pSapCtx = NULL;
1847 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1848 if(pSapCtx == NULL){
1849 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1850 FL("psapCtx is NULL"));
1851 return VOS_STATUS_E_FAULT;
1852 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001853 //eCsrEncryptionType connectedCipherAlgo;
1854 //v_BOOL_t fConnected;
1855
1856 /*
1857 * Clean up old entry if it is not cleaned up properly
1858 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301859 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001860 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301861 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001862 "clean up old entry for STA %d", staId);
1863 hdd_softap_DeregisterSTA( pAdapter, staId );
1864 }
1865
1866 // Get the Station ID from the one saved during the assocation.
1867
1868 staDesc.ucSTAId = staId;
1869
1870
1871 /*Save the pAdapter Pointer for this staId*/
1872 pHddCtx->sta_to_adapter[staId] = pAdapter;
1873
1874 staDesc.wSTAType = WLAN_STA_SOFTAP;
1875
1876 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1877 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1878 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1879
c_hpothu6d1d2a32014-03-18 20:17:03 +05301880 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001881 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301882 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001883 "station mac " MAC_ADDRESS_STR,
1884 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301885 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001886 "BSSIDforIBSS " MAC_ADDRESS_STR,
1887 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301888 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001889 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1890 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001891
1892 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1893
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301895 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 "HDD SOFTAP register TL QoS_enabled=%d",
1897 staDesc.ucQosEnabled );
1898
1899 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1900
1901
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 // For PRIMA UMA frame translation is not enable yet.
1903 staDesc.ucSwFrameTXXlation = 1;
1904 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 staDesc.ucAddRmvLLC = 1;
1906
1907 // Initialize signatures and state
1908 staDesc.ucUcastSig = ucastSig;
1909 staDesc.ucBcastSig = bcastSig;
1910 staDesc.ucInitState = fAuthRequired ?
1911 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1912
Prathyushaf5442802012-12-12 13:58:11 -08001913 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1914
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301916 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1917 hdd_softap_rx_packet_cbk,
1918 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1920
1921 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1922 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301923 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001924 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001925 vosStatus, vosStatus );
1926 return vosStatus;
1927 }
1928
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001929 //Timer value should be in milliseconds
1930 if ( pHddCtx->cfg_ini->dynSplitscan &&
1931 ( VOS_TIMER_STATE_RUNNING !=
1932 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1933 {
1934 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1935 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1936 }
1937
Jeff Johnson295189b2012-06-20 16:38:30 -07001938 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1939 // then go to 'authenticated'. For all other authentication types (those that do
1940 // not require upper layer authentication) we can put TL directly into 'authenticated'
1941 // state.
1942
1943 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301944 pSapCtx->aStaInfo[staId].ucSTAId = staId;
1945 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 if ( !fAuthRequired )
1947 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301948 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1949 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301950 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001951
1952 // Connections that do not need Upper layer auth, transition TL directly
1953 // to 'Authenticated' state.
1954 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1955 WLANTL_STA_AUTHENTICATED );
1956
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301957 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1959 }
1960 else
1961 {
1962
c_hpothu6d1d2a32014-03-18 20:17:03 +05301963 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301964 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001965
1966 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1967 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301968 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001969
1970 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1971
1972 }
1973 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1974 if(pmonAdapter)
1975 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301976 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
1977 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 netif_carrier_on(pmonAdapter->dev);
1979 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301980 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 netif_tx_start_all_queues(pmonAdapter->dev);
1982 }
1983 netif_carrier_on(pAdapter->dev);
1984 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301985 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001986 netif_tx_start_all_queues(pAdapter->dev);
1987
1988 return( vosStatus );
1989}
1990
1991VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1992{
1993 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1994 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1995 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1996
1997
1998 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1999 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
2000 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
2001
2002 return vosStatus;
2003}
2004
2005VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
2006{
2007 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
2008}
2009
2010VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
2011{
2012 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2013 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302014 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07002015
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302016 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2017 ptSapContext pSapCtx = NULL;
2018 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2019 if(pSapCtx == NULL){
2020 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2021 FL("psapCtx is NULL"));
2022 return VOS_STATUS_E_FAULT;
2023 }
2024
2025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07002026 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05302027 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07002028 {
2029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2030 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
2031 return VOS_STATUS_E_PERM;
2032 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002033
2034 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
2035
Jeff Johnson43971f52012-07-17 12:26:56 -07002036 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002037 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302038 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002039 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002040 }
2041
2042 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2043 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302044 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302046 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
2047 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2048 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302049 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002050 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302051 }
2052 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 }
2054
2055 return vosStatus;
2056}
2057
2058VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
2059{
2060 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
2061 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2062 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002063
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302064 ptSapContext pSapCtx = NULL;
2065 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2066 if(pSapCtx == NULL){
2067 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2068 FL("psapCtx is NULL"));
2069 return VOS_STATUS_E_FAULT;
2070 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302071 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002072 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002073
Jeff Johnson43971f52012-07-17 12:26:56 -07002074 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002075 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302076 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002077 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002078 return VOS_STATUS_E_FAILURE;
2079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002080
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302081 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302083 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002084 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002085 return VOS_STATUS_E_FAILURE;
2086 }
2087
2088 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302089 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002090 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002091
Jeff Johnson43971f52012-07-17 12:26:56 -07002092 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302094 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 }
2096
c_hpothu6d1d2a32014-03-18 20:17:03 +05302097 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002098 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002099
2100 return vosStatus;
2101}
2102
2103
2104VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2105{
2106 v_U8_t i;
2107
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302108 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2109 ptSapContext pSapCtx = NULL;
2110 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2111 if(pSapCtx == NULL){
2112 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2113 FL("psapCtx is NULL"));
2114 return VOS_STATUS_E_FAULT;
2115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002116 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2117 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302118 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2119 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 {
2121 *staId = i;
2122 return VOS_STATUS_SUCCESS;
2123 }
2124 }
2125
2126 return VOS_STATUS_E_FAILURE;
2127}
2128
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302129VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2130{
2131 v_U8_t i;
2132
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302133 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2134 ptSapContext pSapCtx = NULL;
2135 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2136 if(pSapCtx == NULL){
2137 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2138 FL("psapCtx is NULL"));
2139 return VOS_STATUS_E_FAULT;
2140 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302141 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2142 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302143 if (pSapCtx->aStaInfo[i].isUsed &&
2144 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302145 {
2146 *staId = i;
2147 return VOS_STATUS_SUCCESS;
2148 }
2149 }
2150
2151 return VOS_STATUS_E_FAILURE;
2152}