blob: 2d2bb0f18182415b3477db5306843517b4c3175d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -07005 */
6
7/**===========================================================================
8
9 \file wlan_hdd_softap_tx_rx.c
10
11 \brief Linux HDD Tx/RX APIs
Kiet Lamaa8e15a2014-02-11 23:30:06 -080012 Copyright 2008 (c) Qualcomm, Incorporated.
13 All Rights Reserved.
14 Qualcomm Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070015
16 ==========================================================================*/
Jeff Johnson295189b2012-06-20 16:38:30 -070017
18/*---------------------------------------------------------------------------
19 Include files
20 -------------------------------------------------------------------------*/
21#include <linux/semaphore.h>
22#include <wlan_hdd_tx_rx.h>
23#include <wlan_hdd_softap_tx_rx.h>
24#include <wlan_hdd_dp_utils.h>
25#include <wlan_qct_tl.h>
26#include <linux/netdevice.h>
27#include <linux/skbuff.h>
28#include <linux/etherdevice.h>
29//#include <vos_list.h>
30#include <vos_types.h>
31#include <aniGlobal.h>
32#include <halTypes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070033#include <net/ieee80211_radiotap.h>
34
35
36/*---------------------------------------------------------------------------
37 Preprocessor definitions and constants
38 -------------------------------------------------------------------------*/
39
40/*---------------------------------------------------------------------------
41 Type declarations
42 -------------------------------------------------------------------------*/
43
44/*---------------------------------------------------------------------------
45 Function definitions and documenation
46 -------------------------------------------------------------------------*/
47#if 0
48static void hdd_softap_dump_sk_buff(struct sk_buff * skb)
49{
Arif Hussain6d2a3322013-11-17 19:50:10 -080050 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head);
51 //VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data);
52 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail);
53 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end);
54 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
55 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
56 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 -070057
Arif Hussain6d2a3322013-11-17 19:50:10 -080058 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 -070059 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
60 skb->data[5], skb->data[6], skb->data[7]);
Arif Hussain6d2a3322013-11-17 19:50:10 -080061 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 -070062 skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
63 skb->data[13], skb->data[14], skb->data[15]);
64}
65#endif
Leo Chang64d68bc2013-06-04 15:40:52 -070066
67extern void hdd_set_wlan_suspend_mode(bool suspend);
68
69/**============================================================================
70 @brief hdd_softap_traffic_monitor_timeout_handler() -
71 SAP/P2P GO traffin monitor timeout handler function
72 If no traffic during programmed time, trigger suspand mode
73
74 @param pUsrData : [in] pointer to hdd context
75 @return : NONE
76 ===========================================================================*/
77void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData )
78{
79 hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData;
80 v_TIME_t currentTS;
81
82 if (NULL == pHddCtx)
83 {
84 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
85 "%s: Invalid user data, context", __func__);
86 return;
87 }
88
89 currentTS = vos_timer_get_system_time();
90 if (pHddCtx->cfg_ini->trafficIdleTimeout <
91 (currentTS - pHddCtx->traffic_monitor.lastFrameTs))
92 {
Kiet Lambcf38522013-10-26 18:28:27 +053093 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
94 "%s: No Data Activity calling Wlan Suspend", __func__ );
Leo Chang64d68bc2013-06-04 15:40:52 -070095 hdd_set_wlan_suspend_mode(1);
96 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0);
97 }
98 else
99 {
100 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
101 pHddCtx->cfg_ini->trafficIdleTimeout);
102 }
103
104 return;
105}
106
Kiet Lambcf38522013-10-26 18:28:27 +0530107VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter )
108{
109
110 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
111 VOS_STATUS status = VOS_STATUS_SUCCESS;
112
113 status = wlan_hdd_validate_context(pHddCtx);
114
115 if (0 != status)
116 {
117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
118 "%s: HDD context is not valid", __func__);
119 return status;
120 }
121
122 if ((pHddCtx->cfg_ini->enableTrafficMonitor) &&
123 (!pHddCtx->traffic_monitor.isInitialized))
124 {
125 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
126 vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer,
127 VOS_TIMER_TYPE_SW,
128 hdd_softap_traffic_monitor_timeout_handler,
129 pHddCtx);
130 vos_lock_init(&pHddCtx->traffic_monitor.trafficLock);
131 pHddCtx->traffic_monitor.isInitialized = 1;
132 pHddCtx->traffic_monitor.lastFrameTs = 0;
133 /* Start traffic monitor timer here
134 * If no AP assoc, immediatly go into suspend */
135 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
136 "%s Start Traffic Monitor Timer", __func__);
137 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
138 pHddCtx->cfg_ini->trafficIdleTimeout);
139 }
140 else
141 {
142 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
143 "%s Traffic Monitor is not Enable in ini file", __func__);
144 }
145 return status;
146}
147
148VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter )
149{
150 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
151 VOS_STATUS status = VOS_STATUS_SUCCESS;
152
153 status = wlan_hdd_validate_context(pHddCtx);
154
Kiet Lamae69d7a2013-11-08 14:38:04 +0530155 if (-ENODEV == status)
Kiet Lambcf38522013-10-26 18:28:27 +0530156 {
157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
158 "%s: HDD context is not valid", __func__);
159 return status;
160 }
161
162 if (pHddCtx->traffic_monitor.isInitialized)
163 {
164 if (VOS_TIMER_STATE_STOPPED !=
165 vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer))
166 {
167 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
168 "%s Stop Traffic Monitor Timer", __func__);
169 vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer);
170 }
171 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
172 "%s Destroy Traffic Monitor Timer", __func__);
173 vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer);
174 vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock);
175 pHddCtx->traffic_monitor.isInitialized = 0;
176 }
Kiet Lamae69d7a2013-11-08 14:38:04 +0530177 return VOS_STATUS_SUCCESS;
Kiet Lambcf38522013-10-26 18:28:27 +0530178}
179
Jeff Johnson295189b2012-06-20 16:38:30 -0700180/**============================================================================
181 @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues
182
183 @param pAdapter : [in] pointer to adapter context
184 @return : VOS_STATUS_E_FAILURE if any errors encountered
185 : VOS_STATUS_SUCCESS otherwise
186 ===========================================================================*/
187static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
188{
189 VOS_STATUS status = VOS_STATUS_SUCCESS;
190 v_SINT_t i = -1;
191 v_U8_t STAId = 0;
192 hdd_list_node_t *anchor = NULL;
193 skb_list_node_t *pktNode = NULL;
194 struct sk_buff *skb = NULL;
195
196 spin_lock_bh( &pAdapter->staInfo_lock );
197 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
198 {
199 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
200 {
201 continue;
202 }
203
204 for (i = 0; i < NUM_TX_QUEUES; i ++)
205 {
206 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
207 while (true)
208 {
209 status = hdd_list_remove_front ( &pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
210
211 if (VOS_STATUS_E_EMPTY != status)
212 {
213 //If success then we got a valid packet from some AC
214 pktNode = list_entry(anchor, skb_list_node_t, anchor);
215 skb = pktNode->skb;
216 ++pAdapter->stats.tx_dropped;
217 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
218 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
219 kfree_skb(skb);
220 continue;
221 }
222
223 //current list is empty
224 break;
225 }
226 pAdapter->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
227 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
228 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530229 pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700230 }
231
232 spin_unlock_bh( &pAdapter->staInfo_lock );
233
234 return status;
235}
236
237/**============================================================================
238 @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for
239 transmitting packets. There are 2 versions of this function. One that uses
240 locked queue and other that uses lockless queues. Both have been retained to
241 do some performance testing
242
243 @param skb : [in] pointer to OS packet (sk_buff)
244 @param dev : [in] pointer to Libra network device
245
246 @return : NET_XMIT_DROP if packets are dropped
247 : NET_XMIT_SUCCESS if packet is enqueued succesfully
248 ===========================================================================*/
249int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
250{
251 VOS_STATUS status;
252 WLANTL_ACEnumType ac = WLANTL_AC_BE;
253 sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
254 skb_list_node_t *pktNode = NULL;
255 v_SIZE_t pktListSize = 0;
256 v_BOOL_t txSuspended = VOS_FALSE;
257 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
258 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
259 vos_list_node_t *anchor = NULL;
260 v_U8_t STAId = WLAN_MAX_STA_COUNT;
261 //Extract the destination address from ethernet frame
262 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
263 int os_status = NETDEV_TX_OK;
264
265 pDestMacAddress = (v_MACADDR_t*)skb->data;
266
267 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
268
269 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700270 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700271
272 spin_lock_bh( &pAdapter->staInfo_lock );
273 if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress))
274 {
275 //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station
276 //ID used for BC/MC traffic. The station id is registered to TL as well.
277 STAId = pHddApCtx->uBCStaId;
278
279 /* Setting priority for broadcast packets which doesn't go to select_queue function */
280 skb->priority = SME_QOS_WMM_UP_BE;
281 skb->queue_mapping = HDD_LINUX_AC_BE;
282
283 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800284 "%s: BC/MC packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700285 }
286 else
287 {
288 STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
289 if (STAId == HDD_WLAN_INVALID_STA_ID)
290 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700291 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700292 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 ++pAdapter->stats.tx_dropped;
294 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
295 kfree_skb(skb);
296 goto xmit_done;
297 }
298 else if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
299 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530300 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 -0700301 ++pAdapter->stats.tx_dropped;
302 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
303 kfree_skb(skb);
304 goto xmit_done;
305 }
306
307 if ( (WLANTL_STA_CONNECTED != pAdapter->aStaInfo[STAId].tlSTAState) &&
308 (WLANTL_STA_AUTHENTICATED != pAdapter->aStaInfo[STAId].tlSTAState) )
309 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700310 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700311 "%s: Station not connected yet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 ++pAdapter->stats.tx_dropped;
313 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
314 kfree_skb(skb);
315 goto xmit_done;
316 }
317 else if(WLANTL_STA_CONNECTED == pAdapter->aStaInfo[STAId].tlSTAState)
318 {
319 if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X)
320 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700321 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700322 "%s: NON-EAPOL packet in non-Authenticated state", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 ++pAdapter->stats.tx_dropped;
324 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
325 kfree_skb(skb);
326 goto xmit_done;
327 }
328 }
329 }
330
331 //Get TL AC corresponding to Qdisc queue index/AC.
332 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
333 //user priority from IP header, which is already extracted and set from
334 //select_queue call back function
335 up = skb->priority;
336 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
337
338 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700339 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700340
341 // If the memory differentiation mode is enabled, the memory limit of each queue will be
342 // checked. Over-limit packets will be dropped.
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700343 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700344 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
345 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
346 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700347 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800348 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700349 pAdapter->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
350 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
351 txSuspended = VOS_TRUE;
352 }
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530353
354 /* If 3/4th of the max queue size is used then enable the flag.
355 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
356 if (WLANTL_AC_BE == ac)
357 {
358 if (pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
359 {
360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
361 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
362 pAdapter->aStaInfo[STAId].vosLowResource = VOS_TRUE;
363 }
364 else
365 {
366 pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
367 }
368 }
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700369 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370
371 if (VOS_TRUE == txSuspended)
372 {
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
374 "%s: TX queue full for AC=%d Disable OS TX queue",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700375 __func__, ac );
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 os_status = NETDEV_TX_BUSY;
377 goto xmit_done;
378 }
379
380 //Use the skb->cb field to hold the list node information
381 pktNode = (skb_list_node_t *)&skb->cb;
382
383 //Stick the OS packet inside this node.
384 pktNode->skb = skb;
385
386 //Stick the User Priority inside this node
387 pktNode->userPriority = up;
388
389 INIT_LIST_HEAD(&pktNode->anchor);
390
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700391 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700392 status = hdd_list_insert_back_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700393 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700394
395 if ( !VOS_IS_STATUS_SUCCESS( status ) )
396 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700397 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 -0700398 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
399 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
400 ++pAdapter->stats.tx_dropped;
401 kfree_skb(skb);
402 goto xmit_done;
403 }
404
405 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
406 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
Rashmi Ramannacbffcb12014-01-07 13:22:13 +0530407 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700408
409 if (1 == pktListSize)
410 {
411 //Let TL know we have a packet to send for this AC
412 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
413
414 if ( !VOS_IS_STATUS_SUCCESS( status ) )
415 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700416 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 -0700417 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700418
419 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
420 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
421 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
422 status = hdd_list_remove_back( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
423 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
424 ++pAdapter->stats.tx_dropped;
425 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
426 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
427 kfree_skb(skb);
428 goto xmit_done;
429 }
430 }
431 dev->trans_start = jiffies;
432
Arif Hussain6d2a3322013-11-17 19:50:10 -0800433 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700434
435xmit_done:
436 spin_unlock_bh( &pAdapter->staInfo_lock );
437 return os_status;
438}
439
440/**============================================================================
441 @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations.
442
443 @param skb : [in] pointer to packet (sk_buff)
444 @param dev : [in] pointer to Libra network device
445 @param STAId : [in] Station Id of Destination Station
446 @param up : [in] User Priority
447
448 @return : NET_XMIT_DROP if packets are dropped
449 : NET_XMIT_SUCCESS if packet is enqueued succesfully
450 ===========================================================================*/
451VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb,
452 struct net_device *dev,
453 v_U8_t STAId,
454 v_U8_t up)
455{
456 VOS_STATUS status = VOS_STATUS_SUCCESS;
457 skb_list_node_t *pktNode = NULL;
458 v_SIZE_t pktListSize = 0;
459 hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
460 v_U8_t ac;
461 vos_list_node_t *anchor = NULL;
462
463 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
464
465 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700466 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700467
468 spin_lock_bh( &pAdapter->staInfo_lock );
469 if ( FALSE == pAdapter->aStaInfo[STAId].isUsed )
470 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700471 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530472 "%s: STA %d is unregistered", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700473 kfree_skb(skb);
474 status = VOS_STATUS_E_FAILURE;
475 goto xmit_end;
476 }
477
478 /* If the QoS is not enabled on the receiving station, then send it with BE priority */
479 if ( !pAdapter->aStaInfo[STAId].isQosEnabled )
480 up = SME_QOS_WMM_UP_BE;
481
482 ac = hddWmmUpToAcMap[up];
483 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
484 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700485 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700486
487 skb->queue_mapping = hddLinuxUpToAcMap[up];
488
489 //Use the skb->cb field to hold the list node information
490 pktNode = (skb_list_node_t *)&skb->cb;
491
492 //Stick the OS packet inside this node.
493 pktNode->skb = skb;
494
495 //Stick the User Priority inside this node
496 pktNode->userPriority = up;
497
498 INIT_LIST_HEAD(&pktNode->anchor);
499
500 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
501 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
502 if(pAdapter->aStaInfo[STAId].txSuspended[ac] ||
503 pktListSize >= pAdapter->aTxQueueLimit[ac])
504 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700505 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_WARN,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800506 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700507 /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side.
508 * SUSPEND should be done based on Threshold. RESUME would be
509 * triggered in fetch cbk after recovery.
510 */
511 kfree_skb(skb);
512 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
513 status = VOS_STATUS_E_FAILURE;
514 goto xmit_end;
515 }
516 status = hdd_list_insert_back_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize );
517 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
518
519 if ( !VOS_IS_STATUS_SUCCESS( status ) )
520 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700521 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 -0700522 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
523 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
524 ++pAdapter->stats.tx_dropped;
525 kfree_skb(skb);
526 status = VOS_STATUS_E_FAILURE;
527 goto xmit_end;
528 }
529
530 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
531 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
532
533 if (1 == pktListSize)
534 {
535 //Let TL know we have a packet to send for this AC
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700536 //VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700537 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac );
538
539 if ( !VOS_IS_STATUS_SUCCESS( status ) )
540 {
Madan Mohan Koyyalamudi60a6a8d2012-10-21 11:57:42 -0700541 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 -0700542 __func__, ac, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700543
544 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
545 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
546 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
547 status = hdd_list_remove_back( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor);
548 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
549 ++pAdapter->stats.tx_dropped;
550 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
551 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
552 kfree_skb(skb);
553 status = VOS_STATUS_E_FAILURE;
554 goto xmit_end;
555 }
556 }
557
Arif Hussain6d2a3322013-11-17 19:50:10 -0800558 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700559
560xmit_end:
561 spin_unlock_bh( &pAdapter->staInfo_lock );
562 return status;
563}
564
565/**============================================================================
566 @brief hdd_softap_tx_timeout() - Function called by OS if there is any
567 timeout during transmission. Since HDD simply enqueues packet
568 and returns control to OS right away, this would never be invoked
569
570 @param dev : [in] pointer to Libra network device
571 @return : None
572 ===========================================================================*/
573void hdd_softap_tx_timeout(struct net_device *dev)
574{
575 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700576 "%s: Transmission timeout occurred", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700577 //Getting here implies we disabled the TX queues for too long. Queues are
578 //disabled either because of disassociation or low resource scenarios. In
579 //case of disassociation it is ok to ignore this. But if associated, we have
580 //do possible recovery here
581}
582
583
584/**============================================================================
585 @brief hdd_softap_stats() - Function registered with the Linux OS for
586 device TX/RX statistic
587
588 @param dev : [in] pointer to Libra network device
589
590 @return : pointer to net_device_stats structure
591 ===========================================================================*/
592struct net_device_stats* hdd_softap_stats(struct net_device *dev)
593{
594 hdd_adapter_t* priv = netdev_priv(dev);
595 return &priv->stats;
596}
597
598
599/**============================================================================
600 @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX
601 modules in HDD
602
603 @param pAdapter : [in] pointer to adapter context
604 @return : VOS_STATUS_E_FAILURE if any errors encountered
605 : VOS_STATUS_SUCCESS otherwise
606 ===========================================================================*/
607VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
608{
609 VOS_STATUS status = VOS_STATUS_SUCCESS;
610 v_SINT_t i = -1;
611 v_SIZE_t size = 0;
612
613 v_U8_t STAId = 0;
614
615 v_U8_t pACWeights[] = {
616 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
617 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
618 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
619 HDD_SOFTAP_VO_WEIGHT_DEFAULT
620 };
Leo Chang64d68bc2013-06-04 15:40:52 -0700621
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530623 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700624
625 vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
626
627 while (++i != NUM_TX_QUEUES)
628 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
629
630 /* Initial HDD buffer control / flow control fields*/
631 vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size);
632
633 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
634 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
635 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
636 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
637
638 spin_lock_init( &pAdapter->staInfo_lock );
639
640 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
641 {
642 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
643 for (i = 0; i < NUM_TX_QUEUES; i ++)
644 {
645 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
646 }
647 }
648
Yue Ma3ede6052013-08-29 00:33:26 -0700649 /* Update the AC weights suitable for SoftAP mode of operation */
650 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
651
Kiet Lambcf38522013-10-26 18:28:27 +0530652 if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter))
Leo Chang64d68bc2013-06-04 15:40:52 -0700653 {
Kiet Lambcf38522013-10-26 18:28:27 +0530654 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
655 "%s: failed to start Traffic Monito timer ", __func__ );
656 return VOS_STATUS_E_INVAL;
Leo Chang64d68bc2013-06-04 15:40:52 -0700657 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 return status;
659}
660
661/**============================================================================
662 @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX
663 modules in HDD
664
665 @param pAdapter : [in] pointer to adapter context
666 @return : VOS_STATUS_E_FAILURE if any errors encountered
667 : VOS_STATUS_SUCCESS otherwise
668 ===========================================================================*/
669VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter )
670{
671 VOS_STATUS status = VOS_STATUS_SUCCESS;
Leo Chang64d68bc2013-06-04 15:40:52 -0700672
Kiet Lambcf38522013-10-26 18:28:27 +0530673 if (VOS_STATUS_SUCCESS != hdd_stop_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: Fail to Stop 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
680 status = hdd_softap_flush_tx_queues(pAdapter);
681
682 return status;
683}
684
685/**============================================================================
686 @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station
687
688 @param pAdapter : [in] pointer to adapter context
689 @param STAId : [in] Station ID to deinit
690 @return : VOS_STATUS_E_FAILURE if any errors encountered
691 : VOS_STATUS_SUCCESS otherwise
692 ===========================================================================*/
693static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId )
694{
695 VOS_STATUS status = VOS_STATUS_SUCCESS;
696 v_U8_t i = -1;
697
698 hdd_list_node_t *anchor = NULL;
699
700 skb_list_node_t *pktNode = NULL;
701 struct sk_buff *skb = NULL;
702
703 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
704 {
705 return status;
706 }
707
708 for (i = 0; i < NUM_TX_QUEUES; i ++)
709 {
710 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
711 while (true)
712 {
713 status = hdd_list_remove_front ( &pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &anchor);
714 if (VOS_STATUS_E_EMPTY != status)
715 {
716 //If success then we got a valid packet from some AC
717 pktNode = list_entry(anchor, skb_list_node_t, anchor);
718 skb = pktNode->skb;
719 ++pAdapter->stats.tx_dropped;
720 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
721 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
722 kfree_skb(skb);
723 continue;
724 }
725
726 //current list is empty
727 break;
728 }
729 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
730 }
731
732 return status;
733}
734
735/**============================================================================
736 @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX
737 modules in HDD
738
739 @param pAdapter : [in] pointer to adapter context
740 @param STAId : [in] Station ID to deinit
741 @param pmacAddrSTA : [in] pointer to the MAC address of the station
742 @return : VOS_STATUS_E_FAILURE if any errors encountered
743 : VOS_STATUS_SUCCESS otherwise
744 ===========================================================================*/
745VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA)
746{
747 v_U8_t i = 0;
748 spin_lock_bh( &pAdapter->staInfo_lock );
749 if (pAdapter->aStaInfo[STAId].isUsed)
750 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700751 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR, "%s: Reinit station %d", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700752 spin_unlock_bh( &pAdapter->staInfo_lock );
753 return VOS_STATUS_E_FAILURE;
754 }
755
756 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
757 for (i = 0; i < NUM_TX_QUEUES; i ++)
758 {
759 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
760 }
761
762 pAdapter->aStaInfo[STAId].isUsed = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800763 pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700764 vos_copy_macaddr( &pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
765
766 spin_unlock_bh( &pAdapter->staInfo_lock );
767 return VOS_STATUS_SUCCESS;
768}
769
770/**============================================================================
771 @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX
772 modules in HDD
773
774 @param pAdapter : [in] pointer to adapter context
775 @param STAId : [in] Station ID to deinit
776 @return : VOS_STATUS_E_FAILURE if any errors encountered
777 : VOS_STATUS_SUCCESS otherwise
778 ===========================================================================*/
779VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId )
780{
781 VOS_STATUS status = VOS_STATUS_SUCCESS;
782 v_U8_t ac;
783 /**Track whether OS TX queue has been disabled.*/
784 v_BOOL_t txSuspended[NUM_TX_QUEUES];
785 v_U8_t tlAC;
786 hdd_hostapd_state_t *pHostapdState;
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700787 v_U8_t i;
Jeff Johnson295189b2012-06-20 16:38:30 -0700788
789 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
790
791 spin_lock_bh( &pAdapter->staInfo_lock );
792 if (FALSE == pAdapter->aStaInfo[STAId].isUsed)
793 {
794 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700795 "%s: Deinit station not inited %d", __func__, STAId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700796 spin_unlock_bh( &pAdapter->staInfo_lock );
797 return VOS_STATUS_E_FAILURE;
798 }
799
800 status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId);
801
802 pAdapter->aStaInfo[STAId].isUsed = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -0800803 pAdapter->aStaInfo[STAId].isDeauthInProgress = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700804
805 /* if this STA had any of its WMM TX queues suspended, then the
806 associated queue on the network interface was disabled. check
807 to see if that is the case, in which case we need to re-enable
808 the interface queue. but we only do this if the BSS is running
809 since, if the BSS is stopped, all of the interfaces have been
810 stopped and should not be re-enabled */
811
812 if (BSS_START == pHostapdState->bssState)
813 {
814 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
815 {
816 tlAC = hdd_QdiscAcToTlAC[ac];
817 txSuspended[ac] = pAdapter->aStaInfo[STAId].txSuspended[tlAC];
818 }
819 }
820 vos_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
821
Rajesh Chauhan52d885b2013-11-01 10:54:25 -0700822 /* re-init spin lock, since netdev can still open adapter until
823 * driver gets unloaded
824 */
825 for (i = 0; i < NUM_TX_QUEUES; i ++)
826 {
827 hdd_list_init(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i],
828 HDD_TX_QUEUE_MAX_LEN);
829 }
830
Jeff Johnson295189b2012-06-20 16:38:30 -0700831 if (BSS_START == pHostapdState->bssState)
832 {
833 for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++)
834 {
835 if (txSuspended[ac])
836 {
837 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700838 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 netif_wake_subqueue(pAdapter->dev, ac);
840 }
841 }
842 }
843
844 spin_unlock_bh( &pAdapter->staInfo_lock );
845 return status;
846}
847
848/**============================================================================
849 @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
850 modules in HDD
851
852 @param pAdapter : [in] pointer to adapter context
853 @return : VOS_STATUS_E_FAILURE if any errors encountered
854 : VOS_STATUS_SUCCESS otherwise
855 ===========================================================================*/
856VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter )
857{
858 return hdd_softap_flush_tx_queues(pAdapter);
859}
860
861/**============================================================================
862 @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL
863 to indicate that a packet has been transmitted across the bus
864 succesfully. OS packet resources can be released after this cbk.
865
866 @param vosContext : [in] pointer to VOS context
867 @param pVosPacket : [in] pointer to VOS packet (containing skb)
868 @param vosStatusIn : [in] status of the transmission
869
870 @return : VOS_STATUS_E_FAILURE if any errors encountered
871 : VOS_STATUS_SUCCESS otherwise
872 ===========================================================================*/
873VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext,
874 vos_pkt_t *pVosPacket,
875 VOS_STATUS vosStatusIn )
876{
877 VOS_STATUS status = VOS_STATUS_SUCCESS;
878 hdd_adapter_t *pAdapter = NULL;
879 void* pOsPkt = NULL;
880
881 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
882 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700883 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 return VOS_STATUS_E_FAILURE;
885 }
886
887 //Return the skb to the OS
888 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Rajesh Chauhana0516c62014-01-30 16:11:18 -0800889 if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt))
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 {
891 //This is bad but still try to free the VOSS resources if we can
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700892 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 -0700893 vos_pkt_return_packet( pVosPacket );
894 return VOS_STATUS_E_FAILURE;
895 }
896
897 //Get the Adapter context.
898 pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev);
899 if(pAdapter == NULL)
900 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700901 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 -0700902 }
903 else
904 {
905 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
906 }
907
908 kfree_skb((struct sk_buff *)pOsPkt);
909
910 //Return the VOS packet resources.
911 status = vos_pkt_return_packet( pVosPacket );
912 if(!VOS_IS_STATUS_SUCCESS( status ))
913 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700914 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 -0700915 }
916
917 return status;
918}
919
920
921/**============================================================================
922 @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to
923 fetch a packet for transmission.
924
925 @param vosContext : [in] pointer to VOS context
926 @param staId : [in] Station for which TL is requesting a pkt
927 @param ac : [in] access category requested by TL
928 @param pVosPacket : [out] pointer to VOS packet packet pointer
929 @param pPktMetaInfo : [out] pointer to meta info for the pkt
930
931 @return : VOS_STATUS_E_EMPTY if no packets to transmit
932 : VOS_STATUS_E_FAILURE if any errors encountered
933 : VOS_STATUS_SUCCESS otherwise
934 ===========================================================================*/
935VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext,
936 v_U8_t *pStaId,
937 WLANTL_ACEnumType ac,
938 vos_pkt_t **ppVosPacket,
939 WLANTL_MetaInfoType *pPktMetaInfo )
940{
941 VOS_STATUS status = VOS_STATUS_E_FAILURE;
942 hdd_adapter_t *pAdapter = NULL;
943 hdd_list_node_t *anchor = NULL;
944 skb_list_node_t *pktNode = NULL;
945 struct sk_buff *skb = NULL;
946 vos_pkt_t *pVosPacket = NULL;
947 v_MACADDR_t* pDestMacAddress = NULL;
948 v_TIME_t timestamp;
949 v_SIZE_t size = 0;
950 v_U8_t STAId = WLAN_MAX_STA_COUNT;
951 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -0800952 v_U8_t proto_type = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700953
954 //Sanity check on inputs
955 if ( ( NULL == vosContext ) ||
956 ( NULL == pStaId ) ||
957 ( NULL == ppVosPacket ) ||
958 ( NULL == pPktMetaInfo ) )
959 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700960 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700961 return VOS_STATUS_E_FAILURE;
962 }
963
964 //Get the HDD context.
965 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
966 if ( NULL == pHddCtx )
967 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700968 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 -0700969 return VOS_STATUS_E_FAILURE;
970 }
971
Jeff Johnsonb156c922013-12-05 17:19:46 -0800972 STAId = *pStaId;
973 if (STAId >= WLAN_MAX_STA_COUNT)
974 {
975 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
976 "%s: Invalid STAId %d passed by TL", __func__, STAId);
977 return VOS_STATUS_E_FAILURE;
978 }
979
980 pAdapter = pHddCtx->sta_to_adapter[STAId];
981 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 {
983 VOS_ASSERT(0);
984 return VOS_STATUS_E_FAILURE;
985 }
986
Jeff Johnsonb156c922013-12-05 17:19:46 -0800987 if (FALSE == pAdapter->aStaInfo[STAId].isUsed )
988 {
989 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
990 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
991 return VOS_STATUS_E_FAILURE;
992 }
993
Leo Chang64d68bc2013-06-04 15:40:52 -0700994 /* Monitor traffic */
995 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
996 {
997 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
998 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
999 {
1000 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1001 /* It was IDLE mode,
1002 * this is new state, then switch mode from suspend to resume */
1003 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1004 {
1005 hdd_set_wlan_suspend_mode(0);
1006 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1007 pHddCtx->cfg_ini->trafficIdleTimeout);
1008 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1009 }
1010 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1011 }
1012 }
1013
Jeff Johnson295189b2012-06-20 16:38:30 -07001014 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1015
Jeff Johnson295189b2012-06-20 16:38:30 -07001016 *ppVosPacket = NULL;
1017
1018 //Make sure the AC being asked for is sane
1019 if( ac > WLANTL_MAX_AC || ac < 0)
1020 {
1021 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001022 "%s: Invalid AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 return VOS_STATUS_E_FAILURE;
1024 }
1025
1026 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1027
1028 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001029 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001030
1031 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1032 //This simplifies the locking and unlocking of Tx queue
1033 status = vos_pkt_wrap_data_packet( &pVosPacket,
1034 VOS_PKT_TYPE_TX_802_3_DATA,
1035 NULL, //OS Pkt is not being passed
1036 hdd_softap_tx_low_resource_cbk,
1037 pAdapter );
1038
1039 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1040 {
1041 //Remember VOS is in a low resource situation
1042 pAdapter->isVosOutOfResource = VOS_TRUE;
1043 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
1044 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001045 "%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1047 return VOS_STATUS_E_FAILURE;
1048 }
1049
1050 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC
1051 as the other branch does.
1052 */
1053 spin_lock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1054 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &size);
1055
1056 if (0 == size)
1057 {
1058 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1059 vos_pkt_return_packet(pVosPacket);
1060 return VOS_STATUS_E_EMPTY;
1061 }
1062
1063 status = hdd_list_remove_front( &pAdapter->aStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1064 spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);
1065
1066 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001067 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001068
1069 if(VOS_STATUS_SUCCESS == status)
1070 {
1071 //If success then we got a valid packet from some AC
1072 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1073 skb = pktNode->skb;
1074 }
1075 else
1076 {
1077 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1078 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1079 "%s: Error in de-queuing skb from Tx queue status = %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001080 __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 vos_pkt_return_packet(pVosPacket);
1082 return VOS_STATUS_E_FAILURE;
1083 }
1084
1085 //Attach skb to VOS packet.
1086 status = vos_pkt_set_os_packet( pVosPacket, skb );
1087 if (status != VOS_STATUS_SUCCESS)
1088 {
1089 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001090 "%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001091 vos_pkt_return_packet(pVosPacket);
1092 ++pAdapter->stats.tx_dropped;
1093 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1094 kfree_skb(skb);
1095 return VOS_STATUS_E_FAILURE;
1096 }
1097
1098 //Just being paranoid. To be removed later
1099 if(pVosPacket == NULL)
1100 {
1101 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001102 "%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 ++pAdapter->stats.tx_dropped;
1104 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1105 kfree_skb(skb);
1106 return VOS_STATUS_E_FAILURE;
1107 }
1108
1109 //Return VOS packet to TL;
1110 *ppVosPacket = pVosPacket;
1111
1112 //Fill out the meta information needed by TL
1113 //FIXME This timestamp is really the time stamp of wrap_data_packet
1114 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1115 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1116 if ( 1 < size )
1117 {
1118 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1119 }
1120 else
1121 {
1122 pPktMetaInfo->bMorePackets = 0;
1123 }
1124
1125 pPktMetaInfo->ucIsEapol = 0;
1126
1127 if(pAdapter->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED)
1128 {
1129 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
1130 {
1131 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_HIGH,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001132 "%s: VOS packet is EAPOL packet", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001133 pPktMetaInfo->ucIsEapol = 1;
1134 }
1135 }
1136
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001137 if (pHddCtx->cfg_ini->gEnableDebugLog)
1138 {
1139 proto_type = vos_pkt_get_proto_type(skb,
1140 pHddCtx->cfg_ini->gEnableDebugLog);
1141 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1142 {
1143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1144 "SAP TX EAPOL");
1145 }
1146 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1147 {
1148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1149 "SAP TX DHCP");
1150 }
1151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001152//xg: @@@@: temporarily disble these. will revisit later
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 {
1154 pPktMetaInfo->ucUP = pktNode->userPriority;
1155 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1156 }
1157
1158 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
1159 //Extract the destination address from ethernet frame
1160 pDestMacAddress = (v_MACADDR_t*)skb->data;
1161
1162 // we need 802.3 to 802.11 frame translation
1163 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1164 pPktMetaInfo->ucDisableFrmXtl = 0;
1165 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1166 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1167
1168 if ( (pAdapter->aStaInfo[STAId].txSuspended[ac]) &&
1169 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1170 {
1171 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001172 "%s: TX queue re-enabled", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 pAdapter->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
1174 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
1175 }
1176
1177 // We're giving the packet to TL so consider it transmitted from
1178 // a statistics perspective. We account for it here instead of
1179 // when the packet is returned for two reasons. First, TL will
1180 // manipulate the skb to the point where the len field is not
1181 // accurate, leading to inaccurate byte counts if we account for
1182 // it later. Second, TL does not provide any feedback as to
1183 // whether or not the packet was successfully sent over the air,
1184 // so the packet counts will be the same regardless of where we
1185 // account for them
1186 pAdapter->stats.tx_bytes += skb->len;
1187 ++pAdapter->stats.tx_packets;
1188 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1189 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
1190
1191 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001192 "%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001193
1194 return status;
1195}
1196
1197
1198/**============================================================================
1199 @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the
1200 case where VOS packets are not available at the time of the call to get
1201 packets. This callback function is invoked by VOS when packets are
1202 available.
1203
1204 @param pVosPacket : [in] pointer to VOS packet
1205 @param userData : [in] opaque user data that was passed initially
1206
1207 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1208 : VOS_STATUS_SUCCESS otherwise
1209 =============================================================================*/
1210VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
1211 v_VOID_t *userData )
1212{
1213 VOS_STATUS status;
1214 v_SINT_t i = 0;
1215 v_SIZE_t size = 0;
1216 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
1217 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1218
1219 if(pAdapter == NULL)
1220 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001221 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 -07001222 return VOS_STATUS_E_FAILURE;
1223 }
1224
1225 //Return the packet to VOS. We just needed to know that VOS is out of low resource
1226 //situation. Here we will only signal TL that there is a pending data for a STA.
1227 //VOS packet will be requested (if needed) when TL comes back to fetch data.
1228 vos_pkt_return_packet( pVosPacket );
1229
1230 pAdapter->isVosOutOfResource = VOS_FALSE;
1231
1232 // Indicate to TL that there is pending data if a queue is non empty.
1233 // This Code wasnt included in earlier version which resulted in
1234 // Traffic stalling
1235 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++)
1236 {
1237 if ((pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) ||
1238 (pAdapter->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED))
1239 {
1240 for( i=NUM_TX_QUEUES-1; i>=0; --i )
1241 {
1242 size = 0;
1243 hdd_list_size(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i], &size);
1244 if ( size > 0 )
1245 {
1246 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1247 STAId,
1248 (WLANTL_ACEnumType)i );
1249 if( !VOS_IS_STATUS_SUCCESS( status ) )
1250 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001251 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 -07001252 }
1253 }
1254 }
1255 }
1256 }
1257 return VOS_STATUS_SUCCESS;
1258}
1259
1260
1261/**============================================================================
1262 @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL.
1263 TL will call this to notify the HDD when one or more packets were
1264 received for a registered STA.
1265
1266 @param vosContext : [in] pointer to VOS context
1267 @param pVosPacketChain : [in] pointer to VOS packet chain
1268 @param staId : [in] Station Id (Adress 1 Index)
1269 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s).
1270
1271 @return : VOS_STATUS_E_FAILURE if any errors encountered,
1272 : VOS_STATUS_SUCCESS otherwise
1273 ===========================================================================*/
1274VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext,
1275 vos_pkt_t *pVosPacketChain,
1276 v_U8_t staId,
1277 WLANTL_RxMetaInfoType* pRxMetaInfo )
1278{
1279 hdd_adapter_t *pAdapter = NULL;
1280 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1281 int rxstat;
1282 struct sk_buff *skb = NULL;
1283 vos_pkt_t* pVosPacket;
1284 vos_pkt_t* pNextVosPacket;
1285 hdd_context_t *pHddCtx = NULL;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001286 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07001287
1288 //Sanity check on inputs
1289 if ( ( NULL == vosContext ) ||
1290 ( NULL == pVosPacketChain ) ||
1291 ( NULL == pRxMetaInfo ) )
1292 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001293 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 return VOS_STATUS_E_FAILURE;
1295 }
1296
1297 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1298 if ( NULL == pHddCtx )
1299 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001300 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 -07001301 return VOS_STATUS_E_FAILURE;
1302 }
1303
1304 pAdapter = pHddCtx->sta_to_adapter[staId];
1305 if( NULL == pAdapter )
1306 {
1307 VOS_ASSERT(0);
1308 return VOS_STATUS_E_FAILURE;
1309 }
Leo Chang64d68bc2013-06-04 15:40:52 -07001310
1311 /* Monitor traffic */
1312 if ( pHddCtx->cfg_ini->enableTrafficMonitor )
1313 {
1314 pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time();
1315 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1316 {
1317 vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock);
1318 /* It was IDLE mode,
1319 * this is new state, then switch mode from suspend to resume */
1320 if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) )
1321 {
1322 hdd_set_wlan_suspend_mode(0);
1323 vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer,
1324 pHddCtx->cfg_ini->trafficIdleTimeout);
1325 atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1);
1326 }
1327 vos_lock_release(&pHddCtx->traffic_monitor.trafficLock);
1328 }
1329 }
1330
Jeff Johnson295189b2012-06-20 16:38:30 -07001331 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
1332
1333 // walk the chain until all are processed
1334 pVosPacket = pVosPacketChain;
1335 do
1336 {
1337 // get the pointer to the next packet in the chain
1338 // (but don't unlink the packet since we free the entire chain later)
1339 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
1340
1341 // both "success" and "empty" are acceptable results
1342 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
1343 {
1344 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001345 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001346 return VOS_STATUS_E_FAILURE;
1347 }
1348
1349 // Extract the OS packet (skb).
1350 // Tell VOS to detach the OS packet from the VOS packet
1351 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
1352 if(!VOS_IS_STATUS_SUCCESS( status ))
1353 {
1354 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001355 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 -07001356 return VOS_STATUS_E_FAILURE;
1357 }
1358
1359 //hdd_softap_dump_sk_buff(skb);
1360
1361 skb->dev = pAdapter->dev;
1362
1363 if(skb->dev == NULL) {
1364
Arif Hussain6d2a3322013-11-17 19:50:10 -08001365 hddLog(VOS_TRACE_LEVEL_FATAL, "ERROR!!Invalid netdevice");
Jeff Johnson295189b2012-06-20 16:38:30 -07001366 return VOS_STATUS_E_FAILURE;
1367 }
1368 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
1369 ++pAdapter->stats.rx_packets;
1370 pAdapter->stats.rx_bytes += skb->len;
1371
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001372 if (pHddCtx->cfg_ini->gEnableDebugLog)
1373 {
1374 proto_type = vos_pkt_get_proto_type(skb,
1375 pHddCtx->cfg_ini->gEnableDebugLog);
1376 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1377 {
1378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1379 "SAP RX EAPOL");
1380 }
1381 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1382 {
1383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1384 "SAP RX DHCP");
1385 }
1386 }
1387
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId)
1389 {
1390 //MC/BC packets. Duplicate a copy of packet
1391 struct sk_buff *pSkbCopy;
1392 hdd_ap_ctx_t *pHddApCtx;
1393
1394 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
1395 if (!(pHddApCtx->apDisableIntraBssFwd))
1396 {
1397 pSkbCopy = skb_copy(skb, GFP_ATOMIC);
1398 if (pSkbCopy)
1399 {
1400 hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev,
1401 pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP));
1402 }
1403 }
1404 else
1405 {
1406 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001407 "%s: skb allocation fails", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001408 }
1409
1410
1411 } //(WLAN_RX_BCMC_STA_ID == staId)
1412
1413 if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) ||
1414 (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId))
1415 {
1416 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001417 "%s: send one packet to kernel", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001418
1419 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07001420 skb->ip_summed = CHECKSUM_NONE;
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001421#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07001422#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Amar Singhal6144c002013-05-03 16:11:42 -07001423 wake_lock_timeout(&pHddCtx->rx_wake_lock, msecs_to_jiffies(HDD_WAKE_LOCK_DURATION));
Jeff Johnsone7245742012-09-05 17:12:55 -07001424#endif
Sameer Thalappil50dc0092013-02-19 17:23:33 -08001425#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 rxstat = netif_rx_ni(skb);
1427 if (NET_RX_SUCCESS == rxstat)
1428 {
1429 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001430 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 }
1432 else
1433 {
1434 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
1435 }
1436 }
1437 else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd)
1438 {
1439 kfree_skb(skb);
1440 }
1441 else
1442 {
1443 //loopback traffic
1444 status = hdd_softap_sta_2_sta_xmit(skb, skb->dev,
1445 pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP));
1446 }
1447
1448 // now process the next packet in the chain
1449 pVosPacket = pNextVosPacket;
1450
1451 } while (pVosPacket);
1452
1453 //Return the entire VOS packet chain to the resource pool
1454 status = vos_pkt_return_packet( pVosPacketChain );
1455 if(!VOS_IS_STATUS_SUCCESS( status ))
1456 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001457 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 }
1459
1460 pAdapter->dev->last_rx = jiffies;
1461
1462 return status;
1463}
1464
1465VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
1466{
1467 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301468 hdd_context_t *pHddCtx;
1469 if (NULL == pAdapter)
1470 {
1471 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1472 "%s: pAdapter is NULL", __func__);
1473 return VOS_STATUS_E_INVAL;
1474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001475
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301476 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1477 {
1478 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1479 "%s: Invalid pAdapter magic", __func__);
1480 return VOS_STATUS_E_INVAL;
1481 }
1482
1483 pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 //Clear station in TL and then update HDD data structures. This helps
1485 //to block RX frames from other station to this station.
Gopichand Nakkala3bd53fa2013-05-22 20:04:18 +05301486 vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId );
Jeff Johnson295189b2012-06-20 16:38:30 -07001487 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1488 {
1489 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1490 "WLANTL_ClearSTAClient() failed to for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001491 "Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 staId, vosStatus, vosStatus );
1493 }
1494
1495 vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId );
1496 if( VOS_STATUS_E_FAILURE == vosStatus )
1497 {
1498 VOS_TRACE ( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
1499 "hdd_softap_deinit_tx_rx_sta() failed for staID %d. "
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001500 "Status = %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001501 staId, vosStatus, vosStatus );
1502 return( vosStatus );
1503 }
1504
1505 pHddCtx->sta_to_adapter[staId] = NULL;
1506
1507 return( vosStatus );
1508}
1509
1510VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
1511 v_BOOL_t fAuthRequired,
1512 v_BOOL_t fPrivacyBit,
1513 v_U8_t staId,
1514 v_U8_t ucastSig,
1515 v_U8_t bcastSig,
1516 v_MACADDR_t *pPeerMacAddress,
1517 v_BOOL_t fWmmEnabled )
1518{
1519 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
Prathyushaf5442802012-12-12 13:58:11 -08001520 WLAN_STADescType staDesc = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07001521 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
1522 hdd_adapter_t *pmonAdapter = NULL;
1523
1524 //eCsrEncryptionType connectedCipherAlgo;
1525 //v_BOOL_t fConnected;
1526
1527 /*
1528 * Clean up old entry if it is not cleaned up properly
1529 */
1530 if ( pAdapter->aStaInfo[staId].isUsed )
1531 {
1532 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1533 "clean up old entry for STA %d", staId);
1534 hdd_softap_DeregisterSTA( pAdapter, staId );
1535 }
1536
1537 // Get the Station ID from the one saved during the assocation.
1538
1539 staDesc.ucSTAId = staId;
1540
1541
1542 /*Save the pAdapter Pointer for this staId*/
1543 pHddCtx->sta_to_adapter[staId] = pAdapter;
1544
1545 staDesc.wSTAType = WLAN_STA_SOFTAP;
1546
1547 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
1548 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 );
1549 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
1550
1551 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001552 "register station");
Jeff Johnson295189b2012-06-20 16:38:30 -07001553 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001554 "station mac " MAC_ADDRESS_STR,
1555 MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001556 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001557 "BSSIDforIBSS " MAC_ADDRESS_STR,
1558 MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001559 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08001560 "SOFTAP SELFMAC " MAC_ADDRESS_STR,
1561 MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07001562
1563 vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress);
1564
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 staDesc.ucQosEnabled = fWmmEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001566 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1567 "HDD SOFTAP register TL QoS_enabled=%d",
1568 staDesc.ucQosEnabled );
1569
1570 staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ;
1571
1572
Jeff Johnson295189b2012-06-20 16:38:30 -07001573 // For PRIMA UMA frame translation is not enable yet.
1574 staDesc.ucSwFrameTXXlation = 1;
1575 staDesc.ucSwFrameRXXlation = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07001576 staDesc.ucAddRmvLLC = 1;
1577
1578 // Initialize signatures and state
1579 staDesc.ucUcastSig = ucastSig;
1580 staDesc.ucBcastSig = bcastSig;
1581 staDesc.ucInitState = fAuthRequired ?
1582 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
1583
Prathyushaf5442802012-12-12 13:58:11 -08001584 staDesc.ucIsReplayCheckValid = VOS_FALSE;
1585
Jeff Johnson295189b2012-06-20 16:38:30 -07001586 // Register the Station with TL...
1587 vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1588 hdd_softap_rx_packet_cbk,
1589 hdd_softap_tx_complete_cbk,
1590 hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 );
1591
1592 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1593 {
1594 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001595 "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
Jeff Johnson295189b2012-06-20 16:38:30 -07001596 vosStatus, vosStatus );
1597 return vosStatus;
1598 }
1599
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001600 //Timer value should be in milliseconds
1601 if ( pHddCtx->cfg_ini->dynSplitscan &&
1602 ( VOS_TIMER_STATE_RUNNING !=
1603 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
1604 {
1605 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
1606 pHddCtx->cfg_ini->trafficMntrTmrForSplitScan);
1607 }
1608
Jeff Johnson295189b2012-06-20 16:38:30 -07001609 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
1610 // then go to 'authenticated'. For all other authentication types (those that do
1611 // not require upper layer authentication) we can put TL directly into 'authenticated'
1612 // state.
1613
1614 //VOS_ASSERT( fConnected );
1615 pAdapter->aStaInfo[staId].ucSTAId = staId;
1616 pAdapter->aStaInfo[staId].isQosEnabled = fWmmEnabled;
1617
1618 if ( !fAuthRequired )
1619 {
1620 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1621 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", pAdapter->aStaInfo[staId].ucSTAId );
1622
1623 // Connections that do not need Upper layer auth, transition TL directly
1624 // to 'Authenticated' state.
1625 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1626 WLANTL_STA_AUTHENTICATED );
1627
1628 pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED;
1629 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE;
1630 }
1631 else
1632 {
1633
1634 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
1635 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pAdapter->aStaInfo[staId].ucSTAId );
1636
1637 vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId,
1638 WLANTL_STA_CONNECTED );
1639 pAdapter->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED;
1640
1641 pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE;
1642
1643 }
1644 pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx);
1645 if(pmonAdapter)
1646 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001647 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Turn on Monitor the carrier");
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 netif_carrier_on(pmonAdapter->dev);
1649 //Enable Tx queue
1650 netif_tx_start_all_queues(pmonAdapter->dev);
1651 }
1652 netif_carrier_on(pAdapter->dev);
1653 //Enable Tx queue
1654 netif_tx_start_all_queues(pAdapter->dev);
1655
1656 return( vosStatus );
1657}
1658
1659VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit)
1660{
1661 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1662 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1663 v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER;
1664
1665
1666 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
1667 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
1668 vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0);
1669
1670 return vosStatus;
1671}
1672
1673VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter)
1674{
1675 return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
1676}
1677
1678VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter)
1679{
Wilson Yangf80a0542013-10-07 13:02:37 -07001680 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07001681 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1682 v_U8_t staId = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07001683 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1684
1685 /*bss deregister is not allowed during wlan driver loading or unloading*/
1686 if (pHddCtx->isLoadUnloadInProgress)
1687 {
1688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1689 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
1690 return VOS_STATUS_E_PERM;
1691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001692
1693 vosStatus = hdd_softap_Deregister_BC_STA( pAdapter);
1694
Jeff Johnson43971f52012-07-17 12:26:56 -07001695 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001696 {
1697 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001698 "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001699 }
1700
1701 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
1702 {
1703 if (pAdapter->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered
1704 vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId);
1705
Jeff Johnson43971f52012-07-17 12:26:56 -07001706 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07001707 {
1708 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001709 "%s: Failed to deregister sta Id %d", __func__, staId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001710 }
1711 }
1712
1713 return vosStatus;
1714}
1715
1716VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state)
1717{
1718 v_U8_t ucSTAId = WLAN_MAX_STA_COUNT;
1719 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
1720 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001721
1722 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001723 "%s: enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001724
Jeff Johnson43971f52012-07-17 12:26:56 -07001725 if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId))
Jeff Johnson295189b2012-06-20 16:38:30 -07001726 {
1727 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001728 "%s: Failed to find right station", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 return VOS_STATUS_E_FAILURE;
1730 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001731
1732 if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress))
1733 {
1734 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001735 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001736 return VOS_STATUS_E_FAILURE;
1737 }
1738
1739 vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state );
1740 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001741 "%s: change station to state %d succeed", __func__, state);
Jeff Johnson295189b2012-06-20 16:38:30 -07001742
Jeff Johnson43971f52012-07-17 12:26:56 -07001743 if (VOS_STATUS_SUCCESS == vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001744 {
1745 pAdapter->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED;
1746 }
1747
1748 VOS_TRACE(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001749 "%s exit",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001750
1751 return vosStatus;
1752}
1753
1754
1755VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId)
1756{
1757 v_U8_t i;
1758
1759 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
1760 {
1761 if (vos_mem_compare(&pAdapter->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) &&
1762 pAdapter->aStaInfo[i].isUsed)
1763 {
1764 *staId = i;
1765 return VOS_STATUS_SUCCESS;
1766 }
1767 }
1768
1769 return VOS_STATUS_E_FAILURE;
1770}
1771
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05301772VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId)
1773{
1774 v_U8_t i;
1775
1776 for (i = 0; i < WLAN_MAX_STA_COUNT; i++)
1777 {
Kiet Lam61589852013-09-19 17:10:58 +05301778 if (pAdapter->aStaInfo[i].isUsed &&
1779 (!vos_is_macaddr_broadcast(&pAdapter->aStaInfo[i].macAddrSTA)))
Madan Mohan Koyyalamudie68989b2013-09-10 01:15:19 +05301780 {
1781 *staId = i;
1782 return VOS_STATUS_SUCCESS;
1783 }
1784 }
1785
1786 return VOS_STATUS_E_FAILURE;
1787}