blob: a107b03842dbcbf8b6f9f9c6c4fc1e53e7552530 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumantha Reddy Pothula07050f52015-02-24 11:36:12 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Jeff Johnson295189b2012-06-20 16:38:30 -070026 */
27
28/**===========================================================================
29
30 \file wlan_hdd_softap_tx_rx.c
31
32 \brief Linux HDD Tx/RX APIs
Jeff Johnson295189b2012-06-20 16:38:30 -070033
34 ==========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070035
36/*---------------------------------------------------------------------------
37 Include files
38 -------------------------------------------------------------------------*/
39#include <linux/semaphore.h>
40#include <wlan_hdd_tx_rx.h>
41#include <wlan_hdd_softap_tx_rx.h>
42#include <wlan_hdd_dp_utils.h>
43#include <wlan_qct_tl.h>
44#include <linux/netdevice.h>
45#include <linux/skbuff.h>
46#include <linux/etherdevice.h>
47//#include <vos_list.h>
48#include <vos_types.h>
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053049#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070050#include <aniGlobal.h>
51#include <halTypes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070052#include <net/ieee80211_radiotap.h>
Mihir Shetef3473692014-06-27 15:13:20 +053053#include <linux/ratelimit.h>
54#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
55#include <soc/qcom/subsystem_restart.h>
56#else
57#include <mach/subsystem_restart.h>
58#endif
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053059#include "sapInternal.h"
Mihir Shete5d148f12014-12-16 17:54:49 +053060#include "wlan_hdd_trace.h"
Sushant Kaushika8073312015-05-04 17:33:52 +053061#include "vos_diag_core_event.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070062/*---------------------------------------------------------------------------
63 Preprocessor definitions and constants
64 -------------------------------------------------------------------------*/
65
66/*---------------------------------------------------------------------------
67 Type declarations
68 -------------------------------------------------------------------------*/
69
70/*---------------------------------------------------------------------------
71 Function definitions and documenation
72 -------------------------------------------------------------------------*/
73#if 0
74static void hdd_softap_dump_sk_buff(struct sk_buff * skb)
75{
c_hpothu6d1d2a32014-03-18 20:17:03 +053076 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head);
77 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data);
78 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail);
79 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end);
80 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
81 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
82 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070083
c_hpothu6d1d2a32014-03-18 20:17:03 +053084 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
Jeff Johnson295189b2012-06-20 16:38:30 -070085 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
86 skb->data[5], skb->data[6], skb->data[7]);
c_hpothu6d1d2a32014-03-18 20:17:03 +053087 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
Jeff Johnson295189b2012-06-20 16:38:30 -070088 skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
89 skb->data[13], skb->data[14], skb->data[15]);
90}
91#endif
Leo Chang64d68bc2013-06-04 15:40:52 -070092
93extern void hdd_set_wlan_suspend_mode(bool suspend);
94
Mihir Shetef3473692014-06-27 15:13:20 +053095#define HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ
96#define HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST 1
97#define HDD_SAP_TX_STALL_SSR_THRESHOLD 5
Mihir Shete327c2ab2014-11-13 15:17:02 +053098#define HDD_SAP_TX_STALL_RECOVERY_THRESHOLD HDD_SAP_TX_STALL_SSR_THRESHOLD - 2
Mihir Shetef3473692014-06-27 15:13:20 +053099
100static DEFINE_RATELIMIT_STATE(hdd_softap_tx_timeout_rs, \
101 HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL, \
102 HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST);
103
Leo Chang64d68bc2013-06-04 15:40:52 -0700104/**============================================================================
105 @brief hdd_softap_traffic_monitor_timeout_handler() -
106 SAP/P2P GO traffin monitor timeout handler function
107 If no traffic during programmed time, trigger suspand mode
108
109 @param pUsrData : [in] pointer to hdd context
110 @return : NONE
111 ===========================================================================*/
112void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData )
113{
114 hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData;
115 v_TIME_t currentTS;
116
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530117 ENTER();
118 if (0 != (wlan_hdd_validate_context(pHddCtx)))
Leo Chang64d68bc2013-06-04 15:40:52 -0700119 {
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530120 return;
Leo Chang64d68bc2013-06-04 15:40:52 -0700121 }
122
123 currentTS = vos_timer_get_system_time();
124 if (pHddCtx->cfg_ini->trafficIdleTimeout <
125 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
126 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530127 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530128 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -0700129 hdd_set_wlan_suspend_mode(1);
130 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
131 }
132 else
133 {
134 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
135 pHddCtx->cfg_ini->trafficIdleTimeout);
136 }
137
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +0530138 EXIT();
Leo Chang64d68bc2013-06-04 15:40:52 -0700139 return;
140}
141
Kiet Lambcf38522013-10-26 18:28:27 +0530142VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter )
143{
144
145 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
146 VOS_STATUS status = VOS_STATUS_SUCCESS;
147
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530148 ENTER();
Kiet Lambcf38522013-10-26 18:28:27 +0530149 status = wlan_hdd_validate_context(pHddCtx);
Kiet Lambcf38522013-10-26 18:28:27 +0530150 if (0 != status)
151 {
Kiet Lambcf38522013-10-26 18:28:27 +0530152 return status;
153 }
154
155 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
156 (!pHddCtx->traffic_monitor.isInitialized))
157 {
158 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
159 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
160 VOS_TIMER_TYPE_SW,
161 hdd_softap_traffic_monitor_timeout_handler,
162 pHddCtx);
163 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
164 pHddCtx->traffic_monitor.isInitialized = 1;
165 pHddCtx->traffic_monitor.lastFrameTs = 0;
166 /* Start traffic monitor timer here
167 * If no AP assoc, immediatly go into suspend */
c_hpothu6d1d2a32014-03-18 20:17:03 +0530168 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530169 "%s Start Traffic Monitor Timer", __func__);
170 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
171 pHddCtx->cfg_ini->trafficIdleTimeout);
172 }
173 else
174 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530175 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530176 "%s Traffic Monitor is not Enable in ini file", __func__);
177 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530178
179 EXIT();
Kiet Lambcf38522013-10-26 18:28:27 +0530180 return status;
181}
182
183VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter )
184{
185 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
186 VOS_STATUS status = VOS_STATUS_SUCCESS;
187
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530188 ENTER();
Kiet Lambcf38522013-10-26 18:28:27 +0530189 status = wlan_hdd_validate_context(pHddCtx);
Kiet Lamae69d7a2013-11-08 14:38:04 +0530190 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530191 {
Kiet Lambcf38522013-10-26 18:28:27 +0530192 return status;
193 }
194
195 if (pHddCtx->traffic_monitor.isInitialized)
196 {
197 if (VOS_TIMER_STATE_STOPPED !=
198 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
199 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530200 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530201 "%s Stop Traffic Monitor Timer", __func__);
202 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
203 }
c_hpothu6d1d2a32014-03-18 20:17:03 +0530204 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530205 "%s Destroy Traffic Monitor Timer", __func__);
206 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
207 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
208 pHddCtx->traffic_monitor.isInitialized = 0;
209 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530210 EXIT();
Kiet Lamae69d7a2013-11-08 14:38:04 +0530211 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530212}
213
Jeff Johnson295189b2012-06-20 16:38:30 -0700214/**============================================================================
215 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
216
217 @param pAdapter : [in] pointer to adapter context
218 @return : VOS_STATUS_E_FAILURE if any errors encountered
219 : VOS_STATUS_SUCCESS otherwise
220 ===========================================================================*/
221static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
222{
223 VOS_STATUS status = VOS_STATUS_SUCCESS;
224 v_SINT_t i = -1;
225 v_U8_t STAId = 0;
226 hdd_list_node_t *anchor = NULL;
227 skb_list_node_t *pktNode = NULL;
228 struct sk_buff *skb = NULL;
229
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530230 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
231 ptSapContext pSapCtx = NULL;
232 pSapCtx = VOS_GET_SAP_CB(pVosContext);
233 if(pSapCtx == NULL){
234 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
235 FL("psapCtx is NULL"));
236 return VOS_STATUS_E_FAULT;
237 }
238 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
240 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530241 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700242 {
243 continue;
244 }
245
246 for (i = 0; i < NUM_TX_QUEUES; i ++)
247 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530248 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700249 while (true)
250 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530251 status = hdd_list_remove_front ( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
Jeff Johnson295189b2012-06-20 16:38:30 -0700252
253 if (VOS_STATUS_E_EMPTY != status)
254 {
255 //If success then we got a valid packet from some AC
256 pktNode = list_entry(anchor, skb_list_node_t, anchor);
257 skb = pktNode->skb;
258 ++pAdapter->stats.tx_dropped;
259 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
260 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
261 kfree_skb(skb);
262 continue;
263 }
264
265 //current list is empty
266 break;
267 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530268 pSapCtx->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
269 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530271 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 }
273
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530274 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700275
276 return status;
277}
278
279/**============================================================================
280 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
281 transmitting packets. There are 2 versions of this function. One that uses
282 locked queue and other that uses lockless queues. Both have been retained to
283 do some performance testing
284
285 @param skb : [in] pointer to OS packet (sk_buff)
286 @param dev : [in] pointer to Libra network device
287
288 @return : NET_XMIT_DROP if packets are dropped
289 : NET_XMIT_SUCCESS if packet is enqueued succesfully
290 ===========================================================================*/
291int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
292{
293 VOS_STATUS status;
294 WLANTL_ACEnumType ac = WLANTL_AC_BE;
295 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
296 skb_list_node_t *pktNode = NULL;
297 v_SIZE_t pktListSize = 0;
298 v_BOOL_t txSuspended = VOS_FALSE;
299 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
300 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530301 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302 vos_list_node_t *anchor = NULL;
303 v_U8_t STAId = WLAN_MAX_STA_COUNT;
304 //Extract the destination address from ethernet frame
305 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
306 int os_status = NETDEV_TX_OK;
Mihir Shetef8f74532014-12-04 11:53:34 +0530307 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700308
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530309 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
310 ptSapContext pSapCtx = NULL;
311 pSapCtx = VOS_GET_SAP_CB(pVosContext);
312 if(pSapCtx == NULL){
313 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
314 FL("psapCtx is NULL"));
315 ++pAdapter->stats.tx_dropped;
316 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
317 kfree_skb(skb);
318 return os_status;
319 }
320
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 pDestMacAddress = (v_MACADDR_t*)skb->data;
322
323 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
324
c_hpothu6d1d2a32014-03-18 20:17:03 +0530325 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700326 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530328 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
330 {
331 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
332 //ID used for BC/MC traffic. The station id is registered to TL as well.
333 STAId = pHddApCtx->uBCStaId;
334
335 /* Setting priority for broadcast packets which doesn't go to select_queue function */
336 skb->priority = SME_QOS_WMM_UP_BE;
337 skb->queue_mapping = HDD_LINUX_AC_BE;
338
c_hpothu6d1d2a32014-03-18 20:17:03 +0530339 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800340 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 }
342 else
343 {
Nirav Shah7e3c8132015-06-22 23:51:42 +0530344 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 if (STAId == HDD_WLAN_INVALID_STA_ID)
346 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530347 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700348 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700349 ++pAdapter->stats.tx_dropped;
350 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
351 kfree_skb(skb);
352 goto xmit_done;
353 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530354 else if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700355 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530356 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
357 "%s: STA %d is unregistered", __func__, STAId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 ++pAdapter->stats.tx_dropped;
359 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
360 kfree_skb(skb);
361 goto xmit_done;
362 }
363
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530364 if ( (WLANTL_STA_CONNECTED != pSapCtx->aStaInfo[STAId].tlSTAState) &&
365 (WLANTL_STA_AUTHENTICATED != pSapCtx->aStaInfo[STAId].tlSTAState) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700366 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530367 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700368 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700369 ++pAdapter->stats.tx_dropped;
370 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
371 kfree_skb(skb);
372 goto xmit_done;
373 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530374 else if(WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[STAId].tlSTAState)
Jeff Johnson295189b2012-06-20 16:38:30 -0700375 {
376 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
377 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530378 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700379 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 ++pAdapter->stats.tx_dropped;
381 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
382 kfree_skb(skb);
383 goto xmit_done;
384 }
385 }
386 }
387
388 //Get TL AC corresponding to Qdisc queue index/AC.
389 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
390 //user priority from IP header, which is already extracted and set from
391 //select_queue call back function
392 up = skb->priority;
393 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
394
c_hpothu6d1d2a32014-03-18 20:17:03 +0530395 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700396 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700397
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530398 if (( NULL != pHddCtx ) &&
399 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530400 {
401 hdd_dump_dhcp_pkt(skb, TX_PATH);
402 }
403
Jeff Johnson295189b2012-06-20 16:38:30 -0700404 // If the memory differentiation mode is enabled, the memory limit of each queue will be
405 // checked. Over-limit packets will be dropped.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530406 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
407 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700408 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
409 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530410 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800411 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530412 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700413 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
414 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530415 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
416 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -0700417 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530418
419 /* If 3/4th of the max queue size is used then enable the flag.
420 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
421 if (WLANTL_AC_BE == ac)
422 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530423 if (pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530424 {
425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
426 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530427 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_TRUE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530428 }
429 else
430 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530431 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530432 }
433 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530434 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700435
436 if (VOS_TRUE == txSuspended)
437 {
438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
439 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700440 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700441 os_status = NETDEV_TX_BUSY;
442 goto xmit_done;
443 }
444
445 //Use the skb->cb field to hold the list node information
446 pktNode = (skb_list_node_t *)&skb->cb;
447
448 //Stick the OS packet inside this node.
449 pktNode->skb = skb;
450
451 //Stick the User Priority inside this node
452 pktNode->userPriority = up;
453
454 INIT_LIST_HEAD(&pktNode->anchor);
455
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530456 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
457 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
458 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700459 if ( !VOS_IS_STATUS_SUCCESS( status ) )
460 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530461 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
462 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700463 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
464 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
465 ++pAdapter->stats.tx_dropped;
466 kfree_skb(skb);
467 goto xmit_done;
468 }
469
470 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
471 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530472 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700473
474 if (1 == pktListSize)
475 {
476 //Let TL know we have a packet to send for this AC
477 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
478
479 if ( !VOS_IS_STATUS_SUCCESS( status ) )
480 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530481 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
482 "%s: Failed to signal TL for AC=%d STAId =%d",
483 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700484
485 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
486 //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 +0530487 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
488 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
489 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530490 /* Free the skb only if we are able to remove it from the list.
491 * If we are not able to retrieve it from the list it means that
492 * the skb was pulled by TX Thread and is use so we should not free
493 * it here
494 */
495 if (VOS_IS_STATUS_SUCCESS(status))
496 {
497 pktNode = list_entry(anchor, skb_list_node_t, anchor);
498 skb1 = pktNode->skb;
499 kfree_skb(skb1);
500 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700501 ++pAdapter->stats.tx_dropped;
502 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
503 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700504 goto xmit_done;
505 }
506 }
507 dev->trans_start = jiffies;
508
c_hpothu6d1d2a32014-03-18 20:17:03 +0530509 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
510 "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700511
512xmit_done:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530513 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700514 return os_status;
515}
516
517/**============================================================================
518 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
519
520 @param skb : [in] pointer to packet (sk_buff)
521 @param dev : [in] pointer to Libra network device
522 @param STAId : [in] Station Id of Destination Station
523 @param up : [in] User Priority
524
525 @return : NET_XMIT_DROP if packets are dropped
526 : NET_XMIT_SUCCESS if packet is enqueued succesfully
527 ===========================================================================*/
528VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
529 struct net_device *dev,
530 v_U8_t STAId,
531 v_U8_t up)
532{
533 VOS_STATUS status = VOS_STATUS_SUCCESS;
534 skb_list_node_t *pktNode = NULL;
535 v_SIZE_t pktListSize = 0;
536 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
537 v_U8_t ac;
538 vos_list_node_t *anchor = NULL;
Mihir Shetef8f74532014-12-04 11:53:34 +0530539 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700540
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530541 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
542 ptSapContext pSapCtx = NULL;
543 pSapCtx = VOS_GET_SAP_CB(pVosContext);
544 if(pSapCtx == NULL){
545 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
546 FL("psapCtx is NULL"));
547 kfree_skb(skb);
548 status = VOS_STATUS_E_FAILURE;
549 return status;
550 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700551 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
552
c_hpothu6d1d2a32014-03-18 20:17:03 +0530553 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700554 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700555
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530556 spin_lock_bh( &pSapCtx->staInfo_lock );
557 if ( FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700558 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530559 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530560 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700561 kfree_skb(skb);
562 status = VOS_STATUS_E_FAILURE;
563 goto xmit_end;
564 }
565
566 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530567 if ( !pSapCtx->aStaInfo[STAId].isQosEnabled )
Jeff Johnson295189b2012-06-20 16:38:30 -0700568 up = SME_QOS_WMM_UP_BE;
569
570 ac = hddWmmUpToAcMap[up];
571 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
c_hpothu6d1d2a32014-03-18 20:17:03 +0530572 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700573 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700574
575 skb->queue_mapping = hddLinuxUpToAcMap[up];
576
577 //Use the skb->cb field to hold the list node information
578 pktNode = (skb_list_node_t *)&skb->cb;
579
580 //Stick the OS packet inside this node.
581 pktNode->skb = skb;
582
583 //Stick the User Priority inside this node
584 pktNode->userPriority = up;
585
586 INIT_LIST_HEAD(&pktNode->anchor);
587
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530588 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
589 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
590 if(pSapCtx->aStaInfo[STAId].txSuspended[ac] ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700591 pktListSize >= pAdapter->aTxQueueLimit[ac])
592 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530593 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800594 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700595 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
596 * SUSPEND should be done based on Threshold. RESUME would be
597 * triggered in fetch cbk after recovery.
598 */
599 kfree_skb(skb);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530600 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700601 status = VOS_STATUS_E_FAILURE;
602 goto xmit_end;
603 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530604 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
605 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700606
607 if ( !VOS_IS_STATUS_SUCCESS( status ) )
608 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530609 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
610 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
612 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
613 ++pAdapter->stats.tx_dropped;
614 kfree_skb(skb);
615 status = VOS_STATUS_E_FAILURE;
616 goto xmit_end;
617 }
618
619 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
620 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
621
622 if (1 == pktListSize)
623 {
624 //Let TL know we have a packet to send for this AC
c_hpothu6d1d2a32014-03-18 20:17:03 +0530625 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
626 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700627
628 if ( !VOS_IS_STATUS_SUCCESS( status ) )
629 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530630 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
631 "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700632 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700633
634 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
635 //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 +0530636 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
637 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
638 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530639 /* Free the skb only if we are able to remove it from the list.
640 * If we are not able to retrieve it from the list it means that
641 * the skb was pulled by TX Thread and is use so we should not free
642 * it here
643 */
644 if (VOS_IS_STATUS_SUCCESS(status))
645 {
646 pktNode = list_entry(anchor, skb_list_node_t, anchor);
647 skb1 = pktNode->skb;
648 kfree_skb(skb1);
649 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700650 ++pAdapter->stats.tx_dropped;
651 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
652 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700653 status = VOS_STATUS_E_FAILURE;
654 goto xmit_end;
655 }
656 }
657
c_hpothu6d1d2a32014-03-18 20:17:03 +0530658 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700659
660xmit_end:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530661 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700662 return status;
663}
664
665/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530666 @brief __hdd_softap_tx_timeout() - Function called by OS if there is any
Jeff Johnson295189b2012-06-20 16:38:30 -0700667 timeout during transmission. Since HDD simply enqueues packet
668 and returns control to OS right away, this would never be invoked
669
670 @param dev : [in] pointer to Libra network device
671 @return : None
672 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530673void __hdd_softap_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700674{
Mihir Shetef3473692014-06-27 15:13:20 +0530675 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
676 struct netdev_queue *txq;
677 int i = 0;
Mukul Sharma4b322632015-02-28 20:21:43 +0530678 int status = 0;
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530679 hdd_context_t *pHddCtx;
Mihir Shetef3473692014-06-27 15:13:20 +0530680
c_hpothu6d1d2a32014-03-18 20:17:03 +0530681 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700682 "%s: Transmission timeout occurred", __func__);
Mihir Shetef3473692014-06-27 15:13:20 +0530683
684 if ( NULL == pAdapter )
685 {
686 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
687 FL("pAdapter is NULL"));
688 VOS_ASSERT(0);
689 return;
690 }
691
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530692 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mukul Sharma4b322632015-02-28 20:21:43 +0530693 status = wlan_hdd_validate_context(pHddCtx);
694 if (status != 0)
695 {
Anand N Sunkad26d71b92014-12-24 18:08:22 +0530696 return;
697 }
698
Mihir Shetef3473692014-06-27 15:13:20 +0530699 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
700
701 for (i = 0; i < 8; i++)
702 {
703 txq = netdev_get_tx_queue(dev, i);
704 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
705 "Queue%d status: %d", i, netif_tx_queue_stopped(txq));
706 }
707
708 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
709 "carrier state: %d", netif_carrier_ok(dev));
710
711 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
712
Mihir Shete327c2ab2014-11-13 15:17:02 +0530713 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
714 HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
715 {
716 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
717 "%s: Request firmware for recovery",__func__);
718 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
719 }
Mihir Shetef3473692014-06-27 15:13:20 +0530720 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
721 HDD_SAP_TX_STALL_SSR_THRESHOLD)
722 {
723 // Driver could not recover, issue SSR
724 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
725 "%s: Cannot recover from Data stall Issue SSR",
726 __func__);
Mihir Shetefd62d9d2014-08-06 15:08:21 +0530727 WLANTL_FatalError();
Mihir Shetef3473692014-06-27 15:13:20 +0530728 return;
729 }
730
731 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
732 * every 5sec. The TL debug spits out a lot of information on the
733 * serial console, if it is called every time *hdd_tx_timeout* is
734 * called then we may get a watchdog bite on the Application
735 * processor, so ratelimit the TL debug logs.
736 */
737 if (__ratelimit(&hdd_softap_tx_timeout_rs))
738 {
739 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +0530740 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetef3473692014-06-27 15:13:20 +0530741 }
742
Jeff Johnson295189b2012-06-20 16:38:30 -0700743}
744
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530745void hdd_softap_tx_timeout(struct net_device *dev)
746{
747 vos_ssr_protect(__func__);
748 __hdd_softap_tx_timeout(dev);
749 vos_ssr_unprotect(__func__);
750 return;
751}
Jeff Johnson295189b2012-06-20 16:38:30 -0700752
753/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530754 @brief __hdd_softap_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700755 device TX/RX statistic
756
757 @param dev : [in] pointer to Libra network device
758
759 @return : pointer to net_device_stats structure
760 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530761struct net_device_stats* __hdd_softap_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700762{
763 hdd_adapter_t* priv = netdev_priv(dev);
764 return &priv->stats;
765}
766
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530767struct net_device_stats* hdd_softap_stats(struct net_device *dev)
768{
769 struct net_device_stats *priv_stats;
770 vos_ssr_protect(__func__);
771 priv_stats = __hdd_softap_stats(dev);
772 vos_ssr_unprotect(__func__);
773
774 return priv_stats;
775}
Jeff Johnson295189b2012-06-20 16:38:30 -0700776
777/**============================================================================
778 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
779 modules in HDD
780
781 @param pAdapter : [in] pointer to adapter context
782 @return : VOS_STATUS_E_FAILURE if any errors encountered
783 : VOS_STATUS_SUCCESS otherwise
784 ===========================================================================*/
785VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
786{
787 VOS_STATUS status = VOS_STATUS_SUCCESS;
788 v_SINT_t i = -1;
789 v_SIZE_t size = 0;
790
791 v_U8_t STAId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530792 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
793 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700794
795 v_U8_t pACWeights[] = {
796 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
797 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
798 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
799 HDD_SOFTAP_VO_WEIGHT_DEFAULT
800 };
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530801 pSapCtx = VOS_GET_SAP_CB(pVosContext);
802 if(pSapCtx == NULL){
803 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
804 FL("psapCtx is NULL"));
805 return VOS_STATUS_E_FAULT;
806 }
807
Leo Chang64d68bc2013-06-04 15:40:52 -0700808
Jeff Johnson295189b2012-06-20 16:38:30 -0700809 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530810 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700811
812 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
813
814 while (++i != NUM_TX_QUEUES)
815 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
816
817 /* Initial HDD buffer control / flow control fields*/
818 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
819
820 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
821 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
822 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
823 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
824
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
826 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530827 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700828 for (i = 0; i < NUM_TX_QUEUES; i ++)
829 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530830 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700831 }
832 }
833
Yue Ma3ede6052013-08-29 00:33:26 -0700834 /* Update the AC weights suitable for SoftAP mode of operation */
835 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
836
Kiet Lambcf38522013-10-26 18:28:27 +0530837 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700838 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530839 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530840 "%s: failed to start Traffic Monito timer ", __func__ );
841 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700842 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700843 return status;
844}
845
846/**============================================================================
847 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
848 modules in HDD
849
850 @param pAdapter : [in] pointer to adapter context
851 @return : VOS_STATUS_E_FAILURE if any errors encountered
852 : VOS_STATUS_SUCCESS otherwise
853 ===========================================================================*/
854VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
855{
856 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700857
Kiet Lambcf38522013-10-26 18:28:27 +0530858 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700859 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530860 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Kiet Lambcf38522013-10-26 18:28:27 +0530861 "%s: Fail to Stop Traffic Monito timer", __func__ );
862 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700863 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700864
865 status = hdd_softap_flush_tx_queues(pAdapter);
866
867 return status;
868}
869
870/**============================================================================
871 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
872
873 @param pAdapter : [in] pointer to adapter context
874 @param STAId : [in] Station ID to deinit
875 @return : VOS_STATUS_E_FAILURE if any errors encountered
876 : VOS_STATUS_SUCCESS otherwise
877 ===========================================================================*/
878static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
879{
Jeff Johnson295189b2012-06-20 16:38:30 -0700880 v_U8_t i = -1;
881
882 hdd_list_node_t *anchor = NULL;
883
884 skb_list_node_t *pktNode = NULL;
885 struct sk_buff *skb = NULL;
886
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530887 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
888 ptSapContext pSapCtx = NULL;
889 pSapCtx = VOS_GET_SAP_CB(pVosContext);
890 if(pSapCtx == NULL){
891 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
892 FL("psapCtx is NULL"));
893 return VOS_STATUS_E_FAULT;
894 }
895 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700896 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530897 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700898 }
899
900 for (i = 0; i < NUM_TX_QUEUES; i ++)
901 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530902 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700903 while (true)
904 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530905 if (VOS_STATUS_E_EMPTY !=
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530906 hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530907 &anchor))
Jeff Johnson295189b2012-06-20 16:38:30 -0700908 {
909 //If success then we got a valid packet from some AC
910 pktNode = list_entry(anchor, skb_list_node_t, anchor);
911 skb = pktNode->skb;
912 ++pAdapter->stats.tx_dropped;
913 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
914 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
915 kfree_skb(skb);
916 continue;
917 }
918
919 //current list is empty
920 break;
921 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530922 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 }
924
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +0530925 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700926}
927
928/**============================================================================
929 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
930 modules in HDD
931
932 @param pAdapter : [in] pointer to adapter context
933 @param STAId : [in] Station ID to deinit
934 @param pmacAddrSTA : [in] pointer to the MAC address of the station
935 @return : VOS_STATUS_E_FAILURE if any errors encountered
936 : VOS_STATUS_SUCCESS otherwise
937 ===========================================================================*/
938VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
939{
940 v_U8_t i = 0;
Nirav Shah7e3c8132015-06-22 23:51:42 +0530941 VOS_STATUS status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530942 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
943 ptSapContext pSapCtx = NULL;
Nirav Shah7e3c8132015-06-22 23:51:42 +0530944
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530945 pSapCtx = VOS_GET_SAP_CB(pVosContext);
946 if(pSapCtx == NULL){
947 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
948 FL("psapCtx is NULL"));
949 return VOS_STATUS_E_FAULT;
950 }
951
952 spin_lock_bh( &pSapCtx->staInfo_lock );
953 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700954 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530955 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
956 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530957 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700958 return VOS_STATUS_E_FAILURE;
959 }
960
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530961 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 for (i = 0; i < NUM_TX_QUEUES; i ++)
963 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530964 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 }
966
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530967 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
968 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
969 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700970
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530971 spin_unlock_bh( &pSapCtx->staInfo_lock );
Nirav Shah7e3c8132015-06-22 23:51:42 +0530972
973 status = hdd_sta_id_hash_add_entry(pAdapter, STAId, pmacAddrSTA);
974 if (status != VOS_STATUS_SUCCESS) {
975 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
976 FL("Not able to add staid hash %d"), STAId);
977 return VOS_STATUS_E_FAILURE;
978 }
979
980 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
981 FL("New station added sta_id %d mac:"
982 MAC_ADDRESS_STR), STAId,
983 MAC_ADDR_ARRAY(pmacAddrSTA->bytes));
984
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 return VOS_STATUS_SUCCESS;
986}
987
988/**============================================================================
989 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
990 modules in HDD
991
992 @param pAdapter : [in] pointer to adapter context
993 @param STAId : [in] Station ID to deinit
994 @return : VOS_STATUS_E_FAILURE if any errors encountered
995 : VOS_STATUS_SUCCESS otherwise
996 ===========================================================================*/
997VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
998{
999 VOS_STATUS status = VOS_STATUS_SUCCESS;
1000 v_U8_t ac;
1001 /**Track whether OS TX queue has been disabled.*/
1002 v_BOOL_t txSuspended[NUM_TX_QUEUES];
1003 v_U8_t tlAC;
1004 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001005 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -07001006
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301007 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1008 ptSapContext pSapCtx = NULL;
1009 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1010 if(pSapCtx == NULL){
1011 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1012 FL("psapCtx is NULL"));
1013 return VOS_STATUS_E_FAULT;
1014 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1016
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301017 spin_lock_bh( &pSapCtx->staInfo_lock );
1018 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001019 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301020 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001021 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301022 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 return VOS_STATUS_E_FAILURE;
1024 }
1025
1026 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1027
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301028 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1029 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Nirav Shah7e3c8132015-06-22 23:51:42 +05301030
1031 status = hdd_sta_id_hash_remove_entry(pAdapter,
1032 STAId, &pSapCtx->aStaInfo[STAId].macAddrSTA);
1033 if (status != VOS_STATUS_SUCCESS) {
1034 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1035 FL("Not able to remove staid hash %d"), STAId);
1036 return VOS_STATUS_E_FAILURE;
1037 }
1038
1039 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1040 FL("station removed sta_id %d mac:"
1041 MAC_ADDRESS_STR), STAId,
1042 MAC_ADDR_ARRAY(pSapCtx->aStaInfo[STAId].macAddrSTA.bytes));
1043
Jeff Johnson295189b2012-06-20 16:38:30 -07001044 /* if this STA had any of its WMM TX queues suspended, then the
1045 associated queue on the network interface was disabled. check
1046 to see if that is the case, in which case we need to re-enable
1047 the interface queue. but we only do this if the BSS is running
1048 since, if the BSS is stopped, all of the interfaces have been
1049 stopped and should not be re-enabled */
1050
1051 if (BSS_START == pHostapdState->bssState)
1052 {
1053 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1054 {
1055 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301056 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001057 }
1058 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301059 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001060
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001061 /* re-init spin lock, since netdev can still open adapter until
1062 * driver gets unloaded
1063 */
1064 for (i = 0; i < NUM_TX_QUEUES; i ++)
1065 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301066 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001067 HDD_TX_QUEUE_MAX_LEN);
1068 }
1069
Jeff Johnson295189b2012-06-20 16:38:30 -07001070 if (BSS_START == pHostapdState->bssState)
1071 {
1072 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1073 {
1074 if (txSuspended[ac])
1075 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301076 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001077 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 netif_wake_subqueue(pAdapter->dev, ac);
1079 }
1080 }
1081 }
1082
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301083 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 return status;
1085}
1086
1087/**============================================================================
1088 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1089 modules in HDD
1090
1091 @param pAdapter : [in] pointer to adapter context
1092 @return : VOS_STATUS_E_FAILURE if any errors encountered
1093 : VOS_STATUS_SUCCESS otherwise
1094 ===========================================================================*/
1095VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1096{
1097 return hdd_softap_flush_tx_queues(pAdapter);
1098}
1099
1100/**============================================================================
1101 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1102 to indicate that a packet has been transmitted across the bus
1103 succesfully. OS packet resources can be released after this cbk.
1104
1105 @param vosContext : [in] pointer to VOS context
1106 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1107 @param vosStatusIn : [in] status of the transmission
1108
1109 @return : VOS_STATUS_E_FAILURE if any errors encountered
1110 : VOS_STATUS_SUCCESS otherwise
1111 ===========================================================================*/
1112VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1113 vos_pkt_t *pVosPacket,
1114 VOS_STATUS vosStatusIn )
1115{
1116 VOS_STATUS status = VOS_STATUS_SUCCESS;
1117 hdd_adapter_t *pAdapter = NULL;
1118 void* pOsPkt = NULL;
1119
1120 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1121 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301122 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1123 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001124 return VOS_STATUS_E_FAILURE;
1125 }
1126
1127 //Return the skb to the OS
1128 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001129 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001130 {
1131 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301132 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1133 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 vos_pkt_return_packet( pVosPacket );
1135 return VOS_STATUS_E_FAILURE;
1136 }
1137
1138 //Get the Adapter context.
1139 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301140 if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301142 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301143 "%s: HDD adapter context is invalid", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 }
1145 else
1146 {
1147 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1148 }
1149
1150 kfree_skb((struct sk_buff *)pOsPkt);
1151
1152 //Return the VOS packet resources.
1153 status = vos_pkt_return_packet( pVosPacket );
1154 if(!VOS_IS_STATUS_SUCCESS( status ))
1155 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301156 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1157 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001158 }
1159
1160 return status;
1161}
1162
1163
1164/**============================================================================
1165 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1166 fetch a packet for transmission.
1167
1168 @param vosContext : [in] pointer to VOS context
1169 @param staId : [in] Station for which TL is requesting a pkt
1170 @param ac : [in] access category requested by TL
1171 @param pVosPacket : [out] pointer to VOS packet packet pointer
1172 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1173
1174 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1175 : VOS_STATUS_E_FAILURE if any errors encountered
1176 : VOS_STATUS_SUCCESS otherwise
1177 ===========================================================================*/
1178VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1179 v_U8_t *pStaId,
1180 WLANTL_ACEnumType ac,
1181 vos_pkt_t **ppVosPacket,
1182 WLANTL_MetaInfoType *pPktMetaInfo )
1183{
1184 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1185 hdd_adapter_t *pAdapter = NULL;
1186 hdd_list_node_t *anchor = NULL;
1187 skb_list_node_t *pktNode = NULL;
1188 struct sk_buff *skb = NULL;
1189 vos_pkt_t *pVosPacket = NULL;
1190 v_MACADDR_t* pDestMacAddress = NULL;
1191 v_TIME_t timestamp;
1192 v_SIZE_t size = 0;
1193 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1194 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001195 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301196 v_CONTEXT_t pVosContext = NULL;
1197 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 //Sanity check on inputs
1199 if ( ( NULL == vosContext ) ||
1200 ( NULL == pStaId ) ||
1201 ( NULL == ppVosPacket ) ||
1202 ( NULL == pPktMetaInfo ) )
1203 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301204 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1205 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001206 return VOS_STATUS_E_FAILURE;
1207 }
1208
1209 //Get the HDD context.
1210 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1211 if ( NULL == pHddCtx )
1212 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301213 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1214 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 return VOS_STATUS_E_FAILURE;
1216 }
1217
Jeff Johnsonb156c922013-12-05 17:19:46 -08001218 STAId = *pStaId;
1219 if (STAId >= WLAN_MAX_STA_COUNT)
1220 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301221 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001222 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1223 return VOS_STATUS_E_FAILURE;
1224 }
1225
1226 pAdapter = pHddCtx->sta_to_adapter[STAId];
1227 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001228 {
1229 VOS_ASSERT(0);
1230 return VOS_STATUS_E_FAILURE;
1231 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301232 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1233 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1234 if(pSapCtx == NULL){
1235 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1236 FL("psapCtx is NULL"));
1237 return VOS_STATUS_E_FAULT;
1238 }
1239
1240 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001241 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301242 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001243 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1244 return VOS_STATUS_E_FAILURE;
1245 }
1246
Leo Chang64d68bc2013-06-04 15:40:52 -07001247 /* Monitor traffic */
1248 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1249 {
1250 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1251 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1252 {
1253 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1254 /* It was IDLE mode,
1255 * this is new state, then switch mode from suspend to resume */
1256 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1257 {
1258 hdd_set_wlan_suspend_mode(0);
1259 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1260 pHddCtx->cfg_ini->trafficIdleTimeout);
1261 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1262 }
1263 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1264 }
1265 }
1266
Jeff Johnson295189b2012-06-20 16:38:30 -07001267 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1268
Jeff Johnson295189b2012-06-20 16:38:30 -07001269 *ppVosPacket = NULL;
1270
1271 //Make sure the AC being asked for is sane
1272 if( ac > WLANTL_MAX_AC || ac < 0)
1273 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301274 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001275 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 return VOS_STATUS_E_FAILURE;
1277 }
1278
1279 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1280
c_hpothu6d1d2a32014-03-18 20:17:03 +05301281 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001282 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001283
1284 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1285 //This simplifies the locking and unlocking of Tx queue
1286 status = vos_pkt_wrap_data_packet( &pVosPacket,
1287 VOS_PKT_TYPE_TX_802_3_DATA,
1288 NULL, //OS Pkt is not being passed
1289 hdd_softap_tx_low_resource_cbk,
1290 pAdapter );
1291
1292 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1293 {
1294 //Remember VOS is in a low resource situation
1295 pAdapter->isVosOutOfResource = VOS_TRUE;
1296 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301297 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001298 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001299 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1300 return VOS_STATUS_E_FAILURE;
1301 }
1302
1303 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1304 as the other branch does.
1305 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301306 spin_lock_bh( &pSapCtx->staInfo_lock );
1307 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1308 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001309
1310 if (0 == size)
1311 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301312 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1313 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 vos_pkt_return_packet(pVosPacket);
1315 return VOS_STATUS_E_EMPTY;
1316 }
1317
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301318 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1319 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1320 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001321
c_hpothu6d1d2a32014-03-18 20:17:03 +05301322 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001323 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001324
1325 if(VOS_STATUS_SUCCESS == status)
1326 {
1327 //If success then we got a valid packet from some AC
1328 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1329 skb = pktNode->skb;
1330 }
1331 else
1332 {
1333 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301334 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001335 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001336 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001337 vos_pkt_return_packet(pVosPacket);
1338 return VOS_STATUS_E_FAILURE;
1339 }
1340
1341 //Attach skb to VOS packet.
1342 status = vos_pkt_set_os_packet( pVosPacket, skb );
1343 if (status != VOS_STATUS_SUCCESS)
1344 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301345 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001346 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001347 vos_pkt_return_packet(pVosPacket);
1348 ++pAdapter->stats.tx_dropped;
1349 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1350 kfree_skb(skb);
1351 return VOS_STATUS_E_FAILURE;
1352 }
1353
1354 //Just being paranoid. To be removed later
1355 if(pVosPacket == NULL)
1356 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301357 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001358 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 ++pAdapter->stats.tx_dropped;
1360 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1361 kfree_skb(skb);
1362 return VOS_STATUS_E_FAILURE;
1363 }
1364
1365 //Return VOS packet to TL;
1366 *ppVosPacket = pVosPacket;
1367
1368 //Fill out the meta information needed by TL
1369 //FIXME This timestamp is really the time stamp of wrap_data_packet
1370 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1371 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1372 if ( 1 < size )
1373 {
1374 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1375 }
1376 else
1377 {
1378 pPktMetaInfo->bMorePackets = 0;
1379 }
1380
1381 pPktMetaInfo->ucIsEapol = 0;
1382
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301383 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 {
1385 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1386 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001387 pPktMetaInfo->ucIsEapol = 1;
Sushant Kaushika8073312015-05-04 17:33:52 +05301388 wlan_hdd_log_eapol(skb,
1389 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
Jeff Johnson295189b2012-06-20 16:38:30 -07001390 }
1391 }
Sushant Kaushika8073312015-05-04 17:33:52 +05301392
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301393 if ((NULL != pHddCtx) &&
1394 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001395 {
1396 proto_type = vos_pkt_get_proto_type(skb,
1397 pHddCtx->cfg_ini->gEnableDebugLog);
1398 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1399 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001401 "SAP TX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001402 }
1403 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1404 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001406 "SAP TX DHCP");
1407 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301408 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1409 {
1410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1411 "SAP TX ARP");
1412 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001414//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001415 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301416 pPktMetaInfo->ac = ac;
Jeff Johnson295189b2012-06-20 16:38:30 -07001417 pPktMetaInfo->ucUP = pktNode->userPriority;
1418 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1419 }
1420
1421 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1422 //Extract the destination address from ethernet frame
1423 pDestMacAddress = (v_MACADDR_t*)skb->data;
1424
1425 // we need 802.3 to 802.11 frame translation
1426 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1427 pPktMetaInfo->ucDisableFrmXtl = 0;
1428 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1429 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1430
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301431 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001432 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1433 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301434 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001435 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301436 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301438 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1439 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 }
1441
1442 // We're giving the packet to TL so consider it transmitted from
1443 // a statistics perspective. We account for it here instead of
1444 // when the packet is returned for two reasons. First, TL will
1445 // manipulate the skb to the point where the len field is not
1446 // accurate, leading to inaccurate byte counts if we account for
1447 // it later. Second, TL does not provide any feedback as to
1448 // whether or not the packet was successfully sent over the air,
1449 // so the packet counts will be the same regardless of where we
1450 // account for them
1451 pAdapter->stats.tx_bytes += skb->len;
1452 ++pAdapter->stats.tx_packets;
1453 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1454 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301455 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001456
c_hpothu6d1d2a32014-03-18 20:17:03 +05301457 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001458 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001459
1460 return status;
1461}
1462
1463
1464/**============================================================================
1465 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1466 case where VOS packets are not available at the time of the call to get
1467 packets. This callback function is invoked by VOS when packets are
1468 available.
1469
1470 @param pVosPacket : [in] pointer to VOS packet
1471 @param userData : [in] opaque user data that was passed initially
1472
1473 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1474 : VOS_STATUS_SUCCESS otherwise
1475 =============================================================================*/
1476VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1477 v_VOID_t *userData )
1478{
1479 VOS_STATUS status;
1480 v_SINT_t i = 0;
1481 v_SIZE_t size = 0;
1482 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1483 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301484 v_CONTEXT_t pVosContext = NULL;
1485 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301486
1487 if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07001488 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301489 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1490 FL("Invalid adapter %p"), pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001491 return VOS_STATUS_E_FAILURE;
1492 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301493 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1494 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1495 if(pSapCtx == NULL){
1496 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1497 FL("psapCtx is NULL"));
1498 return VOS_STATUS_E_FAULT;
1499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001500 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1501 //situation. Here we will only signal TL that there is a pending data for a STA.
1502 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1503 vos_pkt_return_packet( pVosPacket );
1504
1505 pAdapter->isVosOutOfResource = VOS_FALSE;
1506
1507 // Indicate to TL that there is pending data if a queue is non empty.
1508 // This Code wasnt included in earlier version which resulted in
1509 // Traffic stalling
1510 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1511 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301512 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1513 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001514 {
1515 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1516 {
1517 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301518 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 if ( size > 0 )
1520 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301521 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1522 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001523 (WLANTL_ACEnumType)i );
1524 if( !VOS_IS_STATUS_SUCCESS( status ) )
1525 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301526 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1527 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 }
1529 }
1530 }
1531 }
1532 }
1533 return VOS_STATUS_SUCCESS;
1534}
1535
1536
1537/**============================================================================
1538 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1539 TL will call this to notify the HDD when one or more packets were
1540 received for a registered STA.
1541
1542 @param vosContext : [in] pointer to VOS context
1543 @param pVosPacketChain : [in] pointer to VOS packet chain
1544 @param staId : [in] Station Id (Adress 1 Index)
1545 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1546
1547 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1548 : VOS_STATUS_SUCCESS otherwise
1549 ===========================================================================*/
1550VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1551 vos_pkt_t *pVosPacketChain,
1552 v_U8_t staId,
1553 WLANTL_RxMetaInfoType* pRxMetaInfo )
1554{
1555 hdd_adapter_t *pAdapter = NULL;
1556 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1557 int rxstat;
1558 struct sk_buff *skb = NULL;
1559 vos_pkt_t* pVosPacket;
1560 vos_pkt_t* pNextVosPacket;
1561 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001562 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001563
1564 //Sanity check on inputs
1565 if ( ( NULL == vosContext ) ||
1566 ( NULL == pVosPacketChain ) ||
1567 ( NULL == pRxMetaInfo ) )
1568 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301569 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1570 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001571 return VOS_STATUS_E_FAILURE;
1572 }
1573
1574 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1575 if ( NULL == pHddCtx )
1576 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301577 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1578 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001579 return VOS_STATUS_E_FAILURE;
1580 }
1581
1582 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301583 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001584 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301585 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1586 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001587 VOS_ASSERT(0);
1588 return VOS_STATUS_E_FAILURE;
1589 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001590
1591 /* Monitor traffic */
1592 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1593 {
1594 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1595 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1596 {
1597 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1598 /* It was IDLE mode,
1599 * this is new state, then switch mode from suspend to resume */
1600 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1601 {
1602 hdd_set_wlan_suspend_mode(0);
1603 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1604 pHddCtx->cfg_ini->trafficIdleTimeout);
1605 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1606 }
1607 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1608 }
1609 }
1610
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1612
1613 // walk the chain until all are processed
1614 pVosPacket = pVosPacketChain;
1615 do
1616 {
1617 // get the pointer to the next packet in the chain
1618 // (but don't unlink the packet since we free the entire chain later)
1619 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1620
1621 // both "success" and "empty" are acceptable results
1622 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1623 {
1624 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301625 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1626 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 return VOS_STATUS_E_FAILURE;
1628 }
1629
1630 // Extract the OS packet (skb).
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301631 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 if(!VOS_IS_STATUS_SUCCESS( status ))
1633 {
1634 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301635 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1636 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 return VOS_STATUS_E_FAILURE;
1638 }
Sushant Kaushikd43987b2015-06-05 12:18:34 +05301639
1640 if (TRUE == hdd_IsEAPOLPacket(pVosPacket))
1641 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
1642
1643 pVosPacket->pSkb = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 //hdd_softap_dump_sk_buff(skb);
1645
1646 skb->dev = pAdapter->dev;
1647
1648 if(skb->dev == NULL) {
1649
c_hpothu6d1d2a32014-03-18 20:17:03 +05301650 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1651 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001652 return VOS_STATUS_E_FAILURE;
1653 }
1654 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1655 ++pAdapter->stats.rx_packets;
1656 pAdapter->stats.rx_bytes += skb->len;
1657
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001658 if (pHddCtx->cfg_ini->gEnableDebugLog)
1659 {
1660 proto_type = vos_pkt_get_proto_type(skb,
1661 pHddCtx->cfg_ini->gEnableDebugLog);
1662 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1663 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07001665 "SAP RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001666 }
1667 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1668 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001670 "SAP RX DHCP");
1671 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301672 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1673 {
1674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1675 "SAP RX ARP");
1676 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001677 }
1678
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1680 {
1681 //MC/BC packets. Duplicate a copy of packet
1682 struct sk_buff *pSkbCopy;
1683 hdd_ap_ctx_t *pHddApCtx;
1684
1685 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1686 if (!(pHddApCtx->apDisableIntraBssFwd))
1687 {
1688 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1689 if (pSkbCopy)
1690 {
1691 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1692 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1693 }
1694 }
1695 else
1696 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301697 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001698 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001699 }
1700
1701
1702 } //(WLAN_RX_BCMC_STA_ID == staId)
1703
1704 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1705 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1706 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301707 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001708 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301709 if ((NULL != pHddCtx) &&
1710 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301711 {
1712 hdd_dump_dhcp_pkt(skb, RX_PATH);
1713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001714
1715 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001716 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnsone7245742012-09-05 17:12:55 -07001717#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05301718 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
1719 HDD_WAKE_LOCK_DURATION,
1720 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
1721
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001722#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001723 rxstat = netif_rx_ni(skb);
1724 if (NET_RX_SUCCESS == rxstat)
1725 {
1726 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001727 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001728 }
1729 else
1730 {
1731 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1732 }
1733 }
1734 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1735 {
1736 kfree_skb(skb);
1737 }
1738 else
1739 {
1740 //loopback traffic
1741 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1742 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1743 }
1744
1745 // now process the next packet in the chain
1746 pVosPacket = pNextVosPacket;
1747
1748 } while (pVosPacket);
1749
1750 //Return the entire VOS packet chain to the resource pool
1751 status = vos_pkt_return_packet( pVosPacketChain );
1752 if(!VOS_IS_STATUS_SUCCESS( status ))
1753 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301754 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1755 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001756 }
1757
1758 pAdapter->dev->last_rx = jiffies;
1759
1760 return status;
1761}
1762
1763VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1764{
1765 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301766 hdd_context_t *pHddCtx;
1767 if (NULL == pAdapter)
1768 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301769 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301770 "%s: pAdapter is NULL", __func__);
1771 return VOS_STATUS_E_INVAL;
1772 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001773
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301774 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1775 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301776 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301777 "%s: Invalid pAdapter magic", __func__);
1778 return VOS_STATUS_E_INVAL;
1779 }
1780
1781 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301782 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301784 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001785 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1786 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301787 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001788 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001789 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 staId, vosStatus, vosStatus );
1791 }
1792
1793 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1794 if( VOS_STATUS_E_FAILURE == vosStatus )
1795 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301796 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001798 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001799 staId, vosStatus, vosStatus );
1800 return( vosStatus );
1801 }
1802
1803 pHddCtx->sta_to_adapter[staId] = NULL;
1804
1805 return( vosStatus );
1806}
1807
1808VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1809 v_BOOL_t fAuthRequired,
1810 v_BOOL_t fPrivacyBit,
1811 v_U8_t staId,
1812 v_U8_t ucastSig,
1813 v_U8_t bcastSig,
1814 v_MACADDR_t *pPeerMacAddress,
1815 v_BOOL_t fWmmEnabled )
1816{
1817 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001818 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001819 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1820 hdd_adapter_t *pmonAdapter = NULL;
1821
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301822 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1823 ptSapContext pSapCtx = NULL;
1824 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1825 if(pSapCtx == NULL){
1826 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1827 FL("psapCtx is NULL"));
1828 return VOS_STATUS_E_FAULT;
1829 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 //eCsrEncryptionType connectedCipherAlgo;
1831 //v_BOOL_t fConnected;
1832
1833 /*
1834 * Clean up old entry if it is not cleaned up properly
1835 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301836 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001837 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301838 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001839 "clean up old entry for STA %d", staId);
1840 hdd_softap_DeregisterSTA( pAdapter, staId );
1841 }
1842
1843 // Get the Station ID from the one saved during the assocation.
1844
1845 staDesc.ucSTAId = staId;
1846
1847
1848 /*Save the pAdapter Pointer for this staId*/
1849 pHddCtx->sta_to_adapter[staId] = pAdapter;
1850
1851 staDesc.wSTAType = WLAN_STA_SOFTAP;
1852
1853 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1854 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1855 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1856
c_hpothu6d1d2a32014-03-18 20:17:03 +05301857 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001858 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301859 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001860 "station mac " MAC_ADDRESS_STR,
1861 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301862 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001863 "BSSIDforIBSS " MAC_ADDRESS_STR,
1864 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301865 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001866 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1867 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001868
1869 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1870
Jeff Johnson295189b2012-06-20 16:38:30 -07001871 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301872 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001873 "HDD SOFTAP register TL QoS_enabled=%d",
1874 staDesc.ucQosEnabled );
1875
1876 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1877
1878
Jeff Johnson295189b2012-06-20 16:38:30 -07001879 // For PRIMA UMA frame translation is not enable yet.
1880 staDesc.ucSwFrameTXXlation = 1;
1881 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001882 staDesc.ucAddRmvLLC = 1;
1883
1884 // Initialize signatures and state
1885 staDesc.ucUcastSig = ucastSig;
1886 staDesc.ucBcastSig = bcastSig;
1887 staDesc.ucInitState = fAuthRequired ?
1888 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1889
Prathyushaf5442802012-12-12 13:58:11 -08001890 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1891
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301893 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1894 hdd_softap_rx_packet_cbk,
1895 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001896 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1897
1898 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1899 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301900 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001901 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 vosStatus, vosStatus );
1903 return vosStatus;
1904 }
1905
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001906 //Timer value should be in milliseconds
1907 if ( pHddCtx->cfg_ini->dynSplitscan &&
1908 ( VOS_TIMER_STATE_RUNNING !=
1909 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1910 {
1911 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1912 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1913 }
1914
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1916 // then go to 'authenticated'. For all other authentication types (those that do
1917 // not require upper layer authentication) we can put TL directly into 'authenticated'
1918 // state.
1919
1920 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301921 pSapCtx->aStaInfo[staId].ucSTAId = staId;
1922 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 if ( !fAuthRequired )
1924 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301925 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1926 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301927 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001928
1929 // Connections that do not need Upper layer auth, transition TL directly
1930 // to 'Authenticated' state.
1931 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1932 WLANTL_STA_AUTHENTICATED );
1933
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301934 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001935 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1936 }
1937 else
1938 {
1939
c_hpothu6d1d2a32014-03-18 20:17:03 +05301940 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301941 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001942
1943 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1944 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301945 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001946
1947 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1948
1949 }
1950 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1951 if(pmonAdapter)
1952 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301953 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
1954 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001955 netif_carrier_on(pmonAdapter->dev);
1956 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301957 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 netif_tx_start_all_queues(pmonAdapter->dev);
1959 }
1960 netif_carrier_on(pAdapter->dev);
1961 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301962 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 netif_tx_start_all_queues(pAdapter->dev);
1964
1965 return( vosStatus );
1966}
1967
1968VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1969{
1970 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1971 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1972 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1973
1974
1975 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1976 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1977 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1978
1979 return vosStatus;
1980}
1981
1982VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1983{
1984 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1985}
1986
1987VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1988{
1989 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1990 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301991 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07001992
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301993 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1994 ptSapContext pSapCtx = NULL;
1995 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1996 if(pSapCtx == NULL){
1997 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1998 FL("psapCtx is NULL"));
1999 return VOS_STATUS_E_FAULT;
2000 }
2001
2002 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07002003 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05302004 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07002005 {
2006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2007 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
2008 return VOS_STATUS_E_PERM;
2009 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002010
2011 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
2012
Jeff Johnson43971f52012-07-17 12:26:56 -07002013 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002014 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302015 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002016 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002017 }
2018
2019 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2020 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302021 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302023 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
2024 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
2025 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302026 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002027 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05302028 }
2029 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 }
2031
2032 return vosStatus;
2033}
2034
2035VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
2036{
2037 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
2038 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2039 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002040
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302041 ptSapContext pSapCtx = NULL;
2042 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2043 if(pSapCtx == NULL){
2044 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2045 FL("psapCtx is NULL"));
2046 return VOS_STATUS_E_FAULT;
2047 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302048 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002049 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002050
Jeff Johnson43971f52012-07-17 12:26:56 -07002051 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302053 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002054 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002055 return VOS_STATUS_E_FAILURE;
2056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002057
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302058 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302060 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002061 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002062 return VOS_STATUS_E_FAILURE;
2063 }
2064
2065 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302066 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002067 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002068
Jeff Johnson43971f52012-07-17 12:26:56 -07002069 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302071 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 }
2073
c_hpothu6d1d2a32014-03-18 20:17:03 +05302074 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002075 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002076
2077 return vosStatus;
2078}
2079
2080
2081VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2082{
2083 v_U8_t i;
2084
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302085 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2086 ptSapContext pSapCtx = NULL;
2087 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2088 if(pSapCtx == NULL){
2089 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2090 FL("psapCtx is NULL"));
2091 return VOS_STATUS_E_FAULT;
2092 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2094 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302095 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2096 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 {
2098 *staId = i;
2099 return VOS_STATUS_SUCCESS;
2100 }
2101 }
2102
2103 return VOS_STATUS_E_FAILURE;
2104}
2105
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302106VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2107{
2108 v_U8_t i;
2109
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302110 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2111 ptSapContext pSapCtx = NULL;
2112 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2113 if(pSapCtx == NULL){
2114 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2115 FL("psapCtx is NULL"));
2116 return VOS_STATUS_E_FAULT;
2117 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302118 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2119 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302120 if (pSapCtx->aStaInfo[i].isUsed &&
2121 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302122 {
2123 *staId = i;
2124 return VOS_STATUS_SUCCESS;
2125 }
2126 }
2127
2128 return VOS_STATUS_E_FAILURE;
2129}