blob: af949bd7dfaf503feacf8c778907bc828b26d69d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mihir Shete0be28772015-02-17 18:42:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**===========================================================================
29
30 \file wlan_hdd_tx_rx.c
31
32 \brief Linux HDD Tx/RX APIs
Jeff Johnson295189b2012-06-20 16:38:30 -070033
34 ==========================================================================*/
35
36/*---------------------------------------------------------------------------
37 Include files
38 -------------------------------------------------------------------------*/
39#include <wlan_hdd_tx_rx.h>
40#include <wlan_hdd_softap_tx_rx.h>
41#include <wlan_hdd_dp_utils.h>
42#include <wlan_qct_tl.h>
43#include <linux/netdevice.h>
44#include <linux/skbuff.h>
45#include <linux/etherdevice.h>
Mihir Shetec8fe71b2014-06-16 15:32:59 +053046#include <linux/ratelimit.h>
Mihir Shetef3473692014-06-27 15:13:20 +053047#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
48#include <soc/qcom/subsystem_restart.h>
49#else
50#include <mach/subsystem_restart.h>
51#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070052
Jeff Johnson295189b2012-06-20 16:38:30 -070053#include <wlan_hdd_p2p.h>
54#include <linux/wireless.h>
55#include <net/cfg80211.h>
56#include <net/ieee80211_radiotap.h>
57#include "sapApi.h"
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053058#include <vos_sched.h>
Chilam NG571c65a2013-01-19 12:27:36 +053059#ifdef FEATURE_WLAN_TDLS
60#include "wlan_hdd_tdls.h"
61#endif
62
Sushant Kaushika8073312015-05-04 17:33:52 +053063#include "vos_diag_core_event.h"
Mukul Sharma84f27252014-07-14 18:11:42 +053064#include "vos_utils.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053065#include "sapInternal.h"
Mihir Shete5d148f12014-12-16 17:54:49 +053066#include "wlan_hdd_trace.h"
Katya Nigame7b69a82015-04-28 15:24:06 +053067#include "wlan_qct_wda.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070068/*---------------------------------------------------------------------------
69 Preprocessor definitions and constants
70 -------------------------------------------------------------------------*/
71
72const v_U8_t hddWmmAcToHighestUp[] = {
73 SME_QOS_WMM_UP_RESV,
74 SME_QOS_WMM_UP_EE,
75 SME_QOS_WMM_UP_VI,
76 SME_QOS_WMM_UP_NC
77};
78
79//Mapping Linux AC interpretation to TL AC.
80const v_U8_t hdd_QdiscAcToTlAC[] = {
81 WLANTL_AC_VO,
82 WLANTL_AC_VI,
83 WLANTL_AC_BE,
84 WLANTL_AC_BK,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +053085 WLANTL_AC_HIGH_PRIO,
Jeff Johnson295189b2012-06-20 16:38:30 -070086};
87
Mihir Shetec8fe71b2014-06-16 15:32:59 +053088#define HDD_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ
89#define HDD_TX_TIMEOUT_RATELIMIT_BURST 1
Mihir Shetef3473692014-06-27 15:13:20 +053090#define HDD_TX_STALL_SSR_THRESHOLD 5
Mihir Shete0be28772015-02-17 18:42:14 +053091#define HDD_TX_STALL_SSR_THRESHOLD_HIGH 13
Mihir Shete327c2ab2014-11-13 15:17:02 +053092#define HDD_TX_STALL_RECOVERY_THRESHOLD HDD_TX_STALL_SSR_THRESHOLD - 2
Mihir Shetec8fe71b2014-06-16 15:32:59 +053093
Katya Nigame7b69a82015-04-28 15:24:06 +053094int gRatefromIdx[] = {
95 10,20,55,100,
96 10,20,55,110,
97 60,90,120,180,240,360,480,540,
98 65,130,195,260,390,520,585,650,
99 72,144,217,289,434,578,650,722,
100 65,130,195,260,390,520,585,650,
101 135,270,405,540,810,1080,1215,1350,
102 150,300,450,600,900,1200,1350,1500,
103 135,270,405,540,810,1080,1215,1350,
104 1350,1350,65,130,195,260,390, 520,
105 585,650,780,1350,1350,1350,1350,1350,
106 1350,1350,1350,1350,655,722,866,1350,
107 1350,1350,135,270,405,540,810,1080,
108 1215,1350,1350,1620,1800,1350,1350,1350,
109 1350,1350,1350,1200,1350,1500,1350,1800,
110 2000,1350, 292,585,877,1170,1755,2340,
111 2632,2925,1350,3510,3900,1350,1350,1350,
112 1350,1350,1350,1350,2925,3250,1350,3900,
113 4333
114 };
Sushant Kaushika8073312015-05-04 17:33:52 +0530115#ifdef FEATURE_WLAN_DIAG_SUPPORT
116#define HDD_EAPOL_PACKET_TYPE_OFFSET (15)
117#define HDD_EAPOL_KEY_INFO_OFFSET (19)
118#define HDD_EAPOL_DEST_MAC_OFFSET (0)
119#define HDD_EAPOL_SRC_MAC_OFFSET (6)
120#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Katya Nigame7b69a82015-04-28 15:24:06 +0530121
122
Mihir Shetec8fe71b2014-06-16 15:32:59 +0530123static DEFINE_RATELIMIT_STATE(hdd_tx_timeout_rs, \
124 HDD_TX_TIMEOUT_RATELIMIT_INTERVAL, \
125 HDD_TX_TIMEOUT_RATELIMIT_BURST);
126
Jeff Johnson295189b2012-06-20 16:38:30 -0700127static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129/*---------------------------------------------------------------------------
130 Type declarations
131 -------------------------------------------------------------------------*/
132
133/*---------------------------------------------------------------------------
134 Function definitions and documenation
135 -------------------------------------------------------------------------*/
136
137#ifdef DATA_PATH_UNIT_TEST
138//Utility function to dump an sk_buff
139static void dump_sk_buff(struct sk_buff * skb)
140{
c_hpothu32490782014-03-14 19:14:34 +0530141 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head);
142 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data);
143 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail);
144 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end);
145 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
146 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
147 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len);
Jeff Johnson295189b2012-06-20 16:38:30 -0700148
c_hpothu32490782014-03-14 19:14:34 +0530149 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
Jeff Johnson295189b2012-06-20 16:38:30 -0700150 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
151 skb->data[5], skb->data[6], skb->data[7]);
c_hpothu32490782014-03-14 19:14:34 +0530152 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
Jeff Johnson295189b2012-06-20 16:38:30 -0700153 skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
154 skb->data[13], skb->data[14], skb->data[15]);
155}
156
157//Function for Unit Test only
158static void transport_thread(hdd_adapter_t *pAdapter)
159{
160 v_U8_t staId;
161 WLANTL_ACEnumType ac = WLANTL_AC_BE;
162 vos_pkt_t *pVosPacket = NULL ;
163 vos_pkt_t dummyPacket;
164 WLANTL_MetaInfoType pktMetaInfo;
165 WLANTL_RxMetaInfoType pktRxMetaInfo;
166 VOS_STATUS status = VOS_STATUS_E_FAILURE;
167
c_hpothub8245442013-11-20 23:41:09 +0530168 if (NULL == pAdapter)
169 {
c_hpothu32490782014-03-14 19:14:34 +0530170 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +0530171 FL("pAdapter is NULL"));
172 VOS_ASSERT(0);
173 return;
174 }
175
Jeff Johnson295189b2012-06-20 16:38:30 -0700176 status = hdd_tx_fetch_packet_cbk( pAdapter->pvosContext,
177 &staId,
178 &ac,
179 &pVosPacket,
180 &pktMetaInfo );
181 if (status != VOS_STATUS_SUCCESS && status != VOS_STATUS_E_EMPTY)
c_hpothu32490782014-03-14 19:14:34 +0530182 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
183 "%s: Test FAIL hdd_tx_fetch_packet_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700184 else
c_hpothu32490782014-03-14 19:14:34 +0530185 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
186 "%s: Test PASS hdd_tx_fetch_packet_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700187
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -0700188 status = hdd_tx_complete_cbk(pAdapter->pvosContext, &dummyPacket, VOS_STATUS_SUCCESS);
Jeff Johnson295189b2012-06-20 16:38:30 -0700189 if (status != VOS_STATUS_SUCCESS)
c_hpothu32490782014-03-14 19:14:34 +0530190 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
191 "%s: Test FAIL hdd_tx_complete_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 else
c_hpothu32490782014-03-14 19:14:34 +0530193 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
194 "%s: Test PASS hdd_tx_complete_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700195
196 status = hdd_tx_low_resource_cbk(pVosPacket, pAdapter);
197 if (status != VOS_STATUS_SUCCESS)
c_hpothu32490782014-03-14 19:14:34 +0530198 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
199 "%s: Test FAIL hdd_tx_low_resource_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700200 else
c_hpothu32490782014-03-14 19:14:34 +0530201 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
202 "%s: Test PASS hdd_tx_low_resource_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700203
204 status = hdd_rx_packet_cbk( pAdapter->pvosContext,
205 &dummyPacket,
206 staId,
207 &pktRxMetaInfo);
208 if (status != VOS_STATUS_SUCCESS)
c_hpothu32490782014-03-14 19:14:34 +0530209 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
210 "%s: Test FAIL hdd_rx_packet_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700211 else
c_hpothu32490782014-03-14 19:14:34 +0530212 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
213 "%s: Test PASS hdd_rx_packet_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700214
215}
216#endif
217
218
219/**============================================================================
220 @brief hdd_flush_tx_queues() - Utility function to flush the TX queues
221
222 @param pAdapter : [in] pointer to adapter context
223 @return : VOS_STATUS_E_FAILURE if any errors encountered
224 : VOS_STATUS_SUCCESS otherwise
225 ===========================================================================*/
226static VOS_STATUS hdd_flush_tx_queues( hdd_adapter_t *pAdapter )
227{
228 VOS_STATUS status = VOS_STATUS_SUCCESS;
229 v_SINT_t i = -1;
230 hdd_list_node_t *anchor = NULL;
231 skb_list_node_t *pktNode = NULL;
232 struct sk_buff *skb = NULL;
233
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530234 pAdapter->isVosLowResource = VOS_FALSE;
235
Mihir Shete5d148f12014-12-16 17:54:49 +0530236 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_FLUSH_TX_QUEUES,
237 pAdapter->sessionId, 0));
238
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 while (++i != NUM_TX_QUEUES)
240 {
241 //Free up any packets in the Tx queue
242 spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock);
243 while (true)
244 {
245 status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[i], &anchor );
246 if(VOS_STATUS_E_EMPTY != status)
247 {
248 pktNode = list_entry(anchor, skb_list_node_t, anchor);
249 skb = pktNode->skb;
250 //TODO
251 //++pAdapter->stats.tx_dropped;
252 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
253 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
254 kfree_skb(skb);
255 continue;
256 }
257 break;
258 }
259 spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock);
260 // backpressure is no longer in effect
261 pAdapter->isTxSuspended[i] = VOS_FALSE;
262 }
263
264 return status;
265}
266
Ravi Joshif9520d62013-10-18 04:11:46 -0700267/**============================================================================
268 @brief hdd_flush_ibss_tx_queues() - Utility function to flush the TX queues
269 in IBSS mode
270
271 @param pAdapter : [in] pointer to adapter context
272 : [in] Staion Id
273 @return : VOS_STATUS_E_FAILURE if any errors encountered
274 : VOS_STATUS_SUCCESS otherwise
275 ===========================================================================*/
276void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId)
277{
278 v_U8_t i;
Katya Nigam47528772015-02-11 12:24:49 +0530279 hdd_list_node_t *anchor = NULL;
Ravi Joshi41914632013-10-21 23:02:21 -0700280 skb_list_node_t *pktNode = NULL;
Ravi Joshi41914632013-10-21 23:02:21 -0700281 struct sk_buff *skb = NULL;
Katya Nigam47528772015-02-11 12:24:49 +0530282 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
283 hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info;
Ravi Joshif9520d62013-10-18 04:11:46 -0700284
Katya Nigam47528772015-02-11 12:24:49 +0530285 for (i = 0; i < NUM_TX_QUEUES; i ++)
c_hpothub8245442013-11-20 23:41:09 +0530286 {
Katya Nigam47528772015-02-11 12:24:49 +0530287 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
288 while (true)
Ravi Joshif9520d62013-10-18 04:11:46 -0700289 {
Katya Nigam47528772015-02-11 12:24:49 +0530290 if (VOS_STATUS_E_EMPTY !=
291 hdd_list_remove_front(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i],
292 &anchor))
Ravi Joshif9520d62013-10-18 04:11:46 -0700293 {
Katya Nigam47528772015-02-11 12:24:49 +0530294 //If success then we got a valid packet from some AC
295 pktNode = list_entry(anchor, skb_list_node_t, anchor);
Ravi Joshif9520d62013-10-18 04:11:46 -0700296 skb = pktNode->skb;
Katya Nigam47528772015-02-11 12:24:49 +0530297 ++pAdapter->stats.tx_dropped;
298 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
299 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
300 kfree_skb(skb);
301 continue;
Ravi Joshif9520d62013-10-18 04:11:46 -0700302 }
Katya Nigam47528772015-02-11 12:24:49 +0530303 break;
Ravi Joshif9520d62013-10-18 04:11:46 -0700304 }
Katya Nigam47528772015-02-11 12:24:49 +0530305 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
Ravi Joshif9520d62013-10-18 04:11:46 -0700306 }
307}
308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter)
310{
311 skb_list_node_t *pktNode = NULL;
312 struct sk_buff *skb = NULL;
313 v_SIZE_t size = 0;
314 WLANTL_ACEnumType ac = 0;
315 VOS_STATUS status = VOS_STATUS_E_FAILURE;
316 hdd_list_node_t *anchor = NULL;
317
c_hpothu77731d42014-01-23 13:59:03 +0530318 if (NULL == pAdapter)
319 {
320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
321 FL("pAdapter is NULL"));
322 VOS_ASSERT(0);
323 return NULL;
324 }
325
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 // do we have any packets pending in this AC?
327 hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size );
328 if( size == 0 )
329 {
c_hpothu32490782014-03-14 19:14:34 +0530330 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700331 "%s: NO Packet Pending", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700332 return NULL;
333 }
334
335 //Remove the packet from the queue
336 spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock);
337 status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor );
338 spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock);
339
340 if(VOS_STATUS_SUCCESS == status)
341 {
342 //If success then we got a valid packet from some AC
343 pktNode = list_entry(anchor, skb_list_node_t, anchor);
344 skb = pktNode->skb;
345 }
346 else
347 {
c_hpothu32490782014-03-14 19:14:34 +0530348 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700349 "%s: Not able to remove Packet from the list",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700350 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700351
352 return NULL;
353 }
354
355 // if we are in a backpressure situation see if we can turn the hose back on
356 if ( (pAdapter->isTxSuspended[ac]) &&
357 (size <= HDD_TX_QUEUE_LOW_WATER_MARK) )
358 {
c_hpothu32490782014-03-14 19:14:34 +0530359 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700360 "%s: TX queue[%d] re-enabled", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 pAdapter->isTxSuspended[ac] = VOS_FALSE;
362 /* Enable Queues which we have disabled earlier */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700364 netif_tx_start_all_queues( pAdapter->dev );
365 }
366
367 return skb;
368}
369
370void hdd_mon_tx_mgmt_pkt(hdd_adapter_t* pAdapter)
371{
372 hdd_cfg80211_state_t *cfgState;
373 struct sk_buff* skb;
374 hdd_adapter_t* pMonAdapter = NULL;
375 struct ieee80211_hdr *hdr;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530376 hdd_context_t *pHddCtx;
377 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530379 ENTER();
Mukul Sharma23a92232014-04-07 18:04:00 +0530380 if (pAdapter == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 {
c_hpothu32490782014-03-14 19:14:34 +0530382 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +0530383 FL("pAdapter is NULL"));
384 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 return;
386 }
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530387 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
388 ret = wlan_hdd_validate_context(pHddCtx);
389 if (0 != ret)
390 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530391 return;
392 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700393 pMonAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR );
Mukul Sharma23a92232014-04-07 18:04:00 +0530394 if (pMonAdapter == NULL)
395 {
396 hddLog(VOS_TRACE_LEVEL_ERROR,
397 "%s: pMonAdapter is NULL", __func__);
398 return;
399 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700400 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
401
402 if( NULL != cfgState->buf )
403 {
c_hpothu32490782014-03-14 19:14:34 +0530404 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700405 "%s: Already one MGMT packet Tx going on", __func__);
406 return;
407 }
408
409 skb = hdd_mon_tx_fetch_pkt(pMonAdapter);
410
411 if (NULL == skb)
412 {
c_hpothu32490782014-03-14 19:14:34 +0530413 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700414 "%s: No Packet Pending", __func__);
415 return;
416 }
417
418 cfgState->buf = vos_mem_malloc( skb->len ); //buf;
419 if( cfgState->buf == NULL )
420 {
c_hpothu32490782014-03-14 19:14:34 +0530421 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700422 "%s: Failed to Allocate memory", __func__);
423 goto fail;
424 }
425
426 cfgState->len = skb->len;
427
428 vos_mem_copy( cfgState->buf, skb->data, skb->len);
429
430 cfgState->skb = skb; //buf;
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800431 cfgState->action_cookie = (uintptr_t)cfgState->buf;
Jeff Johnson295189b2012-06-20 16:38:30 -0700432
433 hdr = (struct ieee80211_hdr *)skb->data;
434 if( (hdr->frame_control & HDD_FRAME_TYPE_MASK)
435 == HDD_FRAME_TYPE_MGMT )
436 {
437 if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK)
438 == HDD_FRAME_SUBTYPE_DEAUTH )
439 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +0530440 struct tagCsrDelStaParams delStaParams;
441
Sushant Kaushik4cd28f62014-12-26 14:23:50 +0530442 WLANSAP_PopulateDelStaParams(hdr->addr1,
443 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +0530444 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
445
446 hdd_softap_sta_deauth(pAdapter, &delStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -0700447 goto mgmt_handled;
448 }
449 else if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK)
450 == HDD_FRAME_SUBTYPE_DISASSOC )
451 {
452 hdd_softap_sta_disassoc( pAdapter, hdr->addr1 );
453 goto mgmt_handled;
454 }
455 }
c_hpothu32490782014-03-14 19:14:34 +0530456 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700457 "%s: Sending action frame to SAP to TX, Len %d", __func__, skb->len);
458
Jeff Johnson43971f52012-07-17 12:26:56 -0700459 if (VOS_STATUS_SUCCESS !=
Jeff Johnson295189b2012-06-20 16:38:30 -0700460 WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Jeff Johnsone7245742012-09-05 17:12:55 -0700461 skb->data, skb->len, 0) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700462 {
c_hpothu32490782014-03-14 19:14:34 +0530463 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700464 "%s: WLANSAP_SendAction returned fail", __func__);
465 hdd_sendActionCnf( pAdapter, FALSE );
466 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530467 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700468 return;
469
470mgmt_handled:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530471 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700472 hdd_sendActionCnf( pAdapter, TRUE );
473 return;
474fail:
475 kfree_skb(pAdapter->skb_to_tx);
476 pAdapter->skb_to_tx = NULL;
477 return;
478}
479
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530480void __hdd_mon_tx_work_queue(struct work_struct *work)
Jeff Johnson295189b2012-06-20 16:38:30 -0700481{
482 hdd_adapter_t* pAdapter = container_of(work, hdd_adapter_t, monTxWorkQueue);
483 hdd_mon_tx_mgmt_pkt(pAdapter);
484}
485
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530486void hdd_mon_tx_work_queue(struct work_struct *work)
487{
488 vos_ssr_protect(__func__);
489 __hdd_mon_tx_work_queue(work);
490 vos_ssr_unprotect(__func__);
491}
492
Jeff Johnson295189b2012-06-20 16:38:30 -0700493int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
494{
Katya Nigame7b69a82015-04-28 15:24:06 +0530495 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
496 "%s: Packet Rcvd at Monitor interface,"
497 " Dropping the packet",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700498 kfree_skb(skb);
499 return NETDEV_TX_OK;
500}
Dino Mycled9b7cc12014-09-04 18:43:07 +0530501
502/**============================================================================
503 @brief hdd_dhcp_pkt_info() -
504 Function to log DHCP pkt info
505
506 @param skb : [in] pointer to OS packet (sk_buff)
507 @return : None
508 ===========================================================================*/
509
510void hdd_dhcp_pkt_info(struct sk_buff *skb)
511{
512 /* port no 67 (0x43) or 68 (0x44) */
513
514 if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_REQUEST_MSG)
515 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request"));
516 else if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_RESPONSE_MSG)
517 hddLog(VOS_TRACE_LEVEL_INFO, FL("Response"));
518 else
519 hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP invalid"));
520
521 hddLog(VOS_TRACE_LEVEL_INFO,
522 FL("DHCP Dest Addr: %pM Src Addr %pM "
523 " source port : %d, dest port : %d"),
524 skb->data, (skb->data + 6),
525 ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))),
526 ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))));
527
528 if ((skb->data[DHCP_OPTION53_OFFSET] == DHCP_OPTION53) &&
529 (skb->data[DHCP_OPTION53_LENGTH_OFFSET] == DHCP_OPTION53_LENGTH)) {
530
531 switch (skb->data[DHCP_OPTION53_STATUS_OFFSET]) {
532 case DHCPDISCOVER:
533 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP DISCOVER"));
534 break;
535 case DHCPREQUEST:
536 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP REQUEST"));
537 break;
538 case DHCPOFFER:
539 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP OFFER"));
540 break;
541 case DHCPACK:
542 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP ACK"));
543 break;
544 case DHCPNAK:
545 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP NACK"));
546 break;
547 case DHCPRELEASE:
548 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP RELEASE"));
549 break;
550 case DHCPINFORM:
551 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP INFORM"));
552 break;
553
554 default:
555 hddLog(VOS_TRACE_LEVEL_INFO,
556 "%s: DHCP Not Defined OPTION53 : %d", __func__,
557 skb->data[DHCP_OPTION53_STATUS_OFFSET]);
558 }
559 }
560}
561
562/**============================================================================
563 @brief hdd_dump_dhcp_pkt() -
564 Function to dump DHCP packets in TX and RX path.
565
566 @param skb : [in] pointer to OS packet (sk_buff)
567 @param path : [in] bool indicating TX/RX path
568 @return : None
569 ===========================================================================*/
570void hdd_dump_dhcp_pkt(struct sk_buff *skb, int path)
571{
572
573 if ((ntohs(*((u16*)((u8*)skb->data + ETH_TYPE_OFFSET)))
574 == ETH_TYPE_IP_PKT) ||
575 (ntohs(*((u8*)skb->data + PROTOCOL_OFFSET)) == UDP_PROTOCOL)) {
576
577 /* IP protocol 12 bytes of mac addresses in 802.3 header */
578 if ( ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) ==
579 BOOTP_SERVER_PORT ||
580 ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) ==
581 BOOTP_CLIENT_PORT ||
582 ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) ==
583 BOOTP_SERVER_PORT ||
584 ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) ==
585 BOOTP_CLIENT_PORT ) {
586
587 if (path == TX_PATH) {
588 hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP TX PATH"));
589 } else {
590 hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP RX PATH"));
591 }
592
593 hdd_dhcp_pkt_info(skb);
594 }
595 }
596}
597
Jeff Johnson295189b2012-06-20 16:38:30 -0700598/**============================================================================
Katya Nigam77fcf582015-02-09 16:48:24 +0530599 @brief hdd_ibss_hard_start_xmit() - Function registered with the Linux OS for
600 transmitting packets in case of IBSS. There are 2 versions of this function.
601 One that uses locked queue and other that uses lockless queues. Both have been
602 retained to do some performance testing
603
604 @param skb : [in] pointer to OS packet (sk_buff)
605 @param dev : [in] pointer to network device
606
607 @return : NET_XMIT_DROP if packets are dropped
608 : NET_XMIT_SUCCESS if packet is enqueued succesfully
609 ===========================================================================*/
610 int hdd_ibss_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
611 {
612 VOS_STATUS status;
613 WLANTL_ACEnumType ac;
614 sme_QosWmmUpType up;
615 skb_list_node_t *pktNode = NULL;
616 hdd_list_node_t *anchor = NULL;
617 v_SIZE_t pktListSize = 0;
618 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
619 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
620 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
621 hdd_ibss_peer_info_t * pPeerInfo;
622 v_U8_t STAId = WLAN_MAX_STA_COUNT;
623 v_BOOL_t txSuspended = VOS_FALSE;
624 struct sk_buff *skb1;
625 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
626
627 if (NULL == pHddCtx || NULL == pHddStaCtx) {
628 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
629 "%s HDD context is NULL", __func__);
630 return NETDEV_TX_BUSY;
631 }
632 pPeerInfo = &pHddStaCtx->ibss_peer_info;
633 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
634
635 //Get TL AC corresponding to Qdisc queue index/AC.
636 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
637
638 if (eConnectionState_IbssDisconnected == pHddStaCtx->conn_info.connState)
639 {
640 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
641 "%s: Tx frame in disconnected state in IBSS mode", __func__);
642 ++pAdapter->stats.tx_dropped;
643 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
644 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
645 kfree_skb(skb);
646 return NETDEV_TX_OK;
647 }
648
649 STAId = *(v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
650
651 if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
652 (vos_is_macaddr_broadcast( pDestMacAddress ) ||
653 vos_is_macaddr_group(pDestMacAddress)))
654 {
655 STAId = IBSS_BROADCAST_STAID;
656 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,
657 "%s: BC/MC packet", __func__);
658 }
659 else if (STAId >= HDD_MAX_NUM_IBSS_STA)
660 {
661 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
662 "%s: Received Unicast frame with invalid staID", __func__);
663 ++pAdapter->stats.tx_dropped;
664 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
665 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
666 kfree_skb(skb);
667 return NETDEV_TX_OK;
668 }
669
670 //user priority from IP header, which is already extracted and set from
671 //select_queue call back function
672 up = skb->priority;
673 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
674
675 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
676 "%s: Classified as ac %d up %d", __func__, ac, up);
677
678 if ( pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP )
679 {
680 hdd_dump_dhcp_pkt(skb, TX_PATH);
681 }
682
683 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
684 hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
685 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
686 {
687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
688 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
689 pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
690 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
691 txSuspended = VOS_TRUE;
692 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
694 "%s: TX queue full for AC=%d Disable OS TX queue",
695 __func__, ac );
696 return NETDEV_TX_BUSY;
697 }
698
699 /* If 3/4th of the max queue size is used then enable the flag.
700 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
701 if (WLANTL_AC_BE == ac)
702 {
703 if (pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
704 {
705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
706 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
707 pAdapter->isVosLowResource = VOS_TRUE;
708 }
709 else
710 {
711 pAdapter->isVosLowResource = VOS_FALSE;
712 }
713 }
714
715 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
716
717 //Use the skb->cb field to hold the list node information
718 pktNode = (skb_list_node_t *)&skb->cb;
719
720 //Stick the OS packet inside this node.
721 pktNode->skb = skb;
722
723 //Stick the User Priority inside this node
724 pktNode->userPriority = up;
725
726 INIT_LIST_HEAD(&pktNode->anchor);
727
728 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
729 status = hdd_list_insert_back_size( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac],
730 &pktNode->anchor, &pktListSize );
731 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
732 if ( !VOS_IS_STATUS_SUCCESS( status ) )
733 {
734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
735 "%s:Insert Tx queue failed. Pkt dropped", __func__);
736 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
737 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
738 ++pAdapter->stats.tx_dropped;
739 kfree_skb(skb);
740 return NETDEV_TX_OK;
741 }
742
743 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
744 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
745 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
746
747 if (1 == pktListSize)
748 {
749 //Let TL know we have a packet to send for this AC
750 status = WLANTL_STAPktPending( pHddCtx->pvosContext, STAId, ac );
751
752 if ( !VOS_IS_STATUS_SUCCESS( status ) )
753 {
754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
755 "%s: Failed to signal TL for AC=%d STAId =%d",
756 __func__, ac, STAId );
757
758 /* Remove the packet from queue. It must be at the back of the queue, as TX thread
759 * cannot preempt us in the middle as we are in a soft irq context.
760 * Also it must be the same packet that we just allocated.
761 */
762 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
763 status = hdd_list_remove_back( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor);
764 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
765 /* Free the skb only if we are able to remove it from the list.
766 * If we are not able to retrieve it from the list it means that
767 * the skb was pulled by TX Thread and is use so we should not free
768 * it here
769 */
770 if (VOS_IS_STATUS_SUCCESS(status))
771 {
772 pktNode = list_entry(anchor, skb_list_node_t, anchor);
773 skb1 = pktNode->skb;
774 kfree_skb(skb1);
775 }
776 ++pAdapter->stats.tx_dropped;
777 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
778 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
779 return NETDEV_TX_OK;
780 }
781 }
782
783 dev->trans_start = jiffies;
784
785 return NETDEV_TX_OK;
786 }
787
788/**============================================================================
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530789 @brief hdd_hard_start_xmit() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700790 transmitting packets. There are 2 versions of this function. One that uses
791 locked queue and other that uses lockless queues. Both have been retained to
792 do some performance testing
793
794 @param skb : [in] pointer to OS packet (sk_buff)
795 @param dev : [in] pointer to Libra network device
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530796
Jeff Johnson295189b2012-06-20 16:38:30 -0700797 @return : NET_XMIT_DROP if packets are dropped
798 : NET_XMIT_SUCCESS if packet is enqueued succesfully
799 ===========================================================================*/
800int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
801{
802 VOS_STATUS status;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530803 WLANTL_ACEnumType qid, ac;
Jeff Johnson295189b2012-06-20 16:38:30 -0700804 sme_QosWmmUpType up;
805 skb_list_node_t *pktNode = NULL;
806 hdd_list_node_t *anchor = NULL;
807 v_SIZE_t pktListSize = 0;
808 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
809 v_BOOL_t granted;
Shailender Karmuchia734f332013-04-19 14:02:48 -0700810 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700811 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
Dino Mycled9b7cc12014-09-04 18:43:07 +0530812 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 v_BOOL_t txSuspended = VOS_FALSE;
Mihir Shetef8f74532014-12-04 11:53:34 +0530814 struct sk_buff *skb1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700815
Girish Gowlibf0e1ab2015-01-19 16:05:16 +0530816 if (NULL == pHddCtx) {
817 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
818 "%s HDD context is NULL", __func__);
819 return NETDEV_TX_BUSY;
820 }
821
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
823
Ravi Joshif9520d62013-10-18 04:11:46 -0700824 if (unlikely(netif_subqueue_stopped(dev, skb))) {
c_hpothu32490782014-03-14 19:14:34 +0530825 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshif9520d62013-10-18 04:11:46 -0700826 "%s is called when netif TX %d is disabled",
827 __func__, skb->queue_mapping);
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530828 return NETDEV_TX_BUSY;
829 }
830
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530831 //Get TL Q index corresponding to Qdisc queue index/AC.
832 qid = hdd_QdiscAcToTlAC[skb->queue_mapping];
833 ac = qid;
834
835 if (qid == WLANTL_AC_HIGH_PRIO)
836 {
837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
838 "%s It must be a Eapol/Wapi/DHCP packet device_mode:%d",
839 __func__, pAdapter->device_mode);
840 ac = hddWmmUpToAcMap[skb->priority];
841 }
Ravi Joshicc57ed42013-10-12 16:31:25 -0700842
c_hpothu851d9862015-01-19 18:39:06 +0530843 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
844 {
845 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
846 FL("Tx frame in not associated state in %d context"),
847 pAdapter->device_mode);
848 ++pAdapter->stats.tx_dropped;
849 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530850 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
c_hpothu851d9862015-01-19 18:39:06 +0530851 kfree_skb(skb);
852 return NETDEV_TX_OK;
853 }
Shailender Karmuchia734f332013-04-19 14:02:48 -0700854 STAId = pHddStaCtx->conn_info.staId[0];
Jeff Johnson295189b2012-06-20 16:38:30 -0700855
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530856 //user priority from IP header, which is already extracted and set from
Jeff Johnson295189b2012-06-20 16:38:30 -0700857 //select_queue call back function
858 up = skb->priority;
859
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530860 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[qid];
Jeff Johnson295189b2012-06-20 16:38:30 -0700861
862#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +0530863 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700864 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700865#endif // HDD_WMM_DEBUG
866
Girish Gowlibf0e1ab2015-01-19 16:05:16 +0530867 if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
Mukul Sharma84f27252014-07-14 18:11:42 +0530868 {
Girish Gowlibf0e1ab2015-01-19 16:05:16 +0530869 vos_record_roam_event(e_HDD_FIRST_XMIT_TIME, (void *)skb, 0);
Mukul Sharma84f27252014-07-14 18:11:42 +0530870 }
Mukul Sharma84f27252014-07-14 18:11:42 +0530871
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530872 spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
Varun Reddy Yeturu5ba69222013-04-01 18:22:20 -0700873 /*CR 463598,384996*/
874 /*For every increment of 10 pkts in the queue, we inform TL about pending pkts.
875 *We check for +1 in the logic,to take care of Zero count which
876 *occurs very frequently in low traffic cases */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530877 if((pAdapter->wmm_tx_queue[qid].count + 1) % 10 == 0)
Varun Reddy Yeturu5ba69222013-04-01 18:22:20 -0700878 {
Shailender Karmuchia734f332013-04-19 14:02:48 -0700879 /* Use the following debug statement during Engineering Debugging.There are chance that this will lead to a Watchdog Bark
Varun Reddy Yeturu5ba69222013-04-01 18:22:20 -0700880 * if it is in the mainline code and if the log level is enabled by someone for debugging
c_hpothu32490782014-03-14 19:14:34 +0530881 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,"%s:Queue is Filling up.Inform TL again about pending packets", __func__);*/
Shailender Karmuchia734f332013-04-19 14:02:48 -0700882
Ravi Joshi8a934352013-09-25 16:46:58 -0700883 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530884 STAId, qid
Ravi Joshi8a934352013-09-25 16:46:58 -0700885 );
886 if ( !VOS_IS_STATUS_SUCCESS( status ) )
887 {
c_hpothu32490782014-03-14 19:14:34 +0530888 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshi8a934352013-09-25 16:46:58 -0700889 "%s: WLANTL_STAPktPending() returned error code %d",
890 __func__, status);
Ravi Joshicc57ed42013-10-12 16:31:25 -0700891 ++pAdapter->stats.tx_dropped;
892 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530893 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
Ravi Joshi8a934352013-09-25 16:46:58 -0700894 kfree_skb(skb);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530895 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Ravi Joshi8a934352013-09-25 16:46:58 -0700896 return NETDEV_TX_OK;
897 }
Varun Reddy Yeturu5ba69222013-04-01 18:22:20 -0700898 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700899 //If we have already reached the max queue size, disable the TX queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530900 if ( pAdapter->wmm_tx_queue[qid].count == pAdapter->wmm_tx_queue[qid].max_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 {
Ravi Joshicc57ed42013-10-12 16:31:25 -0700902 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530903 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[qid];
904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queue for QId %d"), qid);
Ravi Joshicc57ed42013-10-12 16:31:25 -0700905 netif_tx_stop_queue(netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)));
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530906 pAdapter->isTxSuspended[qid] = VOS_TRUE;
Ravi Joshicc57ed42013-10-12 16:31:25 -0700907 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530908 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530909 pAdapter->sessionId, qid));
Jeff Johnson295189b2012-06-20 16:38:30 -0700910 }
911
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530912 /* If 3/4th of the max queue size is used then enable the flag.
913 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530914 if (WLANTL_AC_BE == qid)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530915 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530916 if (pAdapter->wmm_tx_queue[qid].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530917 {
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530918 pAdapter->isVosLowResource = VOS_TRUE;
919 }
920 else
921 {
922 pAdapter->isVosLowResource = VOS_FALSE;
923 }
924 }
925
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530926 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530927
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530928 if (( NULL != pHddCtx ) &&
929 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530930 {
931 hdd_dump_dhcp_pkt(skb, TX_PATH);
932 }
933
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 if (VOS_TRUE == txSuspended)
935 {
c_hpothu32490782014-03-14 19:14:34 +0530936 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530937 "%s: TX queue full for QId=%d Disable OS TX queue",
938 __func__, qid );
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530939 return NETDEV_TX_BUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 }
941
942 //Use the skb->cb field to hold the list node information
943 pktNode = (skb_list_node_t *)&skb->cb;
944
945 //Stick the OS packet inside this node.
946 pktNode->skb = skb;
947
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530948 //Stick the User Priority inside this node
Jeff Johnson295189b2012-06-20 16:38:30 -0700949 pktNode->userPriority = up;
950
951
952 INIT_LIST_HEAD(&pktNode->anchor);
953
954 //Insert the OS packet into the appropriate AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530955 spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
956 status = hdd_list_insert_back_size( &pAdapter->wmm_tx_queue[qid], &pktNode->anchor, &pktListSize );
957 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700958
959 if ( !VOS_IS_STATUS_SUCCESS( status ) )
960 {
c_hpothu32490782014-03-14 19:14:34 +0530961 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s:Insert Tx queue failed. Pkt dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530963 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 ++pAdapter->stats.tx_dropped;
965 kfree_skb(skb);
966 return NETDEV_TX_OK;
967 }
968
969 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530970 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[qid];
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700971 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -0700972
Kiet Lamf040f472013-11-20 21:15:23 +0530973 if (HDD_PSB_CHANGED == pAdapter->psbChanged)
974 {
975 /* Function which will determine acquire admittance for a
976 * WMM AC is required or not based on psb configuration done
977 * in the framework
978 */
979 hdd_wmm_acquire_access_required(pAdapter, ac);
980 }
981
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 //Make sure we have access to this access category
Kiet Lamf040f472013-11-20 21:15:23 +0530983 if (((pAdapter->psbChanged & (1 << ac)) && likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed)) ||
984 (pHddStaCtx->conn_info.uIsAuthenticated == VOS_FALSE))
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 {
986 granted = VOS_TRUE;
987 }
988 else
989 {
990 status = hdd_wmm_acquire_access( pAdapter, ac, &granted );
Kiet Lamf040f472013-11-20 21:15:23 +0530991 pAdapter->psbChanged |= (1 << ac);
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 }
Nirav Shah4f765af2015-01-21 19:51:30 +0530993
994 if ( (granted && ( pktListSize == 1 )) ||
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530995 (qid == WLANTL_AC_HIGH_PRIO))
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 {
997 //Let TL know we have a packet to send for this AC
c_hpothu32490782014-03-14 19:14:34 +0530998 //VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
Shailender Karmuchia734f332013-04-19 14:02:48 -0700999 status = WLANTL_STAPktPending(
1000 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301001 STAId, qid );
Jeff Johnson295189b2012-06-20 16:38:30 -07001002 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1003 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301004 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
1005 "%s: Failed to signal TL for QId=%d", __func__, qid );
Jeff Johnson295189b2012-06-20 16:38:30 -07001006
1007 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
1008 //as we are in a soft irq context. Also it must be the same packet that we just allocated.
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301009 spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
1010 status = hdd_list_remove_back( &pAdapter->wmm_tx_queue[qid], &anchor );
1011 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +05301012 /* Free the skb only if we are able to remove it from the list.
1013 * If we are not able to retrieve it from the list it means that
1014 * the skb was pulled by TX Thread and is use so we should not free
1015 * it here
1016 */
1017 if (VOS_IS_STATUS_SUCCESS(status))
1018 {
1019 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1020 skb1 = pktNode->skb;
1021 kfree_skb(skb1);
1022 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 ++pAdapter->stats.tx_dropped;
1024 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301025 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
Jeff Johnson295189b2012-06-20 16:38:30 -07001026 return NETDEV_TX_OK;
1027 }
1028 }
1029
1030 dev->trans_start = jiffies;
1031
1032 return NETDEV_TX_OK;
1033}
1034
1035/**============================================================================
Shailender Karmuchia734f332013-04-19 14:02:48 -07001036 @brief hdd_Ibss_GetStaId() - Get the StationID using the Peer Mac address
1037
1038 @param pHddStaCtx : [in] pointer to HDD Station Context
1039 pMacAddress [in] pointer to Peer Mac address
1040 staID [out] pointer to Station Index
1041 @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE
1042 ===========================================================================*/
1043
1044VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, v_MACADDR_t *pMacAddress, v_U8_t *staId)
1045{
1046 v_U8_t idx;
1047
1048 for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++)
1049 {
1050 if (vos_mem_compare(&pHddStaCtx->conn_info.peerMacAddress[ idx ],
1051 pMacAddress, sizeof(v_MACADDR_t)))
1052 {
1053 *staId = pHddStaCtx->conn_info.staId[idx];
1054 return VOS_STATUS_SUCCESS;
1055 }
1056 }
1057
1058 return VOS_STATUS_E_FAILURE;
1059}
1060
1061/**============================================================================
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301062 @brief __hdd_tx_timeout() - Function handles timeout during transmission.
Jeff Johnson295189b2012-06-20 16:38:30 -07001063
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301064 @param dev : [in] pointer to network device
Jeff Johnson295189b2012-06-20 16:38:30 -07001065 @return : None
1066 ===========================================================================*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301067void __hdd_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07001068{
Ravi Joshicc57ed42013-10-12 16:31:25 -07001069 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mihir Shete0be28772015-02-17 18:42:14 +05301070 hdd_context_t *pHddCtx;
Ravi Joshicc57ed42013-10-12 16:31:25 -07001071 struct netdev_queue *txq;
Mihir Shete0be28772015-02-17 18:42:14 +05301072 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
Ravi Joshicc57ed42013-10-12 16:31:25 -07001073 int i = 0;
Mukul Sharma4b322632015-02-28 20:21:43 +05301074 int status = 0;
Mukul Sharma42b3d432014-10-16 16:13:40 +05301075 v_ULONG_t diff_in_jiffies = 0;
Ravi Joshicc57ed42013-10-12 16:31:25 -07001076
Mihir Shetef3473692014-06-27 15:13:20 +05301077 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Padma, Santhosh Kumarce7aef82014-12-17 17:31:49 +05301078 "%s: Transmission timeout occurred jiffies %lu dev->trans_start %lu",
1079 __func__,jiffies,dev->trans_start);
Mihir Shetef3473692014-06-27 15:13:20 +05301080
c_hpothub8245442013-11-20 23:41:09 +05301081 if ( NULL == pAdapter )
1082 {
c_hpothu32490782014-03-14 19:14:34 +05301083 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301084 FL("pAdapter is NULL"));
1085 VOS_ASSERT(0);
1086 return;
1087 }
1088
Mihir Shete0be28772015-02-17 18:42:14 +05301089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mukul Sharma4b322632015-02-28 20:21:43 +05301090 status = wlan_hdd_validate_context(pHddCtx);
1091 if (status !=0 )
Mihir Shete0be28772015-02-17 18:42:14 +05301092 {
Mukul Sharma4b322632015-02-28 20:21:43 +05301093 return;
Mihir Shete0be28772015-02-17 18:42:14 +05301094 }
1095
Mihir Shetef3473692014-06-27 15:13:20 +05301096 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
1097
Jeff Johnson295189b2012-06-20 16:38:30 -07001098 //Getting here implies we disabled the TX queues for too long. Queues are
1099 //disabled either because of disassociation or low resource scenarios. In
1100 //case of disassociation it is ok to ignore this. But if associated, we have
1101 //do possible recovery here
Ravi Joshicc57ed42013-10-12 16:31:25 -07001102
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301103 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshicc57ed42013-10-12 16:31:25 -07001104 "num_bytes AC0: %d AC1: %d AC2: %d AC3: %d",
1105 pAdapter->wmm_tx_queue[0].count,
1106 pAdapter->wmm_tx_queue[1].count,
1107 pAdapter->wmm_tx_queue[2].count,
1108 pAdapter->wmm_tx_queue[3].count);
1109
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301110 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshicc57ed42013-10-12 16:31:25 -07001111 "tx_suspend AC0: %d AC1: %d AC2: %d AC3: %d",
1112 pAdapter->isTxSuspended[0],
1113 pAdapter->isTxSuspended[1],
1114 pAdapter->isTxSuspended[2],
1115 pAdapter->isTxSuspended[3]);
1116
Mihir Shete0be28772015-02-17 18:42:14 +05301117 for (i = 0; i < dev->num_tx_queues; i++)
Ravi Joshicc57ed42013-10-12 16:31:25 -07001118 {
1119 txq = netdev_get_tx_queue(dev, i);
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301120 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Padma, Santhosh Kumarce7aef82014-12-17 17:31:49 +05301121 "Queue%d status: %d txq->trans_start %lu",
1122 i, netif_tx_queue_stopped(txq),txq->trans_start);
Ravi Joshicc57ed42013-10-12 16:31:25 -07001123 }
1124
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301125 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshicc57ed42013-10-12 16:31:25 -07001126 "carrier state: %d", netif_carrier_ok(dev));
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301127
Mihir Shetef3473692014-06-27 15:13:20 +05301128 /* continuousTxTimeoutCount will be reset whenever TL fetches packet
1129 * from HDD
1130 */
1131 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
1132
Mukul Sharma42b3d432014-10-16 16:13:40 +05301133 diff_in_jiffies = jiffies - pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut;
1134 if((pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount > 1)&&
1135 ((diff_in_jiffies) > (HDD_TX_TIMEOUT * 2 ))
1136 )
1137 {
1138 /*
1139 * In Open security case when there is no traffic is running, it may possible
1140 * tx time-out may once happen and later we recovered then we need to
1141 * reset the continuousTxTimeoutCount because it is only getting modified
1142 * when traffic is running. So if over a period of time if this count reaches
1143 * to HDD_TX_STALL_SSR_THRESHOLD then host is triggering false subsystem restart.
1144 * so in genuine Tx Time out case kernel will call the tx time-out back to back at
1145 * interval of HDD_TX_TIMEOUT.So now we are checking if previous TX TIME out was
1146 * occurred more then twice of HDD_TX_TIMEOUT back then we may recovered here.
1147 */
1148 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
1149 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1150 FL("This is false alarm so resetting the continuousTxTimeoutCount"));
1151 }
1152
1153 //update last jiffies after the check
1154 pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut = jiffies;
1155
Mihir Shete327c2ab2014-11-13 15:17:02 +05301156 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
1157 HDD_TX_STALL_RECOVERY_THRESHOLD)
1158 {
1159 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1160 "%s: Request firmware for recovery",__func__);
1161 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
1162 }
1163
Mihir Shete0be28772015-02-17 18:42:14 +05301164 pRemainChanCtx = hdd_get_remain_on_channel_ctx(pHddCtx);
1165 if (!pRemainChanCtx)
Mihir Shetef3473692014-06-27 15:13:20 +05301166 {
Mihir Shete0be28772015-02-17 18:42:14 +05301167 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
1168 HDD_TX_STALL_SSR_THRESHOLD)
1169 {
1170 // Driver could not recover, issue SSR
1171 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1172 "%s: Cannot recover from Data stall Issue SSR",
1173 __func__);
1174 WLANTL_FatalError();
1175 return;
1176 }
1177 }
1178 else
1179 {
1180 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1181 "Remain on channel in progress");
1182 /* The supplicant can retry "P2P Invitation Request" for 120 times
1183 * and so there is a possbility that we can remain off channel for
1184 * the entire duration of these retries(which can be max 60sec).
1185 * If we encounter such a case, let us not trigger SSR after 30sec
1186 * but wait for 60sec to let the device go on home channel and start
1187 * tx. If tx does not start within 70sec we will issue SSR.
1188 */
1189 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
1190 HDD_TX_STALL_SSR_THRESHOLD_HIGH)
1191 {
1192 // Driver could not recover, issue SSR
1193 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1194 "%s: Cannot recover from Data stall Issue SSR",
1195 __func__);
1196 WLANTL_FatalError();
1197 return;
1198 }
Mihir Shetef3473692014-06-27 15:13:20 +05301199 }
1200
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301201 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
1202 * every 5sec. The TL debug spits out a lot of information on the
1203 * serial console, if it is called every time *hdd_tx_timeout* is
1204 * called then we may get a watchdog bite on the Application
1205 * processor, so ratelimit the TL debug logs.
1206 */
1207 if (__ratelimit(&hdd_tx_timeout_rs))
1208 {
1209 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +05301210 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301211 }
Mihir Shetef3473692014-06-27 15:13:20 +05301212
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301213}
Jeff Johnson295189b2012-06-20 16:38:30 -07001214
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301215/**============================================================================
1216 @brief hdd_tx_timeout() - Function called by OS if there is any
1217 timeout during transmission. Since HDD simply enqueues packet
1218 and returns control to OS right away, this would never be invoked
1219
1220 @param dev : [in] pointer to network device
1221 @return : None
1222 ===========================================================================*/
1223void hdd_tx_timeout(struct net_device *dev)
1224{
1225 vos_ssr_protect(__func__);
1226 __hdd_tx_timeout(dev);
1227 vos_ssr_unprotect(__func__);
1228}
Jeff Johnson295189b2012-06-20 16:38:30 -07001229
1230/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05301231 @brief __hdd_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 device TX/RX statistic
1233
1234 @param dev : [in] pointer to Libra network device
1235
1236 @return : pointer to net_device_stats structure
1237 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05301238struct net_device_stats* __hdd_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07001239{
1240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
c_hpothub8245442013-11-20 23:41:09 +05301241
1242 if ( NULL == pAdapter )
1243 {
c_hpothu32490782014-03-14 19:14:34 +05301244 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301245 FL("pAdapter is NULL"));
1246 VOS_ASSERT(0);
1247 return NULL;
1248 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001249
1250 return &pAdapter->stats;
1251}
1252
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05301253struct net_device_stats* hdd_stats(struct net_device *dev)
1254{
1255 struct net_device_stats* dev_stats;
1256
1257 vos_ssr_protect(__func__);
1258 dev_stats = __hdd_stats(dev);
1259 vos_ssr_unprotect(__func__);
1260
1261 return dev_stats;
1262}
Jeff Johnson295189b2012-06-20 16:38:30 -07001263
1264/**============================================================================
Katya Nigam1fd24402015-02-16 14:52:19 +05301265 @brief hdd_ibss_init_tx_rx() - Init function to initialize Tx/RX
1266 modules in HDD
1267
1268 @param pAdapter : [in] pointer to adapter context
1269 @return : VOS_STATUS_E_FAILURE if any errors encountered
1270 : VOS_STATUS_SUCCESS otherwise
1271 ===========================================================================*/
1272void hdd_ibss_init_tx_rx( hdd_adapter_t *pAdapter )
1273{
1274 v_U8_t i;
1275 v_U8_t STAId = 0;
1276 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
1277 hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info;
1278 v_U8_t pACWeights[] = {
1279 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
1280 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
1281 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
1282 HDD_SOFTAP_VO_WEIGHT_DEFAULT
1283 };
1284
1285 pAdapter->isVosOutOfResource = VOS_FALSE;
1286 pAdapter->isVosLowResource = VOS_FALSE;
1287
1288 // Since SAP model is used for IBSS also. Using same queue length as in SAP.
1289 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
1290 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
1291 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
1292 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
1293
1294 for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++)
1295 {
1296 vos_mem_zero(&pPeerInfo->ibssStaInfo[STAId], sizeof(hdd_ibss_station_info_t));
1297 for (i = 0; i < NUM_TX_QUEUES; i ++)
1298 {
1299 hdd_list_init(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
1300 }
1301 }
1302
1303 /* Update the AC weights suitable for SoftAP mode of operation */
1304 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
1305}
1306
1307/**============================================================================
1308 @brief hdd_ibss_deinit_tx_rx() - Deinit function to clean up Tx/RX
1309 modules in HDD
1310
1311 @param pAdapter : [in] pointer to adapter context..
1312 @return : VOS_STATUS_E_FAILURE if any errors encountered.
1313 : VOS_STATUS_SUCCESS otherwise
1314 ===========================================================================*/
1315VOS_STATUS hdd_ibss_deinit_tx_rx( hdd_adapter_t *pAdapter )
1316{
1317 VOS_STATUS status = VOS_STATUS_SUCCESS;
1318 v_U8_t STAId = 0;
1319 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
1320 hdd_ibss_peer_info_t * pPeerInfo = &pHddStaCtx->ibss_peer_info;
1321 hdd_list_node_t *anchor = NULL;
1322 skb_list_node_t *pktNode = NULL;
1323 struct sk_buff *skb = NULL;
1324 v_SINT_t i = -1;
1325
1326 for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++)
1327 {
1328 if (VOS_FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed)
1329 {
1330 continue;
1331 }
1332 for (i = 0; i < NUM_TX_QUEUES; i ++)
1333 {
1334 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
1335 while (true)
1336 {
1337 status = hdd_list_remove_front ( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], &anchor);
1338
1339 if (VOS_STATUS_E_EMPTY != status)
1340 {
1341 //If success then we got a valid packet from some AC
1342 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1343 skb = pktNode->skb;
1344 ++pAdapter->stats.tx_dropped;
1345 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
1346 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
1347 kfree_skb(skb);
1348 continue;
1349 }
1350
1351 //current list is empty
1352 break;
1353 }
1354 pPeerInfo->ibssStaInfo[STAId].txSuspended[i] = VOS_FALSE;
1355 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
1356 }
1357 }
1358 pAdapter->isVosLowResource = VOS_FALSE;
1359
1360 return status;
1361}
1362
1363/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001364 @brief hdd_init_tx_rx() - Init function to initialize Tx/RX
1365 modules in HDD
1366
1367 @param pAdapter : [in] pointer to adapter context
1368 @return : VOS_STATUS_E_FAILURE if any errors encountered
1369 : VOS_STATUS_SUCCESS otherwise
1370 ===========================================================================*/
1371VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter )
1372{
1373 VOS_STATUS status = VOS_STATUS_SUCCESS;
1374 v_SINT_t i = -1;
1375
c_hpothub8245442013-11-20 23:41:09 +05301376 if ( NULL == pAdapter )
1377 {
c_hpothu32490782014-03-14 19:14:34 +05301378 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301379 FL("pAdapter is NULL"));
1380 VOS_ASSERT(0);
1381 return VOS_STATUS_E_FAILURE;
1382 }
1383
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301385 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001386
1387 //vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
1388 //Will be zeroed out during alloc
1389
1390 while (++i != NUM_TX_QUEUES)
1391 {
1392 pAdapter->isTxSuspended[i] = VOS_FALSE;
1393 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
1394 }
1395
1396 return status;
1397}
1398
1399
1400/**============================================================================
1401 @brief hdd_deinit_tx_rx() - Deinit function to clean up Tx/RX
1402 modules in HDD
1403
1404 @param pAdapter : [in] pointer to adapter context
1405 @return : VOS_STATUS_E_FAILURE if any errors encountered
1406 : VOS_STATUS_SUCCESS otherwise
1407 ===========================================================================*/
1408VOS_STATUS hdd_deinit_tx_rx( hdd_adapter_t *pAdapter )
1409{
1410 VOS_STATUS status = VOS_STATUS_SUCCESS;
1411 v_SINT_t i = -1;
1412
c_hpothub8245442013-11-20 23:41:09 +05301413 if ( NULL == pAdapter )
1414 {
c_hpothu32490782014-03-14 19:14:34 +05301415 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301416 FL("pAdapter is NULL"));
1417 VOS_ASSERT(0);
1418 return VOS_STATUS_E_FAILURE;
1419 }
1420
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 status = hdd_flush_tx_queues(pAdapter);
c_hpothub8245442013-11-20 23:41:09 +05301422 if (VOS_STATUS_SUCCESS != status)
c_hpothu32490782014-03-14 19:14:34 +05301423 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
c_hpothub8245442013-11-20 23:41:09 +05301424 FL("failed to flush tx queues"));
1425
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 while (++i != NUM_TX_QUEUES)
1427 {
1428 //Free up actual list elements in the Tx queue
1429 hdd_list_destroy( &pAdapter->wmm_tx_queue[i] );
1430 }
1431
1432 return status;
1433}
1434
1435
1436/**============================================================================
1437 @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1438 modules in HDD
1439
1440 @param pAdapter : [in] pointer to adapter context
1441 @return : VOS_STATUS_E_FAILURE if any errors encountered
1442 : VOS_STATUS_SUCCESS otherwise
1443 ===========================================================================*/
1444VOS_STATUS hdd_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1445{
1446 return hdd_flush_tx_queues(pAdapter);
1447}
1448
1449
1450/**============================================================================
1451 @brief hdd_IsEAPOLPacket() - Checks the packet is EAPOL or not.
1452
1453 @param pVosPacket : [in] pointer to vos packet
1454 @return : VOS_TRUE if the packet is EAPOL
1455 : VOS_FALSE otherwise
1456 ===========================================================================*/
1457
1458v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket )
1459{
1460 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1461 v_BOOL_t fEAPOL = VOS_FALSE;
1462 void *pBuffer = NULL;
1463
1464
1465 vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
1466 &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
Abhishek Singhfa011222014-04-14 10:57:08 +05301467 if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001468 {
Abhishek Singhfa011222014-04-14 10:57:08 +05301469 if ( pBuffer && *(unsigned short*)pBuffer ==
1470 vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001471 {
1472 fEAPOL = VOS_TRUE;
1473 }
1474 }
1475
1476 return fEAPOL;
1477}
1478
Abhishek Singhfa011222014-04-14 10:57:08 +05301479/**============================================================================
1480 @brief hdd_IsARP() - Checks the packet is ARP or not.
1481
1482 @param pVosPacket : [in] pointer to vos packet
1483 @return : VOS_TRUE if the packet is ARP
1484 : VOS_FALSE otherwise
1485 ===========================================================================*/
1486
1487v_BOOL_t hdd_IsARP( vos_pkt_t *pVosPacket )
1488{
1489 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1490 v_BOOL_t fIsARP = VOS_FALSE;
1491 void *pBuffer = NULL;
1492
1493
1494 vosStatus = vos_pkt_peek_data( pVosPacket,
1495 (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
1496 &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
1497 if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
1498 {
1499 if ( pBuffer && *(unsigned short*)pBuffer ==
1500 vos_cpu_to_be16(HDD_ETHERTYPE_ARP) )
1501 {
1502 fIsARP = VOS_TRUE;
1503 }
1504 }
1505
1506 return fIsARP;
1507}
Jeff Johnson295189b2012-06-20 16:38:30 -07001508
1509#ifdef FEATURE_WLAN_WAPI // Need to update this function
1510/**============================================================================
1511 @brief hdd_IsWAIPacket() - Checks the packet is WAI or not.
1512
1513 @param pVosPacket : [in] pointer to vos packet
1514 @return : VOS_TRUE if the packet is WAI
1515 : VOS_FALSE otherwise
1516 ===========================================================================*/
1517
1518v_BOOL_t hdd_IsWAIPacket( vos_pkt_t *pVosPacket )
1519{
1520 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1521 v_BOOL_t fIsWAI = VOS_FALSE;
1522 void *pBuffer = NULL;
1523
1524 // Need to update this function
1525 vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
1526 &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
1527
1528 if (VOS_IS_STATUS_SUCCESS( vosStatus ) )
1529 {
Abhishek Singhfa011222014-04-14 10:57:08 +05301530 if ( pBuffer && *(unsigned short*)pBuffer ==
1531 vos_cpu_to_be16(HDD_ETHERTYPE_WAI) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001532 {
1533 fIsWAI = VOS_TRUE;
1534 }
1535 }
1536
1537 return fIsWAI;
1538}
1539#endif /* FEATURE_WLAN_WAPI */
1540
1541/**============================================================================
1542 @brief hdd_tx_complete_cbk() - Callback function invoked by TL
1543 to indicate that a packet has been transmitted across the SDIO bus
1544 succesfully. OS packet resources can be released after this cbk.
1545
1546 @param vosContext : [in] pointer to VOS context
1547 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1548 @param vosStatusIn : [in] status of the transmission
1549
1550 @return : VOS_STATUS_E_FAILURE if any errors encountered
1551 : VOS_STATUS_SUCCESS otherwise
1552 ===========================================================================*/
1553VOS_STATUS hdd_tx_complete_cbk( v_VOID_t *vosContext,
1554 vos_pkt_t *pVosPacket,
1555 VOS_STATUS vosStatusIn )
1556{
1557 VOS_STATUS status = VOS_STATUS_SUCCESS;
1558 hdd_adapter_t *pAdapter = NULL;
1559 hdd_context_t *pHddCtx = NULL;
1560 void* pOsPkt = NULL;
1561
1562 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1563 {
c_hpothu32490782014-03-14 19:14:34 +05301564 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301565 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001566 return VOS_STATUS_E_FAILURE;
1567 }
1568
1569 //Return the skb to the OS
1570 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Agarwal Ashish971c2882013-10-30 20:11:12 +05301571 if (!VOS_IS_STATUS_SUCCESS( status ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001572 {
1573 //This is bad but still try to free the VOSS resources if we can
c_hpothu32490782014-03-14 19:14:34 +05301574 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301575 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001576 vos_pkt_return_packet( pVosPacket );
1577 return VOS_STATUS_E_FAILURE;
1578 }
1579
1580 //Get the HDD context.
Kiet Lam3c2ee302014-03-23 23:23:22 -07001581 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 //Get the Adapter context.
1583 pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_INFRA_STATION);
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301584 if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07001585 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301586 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1587 "%s: Invalid adapter %p", __func__, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 }
1589 else
1590 {
1591 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1592 }
1593
1594 kfree_skb((struct sk_buff *)pOsPkt);
1595
1596 //Return the VOS packet resources.
1597 status = vos_pkt_return_packet( pVosPacket );
Agarwal Ashish971c2882013-10-30 20:11:12 +05301598 if (!VOS_IS_STATUS_SUCCESS( status ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 {
c_hpothu32490782014-03-14 19:14:34 +05301600 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301601 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 }
1603
1604 return status;
1605}
1606
Katya Nigamf944e5e2015-02-10 15:05:43 +05301607/**============================================================================
1608 @brief hdd_ibss_tx_fetch_packet_cbk() - Callback function invoked by TL to
1609 fetch a packet for transmission.
1610
1611 @param vosContext : [in] pointer to VOS context
1612 @param staId : [in] Station for which TL is requesting a pkt
1613 @param ac : [in] access category requested by TL
1614 @param pVosPacket : [out] pointer to VOS packet packet pointer
1615 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1616
1617 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1618 : VOS_STATUS_E_FAILURE if any errors encountered
1619 : VOS_STATUS_SUCCESS otherwise
1620 ===========================================================================*/
1621VOS_STATUS hdd_ibss_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1622 v_U8_t *pStaId,
1623 WLANTL_ACEnumType ac,
1624 vos_pkt_t **ppVosPacket,
1625 WLANTL_MetaInfoType *pPktMetaInfo )
1626{
1627 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1628 hdd_adapter_t *pAdapter = NULL;
1629 hdd_list_node_t *anchor = NULL;
1630 skb_list_node_t *pktNode = NULL;
1631 struct sk_buff *skb = NULL;
1632 vos_pkt_t *pVosPacket = NULL;
1633 v_MACADDR_t* pDestMacAddress = NULL;
1634 v_TIME_t timestamp;
1635 v_SIZE_t size = 0;
1636 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1637 hdd_context_t *pHddCtx = NULL;
1638 hdd_station_ctx_t *pHddStaCtx = NULL;
1639 hdd_ibss_peer_info_t *pPeerInfo = NULL;
1640 v_U8_t proto_type = 0;
Abhishek Singh99f725a2015-05-15 17:50:26 +05301641 v_U16_t packet_size;
Katya Nigamf944e5e2015-02-10 15:05:43 +05301642
1643 //Sanity check on inputs
1644 if ( ( NULL == vosContext ) ||
1645 ( NULL == pStaId ) ||
1646 ( NULL == ppVosPacket ) ||
1647 ( NULL == pPktMetaInfo ) )
1648 {
1649 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1650 "%s: Null Params being passed", __func__);
1651 return VOS_STATUS_E_FAILURE;
1652 }
1653
1654 //Get the HDD context.
1655 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1656 if ( NULL == pHddCtx )
1657 {
1658 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1659 "%s: HDD adapter context is Null", __func__);
1660 return VOS_STATUS_E_FAILURE;
1661 }
1662
1663 STAId = *pStaId;
1664 pAdapter = pHddCtx->sta_to_adapter[STAId];
1665 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1666 {
1667 VOS_ASSERT(0);
1668 return VOS_STATUS_E_FAILURE;
1669 }
1670
1671 pHddStaCtx = &pAdapter->sessionCtx.station;
1672 pPeerInfo = &pHddStaCtx->ibss_peer_info;
1673
1674 if (FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed )
1675 {
1676 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1677 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1678 return VOS_STATUS_E_FAILURE;
1679 }
1680
1681 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1682
1683 *ppVosPacket = NULL;
1684
1685 //Make sure the AC being asked for is sane
1686 if( ac > WLANTL_MAX_AC || ac < 0)
1687 {
1688 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1689 "%s: Invalid AC %d passed by TL", __func__, ac);
1690 return VOS_STATUS_E_FAILURE;
1691 }
1692
1693 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1694
Katya Nigamf944e5e2015-02-10 15:05:43 +05301695 //Get the vos packet before so that we are prepare for VOS low reseurce condition
1696 //This simplifies the locking and unlocking of Tx queue
1697 status = vos_pkt_wrap_data_packet( &pVosPacket,
1698 VOS_PKT_TYPE_TX_802_3_DATA,
1699 NULL, //OS Pkt is not being passed
1700 hdd_tx_low_resource_cbk,
1701 pAdapter );
1702
1703 if ((status == VOS_STATUS_E_ALREADY) || (status == VOS_STATUS_E_RESOURCES))
1704 {
1705 //Remember VOS is in a low resource situation
1706 pAdapter->isVosOutOfResource = VOS_TRUE;
1707 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
1708 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
1709 "%s: VOSS in Low Resource scenario", __func__);
1710 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1711 return VOS_STATUS_E_FAILURE;
1712 }
1713
1714 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there.
1715 Do not get next AC as the other branch does.
1716 */
1717 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
1718 hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &size);
1719
1720 if (0 == size)
1721 {
1722 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
1723 vos_pkt_return_packet(pVosPacket);
1724 return VOS_STATUS_E_EMPTY;
1725 }
1726
1727 status = hdd_list_remove_front( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1728 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
1729
1730 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1731 "%s: AC %d has packets pending", __func__, ac);
1732
1733 if(VOS_STATUS_SUCCESS == status)
1734 {
1735 //If success then we got a valid packet from some AC
1736 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1737 skb = pktNode->skb;
1738 }
1739 else
1740 {
1741 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1742 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1743 "%s: Error in de-queuing skb from Tx queue status = %d",
1744 __func__, status );
1745 vos_pkt_return_packet(pVosPacket);
1746 return VOS_STATUS_E_FAILURE;
1747 }
1748
1749 //Attach skb to VOS packet.
1750 status = vos_pkt_set_os_packet( pVosPacket, skb );
1751 if (status != VOS_STATUS_SUCCESS)
1752 {
1753 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1754 "%s: Error attaching skb", __func__);
1755 vos_pkt_return_packet(pVosPacket);
1756 ++pAdapter->stats.tx_dropped;
1757 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1758 kfree_skb(skb);
1759 return VOS_STATUS_E_FAILURE;
1760 }
1761
1762 //Return VOS packet to TL;
1763 *ppVosPacket = pVosPacket;
1764
1765 //Fill out the meta information needed by TL
1766 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1767 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1768 if ( 1 < size )
1769 {
1770 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1771 }
1772 else
1773 {
1774 pPktMetaInfo->bMorePackets = 0;
1775 }
1776
1777 if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE)
1778 pPktMetaInfo->ucIsEapol = 0;
1779 else
1780 pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0;
1781
1782 if ((NULL != pHddCtx) &&
1783 (pHddCtx->cfg_ini->gEnableDebugLog))
1784 {
1785 proto_type = vos_pkt_get_proto_type(skb,
1786 pHddCtx->cfg_ini->gEnableDebugLog);
1787 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1788 {
1789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1790 "IBSS STA TX EAPOL");
1791 }
1792 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1795 "IBSS STA TX DHCP");
1796 }
1797 }
1798
Abhishek Singh99f725a2015-05-15 17:50:26 +05301799 vos_pkt_get_packet_length( pVosPacket,&packet_size );
1800 if ( HDD_ETHERTYPE_ARP_SIZE == packet_size )
1801 pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;
1802
Katya Nigamf944e5e2015-02-10 15:05:43 +05301803 pPktMetaInfo->ucUP = pktNode->userPriority;
1804 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1805 pPktMetaInfo->ucType = 0;
1806
1807 //Extract the destination address from ethernet frame
1808 pDestMacAddress = (v_MACADDR_t*)skb->data;
1809
1810 // we need 802.3 to 802.11 frame translation
1811 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1812 pPktMetaInfo->ucDisableFrmXtl = 0;
1813 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1814 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1815
1816 if ( (pPeerInfo->ibssStaInfo[STAId].txSuspended[ac]) &&
1817 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1818 {
1819 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1820 "%s: TX queue re-enabled", __func__);
1821 pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
1822 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
1823 }
1824
1825 // We're giving the packet to TL so consider it transmitted from
1826 // a statistics perspective. We account for it here instead of
1827 // when the packet is returned for two reasons. First, TL will
1828 // manipulate the skb to the point where the len field is not
1829 // accurate, leading to inaccurate byte counts if we account for
1830 // it later. Second, TL does not provide any feedback as to
1831 // whether or not the packet was successfully sent over the air,
1832 // so the packet counts will be the same regardless of where we
1833 // account for them
1834 pAdapter->stats.tx_bytes += skb->len;
1835 ++pAdapter->stats.tx_packets;
1836 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1837 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
1838 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
1839
1840 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1841 "%s: Valid VOS PKT returned to TL", __func__);
1842
1843 return status;
1844}
Jeff Johnson295189b2012-06-20 16:38:30 -07001845
1846/**============================================================================
1847 @brief hdd_tx_fetch_packet_cbk() - Callback function invoked by TL to
1848 fetch a packet for transmission.
1849
1850 @param vosContext : [in] pointer to VOS context
1851 @param staId : [in] Station for which TL is requesting a pkt
1852 @param ac : [in] access category requested by TL
1853 @param pVosPacket : [out] pointer to VOS packet packet pointer
1854 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1855
1856 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1857 : VOS_STATUS_E_FAILURE if any errors encountered
1858 : VOS_STATUS_SUCCESS otherwise
1859 ===========================================================================*/
1860VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1861 v_U8_t *pStaId,
1862 WLANTL_ACEnumType ac,
1863 vos_pkt_t **ppVosPacket,
1864 WLANTL_MetaInfoType *pPktMetaInfo )
1865{
1866 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1867 hdd_adapter_t *pAdapter = NULL;
1868 hdd_context_t *pHddCtx = NULL;
1869 hdd_list_node_t *anchor = NULL;
1870 skb_list_node_t *pktNode = NULL;
1871 struct sk_buff *skb = NULL;
1872 vos_pkt_t *pVosPacket = NULL;
1873 v_MACADDR_t* pDestMacAddress = NULL;
1874 v_TIME_t timestamp;
1875 WLANTL_ACEnumType newAc;
1876 v_SIZE_t size = 0;
Abhishek Singhfa011222014-04-14 10:57:08 +05301877 v_U16_t packet_size;
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 tANI_U8 acAdmitted, i;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08001879 v_U8_t proto_type = 0;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301880 WLANTL_ACEnumType actualAC;
Jeff Johnson295189b2012-06-20 16:38:30 -07001881
1882 //Sanity check on inputs
1883 if ( ( NULL == vosContext ) ||
1884 ( NULL == pStaId ) ||
1885 ( NULL == ppVosPacket ) ||
1886 ( NULL == pPktMetaInfo ) )
1887 {
c_hpothu32490782014-03-14 19:14:34 +05301888 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301889 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001890 return VOS_STATUS_E_FAILURE;
1891 }
1892
1893 //Get the HDD context.
Kiet Lam3c2ee302014-03-23 23:23:22 -07001894 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
Jeff Johnson295189b2012-06-20 16:38:30 -07001895 if(pHddCtx == NULL)
1896 {
c_hpothu32490782014-03-14 19:14:34 +05301897 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301898 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001899 return VOS_STATUS_E_FAILURE;
1900 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001901 pAdapter = pHddCtx->sta_to_adapter[*pStaId];
Jeff Johnsonb156c922013-12-05 17:19:46 -08001902 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07001903 {
c_hpothu32490782014-03-14 19:14:34 +05301904 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301905 FL("invalid adapter:%p for staId:%u"), pAdapter, *pStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001906 VOS_ASSERT(0);
1907 return VOS_STATUS_E_FAILURE;
1908 }
1909
1910 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1911
1912 *ppVosPacket = NULL;
1913
1914 //Make sure the AC being asked for is sane
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301915 if (ac > WLANTL_AC_HIGH_PRIO || ac < 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07001916 {
c_hpothu32490782014-03-14 19:14:34 +05301917 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301918 "%s: Invalid QId %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001919 return VOS_STATUS_E_FAILURE;
1920 }
1921
1922 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1923
1924#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05301925 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301926 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001927#endif // HDD_WMM_DEBUG
1928
Jeff Johnson295189b2012-06-20 16:38:30 -07001929 // do we have any packets pending in this AC?
1930 hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size );
1931 if( size > 0 )
1932 {
1933 // yes, so process it
1934#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05301935 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001936 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001937#endif // HDD_WMM_DEBUG
1938 }
1939 else
1940 {
1941 ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty;
1942#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05301943 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001944 "%s: no packets pending", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001945#endif // HDD_WMM_DEBUG
1946 return VOS_STATUS_E_FAILURE;
1947 }
1948
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301949 // Note here that we are not checking "wmmAcAccessAllowed" for packets
1950 // in new queue since there is no one AC associated to the new queue.
1951 // Since there will be either eapol or dhcp pkts in new queue overlooking
1952 // this should be okay from implicit QoS perspective.
1953 if (ac != WLANTL_AC_HIGH_PRIO)
1954 {
1955 // We find an AC with packets
1956 // or we determine we have no more packets to send
1957 // HDD is not allowed to change AC.
1958
1959 // has this AC been admitted? or
1960 // To allow EAPOL packets when not authenticated
1961 if (unlikely((0==pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed) &&
1962 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.uIsAuthenticated))
1963 {
1964 ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty;
1965#ifdef HDD_WMM_DEBUG
1966 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
1967 "%s: no packets pending", __func__);
1968#endif // HDD_WMM_DEBUG
1969 return VOS_STATUS_E_FAILURE;
1970 }
1971 }
1972
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
1974 //This simplifies the locking and unlocking of Tx queue
1975 status = vos_pkt_wrap_data_packet( &pVosPacket,
1976 VOS_PKT_TYPE_TX_802_3_DATA,
1977 NULL, //OS Pkt is not being passed
1978 hdd_tx_low_resource_cbk,
1979 pAdapter );
1980
1981 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
1982 {
1983 //Remember VOS is in a low resource situation
1984 pAdapter->isVosOutOfResource = VOS_TRUE;
1985 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu32490782014-03-14 19:14:34 +05301986 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOSS in Low Resource scenario", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 //TL will now think we have no more packets in this AC
1988 return VOS_STATUS_E_FAILURE;
1989 }
1990
1991 //Remove the packet from the queue
1992 spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock);
1993 status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor );
1994 spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock);
1995
1996 if(VOS_STATUS_SUCCESS == status)
1997 {
1998 //If success then we got a valid packet from some AC
1999 pktNode = list_entry(anchor, skb_list_node_t, anchor);
2000 skb = pktNode->skb;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302001 actualAC = hddWmmUpToAcMap[pktNode->userPriority];
2002 if (actualAC >= WLANTL_MAX_AC)
2003 {
2004 /* To fix klocwork */
2005 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
2006 "%s: Invalid AC for packet:%d", __func__, actualAC);
2007 actualAC = WLANTL_AC_BE;
2008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002009 }
2010 else
2011 {
2012 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu32490782014-03-14 19:14:34 +05302013 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, "%s: Error in de-queuing "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002014 "skb from Tx queue status = %d", __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 vos_pkt_return_packet(pVosPacket);
2016 return VOS_STATUS_E_FAILURE;
2017 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002018 //Attach skb to VOS packet.
2019 status = vos_pkt_set_os_packet( pVosPacket, skb );
2020 if (status != VOS_STATUS_SUCCESS)
2021 {
c_hpothu32490782014-03-14 19:14:34 +05302022 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 vos_pkt_return_packet(pVosPacket);
2024 ++pAdapter->stats.tx_dropped;
2025 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
2026 kfree_skb(skb);
2027 return VOS_STATUS_E_FAILURE;
2028 }
2029
2030 //Just being paranoid. To be removed later
2031 if(pVosPacket == NULL)
2032 {
c_hpothu32490782014-03-14 19:14:34 +05302033 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOS packet returned by VOSS is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 ++pAdapter->stats.tx_dropped;
2035 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
2036 kfree_skb(skb);
2037 return VOS_STATUS_E_FAILURE;
2038 }
2039
Dino Mycle3b9536d2014-07-09 22:05:24 +05302040#ifdef WLAN_FEATURE_LINK_LAYER_STATS
2041 {
2042 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
2043 /* vos_is_macaddr_group expects data in v_MACADDR_t format
2044 */
2045 if (vos_is_macaddr_group(pDestMacAddress))
2046 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302047 pAdapter->hdd_stats.hddTxRxStats.txMcast[actualAC]++;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302048 }
2049
2050 }
2051
2052#endif
2053
Chilam NG571c65a2013-01-19 12:27:36 +05302054#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002055 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
Chilam NG571c65a2013-01-19 12:27:36 +05302056 {
2057 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
Chilam NG571c65a2013-01-19 12:27:36 +05302058 u8 mac[6];
2059
Hoonki Lee387663d2013-02-05 18:08:43 -08002060 wlan_hdd_tdls_extract_da(skb, mac);
Chilam NG571c65a2013-01-19 12:27:36 +05302061
Hoonki Lee5fcc4582013-02-05 20:28:26 -08002062 if (vos_is_macaddr_group((v_MACADDR_t *)mac)) {
c_hpothu32490782014-03-14 19:14:34 +05302063 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Chilam NG571c65a2013-01-19 12:27:36 +05302064 "broadcast packet, not adding to peer list");
2065 } else if (memcmp(pHddStaCtx->conn_info.bssId,
2066 mac, 6) != 0) {
c_hpothu32490782014-03-14 19:14:34 +05302067 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002068 "extract mac: " MAC_ADDRESS_STR,
2069 MAC_ADDR_ARRAY(mac) );
Chilam NG571c65a2013-01-19 12:27:36 +05302070
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002071 wlan_hdd_tdls_increment_pkt_count(pAdapter, mac, 1);
Chilam NG571c65a2013-01-19 12:27:36 +05302072 } else {
c_hpothu32490782014-03-14 19:14:34 +05302073 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Chilam NG571c65a2013-01-19 12:27:36 +05302074 "packet da is bssid, not adding to peer list");
2075 }
2076 }
2077#endif
2078
Jeff Johnson295189b2012-06-20 16:38:30 -07002079 //Return VOS packet to TL;
2080 *ppVosPacket = pVosPacket;
2081
2082 //Fill out the meta information needed by TL
2083 //FIXME This timestamp is really the time stamp of wrap_data_packet
2084 vos_pkt_get_timestamp( pVosPacket, &timestamp );
2085 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
2086
2087 if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE)
2088 pPktMetaInfo->ucIsEapol = 0;
Nirav Shah4f765af2015-01-21 19:51:30 +05302089 else
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0;
2091
Sushant Kaushika8073312015-05-04 17:33:52 +05302092 if (pPktMetaInfo->ucIsEapol)
2093 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05302094 if ((NULL != pHddCtx) &&
2095 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002096 {
2097 proto_type = vos_pkt_get_proto_type(skb,
2098 pHddCtx->cfg_ini->gEnableDebugLog);
2099 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
2100 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07002102 "STA TX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002103 }
2104 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
2105 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002107 "STA TX DHCP");
2108 }
2109 }
2110
Abhishek Singhfa011222014-04-14 10:57:08 +05302111 vos_pkt_get_packet_length( pVosPacket,&packet_size );
2112 if( HDD_ETHERTYPE_ARP_SIZE == packet_size )
2113 pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;
2114
Jeff Johnson295189b2012-06-20 16:38:30 -07002115#ifdef FEATURE_WLAN_WAPI
2116 // Override usIsEapol value when its zero for WAPI case
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302117 pPktMetaInfo->ucIsWai = hdd_IsWAIPacket( pVosPacket ) ? 1 : 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002118#endif /* FEATURE_WLAN_WAPI */
2119
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302120 /* 1. Check if ACM is set for this AC
2121 * 2. If set, check if this AC had already admitted
2122 * 3. If not already admitted, downgrade the UP to next best UP
2123 * 4. Allow only when medium time is non zero when Addts accepted
2124 * else downgrade traffic. we opted downgrading over Delts when
2125 * medium time is zero because while doing downgradig driver is not
2126 * clearing the wmm context so consider in subsequent roaming
2127 * if AP (new or same AP) accept the Addts with valid medium time
2128 * no application support is required where if we have opted
2129 * delts Applications have to again do Addts or STA will never
2130 * go for Addts.
2131 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302132 pPktMetaInfo->ac = actualAC;
2133 if(!pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcAccessRequired ||
2134 (pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid &&
2135 pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecInfo.medium_time))
Jeff Johnson295189b2012-06-20 16:38:30 -07002136 {
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302137 pPktMetaInfo->ucUP = pktNode->userPriority;
2138 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 }
2140 else
2141 {
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302142 //Downgrade the UP
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302143 acAdmitted = pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid;
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302144 newAc = WLANTL_AC_BK;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302145 for (i=actualAC-1; i>0; i--)
Jeff Johnson295189b2012-06-20 16:38:30 -07002146 {
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302147 if (pAdapter->hddWmmStatus.wmmAcStatus[i].wmmAcAccessRequired == 0)
2148 {
2149 newAc = i;
2150 break;
2151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002152 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302153 pPktMetaInfo->ucUP = hddWmmAcToHighestUp[newAc];
2154 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
2155 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,
2156 "Downgrading UP %d to UP %d ",
2157 pktNode->userPriority, pPktMetaInfo->ucUP);
Jeff Johnson295189b2012-06-20 16:38:30 -07002158 }
2159
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05302160 if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
2161 {
2162 vos_record_roam_event(e_TL_FIRST_XMIT_TIME, NULL, 0);
2163 }
Mukul Sharma84f27252014-07-14 18:11:42 +05302164
Jeff Johnson295189b2012-06-20 16:38:30 -07002165 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
2166 pPktMetaInfo->ucDisableFrmXtl = 0; //802.3 frame so we need to xlate
2167 if ( 1 < size )
2168 {
2169 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
2170 }
2171 else
2172 {
2173 pPktMetaInfo->bMorePackets = 0;
2174 }
2175
2176 //Extract the destination address from ethernet frame
2177 pDestMacAddress = (v_MACADDR_t*)skb->data;
2178 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
2179 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
2180
2181
2182
2183 // if we are in a backpressure situation see if we can turn the hose back on
2184 if ( (pAdapter->isTxSuspended[ac]) &&
2185 (size <= HDD_TX_QUEUE_LOW_WATER_MARK) )
2186 {
2187 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressured;
2188 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressuredAC[ac];
c_hpothu32490782014-03-14 19:14:34 +05302189 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002190 "%s: TX queue[%d] re-enabled", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002191 pAdapter->isTxSuspended[ac] = VOS_FALSE;
2192 netif_tx_wake_queue(netdev_get_tx_queue(pAdapter->dev,
2193 skb_get_queue_mapping(skb) ));
Mihir Shete5d148f12014-12-16 17:54:49 +05302194 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
2195 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002196 }
2197
2198
2199 // We're giving the packet to TL so consider it transmitted from
2200 // a statistics perspective. We account for it here instead of
2201 // when the packet is returned for two reasons. First, TL will
2202 // manipulate the skb to the point where the len field is not
2203 // accurate, leading to inaccurate byte counts if we account for
2204 // it later. Second, TL does not provide any feedback as to
2205 // whether or not the packet was successfully sent over the air,
2206 // so the packet counts will be the same regardless of where we
2207 // account for them
2208 pAdapter->stats.tx_bytes += skb->len;
2209 ++pAdapter->stats.tx_packets;
2210 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
2211 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05302212 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002213
Leo Chang50bbd252013-04-25 14:58:01 -07002214 if((pHddCtx->cfg_ini->thermalMitigationEnable) &&
2215 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 {
2217 if(mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
2218 {
c_hpothu32490782014-03-14 19:14:34 +05302219 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002220 "%s: Tm Lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002221 return VOS_STATUS_E_FAILURE;
2222 }
2223 if(WLAN_HDD_TM_LEVEL_1 < pHddCtx->tmInfo.currentTmLevel)
2224 {
2225 if(0 == pHddCtx->tmInfo.txFrameCount)
2226 {
2227 /* Just recovered from sleep timeout */
2228 pHddCtx->tmInfo.lastOpenTs = timestamp;
2229 }
2230
Leo Chang50bbd252013-04-25 14:58:01 -07002231 if((VOS_FALSE == pHddCtx->tmInfo.qBlocked) &&
2232 ((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002233 (pHddCtx->tmInfo.txFrameCount >= pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold))
2234 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 /* During TX open duration, TX frame count is larger than threshold
2236 * Block TX during Sleep time */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002238 netif_tx_stop_all_queues(pAdapter->dev);
Leo Chang50bbd252013-04-25 14:58:01 -07002239 pHddCtx->tmInfo.qBlocked = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002240 pHddCtx->tmInfo.lastblockTs = timestamp;
2241 if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pHddCtx->tmInfo.txSleepTimer))
2242 {
2243 vos_timer_start(&pHddCtx->tmInfo.txSleepTimer, pHddCtx->tmInfo.tmAction.txSleepDuration);
2244 }
2245 }
2246 else if(((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) &&
2247 (pHddCtx->tmInfo.txFrameCount < pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold))
2248 {
2249 /* During TX open duration, TX frame count is less than threshold
2250 * Reset count and timestamp to prepare next cycle */
2251 pHddCtx->tmInfo.lastOpenTs = timestamp;
2252 pHddCtx->tmInfo.txFrameCount = 0;
2253 }
2254 else
2255 {
2256 /* Do Nothing */
2257 }
2258 pHddCtx->tmInfo.txFrameCount++;
2259 }
2260 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
2261 }
2262
2263
2264#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05302265 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,"%s: Valid VOS PKT returned to TL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002266#endif // HDD_WMM_DEBUG
2267
2268 return status;
2269}
2270
2271
2272/**============================================================================
2273 @brief hdd_tx_low_resource_cbk() - Callback function invoked in the
2274 case where VOS packets are not available at the time of the call to get
2275 packets. This callback function is invoked by VOS when packets are
2276 available.
2277
2278 @param pVosPacket : [in] pointer to VOS packet
2279 @param userData : [in] opaque user data that was passed initially
2280
2281 @return : VOS_STATUS_E_FAILURE if any errors encountered,
2282 : VOS_STATUS_SUCCESS otherwise
2283 =============================================================================*/
2284VOS_STATUS hdd_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
2285 v_VOID_t *userData )
2286{
2287 VOS_STATUS status;
2288 v_SINT_t i = 0;
2289 v_SIZE_t size = 0;
2290 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
2291
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302292 if (NULL == pAdapter || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07002293 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302294 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2295 FL("Invalid adapter %p"), pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002296 return VOS_STATUS_E_FAILURE;
2297 }
2298
2299 //Return the packet to VOS. We just needed to know that VOS is out of low resource
2300 //situation. Here we will only signal TL that there is a pending data for a STA.
2301 //VOS packet will be requested (if needed) when TL comes back to fetch data.
2302 vos_pkt_return_packet( pVosPacket );
2303
2304 pAdapter->isVosOutOfResource = VOS_FALSE;
2305
2306 //Indicate to TL that there is pending data if a queue is non empty
2307 for( i=NUM_TX_QUEUES-1; i>=0; --i )
2308 {
2309 size = 0;
2310 hdd_list_size( &pAdapter->wmm_tx_queue[i], &size );
2311 if ( size > 0 )
2312 {
2313 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2314 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId [0],
2315 (WLANTL_ACEnumType)i );
2316 if( !VOS_IS_STATUS_SUCCESS( status ) )
2317 {
c_hpothu32490782014-03-14 19:14:34 +05302318 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302319 "%s: Failure in indicating pkt to TL for ac=%d", __func__, i);
Jeff Johnson295189b2012-06-20 16:38:30 -07002320 }
2321 }
2322 }
2323
2324 return VOS_STATUS_SUCCESS;
2325}
2326
Katya Nigame7b69a82015-04-28 15:24:06 +05302327static void hdd_mon_add_rx_radiotap_hdr (struct sk_buff *skb,
2328 int rtap_len, v_PVOID_t pRxPacket, hdd_mon_ctx_t *pMonCtx)
2329{
2330 u8 rtap_temp[20] = {0};
2331 struct ieee80211_radiotap_header *rthdr;
2332 unsigned char *pos;
2333 u16 rx_flags = 0;
2334 u16 rateIdx;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302335 s8 currentRSSI, currentRSSI0, currentRSSI1;
Katya Nigame7b69a82015-04-28 15:24:06 +05302336
2337 rateIdx = WDA_GET_RX_MAC_RATE_IDX(pRxPacket);
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302338 if( rateIdx >= 210 && rateIdx <= 217)
2339 rateIdx-=202;
2340 if( rateIdx >= 218 && rateIdx <= 225 )
2341 rateIdx-=210;
2342 currentRSSI0 = WDA_GETRSSI0(pRxPacket) - 100;
2343 currentRSSI1 = WDA_GETRSSI1(pRxPacket) - 100;
2344 currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1;
Katya Nigame7b69a82015-04-28 15:24:06 +05302345
2346 rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]);
2347
2348 /* radiotap header, set always present flags */
2349 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
2350 (1 << IEEE80211_RADIOTAP_CHANNEL) |
2351 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
2352 rthdr->it_len = cpu_to_le16(rtap_len);
2353
2354 pos = (unsigned char *) (rthdr + 1);
2355
2356 /* IEEE80211_RADIOTAP_FLAGS */
2357 *pos = 0;
2358 pos++;
2359
2360 /* IEEE80211_RADIOTAP_RATE */
2361 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
2362 *pos = gRatefromIdx[rateIdx]/5;
2363
2364 pos++;
2365
2366 /* IEEE80211_RADIOTAP_CHANNEL */
2367 put_unaligned_le16(pMonCtx->ChannelNo, pos);
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302368 pos += 4;
2369
2370 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
2371 *pos = currentRSSI;
2372 rthdr->it_present |=cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
2373 pos++;
Katya Nigame7b69a82015-04-28 15:24:06 +05302374
2375 if ((pos - (u8 *)rthdr) & 1)
2376 pos++;
2377 put_unaligned_le16(rx_flags, pos);
2378 pos += 2;
2379
2380 memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len);
2381}
2382
2383
2384VOS_STATUS hdd_rx_packet_monitor_cbk(v_VOID_t *vosContext,vos_pkt_t *pVosPacket, int conversion)
2385{
2386 struct sk_buff *skb = NULL;
2387 VOS_STATUS status = VOS_STATUS_E_FAILURE;
2388 hdd_adapter_t *pAdapter = NULL;
2389 hdd_context_t *pHddCtx = NULL;
2390 hdd_mon_ctx_t *pMonCtx = NULL;
2391 v_PVOID_t pvBDHeader = NULL;
2392 int rxstat;
2393 int needed_headroom = 0;
2394
2395
2396 //Sanity check on inputs
2397 if ( ( NULL == vosContext ) ||
2398 ( NULL == pVosPacket ) )
2399 {
2400 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2401 "%s: Null params being passed", __func__);
2402 return VOS_STATUS_E_FAILURE;
2403 }
2404
2405 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
2406 pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
2407 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
2408 {
2409 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2410 FL("Invalid adapter %p for MONITOR MODE"), pAdapter);
2411 vos_pkt_return_packet( pVosPacket );
2412 return VOS_STATUS_E_FAILURE;
2413 }
2414
2415 status = WDA_DS_PeekRxPacketInfo( pVosPacket, (v_PVOID_t)&pvBDHeader, 1/*Swap BD*/ );
2416 if ( NULL == pvBDHeader )
2417 {
2418 VOS_TRACE( VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
2419 "Cannot extract BD header");
2420 /* Drop packet */
2421 vos_pkt_return_packet(pVosPacket);
2422 return VOS_STATUS_E_FAILURE;
2423 }
2424
2425 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
2426 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
2427 if(!VOS_IS_STATUS_SUCCESS( status ))
2428 {
2429 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
2430 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2431 "%s: Failure extracting skb from vos pkt", __func__);
2432 vos_pkt_return_packet( pVosPacket );
2433 return VOS_STATUS_E_FAILURE;
2434 }
2435
2436 if(!conversion)
2437 {
2438 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302439 needed_headroom = sizeof(struct ieee80211_radiotap_header) + 10;
Katya Nigame7b69a82015-04-28 15:24:06 +05302440 hdd_mon_add_rx_radiotap_hdr( skb, needed_headroom, pvBDHeader, pMonCtx );
2441 }
2442
2443 skb_reset_mac_header( skb );
2444 skb->dev = pAdapter->dev;
2445 skb->pkt_type = PACKET_OTHERHOST;
2446 skb->protocol = htons(ETH_P_802_2);
2447 skb->ip_summed = CHECKSUM_NONE;
2448 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
2449 ++pAdapter->stats.rx_packets;
2450 pAdapter->stats.rx_bytes += skb->len;
2451
2452 rxstat = netif_rx_ni(skb);
2453 if (NET_RX_SUCCESS == rxstat)
2454 {
2455 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
2456 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
2457 }
2458 else
2459 {
2460 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
2461 }
2462
2463 status = vos_pkt_return_packet( pVosPacket );
2464 if(!VOS_IS_STATUS_SUCCESS( status ))
2465 {
2466 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
2467 }
2468 pAdapter->dev->last_rx = jiffies;
2469
2470return status;
2471}
Jeff Johnson295189b2012-06-20 16:38:30 -07002472
2473/**============================================================================
2474 @brief hdd_rx_packet_cbk() - Receive callback registered with TL.
2475 TL will call this to notify the HDD when one or more packets were
2476 received for a registered STA.
2477
2478 @param vosContext : [in] pointer to VOS context
2479 @param pVosPacketChain : [in] pointer to VOS packet chain
2480 @param staId : [in] Station Id
2481 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s)
2482
2483 @return : VOS_STATUS_E_FAILURE if any errors encountered,
2484 : VOS_STATUS_SUCCESS otherwise
2485 ===========================================================================*/
2486VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext,
2487 vos_pkt_t *pVosPacketChain,
2488 v_U8_t staId,
2489 WLANTL_RxMetaInfoType* pRxMetaInfo )
2490{
2491 hdd_adapter_t *pAdapter = NULL;
2492 hdd_context_t *pHddCtx = NULL;
2493 VOS_STATUS status = VOS_STATUS_E_FAILURE;
2494 int rxstat;
2495 struct sk_buff *skb = NULL;
2496 vos_pkt_t* pVosPacket;
2497 vos_pkt_t* pNextVosPacket;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002498 v_U8_t proto_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002499
2500 //Sanity check on inputs
2501 if ( ( NULL == vosContext ) ||
2502 ( NULL == pVosPacketChain ) ||
2503 ( NULL == pRxMetaInfo ) )
2504 {
c_hpothu32490782014-03-14 19:14:34 +05302505 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302506 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002507 return VOS_STATUS_E_FAILURE;
2508 }
2509
Kiet Lam3c2ee302014-03-23 23:23:22 -07002510 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 if ( NULL == pHddCtx )
2512 {
c_hpothu32490782014-03-14 19:14:34 +05302513 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302514 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002515 return VOS_STATUS_E_FAILURE;
2516 }
2517
2518 pAdapter = pHddCtx->sta_to_adapter[staId];
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302519 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002520 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302521 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2522 FL("Invalid adapter %p for staId %u"), pAdapter, staId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002523 return VOS_STATUS_E_FAILURE;
2524 }
2525
2526 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
2527
2528 // walk the chain until all are processed
2529 pVosPacket = pVosPacketChain;
2530 do
2531 {
2532 // get the pointer to the next packet in the chain
2533 // (but don't unlink the packet since we free the entire chain later)
2534 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
2535
2536 // both "success" and "empty" are acceptable results
2537 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
2538 {
2539 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu32490782014-03-14 19:14:34 +05302540 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302541 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002542 return VOS_STATUS_E_FAILURE;
2543 }
2544
2545 // Extract the OS packet (skb).
Sushant Kaushikd43987b2015-06-05 12:18:34 +05302546 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07002547 if(!VOS_IS_STATUS_SUCCESS( status ))
2548 {
2549 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu32490782014-03-14 19:14:34 +05302550 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302551 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002552 return VOS_STATUS_E_FAILURE;
2553 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002554
Sushant Kaushikd43987b2015-06-05 12:18:34 +05302555 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
2556 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
2557
2558 pVosPacket->pSkb = NULL;
2559
Jeff Johnsone7245742012-09-05 17:12:55 -07002560 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2561 {
c_hpothu32490782014-03-14 19:14:34 +05302562 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsone7245742012-09-05 17:12:55 -07002563 "Magic cookie(%x) for adapter sanity verification is invalid", pAdapter->magic);
2564 return eHAL_STATUS_FAILURE;
2565 }
2566
Chilam Ng1279e232013-01-25 15:06:52 -08002567#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002568 if ((eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) &&
2569 0 != pHddCtx->connected_peer_count)
Chilam Ng1279e232013-01-25 15:06:52 -08002570 {
2571 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
Chilam Ng1279e232013-01-25 15:06:52 -08002572 u8 mac[6];
2573
Hoonki Lee387663d2013-02-05 18:08:43 -08002574 wlan_hdd_tdls_extract_sa(skb, mac);
Chilam Ng1279e232013-01-25 15:06:52 -08002575
Hoonki Lee5fcc4582013-02-05 20:28:26 -08002576 if (vos_is_macaddr_group((v_MACADDR_t *)mac)) {
c_hpothu32490782014-03-14 19:14:34 +05302577 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Chilam Ng1279e232013-01-25 15:06:52 -08002578 "rx broadcast packet, not adding to peer list");
2579 } else if (memcmp(pHddStaCtx->conn_info.bssId,
2580 mac, 6) != 0) {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002581 hddTdlsPeer_t *curr_peer;
c_hpothu32490782014-03-14 19:14:34 +05302582 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002583 "rx extract mac:" MAC_ADDRESS_STR,
2584 MAC_ADDR_ARRAY(mac) );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302585 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala4a2fc1a2013-05-17 16:59:39 +05302586 if ((NULL != curr_peer) && (eTDLS_LINK_CONNECTED == curr_peer->link_status)
2587 && (TRUE == pRxMetaInfo->isStaTdls))
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002588 {
2589 wlan_hdd_tdls_increment_pkt_count(pAdapter, mac, 0);
c_hpothu32490782014-03-14 19:14:34 +05302590 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,"rssi is %d", pRxMetaInfo->rssiAvg);
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07002591 wlan_hdd_tdls_set_rssi (pAdapter, mac, pRxMetaInfo->rssiAvg);
2592 }
Chilam Ng1279e232013-01-25 15:06:52 -08002593 } else {
c_hpothu32490782014-03-14 19:14:34 +05302594 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Chilam Ng1279e232013-01-25 15:06:52 -08002595 "rx packet sa is bssid, not adding to peer list");
2596 }
2597 }
2598#endif
2599
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002600 if (pHddCtx->cfg_ini->gEnableDebugLog)
2601 {
2602 proto_type = vos_pkt_get_proto_type(skb,
2603 pHddCtx->cfg_ini->gEnableDebugLog);
2604 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
2605 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07002607 "STA RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002608 }
2609 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
2610 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002612 "STA RX DHCP");
2613 }
2614 }
2615
Girish Gowli8a7bc042015-01-19 16:20:20 +05302616 if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
2617 {
2618 vos_record_roam_event(e_HDD_RX_PKT_CBK_TIME, (void *)skb, 0);
2619 }
Sachin Ahuja8c65f382014-12-12 15:34:21 +05302620 if (( NULL != pHddCtx ) &&
2621 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05302622 {
2623 hdd_dump_dhcp_pkt(skb, RX_PATH);
2624 }
Mukul Sharma84f27252014-07-14 18:11:42 +05302625
Jeff Johnson295189b2012-06-20 16:38:30 -07002626 skb->dev = pAdapter->dev;
2627 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002628 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002629 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
2630 ++pAdapter->stats.rx_packets;
2631 pAdapter->stats.rx_bytes += skb->len;
Jeff Johnsone7245742012-09-05 17:12:55 -07002632#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302633 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
2634 HDD_WAKE_LOCK_DURATION,
2635 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002636#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002637 rxstat = netif_rx_ni(skb);
2638 if (NET_RX_SUCCESS == rxstat)
2639 {
2640 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002641 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07002642 }
2643 else
2644 {
2645 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
2646 }
2647 // now process the next packet in the chain
2648 pVosPacket = pNextVosPacket;
2649
2650 } while (pVosPacket);
2651
2652 //Return the entire VOS packet chain to the resource pool
2653 status = vos_pkt_return_packet( pVosPacketChain );
2654 if(!VOS_IS_STATUS_SUCCESS( status ))
2655 {
c_hpothu32490782014-03-14 19:14:34 +05302656 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002657 }
2658
2659 pAdapter->dev->last_rx = jiffies;
2660
2661 return status;
2662}
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002663/**============================================================================
2664 @brief hdd_tx_rx_pkt_cnt_stat_timer_handler() -
2665 Enable/Disable split scan based on TX and RX traffic.
2666 @param HddContext : [in] pointer to Hdd context
2667 @return : None
2668 ===========================================================================*/
2669void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *phddctx)
2670{
2671 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2672 hdd_adapter_t *pAdapter = NULL;
2673 hdd_station_ctx_t *pHddStaCtx = NULL;
2674 hdd_context_t *pHddCtx = (hdd_context_t *)phddctx;
2675 hdd_config_t *cfg_param = pHddCtx->cfg_ini;
2676 VOS_STATUS status;
2677 v_U8_t staId = 0;
2678 v_U8_t fconnected = 0;
2679
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +05302680 ENTER();
2681 if (0 != (wlan_hdd_validate_context(pHddCtx)))
2682 {
2683 return;
2684 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002685 if (!cfg_param->dynSplitscan)
2686 {
c_hpothu32490782014-03-14 19:14:34 +05302687 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002688 "%s: Error : Dynamic split scan is not Enabled : %d",
2689 __func__, pHddCtx->cfg_ini->dynSplitscan);
2690 return;
2691 }
2692
2693 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2694 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2695 {
2696 pAdapter = pAdapterNode->pAdapter;
2697
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +05302698 if ((NULL != pAdapter) && (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002699 {
c_hpothu32490782014-03-14 19:14:34 +05302700 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002701 "%s: Adapter with device mode %d exists",
2702 __func__, pAdapter->device_mode);
2703
2704 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2705 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
2706 {
2707 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2708 if ((eConnectionState_Associated ==
2709 pHddStaCtx->conn_info.connState) &&
2710 (VOS_TRUE == pHddStaCtx->conn_info.uIsAuthenticated))
2711 {
2712 fconnected = TRUE;
2713 }
2714 }
2715 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
2716 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
2717 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302718 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2719 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
2720 if(pSapCtx == NULL){
2721 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2722 FL("psapCtx is NULL"));
2723 return;
2724 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002725 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2726 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302727 if ((pSapCtx->aStaInfo[staId].isUsed) &&
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002728 (WLANTL_STA_AUTHENTICATED ==
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302729 pSapCtx->aStaInfo[staId].tlSTAState))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002730 {
2731 fconnected = TRUE;
2732 }
2733 }
2734 }
2735 if ( fconnected )
2736 {
c_hpothu32490782014-03-14 19:14:34 +05302737 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002738 "%s: One of the interface is connected check for scan",
2739 __func__);
c_hpothu32490782014-03-14 19:14:34 +05302740 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Abhishek Singh90485302014-05-15 16:36:57 +05302741 "%s: pkt_tx_count: %d, pkt_rx_count: %d "
2742 "miracast = %d", __func__,
2743 pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count,
2744 pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count,
2745 pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002746
2747 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
2748 cfg_param->trafficMntrTmrForSplitScan);
2749 //Check for the previous statistics count
2750 if ((pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count >
2751 cfg_param->txRxThresholdForSplitScan) ||
2752 (pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count >
2753 cfg_param->txRxThresholdForSplitScan) ||
Abhishek Singh90485302014-05-15 16:36:57 +05302754 pHddCtx->drvr_miracast ||
2755 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002756 {
2757 pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0;
2758 pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0;
2759
2760 if (!pHddCtx->issplitscan_enabled)
2761 {
2762 pHddCtx->issplitscan_enabled = TRUE;
2763 sme_enable_disable_split_scan(
2764 WLAN_HDD_GET_HAL_CTX(pAdapter),
2765 cfg_param->nNumStaChanCombinedConc,
2766 cfg_param->nNumP2PChanCombinedConc);
2767 }
2768 return;
2769 }
2770 else
2771 {
2772 pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0;
2773 pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0;
2774 }
2775 fconnected = FALSE;
2776 }
2777 }
2778 status = hdd_get_next_adapter( pHddCtx, pAdapterNode, &pNext);
2779 pAdapterNode = pNext;
2780 }
2781
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302782 /* If TDLSScanCoexistence is enabled, then the TDLS module shall take care
2783 * of disabling the split scan and thus do not disable the same when the
2784 * low TXRX condition is met.
2785 */
2786 if ((pHddCtx->isTdlsScanCoexistence == FALSE) && (pHddCtx->issplitscan_enabled))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002787 {
c_hpothu32490782014-03-14 19:14:34 +05302788 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002789 "%s: Disable split scan", __func__);
2790 pHddCtx->issplitscan_enabled = FALSE;
2791 sme_enable_disable_split_scan(
2792 pHddCtx->hHal,
2793 SME_DISABLE_SPLIT_SCAN,
2794 SME_DISABLE_SPLIT_SCAN);
2795 }
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +05302796 EXIT();
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002797 return;
2798}
Jeff Johnson295189b2012-06-20 16:38:30 -07002799
Sushant Kaushika8073312015-05-04 17:33:52 +05302800#ifdef FEATURE_WLAN_DIAG_SUPPORT
2801/*
2802 * wlan_hdd_get_eapol_params() - Function to extract EAPOL params
2803 * @skb: skb data
2804 * @eapol_params: Pointer to hold the parsed EAPOL params
2805 * @event_type: Event type to indicate Tx/Rx
2806 *
2807 * This function parses the input skb data to get the EAPOL params,if the
2808 * packet is EAPOL and store it in the pointer passed as input
2809 *
2810 */
2811void wlan_hdd_get_eapol_params(struct sk_buff *skb,
2812 struct vos_event_wlan_eapol *eapol_params,
2813 uint8_t event_type)
2814{
2815 uint8_t packet_type=0;
2816
2817 packet_type = (uint8_t)(*(uint8_t *)
2818 (skb->data + HDD_EAPOL_PACKET_TYPE_OFFSET));
2819
2820 /* EAPOL msg type i.e. whether EAPOL-Start or
2821 * EAPOL-Key etc. messages Present at 15 offset.
2822 */
2823 eapol_params->eapol_packet_type = packet_type;
2824
2825 /* This tells if its a M1/M2/M3/M4 packet.
2826 * Present at 19th offset in EAPOL frame.
2827 */
2828 eapol_params->eapol_key_info = (uint16_t)(*(uint16_t *)
2829 (skb->data + HDD_EAPOL_KEY_INFO_OFFSET));
2830 /* This tells if EAPOL packet is in RX or TX
2831 * direction.
2832 */
2833 eapol_params->event_sub_type = event_type;
2834
2835 /* This tells the rate at which EAPOL packet
2836 * is send or received.
2837 */
2838 //TODO fill data rate for rx packet.
2839 eapol_params->eapol_rate = 0;/* As of now, zero */
2840
2841 vos_mem_copy(eapol_params->dest_addr,
2842 (skb->data + HDD_EAPOL_DEST_MAC_OFFSET),
2843 sizeof(eapol_params->dest_addr));
2844 vos_mem_copy(eapol_params->src_addr,
2845 (skb->data + HDD_EAPOL_SRC_MAC_OFFSET),
2846 sizeof(eapol_params->src_addr));
2847 return;
2848}
2849/*
2850 * wlan_hdd_event_eapol_log() - Function to log EAPOL events
2851 * @eapol_params: Structure containing EAPOL params
2852 *
2853 * This function logs the parsed EAPOL params
2854 *
2855 * Return: None
2856 *
2857 */
2858
2859static void wlan_hdd_event_eapol_log(struct vos_event_wlan_eapol eapol_params)
2860{
2861 WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event, struct vos_event_wlan_eapol);
2862
2863 wlan_diag_event.event_sub_type = eapol_params.event_sub_type;
2864 wlan_diag_event.eapol_packet_type = eapol_params.eapol_packet_type;
2865 wlan_diag_event.eapol_key_info = eapol_params.eapol_key_info;
2866 wlan_diag_event.eapol_rate = eapol_params.eapol_rate;
2867 vos_mem_copy(wlan_diag_event.dest_addr,
2868 eapol_params.dest_addr,
2869 sizeof (wlan_diag_event.dest_addr));
2870 vos_mem_copy(wlan_diag_event.src_addr,
2871 eapol_params.src_addr,
2872 sizeof (wlan_diag_event.src_addr));
2873 WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL);
2874}
2875
2876/*
2877 * wlan_hdd_log_eapol() - Function to check and extract EAPOL params
2878 * @skb: skb data
2879 * @event_type: One of enum wifi_connectivity_events to indicate Tx/Rx
2880 *
2881 * This function parses the input skb data to get the EAPOL params,if the
2882 * packet is EAPOL and store it in the pointer passed as input
2883 *
2884 * Return: None
2885 *
2886 */
2887void wlan_hdd_log_eapol(struct sk_buff *skb,
2888 uint8_t event_type)
2889{
2890 struct vos_event_wlan_eapol eapol_params;
2891
2892 wlan_hdd_get_eapol_params(skb, &eapol_params, event_type);
2893 wlan_hdd_event_eapol_log(eapol_params);
2894 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
2895 "Eapol subtype is %d and key info is %d\n",
2896 eapol_params.event_sub_type,eapol_params.eapol_key_info);
2897}
2898#endif /* FEATURE_WLAN_DIAG_SUPPORT */