blob: 56e8c2b2f6d79d276254743acc02f2394905bd9e [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"
Jeff Johnson295189b2012-06-20 16:38:30 -070061
62/*---------------------------------------------------------------------------
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
117 if (NULL == pHddCtx)
118 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530119 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Leo Chang64d68bc2013-06-04 15:40:52 -0700120 "%s: Invalid user data, context", __func__);
121 return;
122 }
123
124 currentTS = vos_timer_get_system_time();
125 if (pHddCtx->cfg_ini->trafficIdleTimeout <
126 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
127 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530128 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530129 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -0700130 hdd_set_wlan_suspend_mode(1);
131 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
132 }
133 else
134 {
135 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
136 pHddCtx->cfg_ini->trafficIdleTimeout);
137 }
138
139 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
148 status = wlan_hdd_validate_context(pHddCtx);
149
150 if (0 != status)
151 {
152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
153 "%s: HDD context is not valid", __func__);
154 return status;
155 }
156
157 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
158 (!pHddCtx->traffic_monitor.isInitialized))
159 {
160 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
161 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
162 VOS_TIMER_TYPE_SW,
163 hdd_softap_traffic_monitor_timeout_handler,
164 pHddCtx);
165 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
166 pHddCtx->traffic_monitor.isInitialized = 1;
167 pHddCtx->traffic_monitor.lastFrameTs = 0;
168 /* Start traffic monitor timer here
169 * If no AP assoc, immediatly go into suspend */
c_hpothu6d1d2a32014-03-18 20:17:03 +0530170 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530171 "%s Start Traffic Monitor Timer", __func__);
172 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
173 pHddCtx->cfg_ini->trafficIdleTimeout);
174 }
175 else
176 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530177 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530178 "%s Traffic Monitor is not Enable in ini file", __func__);
179 }
180 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
188 status = wlan_hdd_validate_context(pHddCtx);
189
Kiet Lamae69d7a2013-11-08 14:38:04 +0530190 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530191 {
192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
193 "%s: HDD context is not valid", __func__);
194 return status;
195 }
196
197 if (pHddCtx->traffic_monitor.isInitialized)
198 {
199 if (VOS_TIMER_STATE_STOPPED !=
200 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
201 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530202 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530203 "%s Stop Traffic Monitor Timer", __func__);
204 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
205 }
c_hpothu6d1d2a32014-03-18 20:17:03 +0530206 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Kiet Lambcf38522013-10-26 18:28:27 +0530207 "%s Destroy Traffic Monitor Timer", __func__);
208 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
209 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
210 pHddCtx->traffic_monitor.isInitialized = 0;
211 }
Kiet Lamae69d7a2013-11-08 14:38:04 +0530212 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530213}
214
Jeff Johnson295189b2012-06-20 16:38:30 -0700215/**============================================================================
216 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
217
218 @param pAdapter : [in] pointer to adapter context
219 @return : VOS_STATUS_E_FAILURE if any errors encountered
220 : VOS_STATUS_SUCCESS otherwise
221 ===========================================================================*/
222static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
223{
224 VOS_STATUS status = VOS_STATUS_SUCCESS;
225 v_SINT_t i = -1;
226 v_U8_t STAId = 0;
227 hdd_list_node_t *anchor = NULL;
228 skb_list_node_t *pktNode = NULL;
229 struct sk_buff *skb = NULL;
230
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530231 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
232 ptSapContext pSapCtx = NULL;
233 pSapCtx = VOS_GET_SAP_CB(pVosContext);
234 if(pSapCtx == NULL){
235 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
236 FL("psapCtx is NULL"));
237 return VOS_STATUS_E_FAULT;
238 }
239 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700240 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
241 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530242 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700243 {
244 continue;
245 }
246
247 for (i = 0; i < NUM_TX_QUEUES; i ++)
248 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530249 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 while (true)
251 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530252 status = hdd_list_remove_front ( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
Jeff Johnson295189b2012-06-20 16:38:30 -0700253
254 if (VOS_STATUS_E_EMPTY != status)
255 {
256 //If success then we got a valid packet from some AC
257 pktNode = list_entry(anchor, skb_list_node_t, anchor);
258 skb = pktNode->skb;
259 ++pAdapter->stats.tx_dropped;
260 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
261 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
262 kfree_skb(skb);
263 continue;
264 }
265
266 //current list is empty
267 break;
268 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530269 pSapCtx->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
270 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700271 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530272 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 }
274
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530275 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700276
277 return status;
278}
279
280/**============================================================================
281 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
282 transmitting packets. There are 2 versions of this function. One that uses
283 locked queue and other that uses lockless queues. Both have been retained to
284 do some performance testing
285
286 @param skb : [in] pointer to OS packet (sk_buff)
287 @param dev : [in] pointer to Libra network device
288
289 @return : NET_XMIT_DROP if packets are dropped
290 : NET_XMIT_SUCCESS if packet is enqueued succesfully
291 ===========================================================================*/
292int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
293{
294 VOS_STATUS status;
295 WLANTL_ACEnumType ac = WLANTL_AC_BE;
296 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
297 skb_list_node_t *pktNode = NULL;
298 v_SIZE_t pktListSize = 0;
299 v_BOOL_t txSuspended = VOS_FALSE;
300 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
301 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530302 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700303 vos_list_node_t *anchor = NULL;
304 v_U8_t STAId = WLAN_MAX_STA_COUNT;
305 //Extract the destination address from ethernet frame
306 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
307 int os_status = NETDEV_TX_OK;
Mihir Shetef8f74532014-12-04 11:53:34 +0530308 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700309
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530310 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
311 ptSapContext pSapCtx = NULL;
312 pSapCtx = VOS_GET_SAP_CB(pVosContext);
313 if(pSapCtx == NULL){
314 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
315 FL("psapCtx is NULL"));
316 ++pAdapter->stats.tx_dropped;
317 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
318 kfree_skb(skb);
319 return os_status;
320 }
321
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 pDestMacAddress = (v_MACADDR_t*)skb->data;
323
324 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
325
c_hpothu6d1d2a32014-03-18 20:17:03 +0530326 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700327 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700328
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530329 spin_lock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700330 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
331 {
332 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
333 //ID used for BC/MC traffic. The station id is registered to TL as well.
334 STAId = pHddApCtx->uBCStaId;
335
336 /* Setting priority for broadcast packets which doesn't go to select_queue function */
337 skb->priority = SME_QOS_WMM_UP_BE;
338 skb->queue_mapping = HDD_LINUX_AC_BE;
339
c_hpothu6d1d2a32014-03-18 20:17:03 +0530340 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800341 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 }
343 else
344 {
345 STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
346 if (STAId == HDD_WLAN_INVALID_STA_ID)
347 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530348 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700349 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 ++pAdapter->stats.tx_dropped;
351 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
352 kfree_skb(skb);
353 goto xmit_done;
354 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530355 else if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700356 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530357 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
358 "%s: STA %d is unregistered", __func__, STAId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700359 ++pAdapter->stats.tx_dropped;
360 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
361 kfree_skb(skb);
362 goto xmit_done;
363 }
364
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530365 if ( (WLANTL_STA_CONNECTED != pSapCtx->aStaInfo[STAId].tlSTAState) &&
366 (WLANTL_STA_AUTHENTICATED != pSapCtx->aStaInfo[STAId].tlSTAState) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700367 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530368 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700369 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 ++pAdapter->stats.tx_dropped;
371 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
372 kfree_skb(skb);
373 goto xmit_done;
374 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530375 else if(WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[STAId].tlSTAState)
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 {
377 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
378 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530379 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700380 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 ++pAdapter->stats.tx_dropped;
382 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
383 kfree_skb(skb);
384 goto xmit_done;
385 }
386 }
387 }
388
389 //Get TL AC corresponding to Qdisc queue index/AC.
390 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
391 //user priority from IP header, which is already extracted and set from
392 //select_queue call back function
393 up = skb->priority;
394 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
395
c_hpothu6d1d2a32014-03-18 20:17:03 +0530396 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700397 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700398
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530399 if (( NULL != pHddCtx ) &&
400 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530401 {
402 hdd_dump_dhcp_pkt(skb, TX_PATH);
403 }
404
Jeff Johnson295189b2012-06-20 16:38:30 -0700405 // If the memory differentiation mode is enabled, the memory limit of each queue will be
406 // checked. Over-limit packets will be dropped.
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530407 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
408 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700409 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
410 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530411 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800412 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530413 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700414 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
415 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530416 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
417 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -0700418 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530419
420 /* If 3/4th of the max queue size is used then enable the flag.
421 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
422 if (WLANTL_AC_BE == ac)
423 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530424 if (pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530425 {
426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
427 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530428 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_TRUE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530429 }
430 else
431 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530432 pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530433 }
434 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530435 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700436
437 if (VOS_TRUE == txSuspended)
438 {
439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
440 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700441 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700442 os_status = NETDEV_TX_BUSY;
443 goto xmit_done;
444 }
445
446 //Use the skb->cb field to hold the list node information
447 pktNode = (skb_list_node_t *)&skb->cb;
448
449 //Stick the OS packet inside this node.
450 pktNode->skb = skb;
451
452 //Stick the User Priority inside this node
453 pktNode->userPriority = up;
454
455 INIT_LIST_HEAD(&pktNode->anchor);
456
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530457 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
458 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
459 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700460 if ( !VOS_IS_STATUS_SUCCESS( status ) )
461 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530462 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
463 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700464 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
465 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
466 ++pAdapter->stats.tx_dropped;
467 kfree_skb(skb);
468 goto xmit_done;
469 }
470
471 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
472 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530473 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700474
475 if (1 == pktListSize)
476 {
477 //Let TL know we have a packet to send for this AC
478 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
479
480 if ( !VOS_IS_STATUS_SUCCESS( status ) )
481 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530482 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
483 "%s: Failed to signal TL for AC=%d STAId =%d",
484 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700485
486 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
487 //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 +0530488 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
489 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
490 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530491 /* Free the skb only if we are able to remove it from the list.
492 * If we are not able to retrieve it from the list it means that
493 * the skb was pulled by TX Thread and is use so we should not free
494 * it here
495 */
496 if (VOS_IS_STATUS_SUCCESS(status))
497 {
498 pktNode = list_entry(anchor, skb_list_node_t, anchor);
499 skb1 = pktNode->skb;
500 kfree_skb(skb1);
501 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700502 ++pAdapter->stats.tx_dropped;
503 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
504 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700505 goto xmit_done;
506 }
507 }
508 dev->trans_start = jiffies;
509
c_hpothu6d1d2a32014-03-18 20:17:03 +0530510 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
511 "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700512
513xmit_done:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530514 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700515 return os_status;
516}
517
518/**============================================================================
519 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
520
521 @param skb : [in] pointer to packet (sk_buff)
522 @param dev : [in] pointer to Libra network device
523 @param STAId : [in] Station Id of Destination Station
524 @param up : [in] User Priority
525
526 @return : NET_XMIT_DROP if packets are dropped
527 : NET_XMIT_SUCCESS if packet is enqueued succesfully
528 ===========================================================================*/
529VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
530 struct net_device *dev,
531 v_U8_t STAId,
532 v_U8_t up)
533{
534 VOS_STATUS status = VOS_STATUS_SUCCESS;
535 skb_list_node_t *pktNode = NULL;
536 v_SIZE_t pktListSize = 0;
537 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
538 v_U8_t ac;
539 vos_list_node_t *anchor = NULL;
Mihir Shetef8f74532014-12-04 11:53:34 +0530540 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700541
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530542 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
543 ptSapContext pSapCtx = NULL;
544 pSapCtx = VOS_GET_SAP_CB(pVosContext);
545 if(pSapCtx == NULL){
546 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
547 FL("psapCtx is NULL"));
548 kfree_skb(skb);
549 status = VOS_STATUS_E_FAILURE;
550 return status;
551 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700552 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
553
c_hpothu6d1d2a32014-03-18 20:17:03 +0530554 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700555 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700556
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530557 spin_lock_bh( &pSapCtx->staInfo_lock );
558 if ( FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -0700559 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530560 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530561 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700562 kfree_skb(skb);
563 status = VOS_STATUS_E_FAILURE;
564 goto xmit_end;
565 }
566
567 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530568 if ( !pSapCtx->aStaInfo[STAId].isQosEnabled )
Jeff Johnson295189b2012-06-20 16:38:30 -0700569 up = SME_QOS_WMM_UP_BE;
570
571 ac = hddWmmUpToAcMap[up];
572 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
c_hpothu6d1d2a32014-03-18 20:17:03 +0530573 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700574 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
576 skb->queue_mapping = hddLinuxUpToAcMap[up];
577
578 //Use the skb->cb field to hold the list node information
579 pktNode = (skb_list_node_t *)&skb->cb;
580
581 //Stick the OS packet inside this node.
582 pktNode->skb = skb;
583
584 //Stick the User Priority inside this node
585 pktNode->userPriority = up;
586
587 INIT_LIST_HEAD(&pktNode->anchor);
588
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530589 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
590 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
591 if(pSapCtx->aStaInfo[STAId].txSuspended[ac] ||
Jeff Johnson295189b2012-06-20 16:38:30 -0700592 pktListSize >= pAdapter->aTxQueueLimit[ac])
593 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530594 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800595 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700596 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
597 * SUSPEND should be done based on Threshold. RESUME would be
598 * triggered in fetch cbk after recovery.
599 */
600 kfree_skb(skb);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530601 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 status = VOS_STATUS_E_FAILURE;
603 goto xmit_end;
604 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530605 status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
606 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700607
608 if ( !VOS_IS_STATUS_SUCCESS( status ) )
609 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530610 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
611 "%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700612 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
613 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
614 ++pAdapter->stats.tx_dropped;
615 kfree_skb(skb);
616 status = VOS_STATUS_E_FAILURE;
617 goto xmit_end;
618 }
619
620 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
621 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
622
623 if (1 == pktListSize)
624 {
625 //Let TL know we have a packet to send for this AC
c_hpothu6d1d2a32014-03-18 20:17:03 +0530626 //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
627 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700628
629 if ( !VOS_IS_STATUS_SUCCESS( status ) )
630 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530631 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
632 "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700633 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700634
635 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
636 //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 +0530637 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
638 status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
639 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +0530640 /* Free the skb only if we are able to remove it from the list.
641 * If we are not able to retrieve it from the list it means that
642 * the skb was pulled by TX Thread and is use so we should not free
643 * it here
644 */
645 if (VOS_IS_STATUS_SUCCESS(status))
646 {
647 pktNode = list_entry(anchor, skb_list_node_t, anchor);
648 skb1 = pktNode->skb;
649 kfree_skb(skb1);
650 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700651 ++pAdapter->stats.tx_dropped;
652 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
653 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 status = VOS_STATUS_E_FAILURE;
655 goto xmit_end;
656 }
657 }
658
c_hpothu6d1d2a32014-03-18 20:17:03 +0530659 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700660
661xmit_end:
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530662 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700663 return status;
664}
665
666/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530667 @brief __hdd_softap_tx_timeout() - Function called by OS if there is any
Jeff Johnson295189b2012-06-20 16:38:30 -0700668 timeout during transmission. Since HDD simply enqueues packet
669 and returns control to OS right away, this would never be invoked
670
671 @param dev : [in] pointer to Libra network device
672 @return : None
673 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530674void __hdd_softap_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700675{
Mihir Shetef3473692014-06-27 15:13:20 +0530676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
677 struct netdev_queue *txq;
678 int i = 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);
693 if (pHddCtx->isLogpInProgress) {
694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
695 "%s:LOGP in Progress. Ignore!!!",__func__);
696 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;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530941 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
942 ptSapContext pSapCtx = NULL;
943 pSapCtx = VOS_GET_SAP_CB(pVosContext);
944 if(pSapCtx == NULL){
945 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
946 FL("psapCtx is NULL"));
947 return VOS_STATUS_E_FAULT;
948 }
949
950 spin_lock_bh( &pSapCtx->staInfo_lock );
951 if (pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 {
c_hpothu6d1d2a32014-03-18 20:17:03 +0530953 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
954 "%s: Reinit station %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530955 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700956 return VOS_STATUS_E_FAILURE;
957 }
958
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530959 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -0700960 for (i = 0; i < NUM_TX_QUEUES; i ++)
961 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530962 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
Jeff Johnson295189b2012-06-20 16:38:30 -0700963 }
964
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530965 pSapCtx->aStaInfo[STAId].isUsed = TRUE;
966 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
967 vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700968
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530969 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 return VOS_STATUS_SUCCESS;
971}
972
973/**============================================================================
974 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
975 modules in HDD
976
977 @param pAdapter : [in] pointer to adapter context
978 @param STAId : [in] Station ID to deinit
979 @return : VOS_STATUS_E_FAILURE if any errors encountered
980 : VOS_STATUS_SUCCESS otherwise
981 ===========================================================================*/
982VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
983{
984 VOS_STATUS status = VOS_STATUS_SUCCESS;
985 v_U8_t ac;
986 /**Track whether OS TX queue has been disabled.*/
987 v_BOOL_t txSuspended[NUM_TX_QUEUES];
988 v_U8_t tlAC;
989 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700990 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -0700991
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530992 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
993 ptSapContext pSapCtx = NULL;
994 pSapCtx = VOS_GET_SAP_CB(pVosContext);
995 if(pSapCtx == NULL){
996 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
997 FL("psapCtx is NULL"));
998 return VOS_STATUS_E_FAULT;
999 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
1001
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301002 spin_lock_bh( &pSapCtx->staInfo_lock );
1003 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07001004 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301005 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001006 "%s: Deinit station not inited %d", __func__, STAId );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301007 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 return VOS_STATUS_E_FAILURE;
1009 }
1010
1011 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
1012
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301013 pSapCtx->aStaInfo[STAId].isUsed = FALSE;
1014 pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 /* if this STA had any of its WMM TX queues suspended, then the
1016 associated queue on the network interface was disabled. check
1017 to see if that is the case, in which case we need to re-enable
1018 the interface queue. but we only do this if the BSS is running
1019 since, if the BSS is stopped, all of the interfaces have been
1020 stopped and should not be re-enabled */
1021
1022 if (BSS_START == pHostapdState->bssState)
1023 {
1024 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1025 {
1026 tlAC = hdd_QdiscAcToTlAC[ac];
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301027 txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC];
Jeff Johnson295189b2012-06-20 16:38:30 -07001028 }
1029 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301030 vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t));
Jeff Johnson295189b2012-06-20 16:38:30 -07001031
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001032 /* re-init spin lock, since netdev can still open adapter until
1033 * driver gets unloaded
1034 */
1035 for (i = 0; i < NUM_TX_QUEUES; i ++)
1036 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301037 hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i],
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07001038 HDD_TX_QUEUE_MAX_LEN);
1039 }
1040
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 if (BSS_START == pHostapdState->bssState)
1042 {
1043 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
1044 {
1045 if (txSuspended[ac])
1046 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301047 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001048 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001049 netif_wake_subqueue(pAdapter->dev, ac);
1050 }
1051 }
1052 }
1053
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301054 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 return status;
1056}
1057
1058/**============================================================================
1059 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1060 modules in HDD
1061
1062 @param pAdapter : [in] pointer to adapter context
1063 @return : VOS_STATUS_E_FAILURE if any errors encountered
1064 : VOS_STATUS_SUCCESS otherwise
1065 ===========================================================================*/
1066VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1067{
1068 return hdd_softap_flush_tx_queues(pAdapter);
1069}
1070
1071/**============================================================================
1072 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
1073 to indicate that a packet has been transmitted across the bus
1074 succesfully. OS packet resources can be released after this cbk.
1075
1076 @param vosContext : [in] pointer to VOS context
1077 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1078 @param vosStatusIn : [in] status of the transmission
1079
1080 @return : VOS_STATUS_E_FAILURE if any errors encountered
1081 : VOS_STATUS_SUCCESS otherwise
1082 ===========================================================================*/
1083VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
1084 vos_pkt_t *pVosPacket,
1085 VOS_STATUS vosStatusIn )
1086{
1087 VOS_STATUS status = VOS_STATUS_SUCCESS;
1088 hdd_adapter_t *pAdapter = NULL;
1089 void* pOsPkt = NULL;
1090
1091 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1092 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301093 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1094 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001095 return VOS_STATUS_E_FAILURE;
1096 }
1097
1098 //Return the skb to the OS
1099 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08001100 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 {
1102 //This is bad but still try to free the VOSS resources if we can
c_hpothu6d1d2a32014-03-18 20:17:03 +05301103 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1104 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 vos_pkt_return_packet( pVosPacket );
1106 return VOS_STATUS_E_FAILURE;
1107 }
1108
1109 //Get the Adapter context.
1110 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301111 if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301113 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothula2b9f1562015-02-25 13:38:29 +05301114 "%s: HDD adapter context is invalid", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001115 }
1116 else
1117 {
1118 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1119 }
1120
1121 kfree_skb((struct sk_buff *)pOsPkt);
1122
1123 //Return the VOS packet resources.
1124 status = vos_pkt_return_packet( pVosPacket );
1125 if(!VOS_IS_STATUS_SUCCESS( status ))
1126 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301127 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1128 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001129 }
1130
1131 return status;
1132}
1133
1134
1135/**============================================================================
1136 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
1137 fetch a packet for transmission.
1138
1139 @param vosContext : [in] pointer to VOS context
1140 @param staId : [in] Station for which TL is requesting a pkt
1141 @param ac : [in] access category requested by TL
1142 @param pVosPacket : [out] pointer to VOS packet packet pointer
1143 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1144
1145 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1146 : VOS_STATUS_E_FAILURE if any errors encountered
1147 : VOS_STATUS_SUCCESS otherwise
1148 ===========================================================================*/
1149VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1150 v_U8_t *pStaId,
1151 WLANTL_ACEnumType ac,
1152 vos_pkt_t **ppVosPacket,
1153 WLANTL_MetaInfoType *pPktMetaInfo )
1154{
1155 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1156 hdd_adapter_t *pAdapter = NULL;
1157 hdd_list_node_t *anchor = NULL;
1158 skb_list_node_t *pktNode = NULL;
1159 struct sk_buff *skb = NULL;
1160 vos_pkt_t *pVosPacket = NULL;
1161 v_MACADDR_t* pDestMacAddress = NULL;
1162 v_TIME_t timestamp;
1163 v_SIZE_t size = 0;
1164 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1165 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001166 v_U8_t proto_type = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301167 v_CONTEXT_t pVosContext = NULL;
1168 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001169 //Sanity check on inputs
1170 if ( ( NULL == vosContext ) ||
1171 ( NULL == pStaId ) ||
1172 ( NULL == ppVosPacket ) ||
1173 ( NULL == pPktMetaInfo ) )
1174 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301175 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1176 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001177 return VOS_STATUS_E_FAILURE;
1178 }
1179
1180 //Get the HDD context.
1181 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1182 if ( NULL == pHddCtx )
1183 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301184 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1185 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 return VOS_STATUS_E_FAILURE;
1187 }
1188
Jeff Johnsonb156c922013-12-05 17:19:46 -08001189 STAId = *pStaId;
1190 if (STAId >= WLAN_MAX_STA_COUNT)
1191 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301192 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001193 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1194 return VOS_STATUS_E_FAILURE;
1195 }
1196
1197 pAdapter = pHddCtx->sta_to_adapter[STAId];
1198 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001199 {
1200 VOS_ASSERT(0);
1201 return VOS_STATUS_E_FAILURE;
1202 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301203 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1204 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1205 if(pSapCtx == NULL){
1206 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1207 FL("psapCtx is NULL"));
1208 return VOS_STATUS_E_FAULT;
1209 }
1210
1211 if (FALSE == pSapCtx->aStaInfo[STAId].isUsed )
Jeff Johnsonb156c922013-12-05 17:19:46 -08001212 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301213 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonb156c922013-12-05 17:19:46 -08001214 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1215 return VOS_STATUS_E_FAILURE;
1216 }
1217
Leo Chang64d68bc2013-06-04 15:40:52 -07001218 /* Monitor traffic */
1219 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1220 {
1221 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1222 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1223 {
1224 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1225 /* It was IDLE mode,
1226 * this is new state, then switch mode from suspend to resume */
1227 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1228 {
1229 hdd_set_wlan_suspend_mode(0);
1230 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1231 pHddCtx->cfg_ini->trafficIdleTimeout);
1232 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1233 }
1234 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1235 }
1236 }
1237
Jeff Johnson295189b2012-06-20 16:38:30 -07001238 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1239
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 *ppVosPacket = NULL;
1241
1242 //Make sure the AC being asked for is sane
1243 if( ac > WLANTL_MAX_AC || ac < 0)
1244 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301245 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001246 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001247 return VOS_STATUS_E_FAILURE;
1248 }
1249
1250 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1251
c_hpothu6d1d2a32014-03-18 20:17:03 +05301252 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001253 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001254
1255 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1256 //This simplifies the locking and unlocking of Tx queue
1257 status = vos_pkt_wrap_data_packet( &pVosPacket,
1258 VOS_PKT_TYPE_TX_802_3_DATA,
1259 NULL, //OS Pkt is not being passed
1260 hdd_softap_tx_low_resource_cbk,
1261 pAdapter );
1262
1263 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1264 {
1265 //Remember VOS is in a low resource situation
1266 pAdapter->isVosOutOfResource = VOS_TRUE;
1267 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301268 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001269 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001270 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1271 return VOS_STATUS_E_FAILURE;
1272 }
1273
1274 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1275 as the other branch does.
1276 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301277 spin_lock_bh( &pSapCtx->staInfo_lock );
1278 spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1279 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001280
1281 if (0 == size)
1282 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301283 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1284 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001285 vos_pkt_return_packet(pVosPacket);
1286 return VOS_STATUS_E_EMPTY;
1287 }
1288
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301289 status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1290 spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1291 spin_unlock_bh( &pSapCtx->staInfo_lock );
Jeff Johnson295189b2012-06-20 16:38:30 -07001292
c_hpothu6d1d2a32014-03-18 20:17:03 +05301293 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001294 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001295
1296 if(VOS_STATUS_SUCCESS == status)
1297 {
1298 //If success then we got a valid packet from some AC
1299 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1300 skb = pktNode->skb;
1301 }
1302 else
1303 {
1304 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301305 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001307 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001308 vos_pkt_return_packet(pVosPacket);
1309 return VOS_STATUS_E_FAILURE;
1310 }
1311
1312 //Attach skb to VOS packet.
1313 status = vos_pkt_set_os_packet( pVosPacket, skb );
1314 if (status != VOS_STATUS_SUCCESS)
1315 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301316 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001317 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001318 vos_pkt_return_packet(pVosPacket);
1319 ++pAdapter->stats.tx_dropped;
1320 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1321 kfree_skb(skb);
1322 return VOS_STATUS_E_FAILURE;
1323 }
1324
1325 //Just being paranoid. To be removed later
1326 if(pVosPacket == NULL)
1327 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301328 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001329 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 ++pAdapter->stats.tx_dropped;
1331 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1332 kfree_skb(skb);
1333 return VOS_STATUS_E_FAILURE;
1334 }
1335
1336 //Return VOS packet to TL;
1337 *ppVosPacket = pVosPacket;
1338
1339 //Fill out the meta information needed by TL
1340 //FIXME This timestamp is really the time stamp of wrap_data_packet
1341 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1342 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1343 if ( 1 < size )
1344 {
1345 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1346 }
1347 else
1348 {
1349 pPktMetaInfo->bMorePackets = 0;
1350 }
1351
1352 pPktMetaInfo->ucIsEapol = 0;
1353
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301354 if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
Jeff Johnson295189b2012-06-20 16:38:30 -07001355 {
1356 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1357 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301358 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001359 "%s: VOS packet is EAPOL packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001360 pPktMetaInfo->ucIsEapol = 1;
Nirav Shah4f765af2015-01-21 19:51:30 +05301361 pPktMetaInfo->ucEapolSubType = hdd_FindEapolSubType(pVosPacket);
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 }
1363 }
1364
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301365 if ((NULL != pHddCtx) &&
1366 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001367 {
1368 proto_type = vos_pkt_get_proto_type(skb,
1369 pHddCtx->cfg_ini->gEnableDebugLog);
1370 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1371 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4f765af2015-01-21 19:51:30 +05301373 "SAP TX EAPOL SubType %d",pPktMetaInfo->ucEapolSubType);
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001374 }
1375 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1376 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001378 "SAP TX DHCP");
1379 }
1380 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001381//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001382 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301383 pPktMetaInfo->ac = ac;
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 pPktMetaInfo->ucUP = pktNode->userPriority;
1385 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1386 }
1387
1388 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1389 //Extract the destination address from ethernet frame
1390 pDestMacAddress = (v_MACADDR_t*)skb->data;
1391
1392 // we need 802.3 to 802.11 frame translation
1393 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1394 pPktMetaInfo->ucDisableFrmXtl = 0;
1395 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1396 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1397
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301398 if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001399 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1400 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301401 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001402 "%s: TX queue re-enabled", __func__);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301403 pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001404 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
Mihir Shete5d148f12014-12-16 17:54:49 +05301405 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
1406 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 }
1408
1409 // We're giving the packet to TL so consider it transmitted from
1410 // a statistics perspective. We account for it here instead of
1411 // when the packet is returned for two reasons. First, TL will
1412 // manipulate the skb to the point where the len field is not
1413 // accurate, leading to inaccurate byte counts if we account for
1414 // it later. Second, TL does not provide any feedback as to
1415 // whether or not the packet was successfully sent over the air,
1416 // so the packet counts will be the same regardless of where we
1417 // account for them
1418 pAdapter->stats.tx_bytes += skb->len;
1419 ++pAdapter->stats.tx_packets;
1420 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1421 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05301422 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001423
c_hpothu6d1d2a32014-03-18 20:17:03 +05301424 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001425 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001426
1427 return status;
1428}
1429
1430
1431/**============================================================================
1432 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1433 case where VOS packets are not available at the time of the call to get
1434 packets. This callback function is invoked by VOS when packets are
1435 available.
1436
1437 @param pVosPacket : [in] pointer to VOS packet
1438 @param userData : [in] opaque user data that was passed initially
1439
1440 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1441 : VOS_STATUS_SUCCESS otherwise
1442 =============================================================================*/
1443VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1444 v_VOID_t *userData )
1445{
1446 VOS_STATUS status;
1447 v_SINT_t i = 0;
1448 v_SIZE_t size = 0;
1449 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1450 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301451 v_CONTEXT_t pVosContext = NULL;
1452 ptSapContext pSapCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001453 if(pAdapter == NULL)
1454 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301455 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1456 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001457 return VOS_STATUS_E_FAILURE;
1458 }
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301459 pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1460 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1461 if(pSapCtx == NULL){
1462 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1463 FL("psapCtx is NULL"));
1464 return VOS_STATUS_E_FAULT;
1465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001466 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1467 //situation. Here we will only signal TL that there is a pending data for a STA.
1468 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1469 vos_pkt_return_packet( pVosPacket );
1470
1471 pAdapter->isVosOutOfResource = VOS_FALSE;
1472
1473 // Indicate to TL that there is pending data if a queue is non empty.
1474 // This Code wasnt included in earlier version which resulted in
1475 // Traffic stalling
1476 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1477 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301478 if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1479 (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
Jeff Johnson295189b2012-06-20 16:38:30 -07001480 {
1481 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1482 {
1483 size = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301484 hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size);
Jeff Johnson295189b2012-06-20 16:38:30 -07001485 if ( size > 0 )
1486 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301487 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1488 STAId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001489 (WLANTL_ACEnumType)i );
1490 if( !VOS_IS_STATUS_SUCCESS( status ) )
1491 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301492 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1493 "%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001494 }
1495 }
1496 }
1497 }
1498 }
1499 return VOS_STATUS_SUCCESS;
1500}
1501
1502
1503/**============================================================================
1504 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1505 TL will call this to notify the HDD when one or more packets were
1506 received for a registered STA.
1507
1508 @param vosContext : [in] pointer to VOS context
1509 @param pVosPacketChain : [in] pointer to VOS packet chain
1510 @param staId : [in] Station Id (Adress 1 Index)
1511 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1512
1513 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1514 : VOS_STATUS_SUCCESS otherwise
1515 ===========================================================================*/
1516VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1517 vos_pkt_t *pVosPacketChain,
1518 v_U8_t staId,
1519 WLANTL_RxMetaInfoType* pRxMetaInfo )
1520{
1521 hdd_adapter_t *pAdapter = NULL;
1522 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1523 int rxstat;
1524 struct sk_buff *skb = NULL;
1525 vos_pkt_t* pVosPacket;
1526 vos_pkt_t* pNextVosPacket;
1527 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001528 v_U8_t proto_type;
Nirav Shah4f765af2015-01-21 19:51:30 +05301529 EAPOL_SubType eapolSubType;
Jeff Johnson295189b2012-06-20 16:38:30 -07001530
1531 //Sanity check on inputs
1532 if ( ( NULL == vosContext ) ||
1533 ( NULL == pVosPacketChain ) ||
1534 ( NULL == pRxMetaInfo ) )
1535 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301536 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1537 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001538 return VOS_STATUS_E_FAILURE;
1539 }
1540
1541 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1542 if ( NULL == pHddCtx )
1543 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301544 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1545 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 return VOS_STATUS_E_FAILURE;
1547 }
1548
1549 pAdapter = pHddCtx->sta_to_adapter[staId];
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301550 if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001551 {
Abhishek Singh82a7a5b2014-10-07 13:05:12 +05301552 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1553 "%s: invalid adapter or adapter has invalid magic",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001554 VOS_ASSERT(0);
1555 return VOS_STATUS_E_FAILURE;
1556 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001557
1558 /* Monitor traffic */
1559 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1560 {
1561 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1562 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1563 {
1564 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1565 /* It was IDLE mode,
1566 * this is new state, then switch mode from suspend to resume */
1567 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1568 {
1569 hdd_set_wlan_suspend_mode(0);
1570 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1571 pHddCtx->cfg_ini->trafficIdleTimeout);
1572 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1573 }
1574 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1575 }
1576 }
1577
Jeff Johnson295189b2012-06-20 16:38:30 -07001578 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1579
1580 // walk the chain until all are processed
1581 pVosPacket = pVosPacketChain;
1582 do
1583 {
1584 // get the pointer to the next packet in the chain
1585 // (but don't unlink the packet since we free the entire chain later)
1586 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1587
1588 // both "success" and "empty" are acceptable results
1589 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1590 {
1591 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301592 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1593 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001594 return VOS_STATUS_E_FAILURE;
1595 }
1596
Nirav Shah4f765af2015-01-21 19:51:30 +05301597 if (pHddCtx->cfg_ini->gEnableDebugLog)
1598 {
1599 if(hdd_IsEAPOLPacket(pVosPacket))
1600 eapolSubType = hdd_FindEapolSubType(pVosPacket);
1601 }
1602
Jeff Johnson295189b2012-06-20 16:38:30 -07001603 // Extract the OS packet (skb).
1604 // Tell VOS to detach the OS packet from the VOS packet
1605 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
1606 if(!VOS_IS_STATUS_SUCCESS( status ))
1607 {
1608 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301609 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1610 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 return VOS_STATUS_E_FAILURE;
1612 }
1613
1614 //hdd_softap_dump_sk_buff(skb);
1615
1616 skb->dev = pAdapter->dev;
1617
1618 if(skb->dev == NULL) {
1619
c_hpothu6d1d2a32014-03-18 20:17:03 +05301620 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL,
1621 "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001622 return VOS_STATUS_E_FAILURE;
1623 }
1624 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1625 ++pAdapter->stats.rx_packets;
1626 pAdapter->stats.rx_bytes += skb->len;
1627
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001628 if (pHddCtx->cfg_ini->gEnableDebugLog)
1629 {
1630 proto_type = vos_pkt_get_proto_type(skb,
1631 pHddCtx->cfg_ini->gEnableDebugLog);
1632 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1633 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4f765af2015-01-21 19:51:30 +05301635 "SAP RX EAPOL SubType %d",eapolSubType);
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001636 }
1637 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1638 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001640 "SAP RX DHCP");
1641 }
1642 }
1643
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1645 {
1646 //MC/BC packets. Duplicate a copy of packet
1647 struct sk_buff *pSkbCopy;
1648 hdd_ap_ctx_t *pHddApCtx;
1649
1650 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1651 if (!(pHddApCtx->apDisableIntraBssFwd))
1652 {
1653 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1654 if (pSkbCopy)
1655 {
1656 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1657 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1658 }
1659 }
1660 else
1661 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301662 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001663 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001664 }
1665
1666
1667 } //(WLAN_RX_BCMC_STA_ID == staId)
1668
1669 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1670 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1671 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301672 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001673 "%s: send one packet to kernel", __func__);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05301674 if ((NULL != pHddCtx) &&
1675 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05301676 {
1677 hdd_dump_dhcp_pkt(skb, RX_PATH);
1678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001679
1680 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001681 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001682#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07001683#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07001684 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07001685#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001686#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001687 rxstat = netif_rx_ni(skb);
1688 if (NET_RX_SUCCESS == rxstat)
1689 {
1690 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001691 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 }
1693 else
1694 {
1695 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1696 }
1697 }
1698 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1699 {
1700 kfree_skb(skb);
1701 }
1702 else
1703 {
1704 //loopback traffic
1705 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1706 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1707 }
1708
1709 // now process the next packet in the chain
1710 pVosPacket = pNextVosPacket;
1711
1712 } while (pVosPacket);
1713
1714 //Return the entire VOS packet chain to the resource pool
1715 status = vos_pkt_return_packet( pVosPacketChain );
1716 if(!VOS_IS_STATUS_SUCCESS( status ))
1717 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301718 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1719 "%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001720 }
1721
1722 pAdapter->dev->last_rx = jiffies;
1723
1724 return status;
1725}
1726
1727VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1728{
1729 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301730 hdd_context_t *pHddCtx;
1731 if (NULL == pAdapter)
1732 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301733 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301734 "%s: pAdapter is NULL", __func__);
1735 return VOS_STATUS_E_INVAL;
1736 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001737
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301738 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1739 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301740 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301741 "%s: Invalid pAdapter magic", __func__);
1742 return VOS_STATUS_E_INVAL;
1743 }
1744
1745 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
c_hpothu6d1d2a32014-03-18 20:17:03 +05301746 //Clear station in TL and then update HDD data structures. This helps
Jeff Johnson295189b2012-06-20 16:38:30 -07001747 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301748 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001749 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1750 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301751 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001752 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001753 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001754 staId, vosStatus, vosStatus );
1755 }
1756
1757 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1758 if( VOS_STATUS_E_FAILURE == vosStatus )
1759 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301760 VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001761 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001762 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001763 staId, vosStatus, vosStatus );
1764 return( vosStatus );
1765 }
1766
1767 pHddCtx->sta_to_adapter[staId] = NULL;
1768
1769 return( vosStatus );
1770}
1771
1772VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1773 v_BOOL_t fAuthRequired,
1774 v_BOOL_t fPrivacyBit,
1775 v_U8_t staId,
1776 v_U8_t ucastSig,
1777 v_U8_t bcastSig,
1778 v_MACADDR_t *pPeerMacAddress,
1779 v_BOOL_t fWmmEnabled )
1780{
1781 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001782 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1784 hdd_adapter_t *pmonAdapter = NULL;
1785
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301786 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1787 ptSapContext pSapCtx = NULL;
1788 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1789 if(pSapCtx == NULL){
1790 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1791 FL("psapCtx is NULL"));
1792 return VOS_STATUS_E_FAULT;
1793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001794 //eCsrEncryptionType connectedCipherAlgo;
1795 //v_BOOL_t fConnected;
1796
1797 /*
1798 * Clean up old entry if it is not cleaned up properly
1799 */
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301800 if ( pSapCtx->aStaInfo[staId].isUsed )
Jeff Johnson295189b2012-06-20 16:38:30 -07001801 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301802 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001803 "clean up old entry for STA %d", staId);
1804 hdd_softap_DeregisterSTA( pAdapter, staId );
1805 }
1806
1807 // Get the Station ID from the one saved during the assocation.
1808
1809 staDesc.ucSTAId = staId;
1810
1811
1812 /*Save the pAdapter Pointer for this staId*/
1813 pHddCtx->sta_to_adapter[staId] = pAdapter;
1814
1815 staDesc.wSTAType = WLAN_STA_SOFTAP;
1816
1817 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1818 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1819 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1820
c_hpothu6d1d2a32014-03-18 20:17:03 +05301821 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001822 "register station");
c_hpothu6d1d2a32014-03-18 20:17:03 +05301823 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001824 "station mac " MAC_ADDRESS_STR,
1825 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301826 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001827 "BSSIDforIBSS " MAC_ADDRESS_STR,
1828 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
c_hpothu6d1d2a32014-03-18 20:17:03 +05301829 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001830 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1831 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001832
1833 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1834
Jeff Johnson295189b2012-06-20 16:38:30 -07001835 staDesc.ucQosEnabled = fWmmEnabled;
c_hpothu6d1d2a32014-03-18 20:17:03 +05301836 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07001837 "HDD SOFTAP register TL QoS_enabled=%d",
1838 staDesc.ucQosEnabled );
1839
1840 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1841
1842
Jeff Johnson295189b2012-06-20 16:38:30 -07001843 // For PRIMA UMA frame translation is not enable yet.
1844 staDesc.ucSwFrameTXXlation = 1;
1845 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001846 staDesc.ucAddRmvLLC = 1;
1847
1848 // Initialize signatures and state
1849 staDesc.ucUcastSig = ucastSig;
1850 staDesc.ucBcastSig = bcastSig;
1851 staDesc.ucInitState = fAuthRequired ?
1852 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1853
Prathyushaf5442802012-12-12 13:58:11 -08001854 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1855
Jeff Johnson295189b2012-06-20 16:38:30 -07001856 // Register the Station with TL...
c_hpothu6d1d2a32014-03-18 20:17:03 +05301857 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1858 hdd_softap_rx_packet_cbk,
1859 hdd_softap_tx_complete_cbk,
Jeff Johnson295189b2012-06-20 16:38:30 -07001860 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1861
1862 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1863 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301864 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001865 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001866 vosStatus, vosStatus );
1867 return vosStatus;
1868 }
1869
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001870 //Timer value should be in milliseconds
1871 if ( pHddCtx->cfg_ini->dynSplitscan &&
1872 ( VOS_TIMER_STATE_RUNNING !=
1873 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1874 {
1875 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1876 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1877 }
1878
Jeff Johnson295189b2012-06-20 16:38:30 -07001879 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1880 // then go to 'authenticated'. For all other authentication types (those that do
1881 // not require upper layer authentication) we can put TL directly into 'authenticated'
1882 // state.
1883
1884 //VOS_ASSERT( fConnected );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301885 pSapCtx->aStaInfo[staId].ucSTAId = staId;
1886 pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001887 if ( !fAuthRequired )
1888 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301889 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
1890 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301891 pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001892
1893 // Connections that do not need Upper layer auth, transition TL directly
1894 // to 'Authenticated' state.
1895 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1896 WLANTL_STA_AUTHENTICATED );
1897
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301898 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001899 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1900 }
1901 else
1902 {
1903
c_hpothu6d1d2a32014-03-18 20:17:03 +05301904 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301905 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001906
1907 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1908 WLANTL_STA_CONNECTED );
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301909 pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
Jeff Johnson295189b2012-06-20 16:38:30 -07001910
1911 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1912
1913 }
1914 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1915 if(pmonAdapter)
1916 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301917 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
1918 "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 netif_carrier_on(pmonAdapter->dev);
1920 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 netif_tx_start_all_queues(pmonAdapter->dev);
1923 }
1924 netif_carrier_on(pAdapter->dev);
1925 //Enable Tx queue
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05301926 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001927 netif_tx_start_all_queues(pAdapter->dev);
1928
1929 return( vosStatus );
1930}
1931
1932VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1933{
1934 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1935 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1936 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1937
1938
1939 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1940 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1941 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1942
1943 return vosStatus;
1944}
1945
1946VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1947{
1948 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1949}
1950
1951VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1952{
1953 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1954 v_U8_t staId = 0;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301955 hdd_context_t *pHddCtx;
Wilson Yangf80a0542013-10-07 13:02:37 -07001956
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301957 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
1958 ptSapContext pSapCtx = NULL;
1959 pSapCtx = VOS_GET_SAP_CB(pVosContext);
1960 if(pSapCtx == NULL){
1961 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1962 FL("psapCtx is NULL"));
1963 return VOS_STATUS_E_FAULT;
1964 }
1965
1966 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Wilson Yangf80a0542013-10-07 13:02:37 -07001967 /*bss deregister is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05301968 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07001969 {
1970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1971 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
1972 return VOS_STATUS_E_PERM;
1973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001974
1975 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
1976
Jeff Johnson43971f52012-07-17 12:26:56 -07001977 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301979 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001980 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 }
1982
1983 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
1984 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05301985 if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
Jeff Johnson295189b2012-06-20 16:38:30 -07001986 {
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301987 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
1988 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1989 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05301990 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001991 "%s: Failed to deregister sta Id %d", __func__, staId);
Hanumantha Reddy Pothulac7100902013-12-28 18:17:36 +05301992 }
1993 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 }
1995
1996 return vosStatus;
1997}
1998
1999VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
2000{
2001 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
2002 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2003 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07002004
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302005 ptSapContext pSapCtx = NULL;
2006 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2007 if(pSapCtx == NULL){
2008 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2009 FL("psapCtx is NULL"));
2010 return VOS_STATUS_E_FAULT;
2011 }
c_hpothu6d1d2a32014-03-18 20:17:03 +05302012 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002013 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002014
Jeff Johnson43971f52012-07-17 12:26:56 -07002015 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07002016 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302017 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002018 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 return VOS_STATUS_E_FAILURE;
2020 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002021
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302022 if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 {
c_hpothu6d1d2a32014-03-18 20:17:03 +05302024 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002025 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 return VOS_STATUS_E_FAILURE;
2027 }
2028
2029 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
c_hpothu6d1d2a32014-03-18 20:17:03 +05302030 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002031 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07002032
Jeff Johnson43971f52012-07-17 12:26:56 -07002033 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302035 pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
Jeff Johnson295189b2012-06-20 16:38:30 -07002036 }
2037
c_hpothu6d1d2a32014-03-18 20:17:03 +05302038 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002039 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002040
2041 return vosStatus;
2042}
2043
2044
2045VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
2046{
2047 v_U8_t i;
2048
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302049 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2050 ptSapContext pSapCtx = NULL;
2051 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2052 if(pSapCtx == NULL){
2053 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2054 FL("psapCtx is NULL"));
2055 return VOS_STATUS_E_FAULT;
2056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2058 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302059 if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
2060 pSapCtx->aStaInfo[i].isUsed)
Jeff Johnson295189b2012-06-20 16:38:30 -07002061 {
2062 *staId = i;
2063 return VOS_STATUS_SUCCESS;
2064 }
2065 }
2066
2067 return VOS_STATUS_E_FAILURE;
2068}
2069
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302070VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
2071{
2072 v_U8_t i;
2073
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302074 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2075 ptSapContext pSapCtx = NULL;
2076 pSapCtx = VOS_GET_SAP_CB(pVosContext);
2077 if(pSapCtx == NULL){
2078 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
2079 FL("psapCtx is NULL"));
2080 return VOS_STATUS_E_FAULT;
2081 }
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302082 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
2083 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302084 if (pSapCtx->aStaInfo[i].isUsed &&
2085 (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05302086 {
2087 *staId = i;
2088 return VOS_STATUS_SUCCESS;
2089 }
2090 }
2091
2092 return VOS_STATUS_E_FAILURE;
2093}