blob: 016e6423b627eada2af11f8fd5b0dca6103bb6dd [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
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
Kiet Lamaa8e15a2014-02-11 23:30:06 -080033 Copyright 2008 (c) Qualcomm, Incorporated.
34 All Rights Reserved.
35 Qualcomm Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070036
37 ==========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070038
39/*---------------------------------------------------------------------------
40 Include files
41 -------------------------------------------------------------------------*/
42#include <linux/semaphore.h>
43#include <wlan_hdd_tx_rx.h>
44#include <wlan_hdd_softap_tx_rx.h>
45#include <wlan_hdd_dp_utils.h>
46#include <wlan_qct_tl.h>
47#include <linux/netdevice.h>
48#include <linux/skbuff.h>
49#include <linux/etherdevice.h>
50//#include <vos_list.h>
51#include <vos_types.h>
52#include <aniGlobal.h>
53#include <halTypes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070054#include <net/ieee80211_radiotap.h>
55
56
57/*---------------------------------------------------------------------------
58 Preprocessor definitions and constants
59 -------------------------------------------------------------------------*/
60
61/*---------------------------------------------------------------------------
62 Type declarations
63 -------------------------------------------------------------------------*/
64
65/*---------------------------------------------------------------------------
66 Function definitions and documenation
67 -------------------------------------------------------------------------*/
68#if 0
69static void hdd_softap_dump_sk_buff(struct sk_buff * skb)
70{
Arif Hussain6d2a3322013-11-17 19:50:10 -080071 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head);
72 //VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data);
73 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail);
74 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end);
75 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
76 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
77 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070078
Arif Hussain6d2a3322013-11-17 19:50:10 -080079 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, 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 -070080 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
81 skb->data[5], skb->data[6], skb->data[7]);
Arif Hussain6d2a3322013-11-17 19:50:10 -080082 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, 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 -070083 skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
84 skb->data[13], skb->data[14], skb->data[15]);
85}
86#endif
Leo Chang64d68bc2013-06-04 15:40:52 -070087
88extern void hdd_set_wlan_suspend_mode(bool suspend);
89
90/**============================================================================
91 @brief hdd_softap_traffic_monitor_timeout_handler() -
92 SAP/P2P GO traffin monitor timeout handler function
93 If no traffic during programmed time, trigger suspand mode
94
95 @param pUsrData : [in] pointer to hdd context
96 @return : NONE
97 ===========================================================================*/
98void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData )
99{
100 hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData;
101 v_TIME_t currentTS;
102
103 if (NULL == pHddCtx)
104 {
105 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
106 "%s: Invalid user data, context", __func__);
107 return;
108 }
109
110 currentTS = vos_timer_get_system_time();
111 if (pHddCtx->cfg_ini->trafficIdleTimeout <
112 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
113 {
Kiet Lambcf38522013-10-26 18:28:27 +0530114 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
115 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -0700116 hdd_set_wlan_suspend_mode(1);
117 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
118 }
119 else
120 {
121 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
122 pHddCtx->cfg_ini->trafficIdleTimeout);
123 }
124
125 return;
126}
127
Kiet Lambcf38522013-10-26 18:28:27 +0530128VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter )
129{
130
131 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
132 VOS_STATUS status = VOS_STATUS_SUCCESS;
133
134 status = wlan_hdd_validate_context(pHddCtx);
135
136 if (0 != status)
137 {
138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
139 "%s: HDD context is not valid", __func__);
140 return status;
141 }
142
143 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
144 (!pHddCtx->traffic_monitor.isInitialized))
145 {
146 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
147 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
148 VOS_TIMER_TYPE_SW,
149 hdd_softap_traffic_monitor_timeout_handler,
150 pHddCtx);
151 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
152 pHddCtx->traffic_monitor.isInitialized = 1;
153 pHddCtx->traffic_monitor.lastFrameTs = 0;
154 /* Start traffic monitor timer here
155 * If no AP assoc, immediatly go into suspend */
156 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
157 "%s Start Traffic Monitor Timer", __func__);
158 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
159 pHddCtx->cfg_ini->trafficIdleTimeout);
160 }
161 else
162 {
163 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
164 "%s Traffic Monitor is not Enable in ini file", __func__);
165 }
166 return status;
167}
168
169VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter )
170{
171 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
172 VOS_STATUS status = VOS_STATUS_SUCCESS;
173
174 status = wlan_hdd_validate_context(pHddCtx);
175
Kiet Lamae69d7a2013-11-08 14:38:04 +0530176 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530177 {
178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
179 "%s: HDD context is not valid", __func__);
180 return status;
181 }
182
183 if (pHddCtx->traffic_monitor.isInitialized)
184 {
185 if (VOS_TIMER_STATE_STOPPED !=
186 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
187 {
188 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
189 "%s Stop Traffic Monitor Timer", __func__);
190 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
191 }
192 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
193 "%s Destroy Traffic Monitor Timer", __func__);
194 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
195 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
196 pHddCtx->traffic_monitor.isInitialized = 0;
197 }
Kiet Lamae69d7a2013-11-08 14:38:04 +0530198 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530199}
200
Jeff Johnson295189b2012-06-20 16:38:30 -0700201/**============================================================================
202 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
203
204 @param pAdapter : [in] pointer to adapter context
205 @return : VOS_STATUS_E_FAILURE if any errors encountered
206 : VOS_STATUS_SUCCESS otherwise
207 ===========================================================================*/
208static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
209{
210 VOS_STATUS status = VOS_STATUS_SUCCESS;
211 v_SINT_t i = -1;
212 v_U8_t STAId = 0;
213 hdd_list_node_t *anchor = NULL;
214 skb_list_node_t *pktNode = NULL;
215 struct sk_buff *skb = NULL;
216
217 spin_lock_bh( &pAdapter->staInfo_lock );
218 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
219 {
220 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
221 {
222 continue;
223 }
224
225 for (i = 0; i < NUM_TX_QUEUES; i ++)
226 {
227 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
228 while (true)
229 {
230 status = hdd_list_remove_front ( &pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
231
232 if (VOS_STATUS_E_EMPTY != status)
233 {
234 //If success then we got a valid packet from some AC
235 pktNode = list_entry(anchor, skb_list_node_t, anchor);
236 skb = pktNode->skb;
237 ++pAdapter->stats.tx_dropped;
238 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
239 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
240 kfree_skb(skb);
241 continue;
242 }
243
244 //current list is empty
245 break;
246 }
247 pAdapter->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
248 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
249 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530250 pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700251 }
252
253 spin_unlock_bh( &pAdapter->staInfo_lock );
254
255 return status;
256}
257
258/**============================================================================
259 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
260 transmitting packets. There are 2 versions of this function. One that uses
261 locked queue and other that uses lockless queues. Both have been retained to
262 do some performance testing
263
264 @param skb : [in] pointer to OS packet (sk_buff)
265 @param dev : [in] pointer to Libra network device
266
267 @return : NET_XMIT_DROP if packets are dropped
268 : NET_XMIT_SUCCESS if packet is enqueued succesfully
269 ===========================================================================*/
270int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
271{
272 VOS_STATUS status;
273 WLANTL_ACEnumType ac = WLANTL_AC_BE;
274 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
275 skb_list_node_t *pktNode = NULL;
276 v_SIZE_t pktListSize = 0;
277 v_BOOL_t txSuspended = VOS_FALSE;
278 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
279 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
280 vos_list_node_t *anchor = NULL;
281 v_U8_t STAId = WLAN_MAX_STA_COUNT;
282 //Extract the destination address from ethernet frame
283 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
284 int os_status = NETDEV_TX_OK;
285
286 pDestMacAddress = (v_MACADDR_t*)skb->data;
287
288 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
289
290 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700291 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700292
293 spin_lock_bh( &pAdapter->staInfo_lock );
294 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
295 {
296 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
297 //ID used for BC/MC traffic. The station id is registered to TL as well.
298 STAId = pHddApCtx->uBCStaId;
299
300 /* Setting priority for broadcast packets which doesn't go to select_queue function */
301 skb->priority = SME_QOS_WMM_UP_BE;
302 skb->queue_mapping = HDD_LINUX_AC_BE;
303
304 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800305 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 }
307 else
308 {
309 STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
310 if (STAId == HDD_WLAN_INVALID_STA_ID)
311 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700312 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700313 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 ++pAdapter->stats.tx_dropped;
315 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
316 kfree_skb(skb);
317 goto xmit_done;
318 }
319 else if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
320 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530321 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,"%s: STA %d is unregistered", __func__, STAId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 ++pAdapter->stats.tx_dropped;
323 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
324 kfree_skb(skb);
325 goto xmit_done;
326 }
327
328 if ( (WLANTL_STA_CONNECTED != pAdapter->aStaInfo[STAId].tlSTAState) &&
329 (WLANTL_STA_AUTHENTICATED != pAdapter->aStaInfo[STAId].tlSTAState) )
330 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700331 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700332 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 ++pAdapter->stats.tx_dropped;
334 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
335 kfree_skb(skb);
336 goto xmit_done;
337 }
338 else if(WLANTL_STA_CONNECTED == pAdapter->aStaInfo[STAId].tlSTAState)
339 {
340 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
341 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700342 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700343 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700344 ++pAdapter->stats.tx_dropped;
345 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
346 kfree_skb(skb);
347 goto xmit_done;
348 }
349 }
350 }
351
352 //Get TL AC corresponding to Qdisc queue index/AC.
353 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
354 //user priority from IP header, which is already extracted and set from
355 //select_queue call back function
356 up = skb->priority;
357 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
358
359 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700360 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361
362 // If the memory differentiation mode is enabled, the memory limit of each queue will be
363 // checked. Over-limit packets will be dropped.
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700364 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
366 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
367 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700368 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800369 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 pAdapter->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
371 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
372 txSuspended = VOS_TRUE;
373 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530374
375 /* If 3/4th of the max queue size is used then enable the flag.
376 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
377 if (WLANTL_AC_BE == ac)
378 {
379 if (pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
380 {
381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
382 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
383 pAdapter->aStaInfo[STAId].vosLowResource = VOS_TRUE;
384 }
385 else
386 {
387 pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
388 }
389 }
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700390 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700391
392 if (VOS_TRUE == txSuspended)
393 {
394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
395 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700396 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700397 os_status = NETDEV_TX_BUSY;
398 goto xmit_done;
399 }
400
401 //Use the skb->cb field to hold the list node information
402 pktNode = (skb_list_node_t *)&skb->cb;
403
404 //Stick the OS packet inside this node.
405 pktNode->skb = skb;
406
407 //Stick the User Priority inside this node
408 pktNode->userPriority = up;
409
410 INIT_LIST_HEAD(&pktNode->anchor);
411
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700412 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700413 status = hdd_list_insert_back_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700414 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700415
416 if ( !VOS_IS_STATUS_SUCCESS( status ) )
417 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700418 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,"%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700419 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
420 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
421 ++pAdapter->stats.tx_dropped;
422 kfree_skb(skb);
423 goto xmit_done;
424 }
425
426 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
427 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530428 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700429
430 if (1 == pktListSize)
431 {
432 //Let TL know we have a packet to send for this AC
433 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
434
435 if ( !VOS_IS_STATUS_SUCCESS( status ) )
436 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700437 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN, "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700438 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700439
440 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
441 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
442 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
443 status = hdd_list_remove_back( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
444 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
445 ++pAdapter->stats.tx_dropped;
446 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
447 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
448 kfree_skb(skb);
449 goto xmit_done;
450 }
451 }
452 dev->trans_start = jiffies;
453
Arif Hussain6d2a3322013-11-17 19:50:10 -0800454 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700455
456xmit_done:
457 spin_unlock_bh( &pAdapter->staInfo_lock );
458 return os_status;
459}
460
461/**============================================================================
462 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
463
464 @param skb : [in] pointer to packet (sk_buff)
465 @param dev : [in] pointer to Libra network device
466 @param STAId : [in] Station Id of Destination Station
467 @param up : [in] User Priority
468
469 @return : NET_XMIT_DROP if packets are dropped
470 : NET_XMIT_SUCCESS if packet is enqueued succesfully
471 ===========================================================================*/
472VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
473 struct net_device *dev,
474 v_U8_t STAId,
475 v_U8_t up)
476{
477 VOS_STATUS status = VOS_STATUS_SUCCESS;
478 skb_list_node_t *pktNode = NULL;
479 v_SIZE_t pktListSize = 0;
480 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
481 v_U8_t ac;
482 vos_list_node_t *anchor = NULL;
483
484 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
485
486 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700487 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700488
489 spin_lock_bh( &pAdapter->staInfo_lock );
490 if ( FALSE == pAdapter->aStaInfo[STAId].isUsed )
491 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700492 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530493 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700494 kfree_skb(skb);
495 status = VOS_STATUS_E_FAILURE;
496 goto xmit_end;
497 }
498
499 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
500 if ( !pAdapter->aStaInfo[STAId].isQosEnabled )
501 up = SME_QOS_WMM_UP_BE;
502
503 ac = hddWmmUpToAcMap[up];
504 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
505 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700506 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700507
508 skb->queue_mapping = hddLinuxUpToAcMap[up];
509
510 //Use the skb->cb field to hold the list node information
511 pktNode = (skb_list_node_t *)&skb->cb;
512
513 //Stick the OS packet inside this node.
514 pktNode->skb = skb;
515
516 //Stick the User Priority inside this node
517 pktNode->userPriority = up;
518
519 INIT_LIST_HEAD(&pktNode->anchor);
520
521 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
522 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
523 if(pAdapter->aStaInfo[STAId].txSuspended[ac] ||
524 pktListSize >= pAdapter->aTxQueueLimit[ac])
525 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700526 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800527 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700528 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
529 * SUSPEND should be done based on Threshold. RESUME would be
530 * triggered in fetch cbk after recovery.
531 */
532 kfree_skb(skb);
533 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
534 status = VOS_STATUS_E_FAILURE;
535 goto xmit_end;
536 }
537 status = hdd_list_insert_back_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
538 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
539
540 if ( !VOS_IS_STATUS_SUCCESS( status ) )
541 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700542 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,"%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700543 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
544 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
545 ++pAdapter->stats.tx_dropped;
546 kfree_skb(skb);
547 status = VOS_STATUS_E_FAILURE;
548 goto xmit_end;
549 }
550
551 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
552 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
553
554 if (1 == pktListSize)
555 {
556 //Let TL know we have a packet to send for this AC
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700557 //VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700558 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
559
560 if ( !VOS_IS_STATUS_SUCCESS( status ) )
561 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700562 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN, "%s: Failed to signal TL for AC=%d STAId =%d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700563 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700564
565 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
566 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
567 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
568 status = hdd_list_remove_back( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
569 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
570 ++pAdapter->stats.tx_dropped;
571 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
572 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
573 kfree_skb(skb);
574 status = VOS_STATUS_E_FAILURE;
575 goto xmit_end;
576 }
577 }
578
Arif Hussain6d2a3322013-11-17 19:50:10 -0800579 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700580
581xmit_end:
582 spin_unlock_bh( &pAdapter->staInfo_lock );
583 return status;
584}
585
586/**============================================================================
587 @brief hdd_softap_tx_timeout() - Function called by OS if there is any
588 timeout during transmission. Since HDD simply enqueues packet
589 and returns control to OS right away, this would never be invoked
590
591 @param dev : [in] pointer to Libra network device
592 @return : None
593 ===========================================================================*/
594void hdd_softap_tx_timeout(struct net_device *dev)
595{
596 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700597 "%s: Transmission timeout occurred", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 //Getting here implies we disabled the TX queues for too long. Queues are
599 //disabled either because of disassociation or low resource scenarios. In
600 //case of disassociation it is ok to ignore this. But if associated, we have
601 //do possible recovery here
602}
603
604
605/**============================================================================
606 @brief hdd_softap_stats() - Function registered with the Linux OS for
607 device TX/RX statistic
608
609 @param dev : [in] pointer to Libra network device
610
611 @return : pointer to net_device_stats structure
612 ===========================================================================*/
613struct net_device_stats* hdd_softap_stats(struct net_device *dev)
614{
615 hdd_adapter_t* priv = netdev_priv(dev);
616 return &priv->stats;
617}
618
619
620/**============================================================================
621 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
622 modules in HDD
623
624 @param pAdapter : [in] pointer to adapter context
625 @return : VOS_STATUS_E_FAILURE if any errors encountered
626 : VOS_STATUS_SUCCESS otherwise
627 ===========================================================================*/
628VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
629{
630 VOS_STATUS status = VOS_STATUS_SUCCESS;
631 v_SINT_t i = -1;
632 v_SIZE_t size = 0;
633
634 v_U8_t STAId = 0;
635
636 v_U8_t pACWeights[] = {
637 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
638 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
639 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
640 HDD_SOFTAP_VO_WEIGHT_DEFAULT
641 };
Leo Chang64d68bc2013-06-04 15:40:52 -0700642
Jeff Johnson295189b2012-06-20 16:38:30 -0700643 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530644 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700645
646 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
647
648 while (++i != NUM_TX_QUEUES)
649 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
650
651 /* Initial HDD buffer control / flow control fields*/
652 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
653
654 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
655 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
656 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
657 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
658
659 spin_lock_init( &pAdapter->staInfo_lock );
660
661 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
662 {
663 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
664 for (i = 0; i < NUM_TX_QUEUES; i ++)
665 {
666 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
667 }
668 }
669
Yue Ma3ede6052013-08-29 00:33:26 -0700670 /* Update the AC weights suitable for SoftAP mode of operation */
671 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
672
Kiet Lambcf38522013-10-26 18:28:27 +0530673 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700674 {
Kiet Lambcf38522013-10-26 18:28:27 +0530675 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
676 "%s: failed to start Traffic Monito timer ", __func__ );
677 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700678 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700679 return status;
680}
681
682/**============================================================================
683 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
684 modules in HDD
685
686 @param pAdapter : [in] pointer to adapter context
687 @return : VOS_STATUS_E_FAILURE if any errors encountered
688 : VOS_STATUS_SUCCESS otherwise
689 ===========================================================================*/
690VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
691{
692 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700693
Kiet Lambcf38522013-10-26 18:28:27 +0530694 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700695 {
Kiet Lambcf38522013-10-26 18:28:27 +0530696 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
697 "%s: Fail to Stop Traffic Monito timer", __func__ );
698 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700699 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700700
701 status = hdd_softap_flush_tx_queues(pAdapter);
702
703 return status;
704}
705
706/**============================================================================
707 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
708
709 @param pAdapter : [in] pointer to adapter context
710 @param STAId : [in] Station ID to deinit
711 @return : VOS_STATUS_E_FAILURE if any errors encountered
712 : VOS_STATUS_SUCCESS otherwise
713 ===========================================================================*/
714static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
715{
716 VOS_STATUS status = VOS_STATUS_SUCCESS;
717 v_U8_t i = -1;
718
719 hdd_list_node_t *anchor = NULL;
720
721 skb_list_node_t *pktNode = NULL;
722 struct sk_buff *skb = NULL;
723
724 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
725 {
726 return status;
727 }
728
729 for (i = 0; i < NUM_TX_QUEUES; i ++)
730 {
731 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
732 while (true)
733 {
734 status = hdd_list_remove_front ( &pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
735 if (VOS_STATUS_E_EMPTY != status)
736 {
737 //If success then we got a valid packet from some AC
738 pktNode = list_entry(anchor, skb_list_node_t, anchor);
739 skb = pktNode->skb;
740 ++pAdapter->stats.tx_dropped;
741 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
742 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
743 kfree_skb(skb);
744 continue;
745 }
746
747 //current list is empty
748 break;
749 }
750 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
751 }
752
753 return status;
754}
755
756/**============================================================================
757 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
758 modules in HDD
759
760 @param pAdapter : [in] pointer to adapter context
761 @param STAId : [in] Station ID to deinit
762 @param pmacAddrSTA : [in] pointer to the MAC address of the station
763 @return : VOS_STATUS_E_FAILURE if any errors encountered
764 : VOS_STATUS_SUCCESS otherwise
765 ===========================================================================*/
766VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
767{
768 v_U8_t i = 0;
769 spin_lock_bh( &pAdapter->staInfo_lock );
770 if (pAdapter->aStaInfo[STAId].isUsed)
771 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700772 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR, "%s: Reinit station %d", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700773 spin_unlock_bh( &pAdapter->staInfo_lock );
774 return VOS_STATUS_E_FAILURE;
775 }
776
777 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
778 for (i = 0; i < NUM_TX_QUEUES; i ++)
779 {
780 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
781 }
782
783 pAdapter->aStaInfo[STAId].isUsed = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800784 pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 vos_copy_macaddr( &pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
786
787 spin_unlock_bh( &pAdapter->staInfo_lock );
788 return VOS_STATUS_SUCCESS;
789}
790
791/**============================================================================
792 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
793 modules in HDD
794
795 @param pAdapter : [in] pointer to adapter context
796 @param STAId : [in] Station ID to deinit
797 @return : VOS_STATUS_E_FAILURE if any errors encountered
798 : VOS_STATUS_SUCCESS otherwise
799 ===========================================================================*/
800VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
801{
802 VOS_STATUS status = VOS_STATUS_SUCCESS;
803 v_U8_t ac;
804 /**Track whether OS TX queue has been disabled.*/
805 v_BOOL_t txSuspended[NUM_TX_QUEUES];
806 v_U8_t tlAC;
807 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700808 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -0700809
810 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
811
812 spin_lock_bh( &pAdapter->staInfo_lock );
813 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
814 {
815 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700816 "%s: Deinit station not inited %d", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700817 spin_unlock_bh( &pAdapter->staInfo_lock );
818 return VOS_STATUS_E_FAILURE;
819 }
820
821 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
822
823 pAdapter->aStaInfo[STAId].isUsed = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800824 pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700825
826 /* if this STA had any of its WMM TX queues suspended, then the
827 associated queue on the network interface was disabled. check
828 to see if that is the case, in which case we need to re-enable
829 the interface queue. but we only do this if the BSS is running
830 since, if the BSS is stopped, all of the interfaces have been
831 stopped and should not be re-enabled */
832
833 if (BSS_START == pHostapdState->bssState)
834 {
835 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
836 {
837 tlAC = hdd_QdiscAcToTlAC[ac];
838 txSuspended[ac] = pAdapter->aStaInfo[STAId].txSuspended[tlAC];
839 }
840 }
841 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
842
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700843 /* re-init spin lock, since netdev can still open adapter until
844 * driver gets unloaded
845 */
846 for (i = 0; i < NUM_TX_QUEUES; i ++)
847 {
848 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i],
849 HDD_TX_QUEUE_MAX_LEN);
850 }
851
Jeff Johnson295189b2012-06-20 16:38:30 -0700852 if (BSS_START == pHostapdState->bssState)
853 {
854 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
855 {
856 if (txSuspended[ac])
857 {
858 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700859 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700860 netif_wake_subqueue(pAdapter->dev, ac);
861 }
862 }
863 }
864
865 spin_unlock_bh( &pAdapter->staInfo_lock );
866 return status;
867}
868
869/**============================================================================
870 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
871 modules in HDD
872
873 @param pAdapter : [in] pointer to adapter context
874 @return : VOS_STATUS_E_FAILURE if any errors encountered
875 : VOS_STATUS_SUCCESS otherwise
876 ===========================================================================*/
877VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
878{
879 return hdd_softap_flush_tx_queues(pAdapter);
880}
881
882/**============================================================================
883 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
884 to indicate that a packet has been transmitted across the bus
885 succesfully. OS packet resources can be released after this cbk.
886
887 @param vosContext : [in] pointer to VOS context
888 @param pVosPacket : [in] pointer to VOS packet (containing skb)
889 @param vosStatusIn : [in] status of the transmission
890
891 @return : VOS_STATUS_E_FAILURE if any errors encountered
892 : VOS_STATUS_SUCCESS otherwise
893 ===========================================================================*/
894VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
895 vos_pkt_t *pVosPacket,
896 VOS_STATUS vosStatusIn )
897{
898 VOS_STATUS status = VOS_STATUS_SUCCESS;
899 hdd_adapter_t *pAdapter = NULL;
900 void* pOsPkt = NULL;
901
902 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
903 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700904 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700905 return VOS_STATUS_E_FAILURE;
906 }
907
908 //Return the skb to the OS
909 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -0800910 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -0700911 {
912 //This is bad but still try to free the VOSS resources if we can
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700913 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700914 vos_pkt_return_packet( pVosPacket );
915 return VOS_STATUS_E_FAILURE;
916 }
917
918 //Get the Adapter context.
919 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
920 if(pAdapter == NULL)
921 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700922 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 }
924 else
925 {
926 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
927 }
928
929 kfree_skb((struct sk_buff *)pOsPkt);
930
931 //Return the VOS packet resources.
932 status = vos_pkt_return_packet( pVosPacket );
933 if(!VOS_IS_STATUS_SUCCESS( status ))
934 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700935 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 }
937
938 return status;
939}
940
941
942/**============================================================================
943 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
944 fetch a packet for transmission.
945
946 @param vosContext : [in] pointer to VOS context
947 @param staId : [in] Station for which TL is requesting a pkt
948 @param ac : [in] access category requested by TL
949 @param pVosPacket : [out] pointer to VOS packet packet pointer
950 @param pPktMetaInfo : [out] pointer to meta info for the pkt
951
952 @return : VOS_STATUS_E_EMPTY if no packets to transmit
953 : VOS_STATUS_E_FAILURE if any errors encountered
954 : VOS_STATUS_SUCCESS otherwise
955 ===========================================================================*/
956VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
957 v_U8_t *pStaId,
958 WLANTL_ACEnumType ac,
959 vos_pkt_t **ppVosPacket,
960 WLANTL_MetaInfoType *pPktMetaInfo )
961{
962 VOS_STATUS status = VOS_STATUS_E_FAILURE;
963 hdd_adapter_t *pAdapter = NULL;
964 hdd_list_node_t *anchor = NULL;
965 skb_list_node_t *pktNode = NULL;
966 struct sk_buff *skb = NULL;
967 vos_pkt_t *pVosPacket = NULL;
968 v_MACADDR_t* pDestMacAddress = NULL;
969 v_TIME_t timestamp;
970 v_SIZE_t size = 0;
971 v_U8_t STAId = WLAN_MAX_STA_COUNT;
972 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -0800973 v_U8_t proto_type = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700974
975 //Sanity check on inputs
976 if ( ( NULL == vosContext ) ||
977 ( NULL == pStaId ) ||
978 ( NULL == ppVosPacket ) ||
979 ( NULL == pPktMetaInfo ) )
980 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700981 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 return VOS_STATUS_E_FAILURE;
983 }
984
985 //Get the HDD context.
986 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
987 if ( NULL == pHddCtx )
988 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700989 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 return VOS_STATUS_E_FAILURE;
991 }
992
Jeff Johnsonb156c922013-12-05 17:19:46 -0800993 STAId = *pStaId;
994 if (STAId >= WLAN_MAX_STA_COUNT)
995 {
996 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
997 "%s: Invalid STAId %d passed by TL", __func__, STAId);
998 return VOS_STATUS_E_FAILURE;
999 }
1000
1001 pAdapter = pHddCtx->sta_to_adapter[STAId];
1002 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 {
1004 VOS_ASSERT(0);
1005 return VOS_STATUS_E_FAILURE;
1006 }
1007
Jeff Johnsonb156c922013-12-05 17:19:46 -08001008 if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
1009 {
1010 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1011 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1012 return VOS_STATUS_E_FAILURE;
1013 }
1014
Leo Chang64d68bc2013-06-04 15:40:52 -07001015 /* Monitor traffic */
1016 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1017 {
1018 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1019 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1020 {
1021 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1022 /* It was IDLE mode,
1023 * this is new state, then switch mode from suspend to resume */
1024 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1025 {
1026 hdd_set_wlan_suspend_mode(0);
1027 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1028 pHddCtx->cfg_ini->trafficIdleTimeout);
1029 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1030 }
1031 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1032 }
1033 }
1034
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1036
Jeff Johnson295189b2012-06-20 16:38:30 -07001037 *ppVosPacket = NULL;
1038
1039 //Make sure the AC being asked for is sane
1040 if( ac > WLANTL_MAX_AC || ac < 0)
1041 {
1042 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001043 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001044 return VOS_STATUS_E_FAILURE;
1045 }
1046
1047 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1048
1049 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001050 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001051
1052 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1053 //This simplifies the locking and unlocking of Tx queue
1054 status = vos_pkt_wrap_data_packet( &pVosPacket,
1055 VOS_PKT_TYPE_TX_802_3_DATA,
1056 NULL, //OS Pkt is not being passed
1057 hdd_softap_tx_low_resource_cbk,
1058 pAdapter );
1059
1060 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1061 {
1062 //Remember VOS is in a low resource situation
1063 pAdapter->isVosOutOfResource = VOS_TRUE;
1064 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
1065 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001066 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1068 return VOS_STATUS_E_FAILURE;
1069 }
1070
1071 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1072 as the other branch does.
1073 */
1074 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1075 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &size);
1076
1077 if (0 == size)
1078 {
1079 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1080 vos_pkt_return_packet(pVosPacket);
1081 return VOS_STATUS_E_EMPTY;
1082 }
1083
1084 status = hdd_list_remove_front( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1085 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1086
1087 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001088 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001089
1090 if(VOS_STATUS_SUCCESS == status)
1091 {
1092 //If success then we got a valid packet from some AC
1093 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1094 skb = pktNode->skb;
1095 }
1096 else
1097 {
1098 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1099 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1100 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001101 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001102 vos_pkt_return_packet(pVosPacket);
1103 return VOS_STATUS_E_FAILURE;
1104 }
1105
1106 //Attach skb to VOS packet.
1107 status = vos_pkt_set_os_packet( pVosPacket, skb );
1108 if (status != VOS_STATUS_SUCCESS)
1109 {
1110 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001111 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 vos_pkt_return_packet(pVosPacket);
1113 ++pAdapter->stats.tx_dropped;
1114 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1115 kfree_skb(skb);
1116 return VOS_STATUS_E_FAILURE;
1117 }
1118
1119 //Just being paranoid. To be removed later
1120 if(pVosPacket == NULL)
1121 {
1122 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001123 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001124 ++pAdapter->stats.tx_dropped;
1125 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1126 kfree_skb(skb);
1127 return VOS_STATUS_E_FAILURE;
1128 }
1129
1130 //Return VOS packet to TL;
1131 *ppVosPacket = pVosPacket;
1132
1133 //Fill out the meta information needed by TL
1134 //FIXME This timestamp is really the time stamp of wrap_data_packet
1135 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1136 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1137 if ( 1 < size )
1138 {
1139 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1140 }
1141 else
1142 {
1143 pPktMetaInfo->bMorePackets = 0;
1144 }
1145
1146 pPktMetaInfo->ucIsEapol = 0;
1147
1148 if(pAdapter->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
1149 {
1150 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1151 {
1152 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001153 "%s: VOS packet is EAPOL packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001154 pPktMetaInfo->ucIsEapol = 1;
1155 }
1156 }
1157
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001158 if (pHddCtx->cfg_ini->gEnableDebugLog)
1159 {
1160 proto_type = vos_pkt_get_proto_type(skb,
1161 pHddCtx->cfg_ini->gEnableDebugLog);
1162 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1163 {
1164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1165 "SAP TX EAPOL");
1166 }
1167 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1168 {
1169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1170 "SAP TX DHCP");
1171 }
1172 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001173//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 {
1175 pPktMetaInfo->ucUP = pktNode->userPriority;
1176 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1177 }
1178
1179 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1180 //Extract the destination address from ethernet frame
1181 pDestMacAddress = (v_MACADDR_t*)skb->data;
1182
1183 // we need 802.3 to 802.11 frame translation
1184 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1185 pPktMetaInfo->ucDisableFrmXtl = 0;
1186 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1187 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1188
1189 if ( (pAdapter->aStaInfo[STAId].txSuspended[ac]) &&
1190 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1191 {
1192 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001193 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 pAdapter->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
1195 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
1196 }
1197
1198 // We're giving the packet to TL so consider it transmitted from
1199 // a statistics perspective. We account for it here instead of
1200 // when the packet is returned for two reasons. First, TL will
1201 // manipulate the skb to the point where the len field is not
1202 // accurate, leading to inaccurate byte counts if we account for
1203 // it later. Second, TL does not provide any feedback as to
1204 // whether or not the packet was successfully sent over the air,
1205 // so the packet counts will be the same regardless of where we
1206 // account for them
1207 pAdapter->stats.tx_bytes += skb->len;
1208 ++pAdapter->stats.tx_packets;
1209 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1210 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
1211
1212 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001213 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001214
1215 return status;
1216}
1217
1218
1219/**============================================================================
1220 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1221 case where VOS packets are not available at the time of the call to get
1222 packets. This callback function is invoked by VOS when packets are
1223 available.
1224
1225 @param pVosPacket : [in] pointer to VOS packet
1226 @param userData : [in] opaque user data that was passed initially
1227
1228 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1229 : VOS_STATUS_SUCCESS otherwise
1230 =============================================================================*/
1231VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1232 v_VOID_t *userData )
1233{
1234 VOS_STATUS status;
1235 v_SINT_t i = 0;
1236 v_SIZE_t size = 0;
1237 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1238 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1239
1240 if(pAdapter == NULL)
1241 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001242 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001243 return VOS_STATUS_E_FAILURE;
1244 }
1245
1246 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1247 //situation. Here we will only signal TL that there is a pending data for a STA.
1248 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1249 vos_pkt_return_packet( pVosPacket );
1250
1251 pAdapter->isVosOutOfResource = VOS_FALSE;
1252
1253 // Indicate to TL that there is pending data if a queue is non empty.
1254 // This Code wasnt included in earlier version which resulted in
1255 // Traffic stalling
1256 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1257 {
1258 if ((pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1259 (pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
1260 {
1261 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1262 {
1263 size = 0;
1264 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &size);
1265 if ( size > 0 )
1266 {
1267 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1268 STAId,
1269 (WLANTL_ACEnumType)i );
1270 if( !VOS_IS_STATUS_SUCCESS( status ) )
1271 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001272 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure in indicating pkt to TL for ac=%d", __func__,i);
Jeff Johnson295189b2012-06-20 16:38:30 -07001273 }
1274 }
1275 }
1276 }
1277 }
1278 return VOS_STATUS_SUCCESS;
1279}
1280
1281
1282/**============================================================================
1283 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1284 TL will call this to notify the HDD when one or more packets were
1285 received for a registered STA.
1286
1287 @param vosContext : [in] pointer to VOS context
1288 @param pVosPacketChain : [in] pointer to VOS packet chain
1289 @param staId : [in] Station Id (Adress 1 Index)
1290 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1291
1292 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1293 : VOS_STATUS_SUCCESS otherwise
1294 ===========================================================================*/
1295VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1296 vos_pkt_t *pVosPacketChain,
1297 v_U8_t staId,
1298 WLANTL_RxMetaInfoType* pRxMetaInfo )
1299{
1300 hdd_adapter_t *pAdapter = NULL;
1301 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1302 int rxstat;
1303 struct sk_buff *skb = NULL;
1304 vos_pkt_t* pVosPacket;
1305 vos_pkt_t* pNextVosPacket;
1306 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001307 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001308
1309 //Sanity check on inputs
1310 if ( ( NULL == vosContext ) ||
1311 ( NULL == pVosPacketChain ) ||
1312 ( NULL == pRxMetaInfo ) )
1313 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001314 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001315 return VOS_STATUS_E_FAILURE;
1316 }
1317
1318 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1319 if ( NULL == pHddCtx )
1320 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001321 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 return VOS_STATUS_E_FAILURE;
1323 }
1324
1325 pAdapter = pHddCtx->sta_to_adapter[staId];
1326 if( NULL == pAdapter )
1327 {
1328 VOS_ASSERT(0);
1329 return VOS_STATUS_E_FAILURE;
1330 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001331
1332 /* Monitor traffic */
1333 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1334 {
1335 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1336 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1337 {
1338 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1339 /* It was IDLE mode,
1340 * this is new state, then switch mode from suspend to resume */
1341 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1342 {
1343 hdd_set_wlan_suspend_mode(0);
1344 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1345 pHddCtx->cfg_ini->trafficIdleTimeout);
1346 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1347 }
1348 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1349 }
1350 }
1351
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1353
1354 // walk the chain until all are processed
1355 pVosPacket = pVosPacketChain;
1356 do
1357 {
1358 // get the pointer to the next packet in the chain
1359 // (but don't unlink the packet since we free the entire chain later)
1360 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1361
1362 // both "success" and "empty" are acceptable results
1363 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1364 {
1365 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001366 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001367 return VOS_STATUS_E_FAILURE;
1368 }
1369
1370 // Extract the OS packet (skb).
1371 // Tell VOS to detach the OS packet from the VOS packet
1372 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
1373 if(!VOS_IS_STATUS_SUCCESS( status ))
1374 {
1375 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001376 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001377 return VOS_STATUS_E_FAILURE;
1378 }
1379
1380 //hdd_softap_dump_sk_buff(skb);
1381
1382 skb->dev = pAdapter->dev;
1383
1384 if(skb->dev == NULL) {
1385
Arif Hussain6d2a3322013-11-17 19:50:10 -08001386 hddLog(VOS_TRACE_LEVEL_FATAL, "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001387 return VOS_STATUS_E_FAILURE;
1388 }
1389 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1390 ++pAdapter->stats.rx_packets;
1391 pAdapter->stats.rx_bytes += skb->len;
1392
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001393 if (pHddCtx->cfg_ini->gEnableDebugLog)
1394 {
1395 proto_type = vos_pkt_get_proto_type(skb,
1396 pHddCtx->cfg_ini->gEnableDebugLog);
1397 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1398 {
1399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1400 "SAP RX EAPOL");
1401 }
1402 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1403 {
1404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1405 "SAP RX DHCP");
1406 }
1407 }
1408
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1410 {
1411 //MC/BC packets. Duplicate a copy of packet
1412 struct sk_buff *pSkbCopy;
1413 hdd_ap_ctx_t *pHddApCtx;
1414
1415 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1416 if (!(pHddApCtx->apDisableIntraBssFwd))
1417 {
1418 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1419 if (pSkbCopy)
1420 {
1421 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1422 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1423 }
1424 }
1425 else
1426 {
1427 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001428 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001429 }
1430
1431
1432 } //(WLAN_RX_BCMC_STA_ID == staId)
1433
1434 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1435 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1436 {
1437 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001438 "%s: send one packet to kernel", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001439
1440 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001441 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001442#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07001443#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07001444 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07001445#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001446#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 rxstat = netif_rx_ni(skb);
1448 if (NET_RX_SUCCESS == rxstat)
1449 {
1450 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001451 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001452 }
1453 else
1454 {
1455 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1456 }
1457 }
1458 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1459 {
1460 kfree_skb(skb);
1461 }
1462 else
1463 {
1464 //loopback traffic
1465 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1466 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1467 }
1468
1469 // now process the next packet in the chain
1470 pVosPacket = pNextVosPacket;
1471
1472 } while (pVosPacket);
1473
1474 //Return the entire VOS packet chain to the resource pool
1475 status = vos_pkt_return_packet( pVosPacketChain );
1476 if(!VOS_IS_STATUS_SUCCESS( status ))
1477 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001478 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001479 }
1480
1481 pAdapter->dev->last_rx = jiffies;
1482
1483 return status;
1484}
1485
1486VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1487{
1488 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301489 hdd_context_t *pHddCtx;
1490 if (NULL == pAdapter)
1491 {
1492 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1493 "%s: pAdapter is NULL", __func__);
1494 return VOS_STATUS_E_INVAL;
1495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001496
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301497 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1498 {
1499 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1500 "%s: Invalid pAdapter magic", __func__);
1501 return VOS_STATUS_E_INVAL;
1502 }
1503
1504 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001505 //Clear station in TL and then update HDD data structures. This helps
1506 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301507 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1509 {
1510 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1511 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001512 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001513 staId, vosStatus, vosStatus );
1514 }
1515
1516 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1517 if( VOS_STATUS_E_FAILURE == vosStatus )
1518 {
1519 VOS_TRACE ( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1520 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001521 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001522 staId, vosStatus, vosStatus );
1523 return( vosStatus );
1524 }
1525
1526 pHddCtx->sta_to_adapter[staId] = NULL;
1527
1528 return( vosStatus );
1529}
1530
1531VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1532 v_BOOL_t fAuthRequired,
1533 v_BOOL_t fPrivacyBit,
1534 v_U8_t staId,
1535 v_U8_t ucastSig,
1536 v_U8_t bcastSig,
1537 v_MACADDR_t *pPeerMacAddress,
1538 v_BOOL_t fWmmEnabled )
1539{
1540 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001541 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001542 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1543 hdd_adapter_t *pmonAdapter = NULL;
1544
1545 //eCsrEncryptionType connectedCipherAlgo;
1546 //v_BOOL_t fConnected;
1547
1548 /*
1549 * Clean up old entry if it is not cleaned up properly
1550 */
1551 if ( pAdapter->aStaInfo[staId].isUsed )
1552 {
1553 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1554 "clean up old entry for STA %d", staId);
1555 hdd_softap_DeregisterSTA( pAdapter, staId );
1556 }
1557
1558 // Get the Station ID from the one saved during the assocation.
1559
1560 staDesc.ucSTAId = staId;
1561
1562
1563 /*Save the pAdapter Pointer for this staId*/
1564 pHddCtx->sta_to_adapter[staId] = pAdapter;
1565
1566 staDesc.wSTAType = WLAN_STA_SOFTAP;
1567
1568 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1569 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1570 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1571
1572 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001573 "register station");
Jeff Johnson295189b2012-06-20 16:38:30 -07001574 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001575 "station mac " MAC_ADDRESS_STR,
1576 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001577 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001578 "BSSIDforIBSS " MAC_ADDRESS_STR,
1579 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001580 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001581 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1582 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001583
1584 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1585
Jeff Johnson295189b2012-06-20 16:38:30 -07001586 staDesc.ucQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001587 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1588 "HDD SOFTAP register TL QoS_enabled=%d",
1589 staDesc.ucQosEnabled );
1590
1591 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1592
1593
Jeff Johnson295189b2012-06-20 16:38:30 -07001594 // For PRIMA UMA frame translation is not enable yet.
1595 staDesc.ucSwFrameTXXlation = 1;
1596 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001597 staDesc.ucAddRmvLLC = 1;
1598
1599 // Initialize signatures and state
1600 staDesc.ucUcastSig = ucastSig;
1601 staDesc.ucBcastSig = bcastSig;
1602 staDesc.ucInitState = fAuthRequired ?
1603 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1604
Prathyushaf5442802012-12-12 13:58:11 -08001605 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1606
Jeff Johnson295189b2012-06-20 16:38:30 -07001607 // Register the Station with TL...
1608 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1609 hdd_softap_rx_packet_cbk,
1610 hdd_softap_tx_complete_cbk,
1611 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1612
1613 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1614 {
1615 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001616 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001617 vosStatus, vosStatus );
1618 return vosStatus;
1619 }
1620
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001621 //Timer value should be in milliseconds
1622 if ( pHddCtx->cfg_ini->dynSplitscan &&
1623 ( VOS_TIMER_STATE_RUNNING !=
1624 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1625 {
1626 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1627 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1628 }
1629
Jeff Johnson295189b2012-06-20 16:38:30 -07001630 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1631 // then go to 'authenticated'. For all other authentication types (those that do
1632 // not require upper layer authentication) we can put TL directly into 'authenticated'
1633 // state.
1634
1635 //VOS_ASSERT( fConnected );
1636 pAdapter->aStaInfo[staId].ucSTAId = staId;
1637 pAdapter->aStaInfo[staId].isQosEnabled = fWmmEnabled;
1638
1639 if ( !fAuthRequired )
1640 {
1641 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1642 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", pAdapter->aStaInfo[staId].ucSTAId );
1643
1644 // Connections that do not need Upper layer auth, transition TL directly
1645 // to 'Authenticated' state.
1646 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1647 WLANTL_STA_AUTHENTICATED );
1648
1649 pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
1650 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1651 }
1652 else
1653 {
1654
1655 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1656 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pAdapter->aStaInfo[staId].ucSTAId );
1657
1658 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1659 WLANTL_STA_CONNECTED );
1660 pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
1661
1662 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1663
1664 }
1665 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1666 if(pmonAdapter)
1667 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001668 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 netif_carrier_on(pmonAdapter->dev);
1670 //Enable Tx queue
1671 netif_tx_start_all_queues(pmonAdapter->dev);
1672 }
1673 netif_carrier_on(pAdapter->dev);
1674 //Enable Tx queue
1675 netif_tx_start_all_queues(pAdapter->dev);
1676
1677 return( vosStatus );
1678}
1679
1680VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1681{
1682 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1683 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1684 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1685
1686
1687 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1688 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1689 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1690
1691 return vosStatus;
1692}
1693
1694VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1695{
1696 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1697}
1698
1699VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1700{
Wilson Yangf80a0542013-10-07 13:02:37 -07001701 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07001702 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1703 v_U8_t staId = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07001704 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1705
1706 /*bss deregister is not allowed during wlan driver loading or unloading*/
1707 if (pHddCtx->isLoadUnloadInProgress)
1708 {
1709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1710 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
1711 return VOS_STATUS_E_PERM;
1712 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001713
1714 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
1715
Jeff Johnson43971f52012-07-17 12:26:56 -07001716 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001717 {
1718 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001719 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001720 }
1721
1722 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
1723 {
1724 if (pAdapter->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
1725 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
1726
Jeff Johnson43971f52012-07-17 12:26:56 -07001727 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001728 {
1729 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001730 "%s: Failed to deregister sta Id %d", __func__, staId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 }
1732 }
1733
1734 return vosStatus;
1735}
1736
1737VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
1738{
1739 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
1740 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
1741 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001742
1743 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001744 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001745
Jeff Johnson43971f52012-07-17 12:26:56 -07001746 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07001747 {
1748 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001749 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001750 return VOS_STATUS_E_FAILURE;
1751 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001752
1753 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
1754 {
1755 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001756 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001757 return VOS_STATUS_E_FAILURE;
1758 }
1759
1760 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
1761 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001762 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07001763
Jeff Johnson43971f52012-07-17 12:26:56 -07001764 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001765 {
1766 pAdapter->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
1767 }
1768
1769 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001770 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001771
1772 return vosStatus;
1773}
1774
1775
1776VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
1777{
1778 v_U8_t i;
1779
1780 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
1781 {
1782 if (vos_mem_compare(&pAdapter->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
1783 pAdapter->aStaInfo[i].isUsed)
1784 {
1785 *staId = i;
1786 return VOS_STATUS_SUCCESS;
1787 }
1788 }
1789
1790 return VOS_STATUS_E_FAILURE;
1791}
1792
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05301793VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
1794{
1795 v_U8_t i;
1796
1797 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
1798 {
Kiet Lam61589852013-09-19 17:10:58 +05301799 if (pAdapter->aStaInfo[i].isUsed &&
1800 (!vos_is_macaddr_broadcast(&pAdapter->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05301801 {
1802 *staId = i;
1803 return VOS_STATUS_SUCCESS;
1804 }
1805 }
1806
1807 return VOS_STATUS_E_FAILURE;
1808}