blob: 38416ee035424df8bc4630014ef0f67c2d8dce87 [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
1731 if (TRUE == hdd_IsEAPOLPacket(pVosPacket))
1732 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
1733
1734 pVosPacket->pSkb = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001735 //hdd_softap_dump_sk_buff(skb);
1736
1737 skb->dev = pAdapter->dev;
1738
1739 if(skb->dev == NULL) {
1740
c_hpothu6d1d2a32014-03-18 20:17:03 +05301741 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1742 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001743 return VOS_STATUS_E_FAILURE;
1744 }
1745 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1746 ++pAdapter->stats.rx_packets;
1747 pAdapter->stats.rx_bytes += skb->len;
1748
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001749 if (pHddCtx->cfg_ini->gEnableDebugLog)
1750 {
1751 proto_type = vos_pkt_get_proto_type(skb,
1752 pHddCtx->cfg_ini->gEnableDebugLog);
1753 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1754 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001756 "SAP RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001757 }
1758 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1759 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001761 "SAP RX DHCP");
1762 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301763 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1764 {
1765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1766 "SAP RX ARP");
1767 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001768 }
1769
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +05301770 if (pHddCtx->rx_wow_dump) {
1771 if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) &&
1772 !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type))
1773 hdd_log_ip_addr(skb);
1774 pHddCtx->rx_wow_dump = false;
1775 }
1776
Jeff Johnson295189b2012-06-20 16:38:30 -07001777 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1778 {
1779 //MC/BC packets. Duplicate a copy of packet
1780 struct sk_buff *pSkbCopy;
1781 hdd_ap_ctx_t *pHddApCtx;
1782
1783 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1784 if (!(pHddApCtx->apDisableIntraBssFwd))
1785 {
1786 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1787 if (pSkbCopy)
1788 {
1789 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1790 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1791 }
1792 }
1793 else
1794 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301795 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001796 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 }
1798
1799
1800 } //(WLAN_RX_BCMC_STA_ID == staId)
1801
1802 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1803 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1804 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301805 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001806 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301807 if ((NULL != pHddCtx) &&
1808 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301809 {
1810 hdd_dump_dhcp_pkt(skb, RX_PATH);
1811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001812
1813 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001814 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnsone7245742012-09-05 17:12:55 -07001815#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301816 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
1817 HDD_WAKE_LOCK_DURATION,
1818 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
1819
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001820#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001821 rxstat = netif_rx_ni(skb);
1822 if (NET_RX_SUCCESS == rxstat)
1823 {
1824 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001825 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001826 }
1827 else
1828 {
1829 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1830 }
1831 }
1832 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1833 {
1834 kfree_skb(skb);
1835 }
1836 else
1837 {
1838 //loopback traffic
1839 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1840 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1841 }
1842
1843 // now process the next packet in the chain
1844 pVosPacket = pNextVosPacket;
1845
1846 } while (pVosPacket);
1847
1848 //Return the entire VOS packet chain to the resource pool
1849 status = vos_pkt_return_packet( pVosPacketChain );
1850 if(!VOS_IS_STATUS_SUCCESS( status ))
1851 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301852 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1853 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001854 }
1855
1856 pAdapter->dev->last_rx = jiffies;
1857
1858 return status;
1859}
1860
1861VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1862{
1863 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301864 hdd_context_t *pHddCtx;
1865 if (NULL == pAdapter)
1866 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301867 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301868 "%s: pAdapter is NULL", __func__);
1869 return VOS_STATUS_E_INVAL;
1870 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001871
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301872 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1873 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301874 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301875 "%s: Invalid pAdapter magic", __func__);
1876 return VOS_STATUS_E_INVAL;
1877 }
1878
1879 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301880 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001881 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301882 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001883 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1884 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301885 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001886 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001887 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 staId, vosStatus, vosStatus );
1889 }
1890
1891 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1892 if( VOS_STATUS_E_FAILURE == vosStatus )
1893 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301894 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001895 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001896 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 staId, vosStatus, vosStatus );
1898 return( vosStatus );
1899 }
1900
1901 pHddCtx->sta_to_adapter[staId] = NULL;
1902
1903 return( vosStatus );
1904}
1905
1906VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1907 v_BOOL_t fAuthRequired,
1908 v_BOOL_t fPrivacyBit,
1909 v_U8_t staId,
1910 v_U8_t ucastSig,
1911 v_U8_t bcastSig,
1912 v_MACADDR_t *pPeerMacAddress,
1913 v_BOOL_t fWmmEnabled )
1914{
1915 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001916 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001917 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1918 hdd_adapter_t *pmonAdapter = NULL;
1919
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301920 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1921 ptSapContext pSapCtx = NULL;
1922 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1923 if(pSapCtx == NULL){
1924 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1925 FL("psapCtx is NULL"));
1926 return VOS_STATUS_E_FAULT;
1927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001928 //eCsrEncryptionType connectedCipherAlgo;
1929 //v_BOOL_t fConnected;
1930
1931 /*
1932 * Clean up old entry if it is not cleaned up properly
1933 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301934 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001935 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301936 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001937 "clean up old entry for STA %d", staId);
1938 hdd_softap_DeregisterSTA( pAdapter, staId );
1939 }
1940
1941 // Get the Station ID from the one saved during the assocation.
1942
1943 staDesc.ucSTAId = staId;
1944
1945
1946 /*Save the pAdapter Pointer for this staId*/
1947 pHddCtx->sta_to_adapter[staId] = pAdapter;
1948
1949 staDesc.wSTAType = WLAN_STA_SOFTAP;
1950
1951 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1952 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1953 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1954
c_hpothu6d1d2a32014-03-18 20:17:03 +05301955 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001956 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301957 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001958 "station mac " MAC_ADDRESS_STR,
1959 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301960 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001961 "BSSIDforIBSS " MAC_ADDRESS_STR,
1962 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301963 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001964 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1965 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001966
1967 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1968
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301970 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 "HDD SOFTAP register TL QoS_enabled=%d",
1972 staDesc.ucQosEnabled );
1973
1974 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1975
1976
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 // For PRIMA UMA frame translation is not enable yet.
1978 staDesc.ucSwFrameTXXlation = 1;
1979 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001980 staDesc.ucAddRmvLLC = 1;
1981
1982 // Initialize signatures and state
1983 staDesc.ucUcastSig = ucastSig;
1984 staDesc.ucBcastSig = bcastSig;
1985 staDesc.ucInitState = fAuthRequired ?
1986 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1987
Prathyushaf5442802012-12-12 13:58:11 -08001988 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1989
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301991 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1992 hdd_softap_rx_packet_cbk,
1993 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1995
1996 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1997 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301998 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001999 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 vosStatus, vosStatus );
2001 return vosStatus;
2002 }
2003
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002004 //Timer value should be in milliseconds
2005 if ( pHddCtx->cfg_ini->dynSplitscan &&
2006 ( VOS_TIMER_STATE_RUNNING !=
2007 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
2008 {
2009 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
2010 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
2011 }
2012
Jeff Johnson295189b2012-06-20 16:38:30 -07002013 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
2014 // then go to 'authenticated'. For all other authentication types (those that do
2015 // not require upper layer authentication) we can put TL directly into 'authenticated'
2016 // state.
2017
2018 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302019 pSapCtx->aStaInfo[staId].ucSTAId = staId;
2020 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002021 if ( !fAuthRequired )
2022 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302023 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
2024 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302025 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07002026
2027 // Connections that do not need Upper layer auth, transition TL directly
2028 // to 'Authenticated' state.
2029 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
2030 WLANTL_STA_AUTHENTICATED );
2031
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302032 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05302034 if (!vos_is_macaddr_broadcast(pPeerMacAddress))
2035 vosStatus = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
2036 pPeerMacAddress);
2037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002038 else
2039 {
2040
c_hpothu6d1d2a32014-03-18 20:17:03 +05302041 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302042 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07002043
2044 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
2045 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302046 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002047
2048 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
2049
2050 }
2051 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
2052 if(pmonAdapter)
2053 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302054 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
2055 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07002056 netif_carrier_on(pmonAdapter->dev);
2057 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 netif_tx_start_all_queues(pmonAdapter->dev);
2060 }
2061 netif_carrier_on(pAdapter->dev);
2062 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302063 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 netif_tx_start_all_queues(pAdapter->dev);
2065
2066 return( vosStatus );
2067}
2068
2069VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
2070{
2071 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2072 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2073 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
2074
2075
2076 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
2077 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
2078 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
2079
2080 return vosStatus;
2081}
2082
2083VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
2084{
2085 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
2086}
2087
2088VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
2089{
2090 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
2091 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302092 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07002093
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302094 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2095 ptSapContext pSapCtx = NULL;
2096 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2097 if(pSapCtx == NULL){
2098 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2099 FL("psapCtx is NULL"));
2100 return VOS_STATUS_E_FAULT;
2101 }
2102
2103 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07002104 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05302105 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07002106 {
2107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2108 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
2109 return VOS_STATUS_E_PERM;
2110 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002111
2112 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
2113
Jeff Johnson43971f52012-07-17 12:26:56 -07002114 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302116 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002117 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 }
2119
2120 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2121 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302122 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07002123 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302124 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
2125 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2126 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302127 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002128 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302129 }
2130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 }
2132
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05302133 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
2134 wlan_hdd_restore_channels(pHddCtx);
2135
Sourav Mohapatra5817dc42017-12-18 17:45:16 +05302136 /* Mark the indoor channel (passive) to enable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +05302137 if (pHddCtx->cfg_ini->disable_indoor_channel &&
2138 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +05302139 hdd_update_indoor_channel(pHddCtx, false);
2140 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
2141 }
2142
Jeff Johnson295189b2012-06-20 16:38:30 -07002143 return vosStatus;
2144}
2145
2146VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
2147{
2148 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
2149 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2150 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002151
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302152 ptSapContext pSapCtx = NULL;
2153 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2154 if(pSapCtx == NULL){
2155 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2156 FL("psapCtx is NULL"));
2157 return VOS_STATUS_E_FAULT;
2158 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302159 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002160 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002161
Jeff Johnson43971f52012-07-17 12:26:56 -07002162 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002163 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302164 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002165 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 return VOS_STATUS_E_FAILURE;
2167 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002168
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302169 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302171 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002172 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 return VOS_STATUS_E_FAILURE;
2174 }
2175
2176 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302177 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002178 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002179
Jeff Johnson43971f52012-07-17 12:26:56 -07002180 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002181 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302182 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002183 }
2184
c_hpothu6d1d2a32014-03-18 20:17:03 +05302185 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002186 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002187
2188 return vosStatus;
2189}
2190
2191
2192VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2193{
2194 v_U8_t i;
2195
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302196 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2197 ptSapContext pSapCtx = NULL;
2198 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2199 if(pSapCtx == NULL){
2200 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2201 FL("psapCtx is NULL"));
2202 return VOS_STATUS_E_FAULT;
2203 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2205 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302206 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2207 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002208 {
2209 *staId = i;
2210 return VOS_STATUS_SUCCESS;
2211 }
2212 }
2213
2214 return VOS_STATUS_E_FAILURE;
2215}
2216
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302217VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2218{
2219 v_U8_t i;
2220
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302221 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2222 ptSapContext pSapCtx = NULL;
2223 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2224 if(pSapCtx == NULL){
2225 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2226 FL("psapCtx is NULL"));
2227 return VOS_STATUS_E_FAULT;
2228 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302229 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2230 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302231 if (pSapCtx->aStaInfo[i].isUsed &&
2232 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302233 {
2234 *staId = i;
2235 return VOS_STATUS_SUCCESS;
2236 }
2237 }
2238
2239 return VOS_STATUS_E_FAILURE;
2240}