blob: 5aaaebf86179b1e0e08b64117e9ef84bbf95171d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**===========================================================================
43
44 \file wlan_hdd_softap_tx_rx.c
45
46 \brief Linux HDD Tx/RX APIs
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48 ==========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50/*---------------------------------------------------------------------------
51 Include files
52 -------------------------------------------------------------------------*/
53#include <linux/semaphore.h>
54#include <wlan_hdd_tx_rx.h>
55#include <wlan_hdd_softap_tx_rx.h>
56#include <wlan_hdd_dp_utils.h>
57#include <wlan_qct_tl.h>
58#include <linux/netdevice.h>
59#include <linux/skbuff.h>
60#include <linux/etherdevice.h>
61//#include <vos_list.h>
62#include <vos_types.h>
63#include <aniGlobal.h>
64#include <halTypes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070065#include <net/ieee80211_radiotap.h>
66
67
68/*---------------------------------------------------------------------------
69 Preprocessor definitions and constants
70 -------------------------------------------------------------------------*/
71
72/*---------------------------------------------------------------------------
73 Type declarations
74 -------------------------------------------------------------------------*/
75
76/*---------------------------------------------------------------------------
77 Function definitions and documenation
78 -------------------------------------------------------------------------*/
79#if 0
80static void hdd_softap_dump_sk_buff(struct sk_buff * skb)
81{
Arif Hussain6d2a3322013-11-17 19:50:10 -080082 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head);
83 //VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data);
84 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail);
85 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end);
86 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
87 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
88 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 -070089
Arif Hussain6d2a3322013-11-17 19:50:10 -080090 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 -070091 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
92 skb->data[5], skb->data[6], skb->data[7]);
Arif Hussain6d2a3322013-11-17 19:50:10 -080093 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 -070094 skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
95 skb->data[13], skb->data[14], skb->data[15]);
96}
97#endif
Leo Chang64d68bc2013-06-04 15:40:52 -070098
99extern void hdd_set_wlan_suspend_mode(bool suspend);
100
101/**============================================================================
102 @brief hdd_softap_traffic_monitor_timeout_handler() -
103 SAP/P2P GO traffin monitor timeout handler function
104 If no traffic during programmed time, trigger suspand mode
105
106 @param pUsrData : [in] pointer to hdd context
107 @return : NONE
108 ===========================================================================*/
109void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData )
110{
111 hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData;
112 v_TIME_t currentTS;
113
114 if (NULL == pHddCtx)
115 {
116 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
117 "%s: Invalid user data, context", __func__);
118 return;
119 }
120
121 currentTS = vos_timer_get_system_time();
122 if (pHddCtx->cfg_ini->trafficIdleTimeout <
123 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
124 {
Kiet Lambcf38522013-10-26 18:28:27 +0530125 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
126 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -0700127 hdd_set_wlan_suspend_mode(1);
128 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
129 }
130 else
131 {
132 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
133 pHddCtx->cfg_ini->trafficIdleTimeout);
134 }
135
136 return;
137}
138
Kiet Lambcf38522013-10-26 18:28:27 +0530139VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter )
140{
141
142 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
143 VOS_STATUS status = VOS_STATUS_SUCCESS;
144
145 status = wlan_hdd_validate_context(pHddCtx);
146
147 if (0 != status)
148 {
149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
150 "%s: HDD context is not valid", __func__);
151 return status;
152 }
153
154 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
155 (!pHddCtx->traffic_monitor.isInitialized))
156 {
157 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
158 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
159 VOS_TIMER_TYPE_SW,
160 hdd_softap_traffic_monitor_timeout_handler,
161 pHddCtx);
162 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
163 pHddCtx->traffic_monitor.isInitialized = 1;
164 pHddCtx->traffic_monitor.lastFrameTs = 0;
165 /* Start traffic monitor timer here
166 * If no AP assoc, immediatly go into suspend */
167 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
168 "%s Start Traffic Monitor Timer", __func__);
169 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
170 pHddCtx->cfg_ini->trafficIdleTimeout);
171 }
172 else
173 {
174 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
175 "%s Traffic Monitor is not Enable in ini file", __func__);
176 }
177 return status;
178}
179
180VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter )
181{
182 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
183 VOS_STATUS status = VOS_STATUS_SUCCESS;
184
185 status = wlan_hdd_validate_context(pHddCtx);
186
Kiet Lamae69d7a2013-11-08 14:38:04 +0530187 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530188 {
189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
190 "%s: HDD context is not valid", __func__);
191 return status;
192 }
193
194 if (pHddCtx->traffic_monitor.isInitialized)
195 {
196 if (VOS_TIMER_STATE_STOPPED !=
197 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
198 {
199 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
200 "%s Stop Traffic Monitor Timer", __func__);
201 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
202 }
203 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
204 "%s Destroy Traffic Monitor Timer", __func__);
205 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
206 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
207 pHddCtx->traffic_monitor.isInitialized = 0;
208 }
Kiet Lamae69d7a2013-11-08 14:38:04 +0530209 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530210}
211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212/**============================================================================
213 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
214
215 @param pAdapter : [in] pointer to adapter context
216 @return : VOS_STATUS_E_FAILURE if any errors encountered
217 : VOS_STATUS_SUCCESS otherwise
218 ===========================================================================*/
219static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
220{
221 VOS_STATUS status = VOS_STATUS_SUCCESS;
222 v_SINT_t i = -1;
223 v_U8_t STAId = 0;
224 hdd_list_node_t *anchor = NULL;
225 skb_list_node_t *pktNode = NULL;
226 struct sk_buff *skb = NULL;
227
228 spin_lock_bh( &pAdapter->staInfo_lock );
229 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
230 {
231 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
232 {
233 continue;
234 }
235
236 for (i = 0; i < NUM_TX_QUEUES; i ++)
237 {
238 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
239 while (true)
240 {
241 status = hdd_list_remove_front ( &pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
242
243 if (VOS_STATUS_E_EMPTY != status)
244 {
245 //If success then we got a valid packet from some AC
246 pktNode = list_entry(anchor, skb_list_node_t, anchor);
247 skb = pktNode->skb;
248 ++pAdapter->stats.tx_dropped;
249 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
250 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
251 kfree_skb(skb);
252 continue;
253 }
254
255 //current list is empty
256 break;
257 }
258 pAdapter->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
259 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
260 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530261 pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 }
263
264 spin_unlock_bh( &pAdapter->staInfo_lock );
265
266 return status;
267}
268
269/**============================================================================
270 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
271 transmitting packets. There are 2 versions of this function. One that uses
272 locked queue and other that uses lockless queues. Both have been retained to
273 do some performance testing
274
275 @param skb : [in] pointer to OS packet (sk_buff)
276 @param dev : [in] pointer to Libra network device
277
278 @return : NET_XMIT_DROP if packets are dropped
279 : NET_XMIT_SUCCESS if packet is enqueued succesfully
280 ===========================================================================*/
281int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
282{
283 VOS_STATUS status;
284 WLANTL_ACEnumType ac = WLANTL_AC_BE;
285 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
286 skb_list_node_t *pktNode = NULL;
287 v_SIZE_t pktListSize = 0;
288 v_BOOL_t txSuspended = VOS_FALSE;
289 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
290 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
291 vos_list_node_t *anchor = NULL;
292 v_U8_t STAId = WLAN_MAX_STA_COUNT;
293 //Extract the destination address from ethernet frame
294 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
295 int os_status = NETDEV_TX_OK;
296
297 pDestMacAddress = (v_MACADDR_t*)skb->data;
298
299 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
300
301 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700302 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700303
304 spin_lock_bh( &pAdapter->staInfo_lock );
305 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
306 {
307 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
308 //ID used for BC/MC traffic. The station id is registered to TL as well.
309 STAId = pHddApCtx->uBCStaId;
310
311 /* Setting priority for broadcast packets which doesn't go to select_queue function */
312 skb->priority = SME_QOS_WMM_UP_BE;
313 skb->queue_mapping = HDD_LINUX_AC_BE;
314
315 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800316 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 }
318 else
319 {
320 STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
321 if (STAId == HDD_WLAN_INVALID_STA_ID)
322 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700323 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700324 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 ++pAdapter->stats.tx_dropped;
326 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
327 kfree_skb(skb);
328 goto xmit_done;
329 }
330 else if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
331 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530332 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 -0700333 ++pAdapter->stats.tx_dropped;
334 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
335 kfree_skb(skb);
336 goto xmit_done;
337 }
338
339 if ( (WLANTL_STA_CONNECTED != pAdapter->aStaInfo[STAId].tlSTAState) &&
340 (WLANTL_STA_AUTHENTICATED != pAdapter->aStaInfo[STAId].tlSTAState) )
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: Station not connected yet", __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 else if(WLANTL_STA_CONNECTED == pAdapter->aStaInfo[STAId].tlSTAState)
350 {
351 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
352 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700353 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700354 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700355 ++pAdapter->stats.tx_dropped;
356 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
357 kfree_skb(skb);
358 goto xmit_done;
359 }
360 }
361 }
362
363 //Get TL AC corresponding to Qdisc queue index/AC.
364 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
365 //user priority from IP header, which is already extracted and set from
366 //select_queue call back function
367 up = skb->priority;
368 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
369
370 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700371 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372
373 // If the memory differentiation mode is enabled, the memory limit of each queue will be
374 // checked. Over-limit packets will be dropped.
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700375 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
377 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
378 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700379 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800380 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 pAdapter->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
382 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
383 txSuspended = VOS_TRUE;
384 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530385
386 /* If 3/4th of the max queue size is used then enable the flag.
387 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
388 if (WLANTL_AC_BE == ac)
389 {
390 if (pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
391 {
392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
393 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
394 pAdapter->aStaInfo[STAId].vosLowResource = VOS_TRUE;
395 }
396 else
397 {
398 pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
399 }
400 }
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700401 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700402
403 if (VOS_TRUE == txSuspended)
404 {
405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
406 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700407 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700408 os_status = NETDEV_TX_BUSY;
409 goto xmit_done;
410 }
411
412 //Use the skb->cb field to hold the list node information
413 pktNode = (skb_list_node_t *)&skb->cb;
414
415 //Stick the OS packet inside this node.
416 pktNode->skb = skb;
417
418 //Stick the User Priority inside this node
419 pktNode->userPriority = up;
420
421 INIT_LIST_HEAD(&pktNode->anchor);
422
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700423 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700424 status = hdd_list_insert_back_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700425 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700426
427 if ( !VOS_IS_STATUS_SUCCESS( status ) )
428 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700429 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 -0700430 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
431 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
432 ++pAdapter->stats.tx_dropped;
433 kfree_skb(skb);
434 goto xmit_done;
435 }
436
437 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
438 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530439 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700440
441 if (1 == pktListSize)
442 {
443 //Let TL know we have a packet to send for this AC
444 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
445
446 if ( !VOS_IS_STATUS_SUCCESS( status ) )
447 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700448 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 -0700449 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700450
451 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
452 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
453 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
454 status = hdd_list_remove_back( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
455 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
456 ++pAdapter->stats.tx_dropped;
457 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
458 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
459 kfree_skb(skb);
460 goto xmit_done;
461 }
462 }
463 dev->trans_start = jiffies;
464
Arif Hussain6d2a3322013-11-17 19:50:10 -0800465 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700466
467xmit_done:
468 spin_unlock_bh( &pAdapter->staInfo_lock );
469 return os_status;
470}
471
472/**============================================================================
473 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
474
475 @param skb : [in] pointer to packet (sk_buff)
476 @param dev : [in] pointer to Libra network device
477 @param STAId : [in] Station Id of Destination Station
478 @param up : [in] User Priority
479
480 @return : NET_XMIT_DROP if packets are dropped
481 : NET_XMIT_SUCCESS if packet is enqueued succesfully
482 ===========================================================================*/
483VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
484 struct net_device *dev,
485 v_U8_t STAId,
486 v_U8_t up)
487{
488 VOS_STATUS status = VOS_STATUS_SUCCESS;
489 skb_list_node_t *pktNode = NULL;
490 v_SIZE_t pktListSize = 0;
491 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
492 v_U8_t ac;
493 vos_list_node_t *anchor = NULL;
494
495 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
496
497 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700498 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700499
500 spin_lock_bh( &pAdapter->staInfo_lock );
501 if ( FALSE == pAdapter->aStaInfo[STAId].isUsed )
502 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700503 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530504 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700505 kfree_skb(skb);
506 status = VOS_STATUS_E_FAILURE;
507 goto xmit_end;
508 }
509
510 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
511 if ( !pAdapter->aStaInfo[STAId].isQosEnabled )
512 up = SME_QOS_WMM_UP_BE;
513
514 ac = hddWmmUpToAcMap[up];
515 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
516 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700517 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700518
519 skb->queue_mapping = hddLinuxUpToAcMap[up];
520
521 //Use the skb->cb field to hold the list node information
522 pktNode = (skb_list_node_t *)&skb->cb;
523
524 //Stick the OS packet inside this node.
525 pktNode->skb = skb;
526
527 //Stick the User Priority inside this node
528 pktNode->userPriority = up;
529
530 INIT_LIST_HEAD(&pktNode->anchor);
531
532 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
533 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
534 if(pAdapter->aStaInfo[STAId].txSuspended[ac] ||
535 pktListSize >= pAdapter->aTxQueueLimit[ac])
536 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700537 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800538 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700539 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
540 * SUSPEND should be done based on Threshold. RESUME would be
541 * triggered in fetch cbk after recovery.
542 */
543 kfree_skb(skb);
544 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
545 status = VOS_STATUS_E_FAILURE;
546 goto xmit_end;
547 }
548 status = hdd_list_insert_back_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
549 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
550
551 if ( !VOS_IS_STATUS_SUCCESS( status ) )
552 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700553 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 -0700554 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
555 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
556 ++pAdapter->stats.tx_dropped;
557 kfree_skb(skb);
558 status = VOS_STATUS_E_FAILURE;
559 goto xmit_end;
560 }
561
562 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
563 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
564
565 if (1 == pktListSize)
566 {
567 //Let TL know we have a packet to send for this AC
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700568 //VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700569 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
570
571 if ( !VOS_IS_STATUS_SUCCESS( status ) )
572 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700573 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 -0700574 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
576 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
577 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
578 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
579 status = hdd_list_remove_back( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
580 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
581 ++pAdapter->stats.tx_dropped;
582 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
583 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
584 kfree_skb(skb);
585 status = VOS_STATUS_E_FAILURE;
586 goto xmit_end;
587 }
588 }
589
Arif Hussain6d2a3322013-11-17 19:50:10 -0800590 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700591
592xmit_end:
593 spin_unlock_bh( &pAdapter->staInfo_lock );
594 return status;
595}
596
597/**============================================================================
598 @brief hdd_softap_tx_timeout() - Function called by OS if there is any
599 timeout during transmission. Since HDD simply enqueues packet
600 and returns control to OS right away, this would never be invoked
601
602 @param dev : [in] pointer to Libra network device
603 @return : None
604 ===========================================================================*/
605void hdd_softap_tx_timeout(struct net_device *dev)
606{
607 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700608 "%s: Transmission timeout occurred", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700609 //Getting here implies we disabled the TX queues for too long. Queues are
610 //disabled either because of disassociation or low resource scenarios. In
611 //case of disassociation it is ok to ignore this. But if associated, we have
612 //do possible recovery here
613}
614
615
616/**============================================================================
617 @brief hdd_softap_stats() - Function registered with the Linux OS for
618 device TX/RX statistic
619
620 @param dev : [in] pointer to Libra network device
621
622 @return : pointer to net_device_stats structure
623 ===========================================================================*/
624struct net_device_stats* hdd_softap_stats(struct net_device *dev)
625{
626 hdd_adapter_t* priv = netdev_priv(dev);
627 return &priv->stats;
628}
629
630
631/**============================================================================
632 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
633 modules in HDD
634
635 @param pAdapter : [in] pointer to adapter context
636 @return : VOS_STATUS_E_FAILURE if any errors encountered
637 : VOS_STATUS_SUCCESS otherwise
638 ===========================================================================*/
639VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
640{
641 VOS_STATUS status = VOS_STATUS_SUCCESS;
642 v_SINT_t i = -1;
643 v_SIZE_t size = 0;
644
645 v_U8_t STAId = 0;
646
647 v_U8_t pACWeights[] = {
648 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
649 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
650 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
651 HDD_SOFTAP_VO_WEIGHT_DEFAULT
652 };
Leo Chang64d68bc2013-06-04 15:40:52 -0700653
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530655 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700656
657 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
658
659 while (++i != NUM_TX_QUEUES)
660 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
661
662 /* Initial HDD buffer control / flow control fields*/
663 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
664
665 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
666 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
667 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
668 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
669
670 spin_lock_init( &pAdapter->staInfo_lock );
671
672 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
673 {
674 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
675 for (i = 0; i < NUM_TX_QUEUES; i ++)
676 {
677 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
678 }
679 }
680
Yue Ma3ede6052013-08-29 00:33:26 -0700681 /* Update the AC weights suitable for SoftAP mode of operation */
682 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
683
Kiet Lambcf38522013-10-26 18:28:27 +0530684 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700685 {
Kiet Lambcf38522013-10-26 18:28:27 +0530686 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
687 "%s: failed to start Traffic Monito timer ", __func__ );
688 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700689 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700690 return status;
691}
692
693/**============================================================================
694 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
695 modules in HDD
696
697 @param pAdapter : [in] pointer to adapter context
698 @return : VOS_STATUS_E_FAILURE if any errors encountered
699 : VOS_STATUS_SUCCESS otherwise
700 ===========================================================================*/
701VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
702{
703 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700704
Kiet Lambcf38522013-10-26 18:28:27 +0530705 if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700706 {
Kiet Lambcf38522013-10-26 18:28:27 +0530707 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
708 "%s: Fail to Stop Traffic Monito timer", __func__ );
709 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700710 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700711
712 status = hdd_softap_flush_tx_queues(pAdapter);
713
714 return status;
715}
716
717/**============================================================================
718 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
719
720 @param pAdapter : [in] pointer to adapter context
721 @param STAId : [in] Station ID to deinit
722 @return : VOS_STATUS_E_FAILURE if any errors encountered
723 : VOS_STATUS_SUCCESS otherwise
724 ===========================================================================*/
725static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
726{
727 VOS_STATUS status = VOS_STATUS_SUCCESS;
728 v_U8_t i = -1;
729
730 hdd_list_node_t *anchor = NULL;
731
732 skb_list_node_t *pktNode = NULL;
733 struct sk_buff *skb = NULL;
734
735 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
736 {
737 return status;
738 }
739
740 for (i = 0; i < NUM_TX_QUEUES; i ++)
741 {
742 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
743 while (true)
744 {
745 status = hdd_list_remove_front ( &pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
746 if (VOS_STATUS_E_EMPTY != status)
747 {
748 //If success then we got a valid packet from some AC
749 pktNode = list_entry(anchor, skb_list_node_t, anchor);
750 skb = pktNode->skb;
751 ++pAdapter->stats.tx_dropped;
752 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
753 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
754 kfree_skb(skb);
755 continue;
756 }
757
758 //current list is empty
759 break;
760 }
761 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
762 }
763
764 return status;
765}
766
767/**============================================================================
768 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
769 modules in HDD
770
771 @param pAdapter : [in] pointer to adapter context
772 @param STAId : [in] Station ID to deinit
773 @param pmacAddrSTA : [in] pointer to the MAC address of the station
774 @return : VOS_STATUS_E_FAILURE if any errors encountered
775 : VOS_STATUS_SUCCESS otherwise
776 ===========================================================================*/
777VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
778{
779 v_U8_t i = 0;
780 spin_lock_bh( &pAdapter->staInfo_lock );
781 if (pAdapter->aStaInfo[STAId].isUsed)
782 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700783 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR, "%s: Reinit station %d", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 spin_unlock_bh( &pAdapter->staInfo_lock );
785 return VOS_STATUS_E_FAILURE;
786 }
787
788 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
789 for (i = 0; i < NUM_TX_QUEUES; i ++)
790 {
791 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
792 }
793
794 pAdapter->aStaInfo[STAId].isUsed = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800795 pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700796 vos_copy_macaddr( &pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
797
798 spin_unlock_bh( &pAdapter->staInfo_lock );
799 return VOS_STATUS_SUCCESS;
800}
801
802/**============================================================================
803 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
804 modules in HDD
805
806 @param pAdapter : [in] pointer to adapter context
807 @param STAId : [in] Station ID to deinit
808 @return : VOS_STATUS_E_FAILURE if any errors encountered
809 : VOS_STATUS_SUCCESS otherwise
810 ===========================================================================*/
811VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
812{
813 VOS_STATUS status = VOS_STATUS_SUCCESS;
814 v_U8_t ac;
815 /**Track whether OS TX queue has been disabled.*/
816 v_BOOL_t txSuspended[NUM_TX_QUEUES];
817 v_U8_t tlAC;
818 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700819 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -0700820
821 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
822
823 spin_lock_bh( &pAdapter->staInfo_lock );
824 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
825 {
826 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700827 "%s: Deinit station not inited %d", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700828 spin_unlock_bh( &pAdapter->staInfo_lock );
829 return VOS_STATUS_E_FAILURE;
830 }
831
832 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
833
834 pAdapter->aStaInfo[STAId].isUsed = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800835 pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700836
837 /* if this STA had any of its WMM TX queues suspended, then the
838 associated queue on the network interface was disabled. check
839 to see if that is the case, in which case we need to re-enable
840 the interface queue. but we only do this if the BSS is running
841 since, if the BSS is stopped, all of the interfaces have been
842 stopped and should not be re-enabled */
843
844 if (BSS_START == pHostapdState->bssState)
845 {
846 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
847 {
848 tlAC = hdd_QdiscAcToTlAC[ac];
849 txSuspended[ac] = pAdapter->aStaInfo[STAId].txSuspended[tlAC];
850 }
851 }
852 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
853
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700854 /* re-init spin lock, since netdev can still open adapter until
855 * driver gets unloaded
856 */
857 for (i = 0; i < NUM_TX_QUEUES; i ++)
858 {
859 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i],
860 HDD_TX_QUEUE_MAX_LEN);
861 }
862
Jeff Johnson295189b2012-06-20 16:38:30 -0700863 if (BSS_START == pHostapdState->bssState)
864 {
865 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
866 {
867 if (txSuspended[ac])
868 {
869 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700870 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700871 netif_wake_subqueue(pAdapter->dev, ac);
872 }
873 }
874 }
875
876 spin_unlock_bh( &pAdapter->staInfo_lock );
877 return status;
878}
879
880/**============================================================================
881 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
882 modules in HDD
883
884 @param pAdapter : [in] pointer to adapter context
885 @return : VOS_STATUS_E_FAILURE if any errors encountered
886 : VOS_STATUS_SUCCESS otherwise
887 ===========================================================================*/
888VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
889{
890 return hdd_softap_flush_tx_queues(pAdapter);
891}
892
893/**============================================================================
894 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
895 to indicate that a packet has been transmitted across the bus
896 succesfully. OS packet resources can be released after this cbk.
897
898 @param vosContext : [in] pointer to VOS context
899 @param pVosPacket : [in] pointer to VOS packet (containing skb)
900 @param vosStatusIn : [in] status of the transmission
901
902 @return : VOS_STATUS_E_FAILURE if any errors encountered
903 : VOS_STATUS_SUCCESS otherwise
904 ===========================================================================*/
905VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
906 vos_pkt_t *pVosPacket,
907 VOS_STATUS vosStatusIn )
908{
909 VOS_STATUS status = VOS_STATUS_SUCCESS;
910 hdd_adapter_t *pAdapter = NULL;
911 void* pOsPkt = NULL;
912
913 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
914 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700915 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 return VOS_STATUS_E_FAILURE;
917 }
918
919 //Return the skb to the OS
920 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -0800921 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 {
923 //This is bad but still try to free the VOSS resources if we can
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700924 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 -0700925 vos_pkt_return_packet( pVosPacket );
926 return VOS_STATUS_E_FAILURE;
927 }
928
929 //Get the Adapter context.
930 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
931 if(pAdapter == NULL)
932 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700933 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 -0700934 }
935 else
936 {
937 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
938 }
939
940 kfree_skb((struct sk_buff *)pOsPkt);
941
942 //Return the VOS packet resources.
943 status = vos_pkt_return_packet( pVosPacket );
944 if(!VOS_IS_STATUS_SUCCESS( status ))
945 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700946 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 -0700947 }
948
949 return status;
950}
951
952
953/**============================================================================
954 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
955 fetch a packet for transmission.
956
957 @param vosContext : [in] pointer to VOS context
958 @param staId : [in] Station for which TL is requesting a pkt
959 @param ac : [in] access category requested by TL
960 @param pVosPacket : [out] pointer to VOS packet packet pointer
961 @param pPktMetaInfo : [out] pointer to meta info for the pkt
962
963 @return : VOS_STATUS_E_EMPTY if no packets to transmit
964 : VOS_STATUS_E_FAILURE if any errors encountered
965 : VOS_STATUS_SUCCESS otherwise
966 ===========================================================================*/
967VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
968 v_U8_t *pStaId,
969 WLANTL_ACEnumType ac,
970 vos_pkt_t **ppVosPacket,
971 WLANTL_MetaInfoType *pPktMetaInfo )
972{
973 VOS_STATUS status = VOS_STATUS_E_FAILURE;
974 hdd_adapter_t *pAdapter = NULL;
975 hdd_list_node_t *anchor = NULL;
976 skb_list_node_t *pktNode = NULL;
977 struct sk_buff *skb = NULL;
978 vos_pkt_t *pVosPacket = NULL;
979 v_MACADDR_t* pDestMacAddress = NULL;
980 v_TIME_t timestamp;
981 v_SIZE_t size = 0;
982 v_U8_t STAId = WLAN_MAX_STA_COUNT;
983 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -0800984 v_U8_t proto_type = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700985
986 //Sanity check on inputs
987 if ( ( NULL == vosContext ) ||
988 ( NULL == pStaId ) ||
989 ( NULL == ppVosPacket ) ||
990 ( NULL == pPktMetaInfo ) )
991 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700992 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 return VOS_STATUS_E_FAILURE;
994 }
995
996 //Get the HDD context.
997 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
998 if ( NULL == pHddCtx )
999 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001000 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 -07001001 return VOS_STATUS_E_FAILURE;
1002 }
1003
Jeff Johnsonb156c922013-12-05 17:19:46 -08001004 STAId = *pStaId;
1005 if (STAId >= WLAN_MAX_STA_COUNT)
1006 {
1007 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1008 "%s: Invalid STAId %d passed by TL", __func__, STAId);
1009 return VOS_STATUS_E_FAILURE;
1010 }
1011
1012 pAdapter = pHddCtx->sta_to_adapter[STAId];
1013 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001014 {
1015 VOS_ASSERT(0);
1016 return VOS_STATUS_E_FAILURE;
1017 }
1018
Jeff Johnsonb156c922013-12-05 17:19:46 -08001019 if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
1020 {
1021 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1022 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1023 return VOS_STATUS_E_FAILURE;
1024 }
1025
Leo Chang64d68bc2013-06-04 15:40:52 -07001026 /* Monitor traffic */
1027 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1028 {
1029 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1030 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1031 {
1032 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1033 /* It was IDLE mode,
1034 * this is new state, then switch mode from suspend to resume */
1035 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1036 {
1037 hdd_set_wlan_suspend_mode(0);
1038 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1039 pHddCtx->cfg_ini->trafficIdleTimeout);
1040 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1041 }
1042 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1043 }
1044 }
1045
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1047
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 *ppVosPacket = NULL;
1049
1050 //Make sure the AC being asked for is sane
1051 if( ac > WLANTL_MAX_AC || ac < 0)
1052 {
1053 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001054 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 return VOS_STATUS_E_FAILURE;
1056 }
1057
1058 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1059
1060 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001061 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001062
1063 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1064 //This simplifies the locking and unlocking of Tx queue
1065 status = vos_pkt_wrap_data_packet( &pVosPacket,
1066 VOS_PKT_TYPE_TX_802_3_DATA,
1067 NULL, //OS Pkt is not being passed
1068 hdd_softap_tx_low_resource_cbk,
1069 pAdapter );
1070
1071 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1072 {
1073 //Remember VOS is in a low resource situation
1074 pAdapter->isVosOutOfResource = VOS_TRUE;
1075 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
1076 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001077 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1079 return VOS_STATUS_E_FAILURE;
1080 }
1081
1082 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1083 as the other branch does.
1084 */
1085 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1086 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &size);
1087
1088 if (0 == size)
1089 {
1090 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1091 vos_pkt_return_packet(pVosPacket);
1092 return VOS_STATUS_E_EMPTY;
1093 }
1094
1095 status = hdd_list_remove_front( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1096 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1097
1098 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001099 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001100
1101 if(VOS_STATUS_SUCCESS == status)
1102 {
1103 //If success then we got a valid packet from some AC
1104 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1105 skb = pktNode->skb;
1106 }
1107 else
1108 {
1109 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1110 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1111 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001112 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001113 vos_pkt_return_packet(pVosPacket);
1114 return VOS_STATUS_E_FAILURE;
1115 }
1116
1117 //Attach skb to VOS packet.
1118 status = vos_pkt_set_os_packet( pVosPacket, skb );
1119 if (status != VOS_STATUS_SUCCESS)
1120 {
1121 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001122 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 vos_pkt_return_packet(pVosPacket);
1124 ++pAdapter->stats.tx_dropped;
1125 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1126 kfree_skb(skb);
1127 return VOS_STATUS_E_FAILURE;
1128 }
1129
1130 //Just being paranoid. To be removed later
1131 if(pVosPacket == NULL)
1132 {
1133 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001134 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 ++pAdapter->stats.tx_dropped;
1136 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1137 kfree_skb(skb);
1138 return VOS_STATUS_E_FAILURE;
1139 }
1140
1141 //Return VOS packet to TL;
1142 *ppVosPacket = pVosPacket;
1143
1144 //Fill out the meta information needed by TL
1145 //FIXME This timestamp is really the time stamp of wrap_data_packet
1146 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1147 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1148 if ( 1 < size )
1149 {
1150 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1151 }
1152 else
1153 {
1154 pPktMetaInfo->bMorePackets = 0;
1155 }
1156
1157 pPktMetaInfo->ucIsEapol = 0;
1158
1159 if(pAdapter->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
1160 {
1161 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1162 {
1163 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001164 "%s: VOS packet is EAPOL packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001165 pPktMetaInfo->ucIsEapol = 1;
1166 }
1167 }
1168
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001169 if (pHddCtx->cfg_ini->gEnableDebugLog)
1170 {
1171 proto_type = vos_pkt_get_proto_type(skb,
1172 pHddCtx->cfg_ini->gEnableDebugLog);
1173 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1174 {
1175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1176 "SAP TX EAPOL");
1177 }
1178 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1179 {
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1181 "SAP TX DHCP");
1182 }
1183 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001184//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001185 {
1186 pPktMetaInfo->ucUP = pktNode->userPriority;
1187 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1188 }
1189
1190 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1191 //Extract the destination address from ethernet frame
1192 pDestMacAddress = (v_MACADDR_t*)skb->data;
1193
1194 // we need 802.3 to 802.11 frame translation
1195 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1196 pPktMetaInfo->ucDisableFrmXtl = 0;
1197 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1198 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1199
1200 if ( (pAdapter->aStaInfo[STAId].txSuspended[ac]) &&
1201 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1202 {
1203 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001204 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001205 pAdapter->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
1206 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
1207 }
1208
1209 // We're giving the packet to TL so consider it transmitted from
1210 // a statistics perspective. We account for it here instead of
1211 // when the packet is returned for two reasons. First, TL will
1212 // manipulate the skb to the point where the len field is not
1213 // accurate, leading to inaccurate byte counts if we account for
1214 // it later. Second, TL does not provide any feedback as to
1215 // whether or not the packet was successfully sent over the air,
1216 // so the packet counts will be the same regardless of where we
1217 // account for them
1218 pAdapter->stats.tx_bytes += skb->len;
1219 ++pAdapter->stats.tx_packets;
1220 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1221 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
1222
1223 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001224 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001225
1226 return status;
1227}
1228
1229
1230/**============================================================================
1231 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1232 case where VOS packets are not available at the time of the call to get
1233 packets. This callback function is invoked by VOS when packets are
1234 available.
1235
1236 @param pVosPacket : [in] pointer to VOS packet
1237 @param userData : [in] opaque user data that was passed initially
1238
1239 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1240 : VOS_STATUS_SUCCESS otherwise
1241 =============================================================================*/
1242VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1243 v_VOID_t *userData )
1244{
1245 VOS_STATUS status;
1246 v_SINT_t i = 0;
1247 v_SIZE_t size = 0;
1248 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1249 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1250
1251 if(pAdapter == NULL)
1252 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001253 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 -07001254 return VOS_STATUS_E_FAILURE;
1255 }
1256
1257 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1258 //situation. Here we will only signal TL that there is a pending data for a STA.
1259 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1260 vos_pkt_return_packet( pVosPacket );
1261
1262 pAdapter->isVosOutOfResource = VOS_FALSE;
1263
1264 // Indicate to TL that there is pending data if a queue is non empty.
1265 // This Code wasnt included in earlier version which resulted in
1266 // Traffic stalling
1267 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1268 {
1269 if ((pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1270 (pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
1271 {
1272 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1273 {
1274 size = 0;
1275 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &size);
1276 if ( size > 0 )
1277 {
1278 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1279 STAId,
1280 (WLANTL_ACEnumType)i );
1281 if( !VOS_IS_STATUS_SUCCESS( status ) )
1282 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001283 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 -07001284 }
1285 }
1286 }
1287 }
1288 }
1289 return VOS_STATUS_SUCCESS;
1290}
1291
1292
1293/**============================================================================
1294 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1295 TL will call this to notify the HDD when one or more packets were
1296 received for a registered STA.
1297
1298 @param vosContext : [in] pointer to VOS context
1299 @param pVosPacketChain : [in] pointer to VOS packet chain
1300 @param staId : [in] Station Id (Adress 1 Index)
1301 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1302
1303 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1304 : VOS_STATUS_SUCCESS otherwise
1305 ===========================================================================*/
1306VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1307 vos_pkt_t *pVosPacketChain,
1308 v_U8_t staId,
1309 WLANTL_RxMetaInfoType* pRxMetaInfo )
1310{
1311 hdd_adapter_t *pAdapter = NULL;
1312 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1313 int rxstat;
1314 struct sk_buff *skb = NULL;
1315 vos_pkt_t* pVosPacket;
1316 vos_pkt_t* pNextVosPacket;
1317 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001318 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001319
1320 //Sanity check on inputs
1321 if ( ( NULL == vosContext ) ||
1322 ( NULL == pVosPacketChain ) ||
1323 ( NULL == pRxMetaInfo ) )
1324 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001325 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001326 return VOS_STATUS_E_FAILURE;
1327 }
1328
1329 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1330 if ( NULL == pHddCtx )
1331 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001332 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 -07001333 return VOS_STATUS_E_FAILURE;
1334 }
1335
1336 pAdapter = pHddCtx->sta_to_adapter[staId];
1337 if( NULL == pAdapter )
1338 {
1339 VOS_ASSERT(0);
1340 return VOS_STATUS_E_FAILURE;
1341 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001342
1343 /* Monitor traffic */
1344 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1345 {
1346 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1347 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1348 {
1349 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1350 /* It was IDLE mode,
1351 * this is new state, then switch mode from suspend to resume */
1352 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1353 {
1354 hdd_set_wlan_suspend_mode(0);
1355 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1356 pHddCtx->cfg_ini->trafficIdleTimeout);
1357 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1358 }
1359 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1360 }
1361 }
1362
Jeff Johnson295189b2012-06-20 16:38:30 -07001363 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1364
1365 // walk the chain until all are processed
1366 pVosPacket = pVosPacketChain;
1367 do
1368 {
1369 // get the pointer to the next packet in the chain
1370 // (but don't unlink the packet since we free the entire chain later)
1371 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1372
1373 // both "success" and "empty" are acceptable results
1374 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1375 {
1376 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001377 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001378 return VOS_STATUS_E_FAILURE;
1379 }
1380
1381 // Extract the OS packet (skb).
1382 // Tell VOS to detach the OS packet from the VOS packet
1383 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
1384 if(!VOS_IS_STATUS_SUCCESS( status ))
1385 {
1386 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001387 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 -07001388 return VOS_STATUS_E_FAILURE;
1389 }
1390
1391 //hdd_softap_dump_sk_buff(skb);
1392
1393 skb->dev = pAdapter->dev;
1394
1395 if(skb->dev == NULL) {
1396
Arif Hussain6d2a3322013-11-17 19:50:10 -08001397 hddLog(VOS_TRACE_LEVEL_FATAL, "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001398 return VOS_STATUS_E_FAILURE;
1399 }
1400 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1401 ++pAdapter->stats.rx_packets;
1402 pAdapter->stats.rx_bytes += skb->len;
1403
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001404 if (pHddCtx->cfg_ini->gEnableDebugLog)
1405 {
1406 proto_type = vos_pkt_get_proto_type(skb,
1407 pHddCtx->cfg_ini->gEnableDebugLog);
1408 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1409 {
1410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1411 "SAP RX EAPOL");
1412 }
1413 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1414 {
1415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1416 "SAP RX DHCP");
1417 }
1418 }
1419
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1421 {
1422 //MC/BC packets. Duplicate a copy of packet
1423 struct sk_buff *pSkbCopy;
1424 hdd_ap_ctx_t *pHddApCtx;
1425
1426 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1427 if (!(pHddApCtx->apDisableIntraBssFwd))
1428 {
1429 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1430 if (pSkbCopy)
1431 {
1432 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1433 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1434 }
1435 }
1436 else
1437 {
1438 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001439 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 }
1441
1442
1443 } //(WLAN_RX_BCMC_STA_ID == staId)
1444
1445 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1446 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1447 {
1448 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001449 "%s: send one packet to kernel", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001450
1451 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001452 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001453#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07001454#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07001455 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07001456#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001457#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 rxstat = netif_rx_ni(skb);
1459 if (NET_RX_SUCCESS == rxstat)
1460 {
1461 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001462 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 }
1464 else
1465 {
1466 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1467 }
1468 }
1469 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1470 {
1471 kfree_skb(skb);
1472 }
1473 else
1474 {
1475 //loopback traffic
1476 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1477 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1478 }
1479
1480 // now process the next packet in the chain
1481 pVosPacket = pNextVosPacket;
1482
1483 } while (pVosPacket);
1484
1485 //Return the entire VOS packet chain to the resource pool
1486 status = vos_pkt_return_packet( pVosPacketChain );
1487 if(!VOS_IS_STATUS_SUCCESS( status ))
1488 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001489 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001490 }
1491
1492 pAdapter->dev->last_rx = jiffies;
1493
1494 return status;
1495}
1496
1497VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1498{
1499 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301500 hdd_context_t *pHddCtx;
1501 if (NULL == pAdapter)
1502 {
1503 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1504 "%s: pAdapter is NULL", __func__);
1505 return VOS_STATUS_E_INVAL;
1506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001507
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301508 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1509 {
1510 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1511 "%s: Invalid pAdapter magic", __func__);
1512 return VOS_STATUS_E_INVAL;
1513 }
1514
1515 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001516 //Clear station in TL and then update HDD data structures. This helps
1517 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301518 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1520 {
1521 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1522 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001523 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001524 staId, vosStatus, vosStatus );
1525 }
1526
1527 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1528 if( VOS_STATUS_E_FAILURE == vosStatus )
1529 {
1530 VOS_TRACE ( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1531 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001532 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001533 staId, vosStatus, vosStatus );
1534 return( vosStatus );
1535 }
1536
1537 pHddCtx->sta_to_adapter[staId] = NULL;
1538
1539 return( vosStatus );
1540}
1541
1542VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1543 v_BOOL_t fAuthRequired,
1544 v_BOOL_t fPrivacyBit,
1545 v_U8_t staId,
1546 v_U8_t ucastSig,
1547 v_U8_t bcastSig,
1548 v_MACADDR_t *pPeerMacAddress,
1549 v_BOOL_t fWmmEnabled )
1550{
1551 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001552 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001553 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1554 hdd_adapter_t *pmonAdapter = NULL;
1555
1556 //eCsrEncryptionType connectedCipherAlgo;
1557 //v_BOOL_t fConnected;
1558
1559 /*
1560 * Clean up old entry if it is not cleaned up properly
1561 */
1562 if ( pAdapter->aStaInfo[staId].isUsed )
1563 {
1564 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1565 "clean up old entry for STA %d", staId);
1566 hdd_softap_DeregisterSTA( pAdapter, staId );
1567 }
1568
1569 // Get the Station ID from the one saved during the assocation.
1570
1571 staDesc.ucSTAId = staId;
1572
1573
1574 /*Save the pAdapter Pointer for this staId*/
1575 pHddCtx->sta_to_adapter[staId] = pAdapter;
1576
1577 staDesc.wSTAType = WLAN_STA_SOFTAP;
1578
1579 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1580 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1581 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1582
1583 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001584 "register station");
Jeff Johnson295189b2012-06-20 16:38:30 -07001585 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001586 "station mac " MAC_ADDRESS_STR,
1587 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001589 "BSSIDforIBSS " MAC_ADDRESS_STR,
1590 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001591 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001592 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1593 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001594
1595 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1596
Jeff Johnson295189b2012-06-20 16:38:30 -07001597 staDesc.ucQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001598 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1599 "HDD SOFTAP register TL QoS_enabled=%d",
1600 staDesc.ucQosEnabled );
1601
1602 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1603
1604
Jeff Johnson295189b2012-06-20 16:38:30 -07001605 // For PRIMA UMA frame translation is not enable yet.
1606 staDesc.ucSwFrameTXXlation = 1;
1607 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001608 staDesc.ucAddRmvLLC = 1;
1609
1610 // Initialize signatures and state
1611 staDesc.ucUcastSig = ucastSig;
1612 staDesc.ucBcastSig = bcastSig;
1613 staDesc.ucInitState = fAuthRequired ?
1614 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1615
Prathyushaf5442802012-12-12 13:58:11 -08001616 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1617
Jeff Johnson295189b2012-06-20 16:38:30 -07001618 // Register the Station with TL...
1619 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1620 hdd_softap_rx_packet_cbk,
1621 hdd_softap_tx_complete_cbk,
1622 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1623
1624 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1625 {
1626 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001627 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001628 vosStatus, vosStatus );
1629 return vosStatus;
1630 }
1631
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001632 //Timer value should be in milliseconds
1633 if ( pHddCtx->cfg_ini->dynSplitscan &&
1634 ( VOS_TIMER_STATE_RUNNING !=
1635 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1636 {
1637 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1638 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1639 }
1640
Jeff Johnson295189b2012-06-20 16:38:30 -07001641 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1642 // then go to 'authenticated'. For all other authentication types (those that do
1643 // not require upper layer authentication) we can put TL directly into 'authenticated'
1644 // state.
1645
1646 //VOS_ASSERT( fConnected );
1647 pAdapter->aStaInfo[staId].ucSTAId = staId;
1648 pAdapter->aStaInfo[staId].isQosEnabled = fWmmEnabled;
1649
1650 if ( !fAuthRequired )
1651 {
1652 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1653 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", pAdapter->aStaInfo[staId].ucSTAId );
1654
1655 // Connections that do not need Upper layer auth, transition TL directly
1656 // to 'Authenticated' state.
1657 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1658 WLANTL_STA_AUTHENTICATED );
1659
1660 pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
1661 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1662 }
1663 else
1664 {
1665
1666 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1667 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pAdapter->aStaInfo[staId].ucSTAId );
1668
1669 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1670 WLANTL_STA_CONNECTED );
1671 pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
1672
1673 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1674
1675 }
1676 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1677 if(pmonAdapter)
1678 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001679 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 netif_carrier_on(pmonAdapter->dev);
1681 //Enable Tx queue
1682 netif_tx_start_all_queues(pmonAdapter->dev);
1683 }
1684 netif_carrier_on(pAdapter->dev);
1685 //Enable Tx queue
1686 netif_tx_start_all_queues(pAdapter->dev);
1687
1688 return( vosStatus );
1689}
1690
1691VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1692{
1693 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1694 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1695 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1696
1697
1698 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1699 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1700 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1701
1702 return vosStatus;
1703}
1704
1705VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1706{
1707 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1708}
1709
1710VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1711{
Wilson Yangf80a0542013-10-07 13:02:37 -07001712 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07001713 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1714 v_U8_t staId = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07001715 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1716
1717 /*bss deregister is not allowed during wlan driver loading or unloading*/
1718 if (pHddCtx->isLoadUnloadInProgress)
1719 {
1720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
1722 return VOS_STATUS_E_PERM;
1723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001724
1725 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
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 BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 }
1732
1733 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
1734 {
1735 if (pAdapter->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
1736 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
1737
Jeff Johnson43971f52012-07-17 12:26:56 -07001738 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 {
1740 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001741 "%s: Failed to deregister sta Id %d", __func__, staId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 }
1743 }
1744
1745 return vosStatus;
1746}
1747
1748VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
1749{
1750 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
1751 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
1752 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001753
1754 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001755 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001756
Jeff Johnson43971f52012-07-17 12:26:56 -07001757 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07001758 {
1759 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001760 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001761 return VOS_STATUS_E_FAILURE;
1762 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001763
1764 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
1765 {
1766 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001767 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 return VOS_STATUS_E_FAILURE;
1769 }
1770
1771 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
1772 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001773 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07001774
Jeff Johnson43971f52012-07-17 12:26:56 -07001775 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001776 {
1777 pAdapter->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
1778 }
1779
1780 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001781 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001782
1783 return vosStatus;
1784}
1785
1786
1787VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
1788{
1789 v_U8_t i;
1790
1791 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
1792 {
1793 if (vos_mem_compare(&pAdapter->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
1794 pAdapter->aStaInfo[i].isUsed)
1795 {
1796 *staId = i;
1797 return VOS_STATUS_SUCCESS;
1798 }
1799 }
1800
1801 return VOS_STATUS_E_FAILURE;
1802}
1803
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05301804VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
1805{
1806 v_U8_t i;
1807
1808 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
1809 {
Kiet Lam61589852013-09-19 17:10:58 +05301810 if (pAdapter->aStaInfo[i].isUsed &&
1811 (!vos_is_macaddr_broadcast(&pAdapter->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05301812 {
1813 *staId = i;
1814 return VOS_STATUS_SUCCESS;
1815 }
1816 }
1817
1818 return VOS_STATUS_E_FAILURE;
1819}