blob: c728ae12654a081e82e64966f6bad482162af2f5 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Sourav Mohapatra5817dc42017-12-18 17:45:16 +05302 * Copyright (c) 2012-2018 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{
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070076 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %pK", __func__, skb->head);
77 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %pK", __func__, skb->data);
78 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %pK", __func__, skb->tail);
79 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %pK", __func__, skb->end);
c_hpothu6d1d2a32014-03-18 20:17:03 +053080 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 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530576 netif_trans_update(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700577
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
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530759 TX_TIMEOUT_TRACE(dev, VOS_MODULE_ID_HDD_DATA);
Mihir Shetef3473692014-06-27 15:13:20 +0530760
761 if ( NULL == pAdapter )
762 {
763 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
764 FL("pAdapter is NULL"));
765 VOS_ASSERT(0);
766 return;
767 }
768
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530769 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mukul Sharma4b322632015-02-28 20:21:43 +0530770 status = wlan_hdd_validate_context(pHddCtx);
771 if (status != 0)
772 {
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530773 return;
774 }
775
Mihir Shetef3473692014-06-27 15:13:20 +0530776 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
777
mukul sharma2cdb8ea2015-10-01 14:53:38 +0530778 for (i = 0; i < NUM_TX_QUEUES; i++)
Mihir Shetef3473692014-06-27 15:13:20 +0530779 {
780 txq = netdev_get_tx_queue(dev, i);
781 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
782 "Queue%d status: %d", i, netif_tx_queue_stopped(txq));
783 }
784
785 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
mukul sharma2cdb8ea2015-10-01 14:53:38 +0530786 "carrier state: %d", netif_carrier_ok(dev));
Mihir Shetef3473692014-06-27 15:13:20 +0530787
788 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
789
Mihir Shete327c2ab2014-11-13 15:17:02 +0530790 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
791 HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
792 {
793 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
794 "%s: Request firmware for recovery",__func__);
795 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
796 }
Mihir Shetef3473692014-06-27 15:13:20 +0530797 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
798 HDD_SAP_TX_STALL_SSR_THRESHOLD)
799 {
800 // Driver could not recover, issue SSR
801 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
802 "%s: Cannot recover from Data stall Issue SSR",
803 __func__);
Mihir Shetefd62d9d2014-08-06 15:08:21 +0530804 WLANTL_FatalError();
Mukul Sharma987bef02015-11-16 20:04:54 +0530805 // reset count after issuing the SSR
806 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Mihir Shetef3473692014-06-27 15:13:20 +0530807 return;
808 }
809
810 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
811 * every 5sec. The TL debug spits out a lot of information on the
812 * serial console, if it is called every time *hdd_tx_timeout* is
813 * called then we may get a watchdog bite on the Application
814 * processor, so ratelimit the TL debug logs.
815 */
816 if (__ratelimit(&hdd_softap_tx_timeout_rs))
817 {
818 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +0530819 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetef3473692014-06-27 15:13:20 +0530820 }
Abhishek Singh837adf22015-10-01 17:37:37 +0530821 /* Call fatal event if data stall is for
822 * HDD_TX_STALL_FATAL_EVENT_THRESHOLD times
823 */
824 if (HDD_SAP_TX_STALL_FATAL_EVENT_THRESHOLD ==
825 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount)
826 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
827 WLAN_LOG_INDICATOR_HOST_DRIVER,
828 WLAN_LOG_REASON_DATA_STALL,
829 FALSE, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700830}
831
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530832void hdd_softap_tx_timeout(struct net_device *dev)
833{
834 vos_ssr_protect(__func__);
835 __hdd_softap_tx_timeout(dev);
836 vos_ssr_unprotect(__func__);
837 return;
838}
Jeff Johnson295189b2012-06-20 16:38:30 -0700839
840/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530841 @brief __hdd_softap_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700842 device TX/RX statistic
843
844 @param dev : [in] pointer to Libra network device
845
846 @return : pointer to net_device_stats structure
847 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530848struct net_device_stats* __hdd_softap_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700849{
850 hdd_adapter_t* priv = netdev_priv(dev);
851 return &priv->stats;
852}
853
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530854struct net_device_stats* hdd_softap_stats(struct net_device *dev)
855{
856 struct net_device_stats *priv_stats;
857 vos_ssr_protect(__func__);
858 priv_stats = __hdd_softap_stats(dev);
859 vos_ssr_unprotect(__func__);
860
861 return priv_stats;
862}
Jeff Johnson295189b2012-06-20 16:38:30 -0700863
864/**============================================================================
865 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
866 modules in HDD
867
868 @param pAdapter : [in] pointer to adapter context
869 @return : VOS_STATUS_E_FAILURE if any errors encountered
870 : VOS_STATUS_SUCCESS otherwise
871 ===========================================================================*/
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530872VOS_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter, bool re_init)
Jeff Johnson295189b2012-06-20 16:38:30 -0700873{
874 VOS_STATUS status = VOS_STATUS_SUCCESS;
875 v_SINT_t i = -1;
876 v_SIZE_t size = 0;
877
878 v_U8_t STAId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530879 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
880 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700881
882 v_U8_t pACWeights[] = {
883 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
884 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
885 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
886 HDD_SOFTAP_VO_WEIGHT_DEFAULT
887 };
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530888 pSapCtx = VOS_GET_SAP_CB(pVosContext);
889 if(pSapCtx == NULL){
890 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
891 FL("psapCtx is NULL"));
892 return VOS_STATUS_E_FAULT;
893 }
894
Leo Chang64d68bc2013-06-04 15:40:52 -0700895
Jeff Johnson295189b2012-06-20 16:38:30 -0700896 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530897 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700898
899 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
900
901 while (++i != NUM_TX_QUEUES)
902 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
903
904 /* Initial HDD buffer control / flow control fields*/
905 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
906
907 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
908 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
909 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
910 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
911
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
913 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530914 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700915 for (i = 0; i < NUM_TX_QUEUES; i ++)
916 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530917 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700918 }
919 }
920
Yue Ma3ede6052013-08-29 00:33:26 -0700921 /* Update the AC weights suitable for SoftAP mode of operation */
922 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
923
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530924 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter, re_init))
Leo Chang64d68bc2013-06-04 15:40:52 -0700925 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530926 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530927 "%s: failed to start Traffic Monito timer ", __func__ );
928 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700929 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700930 return status;
931}
932
933/**============================================================================
934 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
935 modules in HDD
936
937 @param pAdapter : [in] pointer to adapter context
938 @return : VOS_STATUS_E_FAILURE if any errors encountered
939 : VOS_STATUS_SUCCESS otherwise
940 ===========================================================================*/
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530941VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter, bool re_init)
Jeff Johnson295189b2012-06-20 16:38:30 -0700942{
943 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700944
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +0530945 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter, re_init))
Leo Chang64d68bc2013-06-04 15:40:52 -0700946 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530947 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530948 "%s: Fail to Stop Traffic Monito timer", __func__ );
949 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700950 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700951
952 status = hdd_softap_flush_tx_queues(pAdapter);
953
954 return status;
955}
956
957/**============================================================================
958 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
959
960 @param pAdapter : [in] pointer to adapter context
961 @param STAId : [in] Station ID to deinit
962 @return : VOS_STATUS_E_FAILURE if any errors encountered
963 : VOS_STATUS_SUCCESS otherwise
964 ===========================================================================*/
965static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
966{
Jeff Johnson295189b2012-06-20 16:38:30 -0700967 v_U8_t i = -1;
968
969 hdd_list_node_t *anchor = NULL;
970
971 skb_list_node_t *pktNode = NULL;
972 struct sk_buff *skb = NULL;
973
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530974 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
975 ptSapContext pSapCtx = NULL;
976 pSapCtx = VOS_GET_SAP_CB(pVosContext);
977 if(pSapCtx == NULL){
978 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
979 FL("psapCtx is NULL"));
980 return VOS_STATUS_E_FAULT;
981 }
982 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700983 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530984 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 }
986
987 for (i = 0; i < NUM_TX_QUEUES; i ++)
988 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530989 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 while (true)
991 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530992 if (VOS_STATUS_E_EMPTY !=
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530993 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530994 &anchor))
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 {
996 //If success then we got a valid packet from some AC
997 pktNode = list_entry(anchor, skb_list_node_t, anchor);
998 skb = pktNode->skb;
999 ++pAdapter->stats.tx_dropped;
1000 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
1001 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
1002 kfree_skb(skb);
1003 continue;
1004 }
1005
1006 //current list is empty
1007 break;
1008 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301009 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001010 }
1011
Venkateswara T Asodi Reddycb76f242016-12-09 15:04:25 +05301012 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1013 "%s: flushed the TX queues of sta:%d", __func__, STAId);
1014
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301015 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001016}
1017
1018/**============================================================================
1019 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
1020 modules in HDD
1021
1022 @param pAdapter : [in] pointer to adapter context
1023 @param STAId : [in] Station ID to deinit
1024 @param pmacAddrSTA : [in] pointer to the MAC address of the station
1025 @return : VOS_STATUS_E_FAILURE if any errors encountered
1026 : VOS_STATUS_SUCCESS otherwise
1027 ===========================================================================*/
1028VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
1029{
1030 v_U8_t i = 0;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301031 VOS_STATUS status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301032 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1033 ptSapContext pSapCtx = NULL;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301034
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301035 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1036 if(pSapCtx == NULL){
1037 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1038 FL("psapCtx is NULL"));
1039 return VOS_STATUS_E_FAULT;
1040 }
1041
1042 spin_lock_bh( &pSapCtx->staInfo_lock );
1043 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001044 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301045 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1046 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301047 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 return VOS_STATUS_E_FAILURE;
1049 }
1050
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301051 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 for (i = 0; i < NUM_TX_QUEUES; i ++)
1053 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301054 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 }
1056
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301057 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
1058 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
1059 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -07001060
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301061 spin_unlock_bh( &pSapCtx->staInfo_lock );
Nirav Shah7e3c8132015-06-22 23:51:42 +05301062
1063 status = hdd_sta_id_hash_add_entry(pAdapter, STAId, pmacAddrSTA);
1064 if (status != VOS_STATUS_SUCCESS) {
1065 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1066 FL("Not able to add staid hash %d"), STAId);
1067 return VOS_STATUS_E_FAILURE;
1068 }
1069
1070 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1071 FL("New station added sta_id %d mac:"
1072 MAC_ADDRESS_STR), STAId,
1073 MAC_ADDR_ARRAY(pmacAddrSTA->bytes));
1074
Jeff Johnson295189b2012-06-20 16:38:30 -07001075 return VOS_STATUS_SUCCESS;
1076}
1077
1078/**============================================================================
1079 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
1080 modules in HDD
1081
1082 @param pAdapter : [in] pointer to adapter context
1083 @param STAId : [in] Station ID to deinit
1084 @return : VOS_STATUS_E_FAILURE if any errors encountered
1085 : VOS_STATUS_SUCCESS otherwise
1086 ===========================================================================*/
1087VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
1088{
1089 VOS_STATUS status = VOS_STATUS_SUCCESS;
1090 v_U8_t ac;
1091 /**Track whether OS TX queue has been disabled.*/
1092 v_BOOL_t txSuspended[NUM_TX_QUEUES];
1093 v_U8_t tlAC;
1094 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001095 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -07001096
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301097 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1098 ptSapContext pSapCtx = NULL;
1099 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1100 if(pSapCtx == NULL){
1101 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1102 FL("psapCtx is NULL"));
1103 return VOS_STATUS_E_FAULT;
1104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1106
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301107 spin_lock_bh( &pSapCtx->staInfo_lock );
1108 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001109 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301110 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001111 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301112 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001113 return VOS_STATUS_E_FAILURE;
1114 }
1115
1116 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1117
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301118 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1119 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301120
1121 status = hdd_sta_id_hash_remove_entry(pAdapter,
1122 STAId, &pSapCtx->aStaInfo[STAId].macAddrSTA);
1123 if (status != VOS_STATUS_SUCCESS) {
Hanumantha Reddy Pothulaa88d4182015-12-23 18:19:28 +05301124 spin_unlock_bh( &pSapCtx->staInfo_lock );
Nirav Shah7e3c8132015-06-22 23:51:42 +05301125 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1126 FL("Not able to remove staid hash %d"), STAId);
1127 return VOS_STATUS_E_FAILURE;
1128 }
1129
1130 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1131 FL("station removed sta_id %d mac:"
1132 MAC_ADDRESS_STR), STAId,
1133 MAC_ADDR_ARRAY(pSapCtx->aStaInfo[STAId].macAddrSTA.bytes));
1134
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 /* if this STA had any of its WMM TX queues suspended, then the
1136 associated queue on the network interface was disabled. check
1137 to see if that is the case, in which case we need to re-enable
1138 the interface queue. but we only do this if the BSS is running
1139 since, if the BSS is stopped, all of the interfaces have been
1140 stopped and should not be re-enabled */
1141
1142 if (BSS_START == pHostapdState->bssState)
1143 {
1144 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1145 {
1146 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301147 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001148 }
1149 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301150 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001151
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001152 /* re-init spin lock, since netdev can still open adapter until
1153 * driver gets unloaded
1154 */
1155 for (i = 0; i < NUM_TX_QUEUES; i ++)
1156 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301157 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001158 HDD_TX_QUEUE_MAX_LEN);
1159 }
1160
Jeff Johnson295189b2012-06-20 16:38:30 -07001161 if (BSS_START == pHostapdState->bssState)
1162 {
1163 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1164 {
1165 if (txSuspended[ac])
1166 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301167 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001168 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001169 netif_wake_subqueue(pAdapter->dev, ac);
1170 }
1171 }
1172 }
1173
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301174 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001175 return status;
1176}
1177
1178/**============================================================================
1179 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1180 modules in HDD
1181
1182 @param pAdapter : [in] pointer to adapter context
1183 @return : VOS_STATUS_E_FAILURE if any errors encountered
1184 : VOS_STATUS_SUCCESS otherwise
1185 ===========================================================================*/
1186VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1187{
1188 return hdd_softap_flush_tx_queues(pAdapter);
1189}
1190
1191/**============================================================================
1192 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1193 to indicate that a packet has been transmitted across the bus
1194 succesfully. OS packet resources can be released after this cbk.
1195
1196 @param vosContext : [in] pointer to VOS context
1197 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1198 @param vosStatusIn : [in] status of the transmission
1199
1200 @return : VOS_STATUS_E_FAILURE if any errors encountered
1201 : VOS_STATUS_SUCCESS otherwise
1202 ===========================================================================*/
1203VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1204 vos_pkt_t *pVosPacket,
1205 VOS_STATUS vosStatusIn )
1206{
1207 VOS_STATUS status = VOS_STATUS_SUCCESS;
1208 hdd_adapter_t *pAdapter = NULL;
1209 void* pOsPkt = NULL;
1210
1211 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1212 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301213 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1214 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 return VOS_STATUS_E_FAILURE;
1216 }
1217
1218 //Return the skb to the OS
1219 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001220 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 {
1222 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301223 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1224 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 vos_pkt_return_packet( pVosPacket );
1226 return VOS_STATUS_E_FAILURE;
1227 }
1228
1229 //Get the Adapter context.
1230 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301231 if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301233 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301234 "%s: HDD adapter context is invalid", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001235 }
1236 else
1237 {
1238 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1239 }
1240
1241 kfree_skb((struct sk_buff *)pOsPkt);
1242
1243 //Return the VOS packet resources.
1244 status = vos_pkt_return_packet( pVosPacket );
1245 if(!VOS_IS_STATUS_SUCCESS( status ))
1246 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301247 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1248 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001249 }
1250
1251 return status;
1252}
1253
1254
1255/**============================================================================
1256 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1257 fetch a packet for transmission.
1258
1259 @param vosContext : [in] pointer to VOS context
1260 @param staId : [in] Station for which TL is requesting a pkt
1261 @param ac : [in] access category requested by TL
1262 @param pVosPacket : [out] pointer to VOS packet packet pointer
1263 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1264
1265 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1266 : VOS_STATUS_E_FAILURE if any errors encountered
1267 : VOS_STATUS_SUCCESS otherwise
1268 ===========================================================================*/
1269VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1270 v_U8_t *pStaId,
1271 WLANTL_ACEnumType ac,
1272 vos_pkt_t **ppVosPacket,
1273 WLANTL_MetaInfoType *pPktMetaInfo )
1274{
1275 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1276 hdd_adapter_t *pAdapter = NULL;
1277 hdd_list_node_t *anchor = NULL;
1278 skb_list_node_t *pktNode = NULL;
1279 struct sk_buff *skb = NULL;
1280 vos_pkt_t *pVosPacket = NULL;
1281 v_MACADDR_t* pDestMacAddress = NULL;
1282 v_TIME_t timestamp;
1283 v_SIZE_t size = 0;
1284 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1285 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001286 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301287 v_CONTEXT_t pVosContext = NULL;
1288 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001289 //Sanity check on inputs
1290 if ( ( NULL == vosContext ) ||
1291 ( NULL == pStaId ) ||
1292 ( NULL == ppVosPacket ) ||
1293 ( NULL == pPktMetaInfo ) )
1294 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301295 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1296 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 return VOS_STATUS_E_FAILURE;
1298 }
1299
1300 //Get the HDD context.
1301 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1302 if ( NULL == pHddCtx )
1303 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301304 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1305 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 return VOS_STATUS_E_FAILURE;
1307 }
1308
Jeff Johnsonb156c922013-12-05 17:19:46 -08001309 STAId = *pStaId;
1310 if (STAId >= WLAN_MAX_STA_COUNT)
1311 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301312 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001313 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1314 return VOS_STATUS_E_FAILURE;
1315 }
1316
1317 pAdapter = pHddCtx->sta_to_adapter[STAId];
1318 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001319 {
1320 VOS_ASSERT(0);
1321 return VOS_STATUS_E_FAILURE;
1322 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301323 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1324 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1325 if(pSapCtx == NULL){
1326 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1327 FL("psapCtx is NULL"));
1328 return VOS_STATUS_E_FAULT;
1329 }
1330
1331 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001332 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301333 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001334 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1335 return VOS_STATUS_E_FAILURE;
1336 }
1337
Leo Chang64d68bc2013-06-04 15:40:52 -07001338 /* Monitor traffic */
1339 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1340 {
1341 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1342 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1343 {
1344 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1345 /* It was IDLE mode,
1346 * this is new state, then switch mode from suspend to resume */
1347 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1348 {
1349 hdd_set_wlan_suspend_mode(0);
1350 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1351 pHddCtx->cfg_ini->trafficIdleTimeout);
1352 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1353 }
1354 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1355 }
1356 }
1357
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1359
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 *ppVosPacket = NULL;
1361
1362 //Make sure the AC being asked for is sane
1363 if( ac > WLANTL_MAX_AC || ac < 0)
1364 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301365 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001366 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001367 return VOS_STATUS_E_FAILURE;
1368 }
1369
1370 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1371
c_hpothu6d1d2a32014-03-18 20:17:03 +05301372 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001373 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001374
1375 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1376 //This simplifies the locking and unlocking of Tx queue
1377 status = vos_pkt_wrap_data_packet( &pVosPacket,
1378 VOS_PKT_TYPE_TX_802_3_DATA,
1379 NULL, //OS Pkt is not being passed
1380 hdd_softap_tx_low_resource_cbk,
1381 pAdapter );
1382
1383 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1384 {
1385 //Remember VOS is in a low resource situation
1386 pAdapter->isVosOutOfResource = VOS_TRUE;
1387 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301388 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001389 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001390 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1391 return VOS_STATUS_E_FAILURE;
1392 }
1393
1394 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1395 as the other branch does.
1396 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301397 spin_lock_bh( &pSapCtx->staInfo_lock );
1398 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1399 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001400
1401 if (0 == size)
1402 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301403 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1404 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 vos_pkt_return_packet(pVosPacket);
1406 return VOS_STATUS_E_EMPTY;
1407 }
1408
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301409 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1410 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1411 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001412
c_hpothu6d1d2a32014-03-18 20:17:03 +05301413 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001414 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001415
1416 if(VOS_STATUS_SUCCESS == status)
1417 {
1418 //If success then we got a valid packet from some AC
1419 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1420 skb = pktNode->skb;
1421 }
1422 else
1423 {
1424 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301425 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001427 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 vos_pkt_return_packet(pVosPacket);
1429 return VOS_STATUS_E_FAILURE;
1430 }
1431
1432 //Attach skb to VOS packet.
1433 status = vos_pkt_set_os_packet( pVosPacket, skb );
1434 if (status != VOS_STATUS_SUCCESS)
1435 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301436 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001437 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 vos_pkt_return_packet(pVosPacket);
1439 ++pAdapter->stats.tx_dropped;
1440 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1441 kfree_skb(skb);
1442 return VOS_STATUS_E_FAILURE;
1443 }
1444
1445 //Just being paranoid. To be removed later
1446 if(pVosPacket == NULL)
1447 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301448 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001449 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001450 ++pAdapter->stats.tx_dropped;
1451 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1452 kfree_skb(skb);
1453 return VOS_STATUS_E_FAILURE;
1454 }
1455
1456 //Return VOS packet to TL;
1457 *ppVosPacket = pVosPacket;
1458
1459 //Fill out the meta information needed by TL
1460 //FIXME This timestamp is really the time stamp of wrap_data_packet
1461 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1462 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1463 if ( 1 < size )
1464 {
1465 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1466 }
1467 else
1468 {
1469 pPktMetaInfo->bMorePackets = 0;
1470 }
1471
1472 pPktMetaInfo->ucIsEapol = 0;
1473
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301474 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001475 {
1476 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1477 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001478 pPktMetaInfo->ucIsEapol = 1;
Sushant Kaushika8073312015-05-04 17:33:52 +05301479 wlan_hdd_log_eapol(skb,
1480 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
Jeff Johnson295189b2012-06-20 16:38:30 -07001481 }
1482 }
Sushant Kaushika8073312015-05-04 17:33:52 +05301483
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301484 if ((NULL != pHddCtx) &&
1485 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001486 {
1487 proto_type = vos_pkt_get_proto_type(skb,
1488 pHddCtx->cfg_ini->gEnableDebugLog);
1489 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1490 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001492 "SAP TX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001493 }
1494 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1495 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001497 "SAP TX DHCP");
1498 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301499 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1500 {
1501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1502 "SAP TX ARP");
1503 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001504 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001505//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001506 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301507 pPktMetaInfo->ac = ac;
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 pPktMetaInfo->ucUP = pktNode->userPriority;
1509 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1510 }
1511
1512 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1513 //Extract the destination address from ethernet frame
1514 pDestMacAddress = (v_MACADDR_t*)skb->data;
1515
1516 // we need 802.3 to 802.11 frame translation
1517 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1518 pPktMetaInfo->ucDisableFrmXtl = 0;
1519 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1520 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1521
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301522 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1524 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301525 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001526 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301527 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301529 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1530 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001531 }
1532
1533 // We're giving the packet to TL so consider it transmitted from
1534 // a statistics perspective. We account for it here instead of
1535 // when the packet is returned for two reasons. First, TL will
1536 // manipulate the skb to the point where the len field is not
1537 // accurate, leading to inaccurate byte counts if we account for
1538 // it later. Second, TL does not provide any feedback as to
1539 // whether or not the packet was successfully sent over the air,
1540 // so the packet counts will be the same regardless of where we
1541 // account for them
1542 pAdapter->stats.tx_bytes += skb->len;
1543 ++pAdapter->stats.tx_packets;
1544 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1545 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301546 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001547
c_hpothu6d1d2a32014-03-18 20:17:03 +05301548 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001549 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001550
1551 return status;
1552}
1553
1554
1555/**============================================================================
1556 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1557 case where VOS packets are not available at the time of the call to get
1558 packets. This callback function is invoked by VOS when packets are
1559 available.
1560
1561 @param pVosPacket : [in] pointer to VOS packet
1562 @param userData : [in] opaque user data that was passed initially
1563
1564 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1565 : VOS_STATUS_SUCCESS otherwise
1566 =============================================================================*/
1567VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1568 v_VOID_t *userData )
1569{
1570 VOS_STATUS status;
1571 v_SINT_t i = 0;
1572 v_SIZE_t size = 0;
1573 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1574 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301575 v_CONTEXT_t pVosContext = NULL;
1576 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301577
1578 if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07001579 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301580 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001581 FL("Invalid adapter %pK"), pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 return VOS_STATUS_E_FAILURE;
1583 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301584 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1585 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1586 if(pSapCtx == NULL){
1587 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1588 FL("psapCtx is NULL"));
1589 return VOS_STATUS_E_FAULT;
1590 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001591 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1592 //situation. Here we will only signal TL that there is a pending data for a STA.
1593 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1594 vos_pkt_return_packet( pVosPacket );
1595
1596 pAdapter->isVosOutOfResource = VOS_FALSE;
1597
1598 // Indicate to TL that there is pending data if a queue is non empty.
1599 // This Code wasnt included in earlier version which resulted in
1600 // Traffic stalling
1601 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1602 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301603 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1604 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001605 {
1606 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1607 {
1608 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301609 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001610 if ( size > 0 )
1611 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301612 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1613 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001614 (WLANTL_ACEnumType)i );
1615 if( !VOS_IS_STATUS_SUCCESS( status ) )
1616 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301617 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1618 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001619 }
1620 }
1621 }
1622 }
1623 }
1624 return VOS_STATUS_SUCCESS;
1625}
1626
1627
1628/**============================================================================
1629 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1630 TL will call this to notify the HDD when one or more packets were
1631 received for a registered STA.
1632
1633 @param vosContext : [in] pointer to VOS context
1634 @param pVosPacketChain : [in] pointer to VOS packet chain
1635 @param staId : [in] Station Id (Adress 1 Index)
1636 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1637
1638 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1639 : VOS_STATUS_SUCCESS otherwise
1640 ===========================================================================*/
1641VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1642 vos_pkt_t *pVosPacketChain,
1643 v_U8_t staId,
1644 WLANTL_RxMetaInfoType* pRxMetaInfo )
1645{
1646 hdd_adapter_t *pAdapter = NULL;
1647 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1648 int rxstat;
1649 struct sk_buff *skb = NULL;
1650 vos_pkt_t* pVosPacket;
1651 vos_pkt_t* pNextVosPacket;
1652 hdd_context_t *pHddCtx = NULL;
c_manjee16126372017-01-16 19:29:30 +05301653 v_U8_t proto_type = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001654
1655 //Sanity check on inputs
1656 if ( ( NULL == vosContext ) ||
1657 ( NULL == pVosPacketChain ) ||
1658 ( NULL == pRxMetaInfo ) )
1659 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301660 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1661 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001662 return VOS_STATUS_E_FAILURE;
1663 }
1664
1665 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1666 if ( NULL == pHddCtx )
1667 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301668 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1669 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001670 return VOS_STATUS_E_FAILURE;
1671 }
1672
1673 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301674 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001675 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301676 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1677 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 VOS_ASSERT(0);
1679 return VOS_STATUS_E_FAILURE;
1680 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001681
1682 /* Monitor traffic */
1683 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1684 {
1685 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1686 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1687 {
1688 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1689 /* It was IDLE mode,
1690 * this is new state, then switch mode from suspend to resume */
1691 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1692 {
1693 hdd_set_wlan_suspend_mode(0);
1694 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1695 pHddCtx->cfg_ini->trafficIdleTimeout);
1696 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1697 }
1698 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1699 }
1700 }
1701
Jeff Johnson295189b2012-06-20 16:38:30 -07001702 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1703
1704 // walk the chain until all are processed
1705 pVosPacket = pVosPacketChain;
1706 do
1707 {
1708 // get the pointer to the next packet in the chain
1709 // (but don't unlink the packet since we free the entire chain later)
1710 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1711
1712 // both "success" and "empty" are acceptable results
1713 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1714 {
1715 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301716 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1717 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001718 return VOS_STATUS_E_FAILURE;
1719 }
1720
1721 // Extract the OS packet (skb).
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301722 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001723 if(!VOS_IS_STATUS_SUCCESS( status ))
1724 {
1725 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301726 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1727 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001728 return VOS_STATUS_E_FAILURE;
1729 }
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301730
Dundi Ravitejadf104d72021-03-10 11:56:36 +05301731 if (TRUE == hdd_IsEAPOLPacket(pVosPacket)) {
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301732 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
1733
Dundi Ravitejadf104d72021-03-10 11:56:36 +05301734 if (vos_mem_compare2(skb->data,
1735 pAdapter->macAddressCurrent.bytes, 6) != 0) {
1736 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1737 "Packet is not destined to this address, dropping");
1738 kfree_skb(skb);
1739 pVosPacket = pNextVosPacket;
1740 continue;
1741 }
1742 }
1743
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301744 pVosPacket->pSkb = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001745 //hdd_softap_dump_sk_buff(skb);
1746
1747 skb->dev = pAdapter->dev;
1748
1749 if(skb->dev == NULL) {
1750
c_hpothu6d1d2a32014-03-18 20:17:03 +05301751 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1752 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 return VOS_STATUS_E_FAILURE;
1754 }
1755 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1756 ++pAdapter->stats.rx_packets;
1757 pAdapter->stats.rx_bytes += skb->len;
1758
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001759 if (pHddCtx->cfg_ini->gEnableDebugLog)
1760 {
1761 proto_type = vos_pkt_get_proto_type(skb,
1762 pHddCtx->cfg_ini->gEnableDebugLog);
1763 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1764 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001766 "SAP RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001767 }
1768 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1769 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001771 "SAP RX DHCP");
1772 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301773 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1774 {
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1776 "SAP RX ARP");
1777 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001778 }
1779
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +05301780 if (pHddCtx->rx_wow_dump) {
1781 if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) &&
1782 !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type))
1783 hdd_log_ip_addr(skb);
1784 pHddCtx->rx_wow_dump = false;
1785 }
1786
Jeff Johnson295189b2012-06-20 16:38:30 -07001787 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1788 {
1789 //MC/BC packets. Duplicate a copy of packet
1790 struct sk_buff *pSkbCopy;
1791 hdd_ap_ctx_t *pHddApCtx;
1792
1793 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1794 if (!(pHddApCtx->apDisableIntraBssFwd))
1795 {
1796 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1797 if (pSkbCopy)
1798 {
1799 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1800 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1801 }
1802 }
1803 else
1804 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301805 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001806 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001807 }
1808
1809
1810 } //(WLAN_RX_BCMC_STA_ID == staId)
1811
1812 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1813 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1814 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301815 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001816 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301817 if ((NULL != pHddCtx) &&
1818 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301819 {
1820 hdd_dump_dhcp_pkt(skb, RX_PATH);
1821 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001822
1823 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001824 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnsone7245742012-09-05 17:12:55 -07001825#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301826 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
1827 HDD_WAKE_LOCK_DURATION,
1828 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
1829
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001831 rxstat = netif_rx_ni(skb);
1832 if (NET_RX_SUCCESS == rxstat)
1833 {
1834 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001835 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 }
1837 else
1838 {
1839 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1840 }
1841 }
1842 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1843 {
1844 kfree_skb(skb);
1845 }
1846 else
1847 {
1848 //loopback traffic
1849 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1850 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1851 }
1852
1853 // now process the next packet in the chain
1854 pVosPacket = pNextVosPacket;
1855
1856 } while (pVosPacket);
1857
1858 //Return the entire VOS packet chain to the resource pool
1859 status = vos_pkt_return_packet( pVosPacketChain );
1860 if(!VOS_IS_STATUS_SUCCESS( status ))
1861 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301862 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1863 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001864 }
1865
1866 pAdapter->dev->last_rx = jiffies;
1867
1868 return status;
1869}
1870
1871VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1872{
1873 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301874 hdd_context_t *pHddCtx;
1875 if (NULL == pAdapter)
1876 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301877 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301878 "%s: pAdapter is NULL", __func__);
1879 return VOS_STATUS_E_INVAL;
1880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001881
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301882 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1883 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301884 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301885 "%s: Invalid pAdapter magic", __func__);
1886 return VOS_STATUS_E_INVAL;
1887 }
1888
1889 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301890 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001891 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301892 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001893 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1894 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301895 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001897 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001898 staId, vosStatus, vosStatus );
1899 }
1900
1901 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1902 if( VOS_STATUS_E_FAILURE == vosStatus )
1903 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301904 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001906 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 staId, vosStatus, vosStatus );
1908 return( vosStatus );
1909 }
1910
1911 pHddCtx->sta_to_adapter[staId] = NULL;
1912
1913 return( vosStatus );
1914}
1915
1916VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1917 v_BOOL_t fAuthRequired,
1918 v_BOOL_t fPrivacyBit,
1919 v_U8_t staId,
1920 v_U8_t ucastSig,
1921 v_U8_t bcastSig,
1922 v_MACADDR_t *pPeerMacAddress,
1923 v_BOOL_t fWmmEnabled )
1924{
1925 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001926 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001927 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1928 hdd_adapter_t *pmonAdapter = NULL;
1929
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301930 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1931 ptSapContext pSapCtx = NULL;
1932 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1933 if(pSapCtx == NULL){
1934 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1935 FL("psapCtx is NULL"));
1936 return VOS_STATUS_E_FAULT;
1937 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001938 //eCsrEncryptionType connectedCipherAlgo;
1939 //v_BOOL_t fConnected;
1940
1941 /*
1942 * Clean up old entry if it is not cleaned up properly
1943 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301944 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001945 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301946 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001947 "clean up old entry for STA %d", staId);
1948 hdd_softap_DeregisterSTA( pAdapter, staId );
1949 }
1950
1951 // Get the Station ID from the one saved during the assocation.
1952
1953 staDesc.ucSTAId = staId;
1954
1955
1956 /*Save the pAdapter Pointer for this staId*/
1957 pHddCtx->sta_to_adapter[staId] = pAdapter;
1958
1959 staDesc.wSTAType = WLAN_STA_SOFTAP;
1960
1961 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1962 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1963 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1964
c_hpothu6d1d2a32014-03-18 20:17:03 +05301965 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001966 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301967 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001968 "station mac " MAC_ADDRESS_STR,
1969 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301970 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001971 "BSSIDforIBSS " MAC_ADDRESS_STR,
1972 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301973 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001974 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1975 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001976
1977 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1978
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301980 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 "HDD SOFTAP register TL QoS_enabled=%d",
1982 staDesc.ucQosEnabled );
1983
1984 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1985
1986
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 // For PRIMA UMA frame translation is not enable yet.
1988 staDesc.ucSwFrameTXXlation = 1;
1989 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 staDesc.ucAddRmvLLC = 1;
1991
1992 // Initialize signatures and state
1993 staDesc.ucUcastSig = ucastSig;
1994 staDesc.ucBcastSig = bcastSig;
1995 staDesc.ucInitState = fAuthRequired ?
1996 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1997
Prathyushaf5442802012-12-12 13:58:11 -08001998 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1999
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05302001 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2002 hdd_softap_rx_packet_cbk,
2003 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
2005
2006 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
2007 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302008 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07002009 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002010 vosStatus, vosStatus );
2011 return vosStatus;
2012 }
2013
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002014 //Timer value should be in milliseconds
2015 if ( pHddCtx->cfg_ini->dynSplitscan &&
2016 ( VOS_TIMER_STATE_RUNNING !=
2017 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
2018 {
2019 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
2020 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
2021 }
2022
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
2024 // then go to 'authenticated'. For all other authentication types (those that do
2025 // not require upper layer authentication) we can put TL directly into 'authenticated'
2026 // state.
2027
2028 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302029 pSapCtx->aStaInfo[staId].ucSTAId = staId;
2030 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 if ( !fAuthRequired )
2032 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302033 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
2034 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302035 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07002036
2037 // Connections that do not need Upper layer auth, transition TL directly
2038 // to 'Authenticated' state.
2039 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
2040 WLANTL_STA_AUTHENTICATED );
2041
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302042 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002043 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05302044 if (!vos_is_macaddr_broadcast(pPeerMacAddress))
2045 vosStatus = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
2046 pPeerMacAddress);
2047 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002048 else
2049 {
2050
c_hpothu6d1d2a32014-03-18 20:17:03 +05302051 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302052 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07002053
2054 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
2055 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302056 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002057
2058 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
2059
2060 }
2061 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
2062 if(pmonAdapter)
2063 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302064 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
2065 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 netif_carrier_on(pmonAdapter->dev);
2067 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302068 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 netif_tx_start_all_queues(pmonAdapter->dev);
2070 }
2071 netif_carrier_on(pAdapter->dev);
2072 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002074 netif_tx_start_all_queues(pAdapter->dev);
2075
2076 return( vosStatus );
2077}
2078
2079VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
2080{
2081 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2082 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2083 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
2084
2085
2086 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
2087 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
2088 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
2089
2090 return vosStatus;
2091}
2092
2093VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
2094{
2095 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
2096}
2097
2098VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
2099{
2100 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2101 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302102 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07002103
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302104 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2105 ptSapContext pSapCtx = NULL;
2106 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2107 if(pSapCtx == NULL){
2108 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2109 FL("psapCtx is NULL"));
2110 return VOS_STATUS_E_FAULT;
2111 }
2112
2113 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07002114 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05302115 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07002116 {
2117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2118 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
2119 return VOS_STATUS_E_PERM;
2120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002121
2122 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
2123
Jeff Johnson43971f52012-07-17 12:26:56 -07002124 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002125 {
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 BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002128 }
2129
2130 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2131 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302132 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07002133 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302134 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
2135 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2136 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302137 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002138 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302139 }
2140 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002141 }
2142
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05302143 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2144 wlan_hdd_restore_channels(pHddCtx);
2145
Sourav Mohapatra5817dc42017-12-18 17:45:16 +05302146 /* Mark the indoor channel (passive) to enable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +05302147 if (pHddCtx->cfg_ini->disable_indoor_channel &&
2148 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +05302149 hdd_update_indoor_channel(pHddCtx, false);
2150 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
2151 }
2152
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 return vosStatus;
2154}
2155
2156VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
2157{
2158 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
2159 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2160 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002161
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302162 ptSapContext pSapCtx = NULL;
2163 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2164 if(pSapCtx == NULL){
2165 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2166 FL("psapCtx is NULL"));
2167 return VOS_STATUS_E_FAULT;
2168 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302169 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002170 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002171
Jeff Johnson43971f52012-07-17 12:26:56 -07002172 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302174 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002175 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 return VOS_STATUS_E_FAILURE;
2177 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002178
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302179 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002180 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302181 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002182 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002183 return VOS_STATUS_E_FAILURE;
2184 }
2185
2186 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302187 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002188 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002189
Jeff Johnson43971f52012-07-17 12:26:56 -07002190 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002191 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302192 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 }
2194
c_hpothu6d1d2a32014-03-18 20:17:03 +05302195 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002196 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002197
2198 return vosStatus;
2199}
2200
2201
2202VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2203{
2204 v_U8_t i;
2205
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302206 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2207 ptSapContext pSapCtx = NULL;
2208 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2209 if(pSapCtx == NULL){
2210 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2211 FL("psapCtx is NULL"));
2212 return VOS_STATUS_E_FAULT;
2213 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002214 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2215 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302216 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2217 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002218 {
2219 *staId = i;
2220 return VOS_STATUS_SUCCESS;
2221 }
2222 }
2223
2224 return VOS_STATUS_E_FAILURE;
2225}
2226
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302227VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2228{
2229 v_U8_t i;
2230
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302231 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2232 ptSapContext pSapCtx = NULL;
2233 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2234 if(pSapCtx == NULL){
2235 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2236 FL("psapCtx is NULL"));
2237 return VOS_STATUS_E_FAULT;
2238 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302239 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2240 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302241 if (pSapCtx->aStaInfo[i].isUsed &&
2242 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302243 {
2244 *staId = i;
2245 return VOS_STATUS_SUCCESS;
2246 }
2247 }
2248
2249 return VOS_STATUS_E_FAILURE;
2250}