blob: 2cb3b89887b514a2addf797835c6c1ddb7bffe65 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
c_manjee16126372017-01-16 19:29:30 +05302 * Copyright (c) 2012-2017 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
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530144VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter, bool re_init)
Kiet Lambcf38522013-10-26 18:28:27 +0530145{
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();
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530151
152 if (!re_init) {
153 status = wlan_hdd_validate_context(pHddCtx);
154 if (-ENODEV == status) {
155 return status;
156 }
Kiet Lambcf38522013-10-26 18:28:27 +0530157 }
158
159 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
160 (!pHddCtx->traffic_monitor.isInitialized))
161 {
162 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
163 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
164 VOS_TIMER_TYPE_SW,
165 hdd_softap_traffic_monitor_timeout_handler,
166 pHddCtx);
167 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
168 pHddCtx->traffic_monitor.isInitialized = 1;
169 pHddCtx->traffic_monitor.lastFrameTs = 0;
170 /* Start traffic monitor timer here
171 * If no AP assoc, immediatly go into suspend */
c_hpothu6d1d2a32014-03-18 20:17:03 +0530172 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530173 "%s Start Traffic Monitor Timer", __func__);
174 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
175 pHddCtx->cfg_ini->trafficIdleTimeout);
176 }
177 else
178 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530179 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530180 "%s Traffic Monitor is not Enable in ini file", __func__);
181 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530182
183 EXIT();
Kiet Lambcf38522013-10-26 18:28:27 +0530184 return status;
185}
186
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530187VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter, bool re_init)
Kiet Lambcf38522013-10-26 18:28:27 +0530188{
189 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
190 VOS_STATUS status = VOS_STATUS_SUCCESS;
191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530192 ENTER();
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530193
194 if (!re_init){
195 status = wlan_hdd_validate_context(pHddCtx);
196 if (-ENODEV == status) {
197 return status;
198 }
Kiet Lambcf38522013-10-26 18:28:27 +0530199 }
200
201 if (pHddCtx->traffic_monitor.isInitialized)
202 {
203 if (VOS_TIMER_STATE_STOPPED !=
204 vos_timer_getCurrentState(&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 Stop Traffic Monitor Timer", __func__);
208 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
209 }
c_hpothu6d1d2a32014-03-18 20:17:03 +0530210 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530211 "%s Destroy Traffic Monitor Timer", __func__);
212 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
213 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
214 pHddCtx->traffic_monitor.isInitialized = 0;
215 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530216 EXIT();
Kiet Lamae69d7a2013-11-08 14:38:04 +0530217 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530218}
219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220/**============================================================================
221 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
222
223 @param pAdapter : [in] pointer to adapter context
224 @return : VOS_STATUS_E_FAILURE if any errors encountered
225 : VOS_STATUS_SUCCESS otherwise
226 ===========================================================================*/
227static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
228{
229 VOS_STATUS status = VOS_STATUS_SUCCESS;
230 v_SINT_t i = -1;
231 v_U8_t STAId = 0;
232 hdd_list_node_t *anchor = NULL;
233 skb_list_node_t *pktNode = NULL;
234 struct sk_buff *skb = NULL;
235
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530236 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
237 ptSapContext pSapCtx = NULL;
238 pSapCtx = VOS_GET_SAP_CB(pVosContext);
239 if(pSapCtx == NULL){
240 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
241 FL("psapCtx is NULL"));
242 return VOS_STATUS_E_FAULT;
243 }
244 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
246 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530247 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700248 {
249 continue;
250 }
251
252 for (i = 0; i < NUM_TX_QUEUES; i ++)
253 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530254 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 while (true)
256 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530257 status = hdd_list_remove_front ( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
Jeff Johnson295189b2012-06-20 16:38:30 -0700258
259 if (VOS_STATUS_E_EMPTY != status)
260 {
261 //If success then we got a valid packet from some AC
262 pktNode = list_entry(anchor, skb_list_node_t, anchor);
263 skb = pktNode->skb;
264 ++pAdapter->stats.tx_dropped;
265 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
266 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
267 kfree_skb(skb);
268 continue;
269 }
270
271 //current list is empty
272 break;
273 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530274 pSapCtx->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
275 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530277 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 }
279
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530280 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
282 return status;
283}
284
Bhargav Shahd0715912015-10-01 18:17:37 +0530285/**
286 * hdd_softap_get_connected_sta() - provide number of connected STA
287 * @pHostapdAdapter: pAdapter for SAP
288 *
289 * This function is invoked for SAP mode to get connected STA.
290 *
291 * Return: Total number of connected STA to SAP.
292 */
293v_U8_t hdd_softap_get_connected_sta(hdd_adapter_t *pHostapdAdapter)
294{
295 v_U8_t i, sta_ct = 0;
296 v_CONTEXT_t pVosContext = NULL;
297 ptSapContext pSapCtx = NULL;
298
299 pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
300 pSapCtx = VOS_GET_SAP_CB(pVosContext);
301 if (pSapCtx == NULL) {
302 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
303 FL("psapCtx is NULL"));
304 goto error;
305 }
306
307 spin_lock_bh(&pSapCtx->staInfo_lock);
308 // get stations associated with SAP
309 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
310 if (pSapCtx->aStaInfo[i].isUsed &&
311 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
312 sta_ct++;
313 }
314 spin_unlock_bh( &pSapCtx->staInfo_lock );
315
316error:
317 return sta_ct;
318}
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320/**============================================================================
SaidiReddy Yenuga18d77a62016-10-04 20:26:22 +0530321 @brief __hdd_softap_hard_start_xmit() - Function registered with the Linux OS
322 for transmitting packets. There are 2 versions of this function. One that
323 uses locked queue and other that uses lockless queues. Both have been
324 retained to do some performance testing
Jeff Johnson295189b2012-06-20 16:38:30 -0700325
326 @param skb : [in] pointer to OS packet (sk_buff)
327 @param dev : [in] pointer to Libra network device
328
329 @return : NET_XMIT_DROP if packets are dropped
330 : NET_XMIT_SUCCESS if packet is enqueued succesfully
331 ===========================================================================*/
SaidiReddy Yenuga18d77a62016-10-04 20:26:22 +0530332int __hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700333{
334 VOS_STATUS status;
335 WLANTL_ACEnumType ac = WLANTL_AC_BE;
336 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
337 skb_list_node_t *pktNode = NULL;
338 v_SIZE_t pktListSize = 0;
339 v_BOOL_t txSuspended = VOS_FALSE;
340 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
341 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530342 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700343 vos_list_node_t *anchor = NULL;
344 v_U8_t STAId = WLAN_MAX_STA_COUNT;
345 //Extract the destination address from ethernet frame
346 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
347 int os_status = NETDEV_TX_OK;
Mihir Shetef8f74532014-12-04 11:53:34 +0530348 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700349
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530350 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
351 ptSapContext pSapCtx = NULL;
352 pSapCtx = VOS_GET_SAP_CB(pVosContext);
353 if(pSapCtx == NULL){
354 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
355 FL("psapCtx is NULL"));
356 ++pAdapter->stats.tx_dropped;
357 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
358 kfree_skb(skb);
359 return os_status;
360 }
361
Ratheesh S Pe8f00c62015-08-20 13:03:01 +0530362 if (pHddCtx == NULL)
363 {
364 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
365 FL("pHddCtx is NULL"));
366 goto xmit_done;
367 }
368
Jeff Johnson295189b2012-06-20 16:38:30 -0700369 pDestMacAddress = (v_MACADDR_t*)skb->data;
370
371 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
372
c_hpothu6d1d2a32014-03-18 20:17:03 +0530373 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700374 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700375
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530376 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
378 {
379 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
380 //ID used for BC/MC traffic. The station id is registered to TL as well.
381 STAId = pHddApCtx->uBCStaId;
382
383 /* Setting priority for broadcast packets which doesn't go to select_queue function */
384 skb->priority = SME_QOS_WMM_UP_BE;
385 skb->queue_mapping = HDD_LINUX_AC_BE;
386
c_hpothu6d1d2a32014-03-18 20:17:03 +0530387 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800388 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 }
390 else
391 {
Nirav Shah7e3c8132015-06-22 23:51:42 +0530392 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
SaidiReddy Yenugac0e1e702016-11-22 16:16:26 +0530393 if (STAId == HDD_WLAN_INVALID_STA_ID || STAId >= WLAN_MAX_STA_COUNT)
Jeff Johnson295189b2012-06-20 16:38:30 -0700394 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530395 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700396 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700397 ++pAdapter->stats.tx_dropped;
398 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
399 kfree_skb(skb);
400 goto xmit_done;
401 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530402 else if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700403 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530404 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
405 "%s: STA %d is unregistered", __func__, STAId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700406 ++pAdapter->stats.tx_dropped;
407 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
408 kfree_skb(skb);
409 goto xmit_done;
410 }
411
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530412 if ( (WLANTL_STA_CONNECTED != pSapCtx->aStaInfo[STAId].tlSTAState) &&
413 (WLANTL_STA_AUTHENTICATED != pSapCtx->aStaInfo[STAId].tlSTAState) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700414 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530415 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700416 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700417 ++pAdapter->stats.tx_dropped;
418 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
419 kfree_skb(skb);
420 goto xmit_done;
421 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530422 else if(WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[STAId].tlSTAState)
Jeff Johnson295189b2012-06-20 16:38:30 -0700423 {
424 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
425 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530426 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700427 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700428 ++pAdapter->stats.tx_dropped;
429 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
430 kfree_skb(skb);
431 goto xmit_done;
432 }
433 }
434 }
435
436 //Get TL AC corresponding to Qdisc queue index/AC.
437 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
438 //user priority from IP header, which is already extracted and set from
439 //select_queue call back function
440 up = skb->priority;
441 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
442
c_hpothu6d1d2a32014-03-18 20:17:03 +0530443 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700444 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700445
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530446 if (( NULL != pHddCtx ) &&
447 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530448 {
449 hdd_dump_dhcp_pkt(skb, TX_PATH);
450 }
451
Jeff Johnson295189b2012-06-20 16:38:30 -0700452 // If the memory differentiation mode is enabled, the memory limit of each queue will be
453 // checked. Over-limit packets will be dropped.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530454 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
455 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +0530456
457 if (pHddCtx->bad_sta[STAId]) {
458 hdd_list_node_t *anchor = NULL;
459 skb_list_node_t *pktNode = NULL;
460 struct sk_buff *fskb = NULL;
461 if(pktListSize >= (pAdapter->aTxQueueLimit[ac])/2) {
462 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac],
463 &anchor);
464 pktNode = list_entry(anchor, skb_list_node_t, anchor);
465 fskb = pktNode->skb;
466 kfree_skb(fskb);
467 pktListSize--;
468 ++pAdapter->stats.tx_dropped;
469 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
470 }
471 }
472
Jeff Johnson295189b2012-06-20 16:38:30 -0700473 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
474 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530475 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800476 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Bhargav Shah7f03b812015-08-21 11:17:32 +0530477 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured;
478 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530479 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700480 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
481 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530482 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
483 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -0700484 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530485
486 /* If 3/4th of the max queue size is used then enable the flag.
487 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
488 if (WLANTL_AC_BE == ac)
489 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530490 if (pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530491 {
Sushant Kaushik40bcd6e2015-09-18 12:09:54 +0530492 if (!(pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count % 0x40))
493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530494 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
Sushant Kaushik40bcd6e2015-09-18 12:09:54 +0530495 pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count++;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530496 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_TRUE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530497 }
498 else
499 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530500 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530501 }
502 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530503 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700504
505 if (VOS_TRUE == txSuspended)
506 {
507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
508 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700509 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700510 os_status = NETDEV_TX_BUSY;
511 goto xmit_done;
512 }
513
514 //Use the skb->cb field to hold the list node information
515 pktNode = (skb_list_node_t *)&skb->cb;
516
517 //Stick the OS packet inside this node.
518 pktNode->skb = skb;
519
520 //Stick the User Priority inside this node
521 pktNode->userPriority = up;
522
523 INIT_LIST_HEAD(&pktNode->anchor);
524
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530525 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
526 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
527 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700528 if ( !VOS_IS_STATUS_SUCCESS( status ) )
529 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530530 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
531 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700532 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
533 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
534 ++pAdapter->stats.tx_dropped;
535 kfree_skb(skb);
536 goto xmit_done;
537 }
538
539 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
540 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530541 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700542
543 if (1 == pktListSize)
544 {
545 //Let TL know we have a packet to send for this AC
546 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
547
548 if ( !VOS_IS_STATUS_SUCCESS( status ) )
549 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530550 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
551 "%s: Failed to signal TL for AC=%d STAId =%d",
552 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700553
554 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
555 //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 +0530556 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
557 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
558 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530559 /* Free the skb only if we are able to remove it from the list.
560 * If we are not able to retrieve it from the list it means that
561 * the skb was pulled by TX Thread and is use so we should not free
562 * it here
563 */
564 if (VOS_IS_STATUS_SUCCESS(status))
565 {
566 pktNode = list_entry(anchor, skb_list_node_t, anchor);
567 skb1 = pktNode->skb;
568 kfree_skb(skb1);
569 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700570 ++pAdapter->stats.tx_dropped;
571 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
572 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700573 goto xmit_done;
574 }
575 }
576 dev->trans_start = jiffies;
577
c_hpothu6d1d2a32014-03-18 20:17:03 +0530578 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
579 "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700580
581xmit_done:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530582 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700583 return os_status;
584}
585
SaidiReddy Yenuga18d77a62016-10-04 20:26:22 +0530586int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
587{
588 int ret;
589 vos_ssr_protect(__func__);
590 ret = __hdd_softap_hard_start_xmit(skb, dev);
591 vos_ssr_unprotect(__func__);
592 return ret;
593}
594
Jeff Johnson295189b2012-06-20 16:38:30 -0700595/**============================================================================
596 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
597
598 @param skb : [in] pointer to packet (sk_buff)
599 @param dev : [in] pointer to Libra network device
600 @param STAId : [in] Station Id of Destination Station
601 @param up : [in] User Priority
602
603 @return : NET_XMIT_DROP if packets are dropped
604 : NET_XMIT_SUCCESS if packet is enqueued succesfully
605 ===========================================================================*/
606VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
607 struct net_device *dev,
608 v_U8_t STAId,
609 v_U8_t up)
610{
611 VOS_STATUS status = VOS_STATUS_SUCCESS;
612 skb_list_node_t *pktNode = NULL;
613 v_SIZE_t pktListSize = 0;
614 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
615 v_U8_t ac;
616 vos_list_node_t *anchor = NULL;
Mihir Shetef8f74532014-12-04 11:53:34 +0530617 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700618
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530619 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
620 ptSapContext pSapCtx = NULL;
621 pSapCtx = VOS_GET_SAP_CB(pVosContext);
622 if(pSapCtx == NULL){
623 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
624 FL("psapCtx is NULL"));
625 kfree_skb(skb);
626 status = VOS_STATUS_E_FAILURE;
627 return status;
628 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700629 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
630
c_hpothu6d1d2a32014-03-18 20:17:03 +0530631 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700632 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700633
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530634 spin_lock_bh( &pSapCtx->staInfo_lock );
635 if ( FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700636 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530637 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530638 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700639 kfree_skb(skb);
640 status = VOS_STATUS_E_FAILURE;
641 goto xmit_end;
642 }
643
644 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530645 if ( !pSapCtx->aStaInfo[STAId].isQosEnabled )
Jeff Johnson295189b2012-06-20 16:38:30 -0700646 up = SME_QOS_WMM_UP_BE;
647
648 ac = hddWmmUpToAcMap[up];
649 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
c_hpothu6d1d2a32014-03-18 20:17:03 +0530650 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700651 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700652
653 skb->queue_mapping = hddLinuxUpToAcMap[up];
654
655 //Use the skb->cb field to hold the list node information
656 pktNode = (skb_list_node_t *)&skb->cb;
657
658 //Stick the OS packet inside this node.
659 pktNode->skb = skb;
660
661 //Stick the User Priority inside this node
662 pktNode->userPriority = up;
663
664 INIT_LIST_HEAD(&pktNode->anchor);
665
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530666 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
667 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
668 if(pSapCtx->aStaInfo[STAId].txSuspended[ac] ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700669 pktListSize >= pAdapter->aTxQueueLimit[ac])
670 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530671 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800672 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700673 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
674 * SUSPEND should be done based on Threshold. RESUME would be
675 * triggered in fetch cbk after recovery.
676 */
677 kfree_skb(skb);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530678 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700679 status = VOS_STATUS_E_FAILURE;
680 goto xmit_end;
681 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530682 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
683 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700684
685 if ( !VOS_IS_STATUS_SUCCESS( status ) )
686 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530687 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
688 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
690 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
691 ++pAdapter->stats.tx_dropped;
692 kfree_skb(skb);
693 status = VOS_STATUS_E_FAILURE;
694 goto xmit_end;
695 }
696
697 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
698 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
699
700 if (1 == pktListSize)
701 {
702 //Let TL know we have a packet to send for this AC
c_hpothu6d1d2a32014-03-18 20:17:03 +0530703 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
704 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700705
706 if ( !VOS_IS_STATUS_SUCCESS( status ) )
707 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530708 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
709 "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700710 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700711
712 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
713 //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 +0530714 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
715 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
716 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530717 /* Free the skb only if we are able to remove it from the list.
718 * If we are not able to retrieve it from the list it means that
719 * the skb was pulled by TX Thread and is use so we should not free
720 * it here
721 */
722 if (VOS_IS_STATUS_SUCCESS(status))
723 {
724 pktNode = list_entry(anchor, skb_list_node_t, anchor);
725 skb1 = pktNode->skb;
726 kfree_skb(skb1);
727 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700728 ++pAdapter->stats.tx_dropped;
729 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
730 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700731 status = VOS_STATUS_E_FAILURE;
732 goto xmit_end;
733 }
734 }
735
c_hpothu6d1d2a32014-03-18 20:17:03 +0530736 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700737
738xmit_end:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530739 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700740 return status;
741}
742
743/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530744 @brief __hdd_softap_tx_timeout() - Function called by OS if there is any
Jeff Johnson295189b2012-06-20 16:38:30 -0700745 timeout during transmission. Since HDD simply enqueues packet
746 and returns control to OS right away, this would never be invoked
747
748 @param dev : [in] pointer to Libra network device
749 @return : None
750 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530751void __hdd_softap_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700752{
Mihir Shetef3473692014-06-27 15:13:20 +0530753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
754 struct netdev_queue *txq;
755 int i = 0;
Mukul Sharma4b322632015-02-28 20:21:43 +0530756 int status = 0;
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530757 hdd_context_t *pHddCtx;
Mihir Shetef3473692014-06-27 15:13:20 +0530758
c_hpothu6d1d2a32014-03-18 20:17:03 +0530759 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +0530760 "%s: Transmission timeout occurred jiffies %lu dev->trans_start %lu",
761 __func__, jiffies, dev->trans_start);
Mihir Shetef3473692014-06-27 15:13:20 +0530762
763 if ( NULL == pAdapter )
764 {
765 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
766 FL("pAdapter is NULL"));
767 VOS_ASSERT(0);
768 return;
769 }
770
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530771 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mukul Sharma4b322632015-02-28 20:21:43 +0530772 status = wlan_hdd_validate_context(pHddCtx);
773 if (status != 0)
774 {
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530775 return;
776 }
777
Mihir Shetef3473692014-06-27 15:13:20 +0530778 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
779
mukul sharma2cdb8ea2015-10-01 14:53:38 +0530780 for (i = 0; i < NUM_TX_QUEUES; i++)
Mihir Shetef3473692014-06-27 15:13:20 +0530781 {
782 txq = netdev_get_tx_queue(dev, i);
783 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
784 "Queue%d status: %d", i, netif_tx_queue_stopped(txq));
785 }
786
787 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
mukul sharma2cdb8ea2015-10-01 14:53:38 +0530788 "carrier state: %d", netif_carrier_ok(dev));
Mihir Shetef3473692014-06-27 15:13:20 +0530789
790 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
791
Mihir Shete327c2ab2014-11-13 15:17:02 +0530792 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
793 HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
794 {
795 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
796 "%s: Request firmware for recovery",__func__);
797 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
798 }
Mihir Shetef3473692014-06-27 15:13:20 +0530799 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
800 HDD_SAP_TX_STALL_SSR_THRESHOLD)
801 {
802 // Driver could not recover, issue SSR
803 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
804 "%s: Cannot recover from Data stall Issue SSR",
805 __func__);
Mihir Shetefd62d9d2014-08-06 15:08:21 +0530806 WLANTL_FatalError();
Mukul Sharma987bef02015-11-16 20:04:54 +0530807 // reset count after issuing the SSR
808 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Mihir Shetef3473692014-06-27 15:13:20 +0530809 return;
810 }
811
812 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
813 * every 5sec. The TL debug spits out a lot of information on the
814 * serial console, if it is called every time *hdd_tx_timeout* is
815 * called then we may get a watchdog bite on the Application
816 * processor, so ratelimit the TL debug logs.
817 */
818 if (__ratelimit(&hdd_softap_tx_timeout_rs))
819 {
820 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +0530821 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetef3473692014-06-27 15:13:20 +0530822 }
Abhishek Singh837adf22015-10-01 17:37:37 +0530823 /* Call fatal event if data stall is for
824 * HDD_TX_STALL_FATAL_EVENT_THRESHOLD times
825 */
826 if (HDD_SAP_TX_STALL_FATAL_EVENT_THRESHOLD ==
827 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount)
828 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
829 WLAN_LOG_INDICATOR_HOST_DRIVER,
830 WLAN_LOG_REASON_DATA_STALL,
831 FALSE, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700832}
833
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530834void hdd_softap_tx_timeout(struct net_device *dev)
835{
836 vos_ssr_protect(__func__);
837 __hdd_softap_tx_timeout(dev);
838 vos_ssr_unprotect(__func__);
839 return;
840}
Jeff Johnson295189b2012-06-20 16:38:30 -0700841
842/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530843 @brief __hdd_softap_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 device TX/RX statistic
845
846 @param dev : [in] pointer to Libra network device
847
848 @return : pointer to net_device_stats structure
849 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530850struct net_device_stats* __hdd_softap_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700851{
852 hdd_adapter_t* priv = netdev_priv(dev);
853 return &priv->stats;
854}
855
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530856struct net_device_stats* hdd_softap_stats(struct net_device *dev)
857{
858 struct net_device_stats *priv_stats;
859 vos_ssr_protect(__func__);
860 priv_stats = __hdd_softap_stats(dev);
861 vos_ssr_unprotect(__func__);
862
863 return priv_stats;
864}
Jeff Johnson295189b2012-06-20 16:38:30 -0700865
866/**============================================================================
867 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
868 modules in HDD
869
870 @param pAdapter : [in] pointer to adapter context
871 @return : VOS_STATUS_E_FAILURE if any errors encountered
872 : VOS_STATUS_SUCCESS otherwise
873 ===========================================================================*/
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530874VOS_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter, bool re_init)
Jeff Johnson295189b2012-06-20 16:38:30 -0700875{
876 VOS_STATUS status = VOS_STATUS_SUCCESS;
877 v_SINT_t i = -1;
878 v_SIZE_t size = 0;
879
880 v_U8_t STAId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530881 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
882 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700883
884 v_U8_t pACWeights[] = {
885 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
886 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
887 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
888 HDD_SOFTAP_VO_WEIGHT_DEFAULT
889 };
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530890 pSapCtx = VOS_GET_SAP_CB(pVosContext);
891 if(pSapCtx == NULL){
892 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
893 FL("psapCtx is NULL"));
894 return VOS_STATUS_E_FAULT;
895 }
896
Leo Chang64d68bc2013-06-04 15:40:52 -0700897
Jeff Johnson295189b2012-06-20 16:38:30 -0700898 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530899 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700900
901 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
902
903 while (++i != NUM_TX_QUEUES)
904 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
905
906 /* Initial HDD buffer control / flow control fields*/
907 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
908
909 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
910 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
911 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
912 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
913
Jeff Johnson295189b2012-06-20 16:38:30 -0700914 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
915 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530916 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700917 for (i = 0; i < NUM_TX_QUEUES; i ++)
918 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530919 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 }
921 }
922
Yue Ma3ede6052013-08-29 00:33:26 -0700923 /* Update the AC weights suitable for SoftAP mode of operation */
924 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
925
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530926 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter, re_init))
Leo Chang64d68bc2013-06-04 15:40:52 -0700927 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530928 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530929 "%s: failed to start Traffic Monito timer ", __func__ );
930 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700931 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 return status;
933}
934
935/**============================================================================
936 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
937 modules in HDD
938
939 @param pAdapter : [in] pointer to adapter context
940 @return : VOS_STATUS_E_FAILURE if any errors encountered
941 : VOS_STATUS_SUCCESS otherwise
942 ===========================================================================*/
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530943VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter, bool re_init)
Jeff Johnson295189b2012-06-20 16:38:30 -0700944{
945 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700946
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530947 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter, re_init))
Leo Chang64d68bc2013-06-04 15:40:52 -0700948 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530949 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530950 "%s: Fail to Stop Traffic Monito timer", __func__ );
951 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700952 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700953
954 status = hdd_softap_flush_tx_queues(pAdapter);
955
956 return status;
957}
958
959/**============================================================================
960 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
961
962 @param pAdapter : [in] pointer to adapter context
963 @param STAId : [in] Station ID to deinit
964 @return : VOS_STATUS_E_FAILURE if any errors encountered
965 : VOS_STATUS_SUCCESS otherwise
966 ===========================================================================*/
967static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
968{
Jeff Johnson295189b2012-06-20 16:38:30 -0700969 v_U8_t i = -1;
970
971 hdd_list_node_t *anchor = NULL;
972
973 skb_list_node_t *pktNode = NULL;
974 struct sk_buff *skb = NULL;
975
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530976 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
977 ptSapContext pSapCtx = NULL;
978 pSapCtx = VOS_GET_SAP_CB(pVosContext);
979 if(pSapCtx == NULL){
980 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
981 FL("psapCtx is NULL"));
982 return VOS_STATUS_E_FAULT;
983 }
984 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530986 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 }
988
989 for (i = 0; i < NUM_TX_QUEUES; i ++)
990 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530991 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 while (true)
993 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530994 if (VOS_STATUS_E_EMPTY !=
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530995 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530996 &anchor))
Jeff Johnson295189b2012-06-20 16:38:30 -0700997 {
998 //If success then we got a valid packet from some AC
999 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1000 skb = pktNode->skb;
1001 ++pAdapter->stats.tx_dropped;
1002 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
1003 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
1004 kfree_skb(skb);
1005 continue;
1006 }
1007
1008 //current list is empty
1009 break;
1010 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301011 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 }
1013
Venkateswara T Asodi Reddycb76f242016-12-09 15:04:25 +05301014 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1015 "%s: flushed the TX queues of sta:%d", __func__, STAId);
1016
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301017 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001018}
1019
1020/**============================================================================
1021 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
1022 modules in HDD
1023
1024 @param pAdapter : [in] pointer to adapter context
1025 @param STAId : [in] Station ID to deinit
1026 @param pmacAddrSTA : [in] pointer to the MAC address of the station
1027 @return : VOS_STATUS_E_FAILURE if any errors encountered
1028 : VOS_STATUS_SUCCESS otherwise
1029 ===========================================================================*/
1030VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
1031{
1032 v_U8_t i = 0;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301033 VOS_STATUS status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301034 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1035 ptSapContext pSapCtx = NULL;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301036
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301037 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1038 if(pSapCtx == NULL){
1039 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1040 FL("psapCtx is NULL"));
1041 return VOS_STATUS_E_FAULT;
1042 }
1043
1044 spin_lock_bh( &pSapCtx->staInfo_lock );
1045 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301047 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1048 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301049 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 return VOS_STATUS_E_FAILURE;
1051 }
1052
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301053 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 for (i = 0; i < NUM_TX_QUEUES; i ++)
1055 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301056 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07001057 }
1058
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301059 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
1060 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
1061 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -07001062
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301063 spin_unlock_bh( &pSapCtx->staInfo_lock );
Nirav Shah7e3c8132015-06-22 23:51:42 +05301064
1065 status = hdd_sta_id_hash_add_entry(pAdapter, STAId, pmacAddrSTA);
1066 if (status != VOS_STATUS_SUCCESS) {
1067 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1068 FL("Not able to add staid hash %d"), STAId);
1069 return VOS_STATUS_E_FAILURE;
1070 }
1071
1072 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1073 FL("New station added sta_id %d mac:"
1074 MAC_ADDRESS_STR), STAId,
1075 MAC_ADDR_ARRAY(pmacAddrSTA->bytes));
1076
Jeff Johnson295189b2012-06-20 16:38:30 -07001077 return VOS_STATUS_SUCCESS;
1078}
1079
1080/**============================================================================
1081 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
1082 modules in HDD
1083
1084 @param pAdapter : [in] pointer to adapter context
1085 @param STAId : [in] Station ID to deinit
1086 @return : VOS_STATUS_E_FAILURE if any errors encountered
1087 : VOS_STATUS_SUCCESS otherwise
1088 ===========================================================================*/
1089VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
1090{
1091 VOS_STATUS status = VOS_STATUS_SUCCESS;
1092 v_U8_t ac;
1093 /**Track whether OS TX queue has been disabled.*/
1094 v_BOOL_t txSuspended[NUM_TX_QUEUES];
1095 v_U8_t tlAC;
1096 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001097 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -07001098
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301099 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1100 ptSapContext pSapCtx = NULL;
1101 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1102 if(pSapCtx == NULL){
1103 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1104 FL("psapCtx is NULL"));
1105 return VOS_STATUS_E_FAULT;
1106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1108
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301109 spin_lock_bh( &pSapCtx->staInfo_lock );
1110 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001111 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301112 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001113 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301114 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001115 return VOS_STATUS_E_FAILURE;
1116 }
1117
1118 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1119
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301120 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1121 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301122
1123 status = hdd_sta_id_hash_remove_entry(pAdapter,
1124 STAId, &pSapCtx->aStaInfo[STAId].macAddrSTA);
1125 if (status != VOS_STATUS_SUCCESS) {
Hanumantha Reddy Pothulaa88d4182015-12-23 18:19:28 +05301126 spin_unlock_bh( &pSapCtx->staInfo_lock );
Nirav Shah7e3c8132015-06-22 23:51:42 +05301127 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1128 FL("Not able to remove staid hash %d"), STAId);
1129 return VOS_STATUS_E_FAILURE;
1130 }
1131
1132 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1133 FL("station removed sta_id %d mac:"
1134 MAC_ADDRESS_STR), STAId,
1135 MAC_ADDR_ARRAY(pSapCtx->aStaInfo[STAId].macAddrSTA.bytes));
1136
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 /* if this STA had any of its WMM TX queues suspended, then the
1138 associated queue on the network interface was disabled. check
1139 to see if that is the case, in which case we need to re-enable
1140 the interface queue. but we only do this if the BSS is running
1141 since, if the BSS is stopped, all of the interfaces have been
1142 stopped and should not be re-enabled */
1143
1144 if (BSS_START == pHostapdState->bssState)
1145 {
1146 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1147 {
1148 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301149 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 }
1151 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301152 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001153
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001154 /* re-init spin lock, since netdev can still open adapter until
1155 * driver gets unloaded
1156 */
1157 for (i = 0; i < NUM_TX_QUEUES; i ++)
1158 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301159 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001160 HDD_TX_QUEUE_MAX_LEN);
1161 }
1162
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 if (BSS_START == pHostapdState->bssState)
1164 {
1165 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1166 {
1167 if (txSuspended[ac])
1168 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301169 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001170 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001171 netif_wake_subqueue(pAdapter->dev, ac);
1172 }
1173 }
1174 }
1175
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301176 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001177 return status;
1178}
1179
1180/**============================================================================
1181 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1182 modules in HDD
1183
1184 @param pAdapter : [in] pointer to adapter context
1185 @return : VOS_STATUS_E_FAILURE if any errors encountered
1186 : VOS_STATUS_SUCCESS otherwise
1187 ===========================================================================*/
1188VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1189{
1190 return hdd_softap_flush_tx_queues(pAdapter);
1191}
1192
1193/**============================================================================
1194 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1195 to indicate that a packet has been transmitted across the bus
1196 succesfully. OS packet resources can be released after this cbk.
1197
1198 @param vosContext : [in] pointer to VOS context
1199 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1200 @param vosStatusIn : [in] status of the transmission
1201
1202 @return : VOS_STATUS_E_FAILURE if any errors encountered
1203 : VOS_STATUS_SUCCESS otherwise
1204 ===========================================================================*/
1205VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1206 vos_pkt_t *pVosPacket,
1207 VOS_STATUS vosStatusIn )
1208{
1209 VOS_STATUS status = VOS_STATUS_SUCCESS;
1210 hdd_adapter_t *pAdapter = NULL;
1211 void* pOsPkt = NULL;
1212
1213 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1214 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301215 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1216 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 return VOS_STATUS_E_FAILURE;
1218 }
1219
1220 //Return the skb to the OS
1221 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001222 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001223 {
1224 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301225 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1226 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 vos_pkt_return_packet( pVosPacket );
1228 return VOS_STATUS_E_FAILURE;
1229 }
1230
1231 //Get the Adapter context.
1232 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301233 if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001234 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301235 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301236 "%s: HDD adapter context is invalid", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001237 }
1238 else
1239 {
1240 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1241 }
1242
1243 kfree_skb((struct sk_buff *)pOsPkt);
1244
1245 //Return the VOS packet resources.
1246 status = vos_pkt_return_packet( pVosPacket );
1247 if(!VOS_IS_STATUS_SUCCESS( status ))
1248 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301249 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1250 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001251 }
1252
1253 return status;
1254}
1255
1256
1257/**============================================================================
1258 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1259 fetch a packet for transmission.
1260
1261 @param vosContext : [in] pointer to VOS context
1262 @param staId : [in] Station for which TL is requesting a pkt
1263 @param ac : [in] access category requested by TL
1264 @param pVosPacket : [out] pointer to VOS packet packet pointer
1265 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1266
1267 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1268 : VOS_STATUS_E_FAILURE if any errors encountered
1269 : VOS_STATUS_SUCCESS otherwise
1270 ===========================================================================*/
1271VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1272 v_U8_t *pStaId,
1273 WLANTL_ACEnumType ac,
1274 vos_pkt_t **ppVosPacket,
1275 WLANTL_MetaInfoType *pPktMetaInfo )
1276{
1277 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1278 hdd_adapter_t *pAdapter = NULL;
1279 hdd_list_node_t *anchor = NULL;
1280 skb_list_node_t *pktNode = NULL;
1281 struct sk_buff *skb = NULL;
1282 vos_pkt_t *pVosPacket = NULL;
1283 v_MACADDR_t* pDestMacAddress = NULL;
1284 v_TIME_t timestamp;
1285 v_SIZE_t size = 0;
1286 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1287 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001288 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301289 v_CONTEXT_t pVosContext = NULL;
1290 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001291 //Sanity check on inputs
1292 if ( ( NULL == vosContext ) ||
1293 ( NULL == pStaId ) ||
1294 ( NULL == ppVosPacket ) ||
1295 ( NULL == pPktMetaInfo ) )
1296 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301297 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1298 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001299 return VOS_STATUS_E_FAILURE;
1300 }
1301
1302 //Get the HDD context.
1303 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1304 if ( NULL == pHddCtx )
1305 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301306 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1307 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001308 return VOS_STATUS_E_FAILURE;
1309 }
1310
Jeff Johnsonb156c922013-12-05 17:19:46 -08001311 STAId = *pStaId;
1312 if (STAId >= WLAN_MAX_STA_COUNT)
1313 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301314 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001315 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1316 return VOS_STATUS_E_FAILURE;
1317 }
1318
1319 pAdapter = pHddCtx->sta_to_adapter[STAId];
1320 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001321 {
1322 VOS_ASSERT(0);
1323 return VOS_STATUS_E_FAILURE;
1324 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301325 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1326 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1327 if(pSapCtx == NULL){
1328 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1329 FL("psapCtx is NULL"));
1330 return VOS_STATUS_E_FAULT;
1331 }
1332
1333 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001334 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301335 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001336 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1337 return VOS_STATUS_E_FAILURE;
1338 }
1339
Leo Chang64d68bc2013-06-04 15:40:52 -07001340 /* Monitor traffic */
1341 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1342 {
1343 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1344 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1345 {
1346 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1347 /* It was IDLE mode,
1348 * this is new state, then switch mode from suspend to resume */
1349 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1350 {
1351 hdd_set_wlan_suspend_mode(0);
1352 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1353 pHddCtx->cfg_ini->trafficIdleTimeout);
1354 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1355 }
1356 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1357 }
1358 }
1359
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1361
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 *ppVosPacket = NULL;
1363
1364 //Make sure the AC being asked for is sane
1365 if( ac > WLANTL_MAX_AC || ac < 0)
1366 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301367 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001368 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 return VOS_STATUS_E_FAILURE;
1370 }
1371
1372 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1373
c_hpothu6d1d2a32014-03-18 20:17:03 +05301374 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001375 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001376
1377 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1378 //This simplifies the locking and unlocking of Tx queue
1379 status = vos_pkt_wrap_data_packet( &pVosPacket,
1380 VOS_PKT_TYPE_TX_802_3_DATA,
1381 NULL, //OS Pkt is not being passed
1382 hdd_softap_tx_low_resource_cbk,
1383 pAdapter );
1384
1385 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1386 {
1387 //Remember VOS is in a low resource situation
1388 pAdapter->isVosOutOfResource = VOS_TRUE;
1389 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301390 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001391 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001392 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1393 return VOS_STATUS_E_FAILURE;
1394 }
1395
1396 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1397 as the other branch does.
1398 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301399 spin_lock_bh( &pSapCtx->staInfo_lock );
1400 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1401 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001402
1403 if (0 == size)
1404 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301405 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1406 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 vos_pkt_return_packet(pVosPacket);
1408 return VOS_STATUS_E_EMPTY;
1409 }
1410
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301411 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1412 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1413 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001414
c_hpothu6d1d2a32014-03-18 20:17:03 +05301415 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001416 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001417
1418 if(VOS_STATUS_SUCCESS == status)
1419 {
1420 //If success then we got a valid packet from some AC
1421 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1422 skb = pktNode->skb;
1423 }
1424 else
1425 {
1426 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301427 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001429 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001430 vos_pkt_return_packet(pVosPacket);
1431 return VOS_STATUS_E_FAILURE;
1432 }
1433
1434 //Attach skb to VOS packet.
1435 status = vos_pkt_set_os_packet( pVosPacket, skb );
1436 if (status != VOS_STATUS_SUCCESS)
1437 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301438 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001439 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 vos_pkt_return_packet(pVosPacket);
1441 ++pAdapter->stats.tx_dropped;
1442 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1443 kfree_skb(skb);
1444 return VOS_STATUS_E_FAILURE;
1445 }
1446
1447 //Just being paranoid. To be removed later
1448 if(pVosPacket == NULL)
1449 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301450 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001451 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 ++pAdapter->stats.tx_dropped;
1453 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1454 kfree_skb(skb);
1455 return VOS_STATUS_E_FAILURE;
1456 }
1457
1458 //Return VOS packet to TL;
1459 *ppVosPacket = pVosPacket;
1460
1461 //Fill out the meta information needed by TL
1462 //FIXME This timestamp is really the time stamp of wrap_data_packet
1463 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1464 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1465 if ( 1 < size )
1466 {
1467 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1468 }
1469 else
1470 {
1471 pPktMetaInfo->bMorePackets = 0;
1472 }
1473
1474 pPktMetaInfo->ucIsEapol = 0;
1475
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301476 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001477 {
1478 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1479 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001480 pPktMetaInfo->ucIsEapol = 1;
Sushant Kaushika8073312015-05-04 17:33:52 +05301481 wlan_hdd_log_eapol(skb,
1482 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
Jeff Johnson295189b2012-06-20 16:38:30 -07001483 }
1484 }
Sushant Kaushika8073312015-05-04 17:33:52 +05301485
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301486 if ((NULL != pHddCtx) &&
1487 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001488 {
1489 proto_type = vos_pkt_get_proto_type(skb,
1490 pHddCtx->cfg_ini->gEnableDebugLog);
1491 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1492 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001494 "SAP TX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001495 }
1496 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1497 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001499 "SAP TX DHCP");
1500 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301501 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1502 {
1503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1504 "SAP TX ARP");
1505 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001507//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301509 pPktMetaInfo->ac = ac;
Jeff Johnson295189b2012-06-20 16:38:30 -07001510 pPktMetaInfo->ucUP = pktNode->userPriority;
1511 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1512 }
1513
1514 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1515 //Extract the destination address from ethernet frame
1516 pDestMacAddress = (v_MACADDR_t*)skb->data;
1517
1518 // we need 802.3 to 802.11 frame translation
1519 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1520 pPktMetaInfo->ucDisableFrmXtl = 0;
1521 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1522 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1523
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301524 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001525 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1526 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301527 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001528 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301529 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001530 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301531 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1532 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001533 }
1534
1535 // We're giving the packet to TL so consider it transmitted from
1536 // a statistics perspective. We account for it here instead of
1537 // when the packet is returned for two reasons. First, TL will
1538 // manipulate the skb to the point where the len field is not
1539 // accurate, leading to inaccurate byte counts if we account for
1540 // it later. Second, TL does not provide any feedback as to
1541 // whether or not the packet was successfully sent over the air,
1542 // so the packet counts will be the same regardless of where we
1543 // account for them
1544 pAdapter->stats.tx_bytes += skb->len;
1545 ++pAdapter->stats.tx_packets;
1546 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1547 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301548 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001549
c_hpothu6d1d2a32014-03-18 20:17:03 +05301550 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001551 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001552
1553 return status;
1554}
1555
1556
1557/**============================================================================
1558 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1559 case where VOS packets are not available at the time of the call to get
1560 packets. This callback function is invoked by VOS when packets are
1561 available.
1562
1563 @param pVosPacket : [in] pointer to VOS packet
1564 @param userData : [in] opaque user data that was passed initially
1565
1566 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1567 : VOS_STATUS_SUCCESS otherwise
1568 =============================================================================*/
1569VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1570 v_VOID_t *userData )
1571{
1572 VOS_STATUS status;
1573 v_SINT_t i = 0;
1574 v_SIZE_t size = 0;
1575 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1576 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301577 v_CONTEXT_t pVosContext = NULL;
1578 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301579
1580 if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301582 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1583 FL("Invalid adapter %p"), pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001584 return VOS_STATUS_E_FAILURE;
1585 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301586 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1587 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1588 if(pSapCtx == NULL){
1589 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1590 FL("psapCtx is NULL"));
1591 return VOS_STATUS_E_FAULT;
1592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001593 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1594 //situation. Here we will only signal TL that there is a pending data for a STA.
1595 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1596 vos_pkt_return_packet( pVosPacket );
1597
1598 pAdapter->isVosOutOfResource = VOS_FALSE;
1599
1600 // Indicate to TL that there is pending data if a queue is non empty.
1601 // This Code wasnt included in earlier version which resulted in
1602 // Traffic stalling
1603 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1604 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301605 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1606 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 {
1608 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1609 {
1610 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301611 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001612 if ( size > 0 )
1613 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301614 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1615 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001616 (WLANTL_ACEnumType)i );
1617 if( !VOS_IS_STATUS_SUCCESS( status ) )
1618 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301619 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1620 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001621 }
1622 }
1623 }
1624 }
1625 }
1626 return VOS_STATUS_SUCCESS;
1627}
1628
1629
1630/**============================================================================
1631 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1632 TL will call this to notify the HDD when one or more packets were
1633 received for a registered STA.
1634
1635 @param vosContext : [in] pointer to VOS context
1636 @param pVosPacketChain : [in] pointer to VOS packet chain
1637 @param staId : [in] Station Id (Adress 1 Index)
1638 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1639
1640 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1641 : VOS_STATUS_SUCCESS otherwise
1642 ===========================================================================*/
1643VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1644 vos_pkt_t *pVosPacketChain,
1645 v_U8_t staId,
1646 WLANTL_RxMetaInfoType* pRxMetaInfo )
1647{
1648 hdd_adapter_t *pAdapter = NULL;
1649 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1650 int rxstat;
1651 struct sk_buff *skb = NULL;
1652 vos_pkt_t* pVosPacket;
1653 vos_pkt_t* pNextVosPacket;
1654 hdd_context_t *pHddCtx = NULL;
c_manjee16126372017-01-16 19:29:30 +05301655 v_U8_t proto_type = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001656
1657 //Sanity check on inputs
1658 if ( ( NULL == vosContext ) ||
1659 ( NULL == pVosPacketChain ) ||
1660 ( NULL == pRxMetaInfo ) )
1661 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301662 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1663 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001664 return VOS_STATUS_E_FAILURE;
1665 }
1666
1667 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1668 if ( NULL == pHddCtx )
1669 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301670 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1671 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 return VOS_STATUS_E_FAILURE;
1673 }
1674
1675 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301676 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301678 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1679 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 VOS_ASSERT(0);
1681 return VOS_STATUS_E_FAILURE;
1682 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001683
1684 /* Monitor traffic */
1685 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1686 {
1687 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1688 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1689 {
1690 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1691 /* It was IDLE mode,
1692 * this is new state, then switch mode from suspend to resume */
1693 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1694 {
1695 hdd_set_wlan_suspend_mode(0);
1696 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1697 pHddCtx->cfg_ini->trafficIdleTimeout);
1698 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1699 }
1700 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1701 }
1702 }
1703
Jeff Johnson295189b2012-06-20 16:38:30 -07001704 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1705
1706 // walk the chain until all are processed
1707 pVosPacket = pVosPacketChain;
1708 do
1709 {
1710 // get the pointer to the next packet in the chain
1711 // (but don't unlink the packet since we free the entire chain later)
1712 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1713
1714 // both "success" and "empty" are acceptable results
1715 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1716 {
1717 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301718 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1719 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001720 return VOS_STATUS_E_FAILURE;
1721 }
1722
1723 // Extract the OS packet (skb).
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301724 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001725 if(!VOS_IS_STATUS_SUCCESS( status ))
1726 {
1727 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301728 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1729 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001730 return VOS_STATUS_E_FAILURE;
1731 }
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301732
1733 if (TRUE == hdd_IsEAPOLPacket(pVosPacket))
1734 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
1735
1736 pVosPacket->pSkb = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001737 //hdd_softap_dump_sk_buff(skb);
1738
1739 skb->dev = pAdapter->dev;
1740
1741 if(skb->dev == NULL) {
1742
c_hpothu6d1d2a32014-03-18 20:17:03 +05301743 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1744 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001745 return VOS_STATUS_E_FAILURE;
1746 }
1747 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1748 ++pAdapter->stats.rx_packets;
1749 pAdapter->stats.rx_bytes += skb->len;
1750
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001751 if (pHddCtx->cfg_ini->gEnableDebugLog)
1752 {
1753 proto_type = vos_pkt_get_proto_type(skb,
1754 pHddCtx->cfg_ini->gEnableDebugLog);
1755 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1756 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001758 "SAP RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001759 }
1760 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1761 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001763 "SAP RX DHCP");
1764 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301765 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1766 {
1767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1768 "SAP RX ARP");
1769 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001770 }
1771
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +05301772 if (pHddCtx->rx_wow_dump) {
1773 if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) &&
1774 !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type))
1775 hdd_log_ip_addr(skb);
1776 pHddCtx->rx_wow_dump = false;
1777 }
1778
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1780 {
1781 //MC/BC packets. Duplicate a copy of packet
1782 struct sk_buff *pSkbCopy;
1783 hdd_ap_ctx_t *pHddApCtx;
1784
1785 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1786 if (!(pHddApCtx->apDisableIntraBssFwd))
1787 {
1788 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1789 if (pSkbCopy)
1790 {
1791 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1792 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1793 }
1794 }
1795 else
1796 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301797 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001798 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001799 }
1800
1801
1802 } //(WLAN_RX_BCMC_STA_ID == staId)
1803
1804 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1805 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1806 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301807 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001808 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301809 if ((NULL != pHddCtx) &&
1810 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301811 {
1812 hdd_dump_dhcp_pkt(skb, RX_PATH);
1813 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001814
1815 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001816 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnsone7245742012-09-05 17:12:55 -07001817#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301818 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
1819 HDD_WAKE_LOCK_DURATION,
1820 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
1821
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001822#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 rxstat = netif_rx_ni(skb);
1824 if (NET_RX_SUCCESS == rxstat)
1825 {
1826 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001827 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001828 }
1829 else
1830 {
1831 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1832 }
1833 }
1834 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1835 {
1836 kfree_skb(skb);
1837 }
1838 else
1839 {
1840 //loopback traffic
1841 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1842 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1843 }
1844
1845 // now process the next packet in the chain
1846 pVosPacket = pNextVosPacket;
1847
1848 } while (pVosPacket);
1849
1850 //Return the entire VOS packet chain to the resource pool
1851 status = vos_pkt_return_packet( pVosPacketChain );
1852 if(!VOS_IS_STATUS_SUCCESS( status ))
1853 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301854 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1855 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001856 }
1857
1858 pAdapter->dev->last_rx = jiffies;
1859
1860 return status;
1861}
1862
1863VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1864{
1865 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301866 hdd_context_t *pHddCtx;
1867 if (NULL == pAdapter)
1868 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301869 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301870 "%s: pAdapter is NULL", __func__);
1871 return VOS_STATUS_E_INVAL;
1872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001873
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301874 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1875 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301876 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301877 "%s: Invalid pAdapter magic", __func__);
1878 return VOS_STATUS_E_INVAL;
1879 }
1880
1881 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301882 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001883 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301884 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001885 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1886 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301887 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001889 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001890 staId, vosStatus, vosStatus );
1891 }
1892
1893 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1894 if( VOS_STATUS_E_FAILURE == vosStatus )
1895 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301896 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001898 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001899 staId, vosStatus, vosStatus );
1900 return( vosStatus );
1901 }
1902
1903 pHddCtx->sta_to_adapter[staId] = NULL;
1904
1905 return( vosStatus );
1906}
1907
1908VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1909 v_BOOL_t fAuthRequired,
1910 v_BOOL_t fPrivacyBit,
1911 v_U8_t staId,
1912 v_U8_t ucastSig,
1913 v_U8_t bcastSig,
1914 v_MACADDR_t *pPeerMacAddress,
1915 v_BOOL_t fWmmEnabled )
1916{
1917 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001918 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1920 hdd_adapter_t *pmonAdapter = NULL;
1921
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301922 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1923 ptSapContext pSapCtx = NULL;
1924 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1925 if(pSapCtx == NULL){
1926 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1927 FL("psapCtx is NULL"));
1928 return VOS_STATUS_E_FAULT;
1929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001930 //eCsrEncryptionType connectedCipherAlgo;
1931 //v_BOOL_t fConnected;
1932
1933 /*
1934 * Clean up old entry if it is not cleaned up properly
1935 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301936 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001937 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301938 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001939 "clean up old entry for STA %d", staId);
1940 hdd_softap_DeregisterSTA( pAdapter, staId );
1941 }
1942
1943 // Get the Station ID from the one saved during the assocation.
1944
1945 staDesc.ucSTAId = staId;
1946
1947
1948 /*Save the pAdapter Pointer for this staId*/
1949 pHddCtx->sta_to_adapter[staId] = pAdapter;
1950
1951 staDesc.wSTAType = WLAN_STA_SOFTAP;
1952
1953 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1954 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1955 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1956
c_hpothu6d1d2a32014-03-18 20:17:03 +05301957 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001958 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301959 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001960 "station mac " MAC_ADDRESS_STR,
1961 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301962 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001963 "BSSIDforIBSS " MAC_ADDRESS_STR,
1964 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301965 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001966 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1967 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001968
1969 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1970
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301972 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 "HDD SOFTAP register TL QoS_enabled=%d",
1974 staDesc.ucQosEnabled );
1975
1976 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1977
1978
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 // For PRIMA UMA frame translation is not enable yet.
1980 staDesc.ucSwFrameTXXlation = 1;
1981 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 staDesc.ucAddRmvLLC = 1;
1983
1984 // Initialize signatures and state
1985 staDesc.ucUcastSig = ucastSig;
1986 staDesc.ucBcastSig = bcastSig;
1987 staDesc.ucInitState = fAuthRequired ?
1988 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1989
Prathyushaf5442802012-12-12 13:58:11 -08001990 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1991
Jeff Johnson295189b2012-06-20 16:38:30 -07001992 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301993 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1994 hdd_softap_rx_packet_cbk,
1995 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001996 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1997
1998 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1999 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302000 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07002001 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 vosStatus, vosStatus );
2003 return vosStatus;
2004 }
2005
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002006 //Timer value should be in milliseconds
2007 if ( pHddCtx->cfg_ini->dynSplitscan &&
2008 ( VOS_TIMER_STATE_RUNNING !=
2009 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
2010 {
2011 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
2012 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
2013 }
2014
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
2016 // then go to 'authenticated'. For all other authentication types (those that do
2017 // not require upper layer authentication) we can put TL directly into 'authenticated'
2018 // state.
2019
2020 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302021 pSapCtx->aStaInfo[staId].ucSTAId = staId;
2022 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 if ( !fAuthRequired )
2024 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302025 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
2026 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302027 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07002028
2029 // Connections that do not need Upper layer auth, transition TL directly
2030 // to 'Authenticated' state.
2031 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
2032 WLANTL_STA_AUTHENTICATED );
2033
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302034 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
2036 }
2037 else
2038 {
2039
c_hpothu6d1d2a32014-03-18 20:17:03 +05302040 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302041 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07002042
2043 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
2044 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302045 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002046
2047 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
2048
2049 }
2050 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
2051 if(pmonAdapter)
2052 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302053 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
2054 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07002055 netif_carrier_on(pmonAdapter->dev);
2056 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302057 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 netif_tx_start_all_queues(pmonAdapter->dev);
2059 }
2060 netif_carrier_on(pAdapter->dev);
2061 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302062 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 netif_tx_start_all_queues(pAdapter->dev);
2064
2065 return( vosStatus );
2066}
2067
2068VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
2069{
2070 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2071 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2072 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
2073
2074
2075 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
2076 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
2077 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
2078
2079 return vosStatus;
2080}
2081
2082VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
2083{
2084 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
2085}
2086
2087VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
2088{
2089 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2090 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302091 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07002092
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302093 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2094 ptSapContext pSapCtx = NULL;
2095 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2096 if(pSapCtx == NULL){
2097 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2098 FL("psapCtx is NULL"));
2099 return VOS_STATUS_E_FAULT;
2100 }
2101
2102 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07002103 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05302104 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07002105 {
2106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2107 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
2108 return VOS_STATUS_E_PERM;
2109 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002110
2111 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
2112
Jeff Johnson43971f52012-07-17 12:26:56 -07002113 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302115 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002116 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002117 }
2118
2119 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2120 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302121 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302123 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
2124 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2125 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302126 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002127 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302128 }
2129 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 }
2131
2132 return vosStatus;
2133}
2134
2135VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
2136{
2137 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
2138 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2139 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002140
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302141 ptSapContext pSapCtx = NULL;
2142 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2143 if(pSapCtx == NULL){
2144 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2145 FL("psapCtx is NULL"));
2146 return VOS_STATUS_E_FAULT;
2147 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302148 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002149 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002150
Jeff Johnson43971f52012-07-17 12:26:56 -07002151 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002152 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302153 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002154 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 return VOS_STATUS_E_FAILURE;
2156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002157
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302158 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302160 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002161 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002162 return VOS_STATUS_E_FAILURE;
2163 }
2164
2165 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302166 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002167 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002168
Jeff Johnson43971f52012-07-17 12:26:56 -07002169 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302171 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002172 }
2173
c_hpothu6d1d2a32014-03-18 20:17:03 +05302174 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002175 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002176
2177 return vosStatus;
2178}
2179
2180
2181VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2182{
2183 v_U8_t i;
2184
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302185 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2186 ptSapContext pSapCtx = NULL;
2187 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2188 if(pSapCtx == NULL){
2189 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2190 FL("psapCtx is NULL"));
2191 return VOS_STATUS_E_FAULT;
2192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2194 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302195 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2196 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002197 {
2198 *staId = i;
2199 return VOS_STATUS_SUCCESS;
2200 }
2201 }
2202
2203 return VOS_STATUS_E_FAILURE;
2204}
2205
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302206VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2207{
2208 v_U8_t i;
2209
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302210 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2211 ptSapContext pSapCtx = NULL;
2212 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2213 if(pSapCtx == NULL){
2214 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2215 FL("psapCtx is NULL"));
2216 return VOS_STATUS_E_FAULT;
2217 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302218 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2219 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302220 if (pSapCtx->aStaInfo[i].isUsed &&
2221 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302222 {
2223 *staId = i;
2224 return VOS_STATUS_SUCCESS;
2225 }
2226 }
2227
2228 return VOS_STATUS_E_FAILURE;
2229}