blob: 3fadfa5979aa45f3f7994cbff14500031edbba5a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302 * Copyright (c) 2012-2018 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
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +053093#define HDD_TX_STALL_KICKDXE_THRESHOLD HDD_TX_STALL_SSR_THRESHOLD - 4
Abhishek Singh837adf22015-10-01 17:37:37 +053094#define HDD_TX_STALL_FATAL_EVENT_THRESHOLD 2
Sushant Kaushik9811d8a2015-10-07 15:56:26 +053095#define EAPOL_MASK 0x8013
96#define EAPOL_M1_BIT_MASK 0x8000
97#define EAPOL_M2_BIT_MASK 0x0001
98#define EAPOL_M3_BIT_MASK 0x8013
99#define EAPOL_M4_BIT_MASK 0x0003
Abhishek Singh837adf22015-10-01 17:37:37 +0530100
Mihir Shetec8fe71b2014-06-16 15:32:59 +0530101
Katya Nigame7b69a82015-04-28 15:24:06 +0530102int gRatefromIdx[] = {
103 10,20,55,100,
104 10,20,55,110,
105 60,90,120,180,240,360,480,540,
106 65,130,195,260,390,520,585,650,
107 72,144,217,289,434,578,650,722,
108 65,130,195,260,390,520,585,650,
109 135,270,405,540,810,1080,1215,1350,
110 150,300,450,600,900,1200,1350,1500,
111 135,270,405,540,810,1080,1215,1350,
112 1350,1350,65,130,195,260,390, 520,
113 585,650,780,1350,1350,1350,1350,1350,
114 1350,1350,1350,1350,655,722,866,1350,
115 1350,1350,135,270,405,540,810,1080,
116 1215,1350,1350,1620,1800,1350,1350,1350,
117 1350,1350,1350,1200,1350,1500,1350,1800,
118 2000,1350, 292,585,877,1170,1755,2340,
119 2632,2925,1350,3510,3900,1350,1350,1350,
120 1350,1350,1350,1350,2925,3250,1350,3900,
121 4333
122 };
Sushant Kaushika8073312015-05-04 17:33:52 +0530123#ifdef FEATURE_WLAN_DIAG_SUPPORT
124#define HDD_EAPOL_PACKET_TYPE_OFFSET (15)
125#define HDD_EAPOL_KEY_INFO_OFFSET (19)
126#define HDD_EAPOL_DEST_MAC_OFFSET (0)
127#define HDD_EAPOL_SRC_MAC_OFFSET (6)
128#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Katya Nigame7b69a82015-04-28 15:24:06 +0530129
130
Mihir Shetec8fe71b2014-06-16 15:32:59 +0530131static DEFINE_RATELIMIT_STATE(hdd_tx_timeout_rs, \
132 HDD_TX_TIMEOUT_RATELIMIT_INTERVAL, \
133 HDD_TX_TIMEOUT_RATELIMIT_BURST);
134
Jeff Johnson295189b2012-06-20 16:38:30 -0700135static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700136
137/*---------------------------------------------------------------------------
138 Type declarations
139 -------------------------------------------------------------------------*/
140
141/*---------------------------------------------------------------------------
142 Function definitions and documenation
143 -------------------------------------------------------------------------*/
144
145#ifdef DATA_PATH_UNIT_TEST
146//Utility function to dump an sk_buff
147static void dump_sk_buff(struct sk_buff * skb)
148{
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700149 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %pK", __func__, skb->head);
150 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %pK", __func__, skb->data);
151 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %pK", __func__, skb->tail);
152 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %pK", __func__, skb->end);
c_hpothu32490782014-03-14 19:14:34 +0530153 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
154 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
155 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 -0700156
c_hpothu32490782014-03-14 19:14:34 +0530157 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 -0700158 skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4],
159 skb->data[5], skb->data[6], skb->data[7]);
c_hpothu32490782014-03-14 19:14:34 +0530160 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 -0700161 skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
162 skb->data[13], skb->data[14], skb->data[15]);
163}
164
165//Function for Unit Test only
166static void transport_thread(hdd_adapter_t *pAdapter)
167{
168 v_U8_t staId;
169 WLANTL_ACEnumType ac = WLANTL_AC_BE;
170 vos_pkt_t *pVosPacket = NULL ;
171 vos_pkt_t dummyPacket;
172 WLANTL_MetaInfoType pktMetaInfo;
173 WLANTL_RxMetaInfoType pktRxMetaInfo;
174 VOS_STATUS status = VOS_STATUS_E_FAILURE;
175
c_hpothub8245442013-11-20 23:41:09 +0530176 if (NULL == pAdapter)
177 {
c_hpothu32490782014-03-14 19:14:34 +0530178 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +0530179 FL("pAdapter is NULL"));
180 VOS_ASSERT(0);
181 return;
182 }
183
Jeff Johnson295189b2012-06-20 16:38:30 -0700184 status = hdd_tx_fetch_packet_cbk( pAdapter->pvosContext,
185 &staId,
186 &ac,
187 &pVosPacket,
188 &pktMetaInfo );
189 if (status != VOS_STATUS_SUCCESS && status != VOS_STATUS_E_EMPTY)
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_fetch_packet_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_fetch_packet_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700195
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -0700196 status = hdd_tx_complete_cbk(pAdapter->pvosContext, &dummyPacket, VOS_STATUS_SUCCESS);
Jeff Johnson295189b2012-06-20 16:38:30 -0700197 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_complete_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_complete_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700203
204 status = hdd_tx_low_resource_cbk(pVosPacket, pAdapter);
205 if (status != VOS_STATUS_SUCCESS)
c_hpothu32490782014-03-14 19:14:34 +0530206 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
207 "%s: Test FAIL hdd_tx_low_resource_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700208 else
c_hpothu32490782014-03-14 19:14:34 +0530209 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
210 "%s: Test PASS hdd_tx_low_resource_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700211
212 status = hdd_rx_packet_cbk( pAdapter->pvosContext,
213 &dummyPacket,
214 staId,
215 &pktRxMetaInfo);
216 if (status != VOS_STATUS_SUCCESS)
c_hpothu32490782014-03-14 19:14:34 +0530217 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
218 "%s: Test FAIL hdd_rx_packet_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 else
c_hpothu32490782014-03-14 19:14:34 +0530220 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
221 "%s: Test PASS hdd_rx_packet_cbk", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700222
223}
224#endif
225
226
227/**============================================================================
228 @brief hdd_flush_tx_queues() - Utility function to flush the TX queues
229
230 @param pAdapter : [in] pointer to adapter context
231 @return : VOS_STATUS_E_FAILURE if any errors encountered
232 : VOS_STATUS_SUCCESS otherwise
233 ===========================================================================*/
234static VOS_STATUS hdd_flush_tx_queues( hdd_adapter_t *pAdapter )
235{
236 VOS_STATUS status = VOS_STATUS_SUCCESS;
237 v_SINT_t i = -1;
238 hdd_list_node_t *anchor = NULL;
239 skb_list_node_t *pktNode = NULL;
240 struct sk_buff *skb = NULL;
241
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530242 pAdapter->isVosLowResource = VOS_FALSE;
243
Mihir Shete5d148f12014-12-16 17:54:49 +0530244 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_FLUSH_TX_QUEUES,
245 pAdapter->sessionId, 0));
246
Jeff Johnson295189b2012-06-20 16:38:30 -0700247 while (++i != NUM_TX_QUEUES)
248 {
249 //Free up any packets in the Tx queue
250 spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock);
251 while (true)
252 {
253 status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[i], &anchor );
254 if(VOS_STATUS_E_EMPTY != status)
255 {
256 pktNode = list_entry(anchor, skb_list_node_t, anchor);
257 skb = pktNode->skb;
258 //TODO
259 //++pAdapter->stats.tx_dropped;
260 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
261 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
262 kfree_skb(skb);
263 continue;
264 }
265 break;
266 }
267 spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock);
268 // backpressure is no longer in effect
269 pAdapter->isTxSuspended[i] = VOS_FALSE;
270 }
271
272 return status;
273}
274
Ravi Joshif9520d62013-10-18 04:11:46 -0700275/**============================================================================
276 @brief hdd_flush_ibss_tx_queues() - Utility function to flush the TX queues
277 in IBSS mode
278
279 @param pAdapter : [in] pointer to adapter context
280 : [in] Staion Id
281 @return : VOS_STATUS_E_FAILURE if any errors encountered
282 : VOS_STATUS_SUCCESS otherwise
283 ===========================================================================*/
284void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId)
285{
286 v_U8_t i;
Katya Nigam47528772015-02-11 12:24:49 +0530287 hdd_list_node_t *anchor = NULL;
Ravi Joshi41914632013-10-21 23:02:21 -0700288 skb_list_node_t *pktNode = NULL;
Ravi Joshi41914632013-10-21 23:02:21 -0700289 struct sk_buff *skb = NULL;
Katya Nigam47528772015-02-11 12:24:49 +0530290 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
291 hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info;
Ravi Joshif9520d62013-10-18 04:11:46 -0700292
Katya Nigam47528772015-02-11 12:24:49 +0530293 for (i = 0; i < NUM_TX_QUEUES; i ++)
c_hpothub8245442013-11-20 23:41:09 +0530294 {
Katya Nigam47528772015-02-11 12:24:49 +0530295 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
296 while (true)
Ravi Joshif9520d62013-10-18 04:11:46 -0700297 {
Katya Nigam47528772015-02-11 12:24:49 +0530298 if (VOS_STATUS_E_EMPTY !=
299 hdd_list_remove_front(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i],
300 &anchor))
Ravi Joshif9520d62013-10-18 04:11:46 -0700301 {
Katya Nigam47528772015-02-11 12:24:49 +0530302 //If success then we got a valid packet from some AC
303 pktNode = list_entry(anchor, skb_list_node_t, anchor);
Ravi Joshif9520d62013-10-18 04:11:46 -0700304 skb = pktNode->skb;
Katya Nigam47528772015-02-11 12:24:49 +0530305 ++pAdapter->stats.tx_dropped;
306 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
307 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
308 kfree_skb(skb);
309 continue;
Ravi Joshif9520d62013-10-18 04:11:46 -0700310 }
Katya Nigam47528772015-02-11 12:24:49 +0530311 break;
Ravi Joshif9520d62013-10-18 04:11:46 -0700312 }
Katya Nigam47528772015-02-11 12:24:49 +0530313 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
Ravi Joshif9520d62013-10-18 04:11:46 -0700314 }
315}
316
Jeff Johnson295189b2012-06-20 16:38:30 -0700317static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter)
318{
319 skb_list_node_t *pktNode = NULL;
320 struct sk_buff *skb = NULL;
321 v_SIZE_t size = 0;
322 WLANTL_ACEnumType ac = 0;
323 VOS_STATUS status = VOS_STATUS_E_FAILURE;
324 hdd_list_node_t *anchor = NULL;
325
c_hpothu77731d42014-01-23 13:59:03 +0530326 if (NULL == pAdapter)
327 {
328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
329 FL("pAdapter is NULL"));
330 VOS_ASSERT(0);
331 return NULL;
332 }
333
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 // do we have any packets pending in this AC?
335 hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size );
336 if( size == 0 )
337 {
c_hpothu32490782014-03-14 19:14:34 +0530338 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700339 "%s: NO Packet Pending", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700340 return NULL;
341 }
342
343 //Remove the packet from the queue
344 spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock);
345 status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor );
346 spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock);
347
348 if(VOS_STATUS_SUCCESS == status)
349 {
350 //If success then we got a valid packet from some AC
351 pktNode = list_entry(anchor, skb_list_node_t, anchor);
352 skb = pktNode->skb;
353 }
354 else
355 {
c_hpothu32490782014-03-14 19:14:34 +0530356 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700357 "%s: Not able to remove Packet from the list",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700358 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700359
360 return NULL;
361 }
362
363 // if we are in a backpressure situation see if we can turn the hose back on
364 if ( (pAdapter->isTxSuspended[ac]) &&
365 (size <= HDD_TX_QUEUE_LOW_WATER_MARK) )
366 {
c_hpothu32490782014-03-14 19:14:34 +0530367 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700368 "%s: TX queue[%d] re-enabled", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -0700369 pAdapter->isTxSuspended[ac] = VOS_FALSE;
370 /* Enable Queues which we have disabled earlier */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +0530371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 netif_tx_start_all_queues( pAdapter->dev );
373 }
374
375 return skb;
376}
377
378void hdd_mon_tx_mgmt_pkt(hdd_adapter_t* pAdapter)
379{
380 hdd_cfg80211_state_t *cfgState;
381 struct sk_buff* skb;
382 hdd_adapter_t* pMonAdapter = NULL;
383 struct ieee80211_hdr *hdr;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530384 hdd_context_t *pHddCtx;
385 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530387 ENTER();
Mukul Sharma23a92232014-04-07 18:04:00 +0530388 if (pAdapter == NULL)
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 {
c_hpothu32490782014-03-14 19:14:34 +0530390 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +0530391 FL("pAdapter is NULL"));
392 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700393 return;
394 }
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530395 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
396 ret = wlan_hdd_validate_context(pHddCtx);
397 if (0 != ret)
398 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530399 return;
400 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700401 pMonAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR );
Mukul Sharma23a92232014-04-07 18:04:00 +0530402 if (pMonAdapter == NULL)
403 {
404 hddLog(VOS_TRACE_LEVEL_ERROR,
405 "%s: pMonAdapter is NULL", __func__);
406 return;
407 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700408 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
409
410 if( NULL != cfgState->buf )
411 {
c_hpothu32490782014-03-14 19:14:34 +0530412 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700413 "%s: Already one MGMT packet Tx going on", __func__);
414 return;
415 }
416
417 skb = hdd_mon_tx_fetch_pkt(pMonAdapter);
418
419 if (NULL == skb)
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: No Packet Pending", __func__);
423 return;
424 }
425
426 cfgState->buf = vos_mem_malloc( skb->len ); //buf;
427 if( cfgState->buf == NULL )
428 {
c_hpothu32490782014-03-14 19:14:34 +0530429 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700430 "%s: Failed to Allocate memory", __func__);
431 goto fail;
432 }
433
434 cfgState->len = skb->len;
435
436 vos_mem_copy( cfgState->buf, skb->data, skb->len);
437
438 cfgState->skb = skb; //buf;
Jeff Johnsonf67dca92013-11-08 17:07:40 -0800439 cfgState->action_cookie = (uintptr_t)cfgState->buf;
Jeff Johnson295189b2012-06-20 16:38:30 -0700440
441 hdr = (struct ieee80211_hdr *)skb->data;
442 if( (hdr->frame_control & HDD_FRAME_TYPE_MASK)
443 == HDD_FRAME_TYPE_MGMT )
444 {
445 if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK)
446 == HDD_FRAME_SUBTYPE_DEAUTH )
447 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +0530448 struct tagCsrDelStaParams delStaParams;
449
Sushant Kaushik4cd28f62014-12-26 14:23:50 +0530450 WLANSAP_PopulateDelStaParams(hdr->addr1,
451 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +0530452 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
453
454 hdd_softap_sta_deauth(pAdapter, &delStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -0700455 goto mgmt_handled;
456 }
457 else if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK)
458 == HDD_FRAME_SUBTYPE_DISASSOC )
459 {
460 hdd_softap_sta_disassoc( pAdapter, hdr->addr1 );
461 goto mgmt_handled;
462 }
463 }
c_hpothu32490782014-03-14 19:14:34 +0530464 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -0700465 "%s: Sending action frame to SAP to TX, Len %d", __func__, skb->len);
466
Jeff Johnson43971f52012-07-17 12:26:56 -0700467 if (VOS_STATUS_SUCCESS !=
Jeff Johnson295189b2012-06-20 16:38:30 -0700468 WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Jeff Johnsone7245742012-09-05 17:12:55 -0700469 skb->data, skb->len, 0) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700470 {
c_hpothu32490782014-03-14 19:14:34 +0530471 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -0700472 "%s: WLANSAP_SendAction returned fail", __func__);
473 hdd_sendActionCnf( pAdapter, FALSE );
474 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530475 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700476 return;
477
478mgmt_handled:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530479 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700480 hdd_sendActionCnf( pAdapter, TRUE );
481 return;
482fail:
483 kfree_skb(pAdapter->skb_to_tx);
484 pAdapter->skb_to_tx = NULL;
485 return;
486}
487
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530488void __hdd_mon_tx_work_queue(struct work_struct *work)
Jeff Johnson295189b2012-06-20 16:38:30 -0700489{
490 hdd_adapter_t* pAdapter = container_of(work, hdd_adapter_t, monTxWorkQueue);
491 hdd_mon_tx_mgmt_pkt(pAdapter);
492}
493
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +0530494void hdd_mon_tx_work_queue(struct work_struct *work)
495{
496 vos_ssr_protect(__func__);
497 __hdd_mon_tx_work_queue(work);
498 vos_ssr_unprotect(__func__);
499}
500
Jeff Johnson295189b2012-06-20 16:38:30 -0700501int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
502{
Katya Nigame7b69a82015-04-28 15:24:06 +0530503 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
504 "%s: Packet Rcvd at Monitor interface,"
505 " Dropping the packet",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700506 kfree_skb(skb);
507 return NETDEV_TX_OK;
508}
Dino Mycled9b7cc12014-09-04 18:43:07 +0530509
510/**============================================================================
511 @brief hdd_dhcp_pkt_info() -
512 Function to log DHCP pkt info
513
514 @param skb : [in] pointer to OS packet (sk_buff)
515 @return : None
516 ===========================================================================*/
517
518void hdd_dhcp_pkt_info(struct sk_buff *skb)
519{
520 /* port no 67 (0x43) or 68 (0x44) */
521
522 if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_REQUEST_MSG)
523 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request"));
524 else if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_RESPONSE_MSG)
525 hddLog(VOS_TRACE_LEVEL_INFO, FL("Response"));
526 else
527 hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP invalid"));
528
529 hddLog(VOS_TRACE_LEVEL_INFO,
530 FL("DHCP Dest Addr: %pM Src Addr %pM "
531 " source port : %d, dest port : %d"),
532 skb->data, (skb->data + 6),
533 ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))),
534 ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))));
535
536 if ((skb->data[DHCP_OPTION53_OFFSET] == DHCP_OPTION53) &&
537 (skb->data[DHCP_OPTION53_LENGTH_OFFSET] == DHCP_OPTION53_LENGTH)) {
538
539 switch (skb->data[DHCP_OPTION53_STATUS_OFFSET]) {
540 case DHCPDISCOVER:
541 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP DISCOVER"));
542 break;
543 case DHCPREQUEST:
544 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP REQUEST"));
545 break;
546 case DHCPOFFER:
547 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP OFFER"));
548 break;
549 case DHCPACK:
550 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP ACK"));
551 break;
552 case DHCPNAK:
553 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP NACK"));
554 break;
555 case DHCPRELEASE:
556 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP RELEASE"));
557 break;
558 case DHCPINFORM:
559 hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP INFORM"));
560 break;
561
562 default:
563 hddLog(VOS_TRACE_LEVEL_INFO,
564 "%s: DHCP Not Defined OPTION53 : %d", __func__,
565 skb->data[DHCP_OPTION53_STATUS_OFFSET]);
566 }
567 }
568}
569
570/**============================================================================
571 @brief hdd_dump_dhcp_pkt() -
572 Function to dump DHCP packets in TX and RX path.
573
574 @param skb : [in] pointer to OS packet (sk_buff)
575 @param path : [in] bool indicating TX/RX path
576 @return : None
577 ===========================================================================*/
578void hdd_dump_dhcp_pkt(struct sk_buff *skb, int path)
579{
580
581 if ((ntohs(*((u16*)((u8*)skb->data + ETH_TYPE_OFFSET)))
582 == ETH_TYPE_IP_PKT) ||
583 (ntohs(*((u8*)skb->data + PROTOCOL_OFFSET)) == UDP_PROTOCOL)) {
584
585 /* IP protocol 12 bytes of mac addresses in 802.3 header */
586 if ( ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) ==
587 BOOTP_SERVER_PORT ||
588 ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) ==
589 BOOTP_CLIENT_PORT ||
590 ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) ==
591 BOOTP_SERVER_PORT ||
592 ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) ==
593 BOOTP_CLIENT_PORT ) {
594
595 if (path == TX_PATH) {
596 hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP TX PATH"));
597 } else {
598 hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP RX PATH"));
599 }
600
601 hdd_dhcp_pkt_info(skb);
602 }
603 }
604}
605
Jeff Johnson295189b2012-06-20 16:38:30 -0700606/**============================================================================
Katya Nigam77fcf582015-02-09 16:48:24 +0530607 @brief hdd_ibss_hard_start_xmit() - Function registered with the Linux OS for
608 transmitting packets in case of IBSS. There are 2 versions of this function.
609 One that uses locked queue and other that uses lockless queues. Both have been
610 retained to do some performance testing
611
612 @param skb : [in] pointer to OS packet (sk_buff)
613 @param dev : [in] pointer to network device
614
615 @return : NET_XMIT_DROP if packets are dropped
616 : NET_XMIT_SUCCESS if packet is enqueued succesfully
617 ===========================================================================*/
618 int hdd_ibss_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
619 {
620 VOS_STATUS status;
621 WLANTL_ACEnumType ac;
622 sme_QosWmmUpType up;
623 skb_list_node_t *pktNode = NULL;
624 hdd_list_node_t *anchor = NULL;
625 v_SIZE_t pktListSize = 0;
626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
627 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
628 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
629 hdd_ibss_peer_info_t * pPeerInfo;
630 v_U8_t STAId = WLAN_MAX_STA_COUNT;
631 v_BOOL_t txSuspended = VOS_FALSE;
632 struct sk_buff *skb1;
633 v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
634
635 if (NULL == pHddCtx || NULL == pHddStaCtx) {
636 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
637 "%s HDD context is NULL", __func__);
638 return NETDEV_TX_BUSY;
639 }
640 pPeerInfo = &pHddStaCtx->ibss_peer_info;
641 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
642
643 //Get TL AC corresponding to Qdisc queue index/AC.
644 ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
645
646 if (eConnectionState_IbssDisconnected == pHddStaCtx->conn_info.connState)
647 {
648 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
649 "%s: Tx frame in disconnected state in IBSS mode", __func__);
650 ++pAdapter->stats.tx_dropped;
651 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
652 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
653 kfree_skb(skb);
654 return NETDEV_TX_OK;
655 }
656
Nirav Shah7e3c8132015-06-22 23:51:42 +0530657 STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
Katya Nigam77fcf582015-02-09 16:48:24 +0530658 if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
659 (vos_is_macaddr_broadcast( pDestMacAddress ) ||
660 vos_is_macaddr_group(pDestMacAddress)))
661 {
662 STAId = IBSS_BROADCAST_STAID;
663 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,
664 "%s: BC/MC packet", __func__);
665 }
666 else if (STAId >= HDD_MAX_NUM_IBSS_STA)
667 {
668 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
669 "%s: Received Unicast frame with invalid staID", __func__);
670 ++pAdapter->stats.tx_dropped;
671 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
672 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
673 kfree_skb(skb);
674 return NETDEV_TX_OK;
675 }
676
677 //user priority from IP header, which is already extracted and set from
678 //select_queue call back function
679 up = skb->priority;
680 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
681
682 VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
683 "%s: Classified as ac %d up %d", __func__, ac, up);
684
685 if ( pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP )
686 {
687 hdd_dump_dhcp_pkt(skb, TX_PATH);
688 }
689
690 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
691 hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
692 if(pktListSize >= pAdapter->aTxQueueLimit[ac])
693 {
694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
695 "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
696 pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
697 netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
698 txSuspended = VOS_TRUE;
699 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
701 "%s: TX queue full for AC=%d Disable OS TX queue",
702 __func__, ac );
703 return NETDEV_TX_BUSY;
704 }
705
706 /* If 3/4th of the max queue size is used then enable the flag.
707 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
708 if (WLANTL_AC_BE == ac)
709 {
710 if (pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
711 {
712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
713 "%s: TX queue for Best Effort AC is 3/4th full", __func__);
714 pAdapter->isVosLowResource = VOS_TRUE;
715 }
716 else
717 {
718 pAdapter->isVosLowResource = VOS_FALSE;
719 }
720 }
721
722 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
723
724 //Use the skb->cb field to hold the list node information
725 pktNode = (skb_list_node_t *)&skb->cb;
726
727 //Stick the OS packet inside this node.
728 pktNode->skb = skb;
729
730 //Stick the User Priority inside this node
731 pktNode->userPriority = up;
732
733 INIT_LIST_HEAD(&pktNode->anchor);
734
735 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
736 status = hdd_list_insert_back_size( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac],
737 &pktNode->anchor, &pktListSize );
738 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
739 if ( !VOS_IS_STATUS_SUCCESS( status ) )
740 {
741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
742 "%s:Insert Tx queue failed. Pkt dropped", __func__);
743 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
744 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
745 ++pAdapter->stats.tx_dropped;
746 kfree_skb(skb);
747 return NETDEV_TX_OK;
748 }
749
750 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
751 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
752 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
753
754 if (1 == pktListSize)
755 {
756 //Let TL know we have a packet to send for this AC
757 status = WLANTL_STAPktPending( pHddCtx->pvosContext, STAId, ac );
758
759 if ( !VOS_IS_STATUS_SUCCESS( status ) )
760 {
761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
762 "%s: Failed to signal TL for AC=%d STAId =%d",
763 __func__, ac, STAId );
764
765 /* Remove the packet from queue. It must be at the back of the queue, as TX thread
766 * cannot preempt us in the middle as we are in a soft irq context.
767 * Also it must be the same packet that we just allocated.
768 */
769 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
770 status = hdd_list_remove_back( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor);
771 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
772 /* Free the skb only if we are able to remove it from the list.
773 * If we are not able to retrieve it from the list it means that
774 * the skb was pulled by TX Thread and is use so we should not free
775 * it here
776 */
777 if (VOS_IS_STATUS_SUCCESS(status))
778 {
779 pktNode = list_entry(anchor, skb_list_node_t, anchor);
780 skb1 = pktNode->skb;
781 kfree_skb(skb1);
782 }
783 ++pAdapter->stats.tx_dropped;
784 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
785 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
786 return NETDEV_TX_OK;
787 }
788 }
789
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530790 netif_trans_update(dev);
Katya Nigam77fcf582015-02-09 16:48:24 +0530791
792 return NETDEV_TX_OK;
793 }
794
795/**============================================================================
SaidiReddy Yenuga18d77a62016-10-04 20:26:22 +0530796 @brief __hdd_hard_start_xmit() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -0700797 transmitting packets. There are 2 versions of this function. One that uses
798 locked queue and other that uses lockless queues. Both have been retained to
799 do some performance testing
800
801 @param skb : [in] pointer to OS packet (sk_buff)
802 @param dev : [in] pointer to Libra network device
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530803
Jeff Johnson295189b2012-06-20 16:38:30 -0700804 @return : NET_XMIT_DROP if packets are dropped
805 : NET_XMIT_SUCCESS if packet is enqueued succesfully
806 ===========================================================================*/
SaidiReddy Yenuga18d77a62016-10-04 20:26:22 +0530807int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -0700808{
809 VOS_STATUS status;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530810 WLANTL_ACEnumType qid, ac;
Jeff Johnson295189b2012-06-20 16:38:30 -0700811 sme_QosWmmUpType up;
812 skb_list_node_t *pktNode = NULL;
813 hdd_list_node_t *anchor = NULL;
814 v_SIZE_t pktListSize = 0;
815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
816 v_BOOL_t granted;
Shailender Karmuchia734f332013-04-19 14:02:48 -0700817 v_U8_t STAId = WLAN_MAX_STA_COUNT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700818 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
Dino Mycled9b7cc12014-09-04 18:43:07 +0530819 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700820 v_BOOL_t txSuspended = VOS_FALSE;
Mihir Shetef8f74532014-12-04 11:53:34 +0530821 struct sk_buff *skb1;
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +0530822 v_BOOL_t arp_pkt;
Jeff Johnson295189b2012-06-20 16:38:30 -0700823
Girish Gowlibf0e1ab2015-01-19 16:05:16 +0530824 if (NULL == pHddCtx) {
825 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
826 "%s HDD context is NULL", __func__);
827 return NETDEV_TX_BUSY;
828 }
829
Jeff Johnson295189b2012-06-20 16:38:30 -0700830 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
831
Ravi Joshif9520d62013-10-18 04:11:46 -0700832 if (unlikely(netif_subqueue_stopped(dev, skb))) {
c_hpothu32490782014-03-14 19:14:34 +0530833 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshif9520d62013-10-18 04:11:46 -0700834 "%s is called when netif TX %d is disabled",
835 __func__, skb->queue_mapping);
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530836 return NETDEV_TX_BUSY;
837 }
838
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +0530839 arp_pkt = vos_is_arp_pkt(skb, false);
840
841 if (arp_pkt)
842 {
843 ++pAdapter->hdd_stats.hddArpStats.txCount;
844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
845 "%s :ARP packet received form net_dev", __func__);
846 }
847
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530848 //Get TL Q index corresponding to Qdisc queue index/AC.
849 qid = hdd_QdiscAcToTlAC[skb->queue_mapping];
850 ac = qid;
851
852 if (qid == WLANTL_AC_HIGH_PRIO)
853 {
854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
855 "%s It must be a Eapol/Wapi/DHCP packet device_mode:%d",
856 __func__, pAdapter->device_mode);
857 ac = hddWmmUpToAcMap[skb->priority];
858 }
Ravi Joshicc57ed42013-10-12 16:31:25 -0700859
c_hpothu851d9862015-01-19 18:39:06 +0530860 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
861 {
862 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
863 FL("Tx frame in not associated state in %d context"),
864 pAdapter->device_mode);
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +0530865
866 if (arp_pkt)
867 {
868 ++pAdapter->hdd_stats.hddArpStats.txDropped;
869 pAdapter->hdd_stats.hddArpStats.reason = HDD_TX_FRAME_IN_NOT_ASSOCIATED_STATE;
870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
871 "%s :Tx frame in not associated state, ARP packet Dropped ",
872 __func__);
873 }
c_hpothu851d9862015-01-19 18:39:06 +0530874 ++pAdapter->stats.tx_dropped;
875 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530876 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
c_hpothu851d9862015-01-19 18:39:06 +0530877 kfree_skb(skb);
878 return NETDEV_TX_OK;
879 }
Shailender Karmuchia734f332013-04-19 14:02:48 -0700880 STAId = pHddStaCtx->conn_info.staId[0];
Jeff Johnson295189b2012-06-20 16:38:30 -0700881
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530882 //user priority from IP header, which is already extracted and set from
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 //select_queue call back function
884 up = skb->priority;
885
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530886 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[qid];
Jeff Johnson295189b2012-06-20 16:38:30 -0700887
888#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +0530889 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700890 "%s: Classified as ac %d up %d", __func__, ac, up);
Jeff Johnson295189b2012-06-20 16:38:30 -0700891#endif // HDD_WMM_DEBUG
892
Girish Gowlibf0e1ab2015-01-19 16:05:16 +0530893 if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
Mukul Sharma84f27252014-07-14 18:11:42 +0530894 {
Girish Gowlibf0e1ab2015-01-19 16:05:16 +0530895 vos_record_roam_event(e_HDD_FIRST_XMIT_TIME, (void *)skb, 0);
Mukul Sharma84f27252014-07-14 18:11:42 +0530896 }
Mukul Sharma84f27252014-07-14 18:11:42 +0530897
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530898 spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
Varun Reddy Yeturu5ba69222013-04-01 18:22:20 -0700899 /*CR 463598,384996*/
900 /*For every increment of 10 pkts in the queue, we inform TL about pending pkts.
901 *We check for +1 in the logic,to take care of Zero count which
902 *occurs very frequently in low traffic cases */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530903 if((pAdapter->wmm_tx_queue[qid].count + 1) % 10 == 0)
Varun Reddy Yeturu5ba69222013-04-01 18:22:20 -0700904 {
Shailender Karmuchia734f332013-04-19 14:02:48 -0700905 /* 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 -0700906 * 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 +0530907 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 -0700908
Ravi Joshi8a934352013-09-25 16:46:58 -0700909 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530910 STAId, qid
Ravi Joshi8a934352013-09-25 16:46:58 -0700911 );
912 if ( !VOS_IS_STATUS_SUCCESS( status ) )
913 {
c_hpothu32490782014-03-14 19:14:34 +0530914 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshi8a934352013-09-25 16:46:58 -0700915 "%s: WLANTL_STAPktPending() returned error code %d",
916 __func__, status);
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +0530917
918 if (arp_pkt)
919 {
920 ++pAdapter->hdd_stats.hddArpStats.txDropped;
921 pAdapter->hdd_stats.hddArpStats.reason = HDD_WLANTL_STAPKTPENDING_RETURNED_ERROR_CODE;
922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
923 "%s:ARP Packet Dropped WLANTL_STAPktPending returned error %d",
924 __func__, status);
925 }
Ravi Joshicc57ed42013-10-12 16:31:25 -0700926 ++pAdapter->stats.tx_dropped;
927 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530928 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
Ravi Joshi8a934352013-09-25 16:46:58 -0700929 kfree_skb(skb);
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530930 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Ravi Joshi8a934352013-09-25 16:46:58 -0700931 return NETDEV_TX_OK;
932 }
Varun Reddy Yeturu5ba69222013-04-01 18:22:20 -0700933 }
Sravan Kumar Kairam7ce69332017-02-15 15:41:43 +0530934
935 if (pHddCtx->bad_sta[STAId]) {
936 hdd_list_node_t *anchor = NULL;
937 skb_list_node_t *pktNode = NULL;
938 struct sk_buff *fskb = NULL;
939
940 if (pAdapter->wmm_tx_queue[qid].count >=
941 pAdapter->wmm_tx_queue[qid].max_size / 2) {
942 hdd_list_remove_front(&pAdapter->wmm_tx_queue[qid],
943 &anchor);
944 pktNode = list_entry(anchor, skb_list_node_t, anchor);
945 fskb = pktNode->skb;
946 kfree_skb(fskb);
947 ++pAdapter->stats.tx_dropped;
948 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
949 }
950 }
951
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 //If we have already reached the max queue size, disable the TX queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530953 if ( pAdapter->wmm_tx_queue[qid].count == pAdapter->wmm_tx_queue[qid].max_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700954 {
Ravi Joshicc57ed42013-10-12 16:31:25 -0700955 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530956 ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[qid];
957 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queue for QId %d"), qid);
Ravi Joshicc57ed42013-10-12 16:31:25 -0700958 netif_tx_stop_queue(netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)));
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530959 pAdapter->isTxSuspended[qid] = VOS_TRUE;
Ravi Joshicc57ed42013-10-12 16:31:25 -0700960 txSuspended = VOS_TRUE;
Mihir Shete5d148f12014-12-16 17:54:49 +0530961 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530962 pAdapter->sessionId, qid));
Jeff Johnson295189b2012-06-20 16:38:30 -0700963 }
964
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530965 /* If 3/4th of the max queue size is used then enable the flag.
966 * This flag indicates to place the DHCP packets in VOICE AC queue.*/
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530967 if (WLANTL_AC_BE == qid)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530968 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530969 if (pAdapter->wmm_tx_queue[qid].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530970 {
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +0530971 pAdapter->isVosLowResource = VOS_TRUE;
972 }
973 else
974 {
975 pAdapter->isVosLowResource = VOS_FALSE;
976 }
977 }
978
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530979 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Dino Mycled9b7cc12014-09-04 18:43:07 +0530980
Sachin Ahuja8c65f382014-12-12 15:34:21 +0530981 if (( NULL != pHddCtx ) &&
982 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +0530983 {
984 hdd_dump_dhcp_pkt(skb, TX_PATH);
985 }
986
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 if (VOS_TRUE == txSuspended)
988 {
c_hpothu32490782014-03-14 19:14:34 +0530989 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +0530990 "%s: TX queue full for QId=%d Disable OS TX queue",
991 __func__, qid );
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +0530992 return NETDEV_TX_BUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 }
994
995 //Use the skb->cb field to hold the list node information
996 pktNode = (skb_list_node_t *)&skb->cb;
997
998 //Stick the OS packet inside this node.
999 pktNode->skb = skb;
1000
Madan Mohan Koyyalamudi0dab1ad2013-08-28 16:19:18 +05301001 //Stick the User Priority inside this node
Jeff Johnson295189b2012-06-20 16:38:30 -07001002 pktNode->userPriority = up;
1003
1004
1005 INIT_LIST_HEAD(&pktNode->anchor);
1006
1007 //Insert the OS packet into the appropriate AC queue
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301008 spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
1009 status = hdd_list_insert_back_size( &pAdapter->wmm_tx_queue[qid], &pktNode->anchor, &pktListSize );
1010 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07001011
1012 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1013 {
c_hpothu32490782014-03-14 19:14:34 +05301014 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s:Insert Tx queue failed. Pkt dropped", __func__);
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05301015
1016 if (arp_pkt)
1017 {
1018 ++pAdapter->hdd_stats.hddArpStats.txDropped;
1019 pAdapter->hdd_stats.hddArpStats.reason = HDD_INSERT_TX_QUEUE_FAILED;
1020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1021 "%s:Insert Tx queue failed. ARP packet dropped", __func__);
1022 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301024 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
Jeff Johnson295189b2012-06-20 16:38:30 -07001025 ++pAdapter->stats.tx_dropped;
1026 kfree_skb(skb);
1027 return NETDEV_TX_OK;
1028 }
1029
1030 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301031 ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[qid];
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07001032 ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001033
Kiet Lamf040f472013-11-20 21:15:23 +05301034 if (HDD_PSB_CHANGED == pAdapter->psbChanged)
1035 {
1036 /* Function which will determine acquire admittance for a
1037 * WMM AC is required or not based on psb configuration done
1038 * in the framework
1039 */
1040 hdd_wmm_acquire_access_required(pAdapter, ac);
1041 }
1042
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 //Make sure we have access to this access category
Kiet Lamf040f472013-11-20 21:15:23 +05301044 if (((pAdapter->psbChanged & (1 << ac)) && likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed)) ||
1045 (pHddStaCtx->conn_info.uIsAuthenticated == VOS_FALSE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 {
1047 granted = VOS_TRUE;
1048 }
1049 else
1050 {
1051 status = hdd_wmm_acquire_access( pAdapter, ac, &granted );
Kiet Lamf040f472013-11-20 21:15:23 +05301052 pAdapter->psbChanged |= (1 << ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001053 }
Nirav Shah4f765af2015-01-21 19:51:30 +05301054
1055 if ( (granted && ( pktListSize == 1 )) ||
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301056 (qid == WLANTL_AC_HIGH_PRIO))
Jeff Johnson295189b2012-06-20 16:38:30 -07001057 {
1058 //Let TL know we have a packet to send for this AC
c_hpothu32490782014-03-14 19:14:34 +05301059 //VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
Shailender Karmuchia734f332013-04-19 14:02:48 -07001060 status = WLANTL_STAPktPending(
1061 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301062 STAId, qid );
Jeff Johnson295189b2012-06-20 16:38:30 -07001063 if ( !VOS_IS_STATUS_SUCCESS( status ) )
1064 {
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301065 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
1066 "%s: Failed to signal TL for QId=%d", __func__, qid );
Jeff Johnson295189b2012-06-20 16:38:30 -07001067
1068 //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
1069 //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 +05301070 spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
1071 status = hdd_list_remove_back( &pAdapter->wmm_tx_queue[qid], &anchor );
1072 spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
Mihir Shetef8f74532014-12-04 11:53:34 +05301073 /* Free the skb only if we are able to remove it from the list.
1074 * If we are not able to retrieve it from the list it means that
1075 * the skb was pulled by TX Thread and is use so we should not free
1076 * it here
1077 */
1078 if (VOS_IS_STATUS_SUCCESS(status))
1079 {
1080 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1081 skb1 = pktNode->skb;
1082 kfree_skb(skb1);
1083 }
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05301084
1085 if (arp_pkt)
1086 {
1087 ++pAdapter->hdd_stats.hddArpStats.txDropped;
1088 pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILED_TO_SIGNAL_TL;
1089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1090 "%s: ARP packet Dropped : Failed to signal TL for QId=%d",
1091 __func__, qid );
1092 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 ++pAdapter->stats.tx_dropped;
1094 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05301095 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 return NETDEV_TX_OK;
1097 }
1098 }
1099
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05301100 netif_trans_update(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07001101
1102 return NETDEV_TX_OK;
1103}
1104
SaidiReddy Yenuga18d77a62016-10-04 20:26:22 +05301105int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
1106{
1107 int ret;
1108 vos_ssr_protect(__func__);
1109 ret = __hdd_hard_start_xmit(skb, dev);
1110 vos_ssr_unprotect(__func__);
1111 return ret;
1112}
1113
Jeff Johnson295189b2012-06-20 16:38:30 -07001114/**============================================================================
Shailender Karmuchia734f332013-04-19 14:02:48 -07001115 @brief hdd_Ibss_GetStaId() - Get the StationID using the Peer Mac address
1116
1117 @param pHddStaCtx : [in] pointer to HDD Station Context
1118 pMacAddress [in] pointer to Peer Mac address
1119 staID [out] pointer to Station Index
1120 @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE
1121 ===========================================================================*/
1122
1123VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, v_MACADDR_t *pMacAddress, v_U8_t *staId)
1124{
1125 v_U8_t idx;
1126
1127 for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++)
1128 {
1129 if (vos_mem_compare(&pHddStaCtx->conn_info.peerMacAddress[ idx ],
1130 pMacAddress, sizeof(v_MACADDR_t)))
1131 {
1132 *staId = pHddStaCtx->conn_info.staId[idx];
1133 return VOS_STATUS_SUCCESS;
1134 }
1135 }
1136
1137 return VOS_STATUS_E_FAILURE;
1138}
1139
1140/**============================================================================
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301141 @brief __hdd_tx_timeout() - Function handles timeout during transmission.
Jeff Johnson295189b2012-06-20 16:38:30 -07001142
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301143 @param dev : [in] pointer to network device
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 @return : None
1145 ===========================================================================*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301146void __hdd_tx_timeout(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07001147{
Ravi Joshicc57ed42013-10-12 16:31:25 -07001148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mihir Shete0be28772015-02-17 18:42:14 +05301149 hdd_context_t *pHddCtx;
Ravi Joshicc57ed42013-10-12 16:31:25 -07001150 struct netdev_queue *txq;
Mihir Shete0be28772015-02-17 18:42:14 +05301151 hdd_remain_on_chan_ctx_t *pRemainChanCtx;
Ravi Joshicc57ed42013-10-12 16:31:25 -07001152 int i = 0;
Mukul Sharma4b322632015-02-28 20:21:43 +05301153 int status = 0;
Mukul Sharma42b3d432014-10-16 16:13:40 +05301154 v_ULONG_t diff_in_jiffies = 0;
mukul sharma4cbba382015-08-14 17:18:49 +05301155 hdd_station_ctx_t *pHddStaCtx = NULL;
Ravi Joshicc57ed42013-10-12 16:31:25 -07001156
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05301157 TX_TIMEOUT_TRACE(dev, VOS_MODULE_ID_HDD_DATA);
Mihir Shetef3473692014-06-27 15:13:20 +05301158
c_hpothub8245442013-11-20 23:41:09 +05301159 if ( NULL == pAdapter )
1160 {
c_hpothu32490782014-03-14 19:14:34 +05301161 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301162 FL("pAdapter is NULL"));
1163 VOS_ASSERT(0);
1164 return;
1165 }
1166
Mihir Shete0be28772015-02-17 18:42:14 +05301167 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mukul Sharma4b322632015-02-28 20:21:43 +05301168 status = wlan_hdd_validate_context(pHddCtx);
1169 if (status !=0 )
Mihir Shete0be28772015-02-17 18:42:14 +05301170 {
Mukul Sharma4b322632015-02-28 20:21:43 +05301171 return;
Mihir Shete0be28772015-02-17 18:42:14 +05301172 }
1173
mukul sharma4cbba382015-08-14 17:18:49 +05301174 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1175 if ( NULL == pHddStaCtx )
1176 {
1177 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1178 FL("pHddStaCtx is NULL"));
1179 return;
1180 }
1181
Mihir Shetef3473692014-06-27 15:13:20 +05301182 ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;
1183
Jeff Johnson295189b2012-06-20 16:38:30 -07001184 //Getting here implies we disabled the TX queues for too long. Queues are
1185 //disabled either because of disassociation or low resource scenarios. In
1186 //case of disassociation it is ok to ignore this. But if associated, we have
1187 //do possible recovery here
Ravi Joshicc57ed42013-10-12 16:31:25 -07001188
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301189 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshicc57ed42013-10-12 16:31:25 -07001190 "num_bytes AC0: %d AC1: %d AC2: %d AC3: %d",
1191 pAdapter->wmm_tx_queue[0].count,
1192 pAdapter->wmm_tx_queue[1].count,
1193 pAdapter->wmm_tx_queue[2].count,
1194 pAdapter->wmm_tx_queue[3].count);
1195
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301196 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshicc57ed42013-10-12 16:31:25 -07001197 "tx_suspend AC0: %d AC1: %d AC2: %d AC3: %d",
1198 pAdapter->isTxSuspended[0],
1199 pAdapter->isTxSuspended[1],
1200 pAdapter->isTxSuspended[2],
1201 pAdapter->isTxSuspended[3]);
1202
Mihir Shete0be28772015-02-17 18:42:14 +05301203 for (i = 0; i < dev->num_tx_queues; i++)
Ravi Joshicc57ed42013-10-12 16:31:25 -07001204 {
1205 txq = netdev_get_tx_queue(dev, i);
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301206 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Padma, Santhosh Kumarce7aef82014-12-17 17:31:49 +05301207 "Queue%d status: %d txq->trans_start %lu",
1208 i, netif_tx_queue_stopped(txq),txq->trans_start);
Ravi Joshicc57ed42013-10-12 16:31:25 -07001209 }
1210
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301211 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Ravi Joshicc57ed42013-10-12 16:31:25 -07001212 "carrier state: %d", netif_carrier_ok(dev));
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301213
Mihir Shetef3473692014-06-27 15:13:20 +05301214 /* continuousTxTimeoutCount will be reset whenever TL fetches packet
1215 * from HDD
1216 */
1217 ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
1218
Mukul Sharma42b3d432014-10-16 16:13:40 +05301219 diff_in_jiffies = jiffies - pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut;
1220 if((pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount > 1)&&
1221 ((diff_in_jiffies) > (HDD_TX_TIMEOUT * 2 ))
1222 )
1223 {
1224 /*
1225 * In Open security case when there is no traffic is running, it may possible
1226 * tx time-out may once happen and later we recovered then we need to
1227 * reset the continuousTxTimeoutCount because it is only getting modified
1228 * when traffic is running. So if over a period of time if this count reaches
1229 * to HDD_TX_STALL_SSR_THRESHOLD then host is triggering false subsystem restart.
1230 * so in genuine Tx Time out case kernel will call the tx time-out back to back at
1231 * interval of HDD_TX_TIMEOUT.So now we are checking if previous TX TIME out was
1232 * occurred more then twice of HDD_TX_TIMEOUT back then we may recovered here.
1233 */
1234 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
1235 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1236 FL("This is false alarm so resetting the continuousTxTimeoutCount"));
1237 }
1238
1239 //update last jiffies after the check
1240 pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut = jiffies;
1241
mukul sharma4cbba382015-08-14 17:18:49 +05301242 if (!pHddStaCtx->conn_info.uIsAuthenticated) {
1243 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1244 FL("TL is not in authenticated state so skipping SSR"));
Karthick S79bbe822015-07-14 15:28:08 +05301245 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
1246 goto print_log;
1247 }
Mihir Shete327c2ab2014-11-13 15:17:02 +05301248 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05301249 HDD_TX_STALL_KICKDXE_THRESHOLD)
1250 {
1251 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1252 "%s: Request Kick DXE for recovery",__func__);
1253 WLANTL_TLDebugMessage(WLANTL_DEBUG_KICKDXE);
1254 }
1255 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
Mihir Shete327c2ab2014-11-13 15:17:02 +05301256 HDD_TX_STALL_RECOVERY_THRESHOLD)
1257 {
1258 VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
1259 "%s: Request firmware for recovery",__func__);
1260 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
1261 }
Ganesh Kondabattinic86625a2015-11-27 15:08:40 +05301262
1263 /*
1264 * This function is getting called in softirq context, So don't hold
1265 * any mutex.
1266 * There is no harm here in not holding the mutex as long as we are
1267 * not accessing the pRemainChanCtx contents.
1268 */
Mihir Shete0be28772015-02-17 18:42:14 +05301269 pRemainChanCtx = hdd_get_remain_on_channel_ctx(pHddCtx);
1270 if (!pRemainChanCtx)
Mihir Shetef3473692014-06-27 15:13:20 +05301271 {
Mihir Shete0be28772015-02-17 18:42:14 +05301272 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
1273 HDD_TX_STALL_SSR_THRESHOLD)
1274 {
1275 // Driver could not recover, issue SSR
1276 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1277 "%s: Cannot recover from Data stall Issue SSR",
1278 __func__);
1279 WLANTL_FatalError();
Mukul Sharma987bef02015-11-16 20:04:54 +05301280 // reset count after issuing the SSR
1281 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Mihir Shete0be28772015-02-17 18:42:14 +05301282 return;
1283 }
1284 }
1285 else
1286 {
1287 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1288 "Remain on channel in progress");
1289 /* The supplicant can retry "P2P Invitation Request" for 120 times
1290 * and so there is a possbility that we can remain off channel for
1291 * the entire duration of these retries(which can be max 60sec).
1292 * If we encounter such a case, let us not trigger SSR after 30sec
1293 * but wait for 60sec to let the device go on home channel and start
1294 * tx. If tx does not start within 70sec we will issue SSR.
1295 */
1296 if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
1297 HDD_TX_STALL_SSR_THRESHOLD_HIGH)
1298 {
1299 // Driver could not recover, issue SSR
1300 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1301 "%s: Cannot recover from Data stall Issue SSR",
1302 __func__);
1303 WLANTL_FatalError();
1304 return;
1305 }
Mihir Shetef3473692014-06-27 15:13:20 +05301306 }
1307
Karthick S79bbe822015-07-14 15:28:08 +05301308print_log:
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301309 /* If Tx stalled for a long time then *hdd_tx_timeout* is called
1310 * every 5sec. The TL debug spits out a lot of information on the
1311 * serial console, if it is called every time *hdd_tx_timeout* is
1312 * called then we may get a watchdog bite on the Application
1313 * processor, so ratelimit the TL debug logs.
1314 */
1315 if (__ratelimit(&hdd_tx_timeout_rs))
1316 {
1317 hdd_wmm_tx_snapshot(pAdapter);
Mihir Shete327c2ab2014-11-13 15:17:02 +05301318 WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301319 }
Abhishek Singh837adf22015-10-01 17:37:37 +05301320 /* Call fatal event if data stall is for
1321 * HDD_TX_STALL_FATAL_EVENT_THRESHOLD times
1322 */
1323 if (HDD_TX_STALL_FATAL_EVENT_THRESHOLD ==
1324 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount)
1325 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
1326 WLAN_LOG_INDICATOR_HOST_DRIVER,
1327 WLAN_LOG_REASON_DATA_STALL,
1328 FALSE, TRUE);
Mihir Shetec8fe71b2014-06-16 15:32:59 +05301329}
Jeff Johnson295189b2012-06-20 16:38:30 -07001330
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05301331/**============================================================================
1332 @brief hdd_tx_timeout() - Function called by OS if there is any
1333 timeout during transmission. Since HDD simply enqueues packet
1334 and returns control to OS right away, this would never be invoked
1335
1336 @param dev : [in] pointer to network device
1337 @return : None
1338 ===========================================================================*/
1339void hdd_tx_timeout(struct net_device *dev)
1340{
1341 vos_ssr_protect(__func__);
1342 __hdd_tx_timeout(dev);
1343 vos_ssr_unprotect(__func__);
1344}
Jeff Johnson295189b2012-06-20 16:38:30 -07001345
1346/**============================================================================
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05301347 @brief __hdd_stats() - Function registered with the Linux OS for
Jeff Johnson295189b2012-06-20 16:38:30 -07001348 device TX/RX statistic
1349
1350 @param dev : [in] pointer to Libra network device
1351
1352 @return : pointer to net_device_stats structure
1353 ===========================================================================*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05301354struct net_device_stats* __hdd_stats(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07001355{
1356 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
c_hpothub8245442013-11-20 23:41:09 +05301357
1358 if ( NULL == pAdapter )
1359 {
c_hpothu32490782014-03-14 19:14:34 +05301360 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301361 FL("pAdapter is NULL"));
1362 VOS_ASSERT(0);
1363 return NULL;
1364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001365
1366 return &pAdapter->stats;
1367}
1368
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05301369struct net_device_stats* hdd_stats(struct net_device *dev)
1370{
1371 struct net_device_stats* dev_stats;
1372
1373 vos_ssr_protect(__func__);
1374 dev_stats = __hdd_stats(dev);
1375 vos_ssr_unprotect(__func__);
1376
1377 return dev_stats;
1378}
Jeff Johnson295189b2012-06-20 16:38:30 -07001379
1380/**============================================================================
Katya Nigam1fd24402015-02-16 14:52:19 +05301381 @brief hdd_ibss_init_tx_rx() - Init function to initialize Tx/RX
1382 modules in HDD
1383
1384 @param pAdapter : [in] pointer to adapter context
1385 @return : VOS_STATUS_E_FAILURE if any errors encountered
1386 : VOS_STATUS_SUCCESS otherwise
1387 ===========================================================================*/
1388void hdd_ibss_init_tx_rx( hdd_adapter_t *pAdapter )
1389{
1390 v_U8_t i;
1391 v_U8_t STAId = 0;
1392 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
1393 hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info;
1394 v_U8_t pACWeights[] = {
1395 HDD_SOFTAP_BK_WEIGHT_DEFAULT,
1396 HDD_SOFTAP_BE_WEIGHT_DEFAULT,
1397 HDD_SOFTAP_VI_WEIGHT_DEFAULT,
1398 HDD_SOFTAP_VO_WEIGHT_DEFAULT
1399 };
1400
1401 pAdapter->isVosOutOfResource = VOS_FALSE;
1402 pAdapter->isVosLowResource = VOS_FALSE;
1403
1404 // Since SAP model is used for IBSS also. Using same queue length as in SAP.
1405 pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
1406 pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
1407 pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
1408 pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;
1409
1410 for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++)
1411 {
1412 vos_mem_zero(&pPeerInfo->ibssStaInfo[STAId], sizeof(hdd_ibss_station_info_t));
1413 for (i = 0; i < NUM_TX_QUEUES; i ++)
1414 {
1415 hdd_list_init(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
1416 }
1417 }
1418
1419 /* Update the AC weights suitable for SoftAP mode of operation */
1420 WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
1421}
1422
1423/**============================================================================
1424 @brief hdd_ibss_deinit_tx_rx() - Deinit function to clean up Tx/RX
1425 modules in HDD
1426
1427 @param pAdapter : [in] pointer to adapter context..
1428 @return : VOS_STATUS_E_FAILURE if any errors encountered.
1429 : VOS_STATUS_SUCCESS otherwise
1430 ===========================================================================*/
1431VOS_STATUS hdd_ibss_deinit_tx_rx( hdd_adapter_t *pAdapter )
1432{
1433 VOS_STATUS status = VOS_STATUS_SUCCESS;
1434 v_U8_t STAId = 0;
1435 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
1436 hdd_ibss_peer_info_t * pPeerInfo = &pHddStaCtx->ibss_peer_info;
1437 hdd_list_node_t *anchor = NULL;
1438 skb_list_node_t *pktNode = NULL;
1439 struct sk_buff *skb = NULL;
1440 v_SINT_t i = -1;
1441
1442 for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++)
1443 {
1444 if (VOS_FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed)
1445 {
1446 continue;
1447 }
1448 for (i = 0; i < NUM_TX_QUEUES; i ++)
1449 {
1450 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
1451 while (true)
1452 {
1453 status = hdd_list_remove_front ( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], &anchor);
1454
1455 if (VOS_STATUS_E_EMPTY != status)
1456 {
1457 //If success then we got a valid packet from some AC
1458 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1459 skb = pktNode->skb;
1460 ++pAdapter->stats.tx_dropped;
1461 ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
1462 ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
1463 kfree_skb(skb);
1464 continue;
1465 }
1466
1467 //current list is empty
1468 break;
1469 }
1470 pPeerInfo->ibssStaInfo[STAId].txSuspended[i] = VOS_FALSE;
1471 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
1472 }
1473 }
1474 pAdapter->isVosLowResource = VOS_FALSE;
1475
1476 return status;
1477}
1478
1479/**============================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001480 @brief hdd_init_tx_rx() - Init function to initialize Tx/RX
1481 modules in HDD
1482
1483 @param pAdapter : [in] pointer to adapter context
1484 @return : VOS_STATUS_E_FAILURE if any errors encountered
1485 : VOS_STATUS_SUCCESS otherwise
1486 ===========================================================================*/
1487VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter )
1488{
1489 VOS_STATUS status = VOS_STATUS_SUCCESS;
1490 v_SINT_t i = -1;
1491
c_hpothub8245442013-11-20 23:41:09 +05301492 if ( NULL == pAdapter )
1493 {
c_hpothu32490782014-03-14 19:14:34 +05301494 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301495 FL("pAdapter is NULL"));
1496 VOS_ASSERT(0);
1497 return VOS_STATUS_E_FAILURE;
1498 }
1499
Jeff Johnson295189b2012-06-20 16:38:30 -07001500 pAdapter->isVosOutOfResource = VOS_FALSE;
Madan Mohan Koyyalamudifd3b7a92013-10-10 15:02:58 +05301501 pAdapter->isVosLowResource = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001502
1503 //vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
1504 //Will be zeroed out during alloc
1505
1506 while (++i != NUM_TX_QUEUES)
1507 {
1508 pAdapter->isTxSuspended[i] = VOS_FALSE;
1509 hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
1510 }
1511
1512 return status;
1513}
1514
1515
1516/**============================================================================
1517 @brief hdd_deinit_tx_rx() - Deinit function to clean up Tx/RX
1518 modules in HDD
1519
1520 @param pAdapter : [in] pointer to adapter context
1521 @return : VOS_STATUS_E_FAILURE if any errors encountered
1522 : VOS_STATUS_SUCCESS otherwise
1523 ===========================================================================*/
1524VOS_STATUS hdd_deinit_tx_rx( hdd_adapter_t *pAdapter )
1525{
1526 VOS_STATUS status = VOS_STATUS_SUCCESS;
1527 v_SINT_t i = -1;
1528
c_hpothub8245442013-11-20 23:41:09 +05301529 if ( NULL == pAdapter )
1530 {
c_hpothu32490782014-03-14 19:14:34 +05301531 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
c_hpothub8245442013-11-20 23:41:09 +05301532 FL("pAdapter is NULL"));
1533 VOS_ASSERT(0);
1534 return VOS_STATUS_E_FAILURE;
1535 }
1536
Jeff Johnson295189b2012-06-20 16:38:30 -07001537 status = hdd_flush_tx_queues(pAdapter);
c_hpothub8245442013-11-20 23:41:09 +05301538 if (VOS_STATUS_SUCCESS != status)
c_hpothu32490782014-03-14 19:14:34 +05301539 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
c_hpothub8245442013-11-20 23:41:09 +05301540 FL("failed to flush tx queues"));
1541
Jeff Johnson295189b2012-06-20 16:38:30 -07001542 while (++i != NUM_TX_QUEUES)
1543 {
1544 //Free up actual list elements in the Tx queue
1545 hdd_list_destroy( &pAdapter->wmm_tx_queue[i] );
1546 }
1547
1548 return status;
1549}
1550
1551
1552/**============================================================================
1553 @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
1554 modules in HDD
1555
1556 @param pAdapter : [in] pointer to adapter context
1557 @return : VOS_STATUS_E_FAILURE if any errors encountered
1558 : VOS_STATUS_SUCCESS otherwise
1559 ===========================================================================*/
1560VOS_STATUS hdd_disconnect_tx_rx( hdd_adapter_t *pAdapter )
1561{
1562 return hdd_flush_tx_queues(pAdapter);
1563}
1564
1565
1566/**============================================================================
1567 @brief hdd_IsEAPOLPacket() - Checks the packet is EAPOL or not.
1568
1569 @param pVosPacket : [in] pointer to vos packet
1570 @return : VOS_TRUE if the packet is EAPOL
1571 : VOS_FALSE otherwise
1572 ===========================================================================*/
1573
1574v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket )
1575{
1576 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1577 v_BOOL_t fEAPOL = VOS_FALSE;
1578 void *pBuffer = NULL;
1579
1580
1581 vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
1582 &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
Abhishek Singhfa011222014-04-14 10:57:08 +05301583 if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001584 {
Abhishek Singhfa011222014-04-14 10:57:08 +05301585 if ( pBuffer && *(unsigned short*)pBuffer ==
1586 vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001587 {
1588 fEAPOL = VOS_TRUE;
1589 }
1590 }
1591
1592 return fEAPOL;
1593}
1594
Abhishek Singhfa011222014-04-14 10:57:08 +05301595/**============================================================================
1596 @brief hdd_IsARP() - Checks the packet is ARP or not.
1597
1598 @param pVosPacket : [in] pointer to vos packet
1599 @return : VOS_TRUE if the packet is ARP
1600 : VOS_FALSE otherwise
1601 ===========================================================================*/
1602
1603v_BOOL_t hdd_IsARP( vos_pkt_t *pVosPacket )
1604{
1605 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1606 v_BOOL_t fIsARP = VOS_FALSE;
1607 void *pBuffer = NULL;
1608
1609
1610 vosStatus = vos_pkt_peek_data( pVosPacket,
1611 (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
1612 &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
1613 if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
1614 {
1615 if ( pBuffer && *(unsigned short*)pBuffer ==
1616 vos_cpu_to_be16(HDD_ETHERTYPE_ARP) )
1617 {
1618 fIsARP = VOS_TRUE;
1619 }
1620 }
1621
1622 return fIsARP;
1623}
Jeff Johnson295189b2012-06-20 16:38:30 -07001624
1625#ifdef FEATURE_WLAN_WAPI // Need to update this function
1626/**============================================================================
1627 @brief hdd_IsWAIPacket() - Checks the packet is WAI or not.
1628
1629 @param pVosPacket : [in] pointer to vos packet
1630 @return : VOS_TRUE if the packet is WAI
1631 : VOS_FALSE otherwise
1632 ===========================================================================*/
1633
1634v_BOOL_t hdd_IsWAIPacket( vos_pkt_t *pVosPacket )
1635{
1636 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1637 v_BOOL_t fIsWAI = VOS_FALSE;
1638 void *pBuffer = NULL;
1639
1640 // Need to update this function
1641 vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
1642 &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
1643
1644 if (VOS_IS_STATUS_SUCCESS( vosStatus ) )
1645 {
Abhishek Singhfa011222014-04-14 10:57:08 +05301646 if ( pBuffer && *(unsigned short*)pBuffer ==
1647 vos_cpu_to_be16(HDD_ETHERTYPE_WAI) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 {
1649 fIsWAI = VOS_TRUE;
1650 }
1651 }
1652
1653 return fIsWAI;
1654}
1655#endif /* FEATURE_WLAN_WAPI */
1656
1657/**============================================================================
1658 @brief hdd_tx_complete_cbk() - Callback function invoked by TL
1659 to indicate that a packet has been transmitted across the SDIO bus
1660 succesfully. OS packet resources can be released after this cbk.
1661
1662 @param vosContext : [in] pointer to VOS context
1663 @param pVosPacket : [in] pointer to VOS packet (containing skb)
1664 @param vosStatusIn : [in] status of the transmission
1665
1666 @return : VOS_STATUS_E_FAILURE if any errors encountered
1667 : VOS_STATUS_SUCCESS otherwise
1668 ===========================================================================*/
1669VOS_STATUS hdd_tx_complete_cbk( v_VOID_t *vosContext,
1670 vos_pkt_t *pVosPacket,
1671 VOS_STATUS vosStatusIn )
1672{
1673 VOS_STATUS status = VOS_STATUS_SUCCESS;
1674 hdd_adapter_t *pAdapter = NULL;
1675 hdd_context_t *pHddCtx = NULL;
1676 void* pOsPkt = NULL;
1677
1678 if( ( NULL == vosContext ) || ( NULL == pVosPacket ) )
1679 {
c_hpothu32490782014-03-14 19:14:34 +05301680 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301681 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001682 return VOS_STATUS_E_FAILURE;
1683 }
1684
1685 //Return the skb to the OS
1686 status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
Agarwal Ashish971c2882013-10-30 20:11:12 +05301687 if (!VOS_IS_STATUS_SUCCESS( status ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001688 {
1689 //This is bad but still try to free the VOSS resources if we can
c_hpothu32490782014-03-14 19:14:34 +05301690 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301691 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 vos_pkt_return_packet( pVosPacket );
1693 return VOS_STATUS_E_FAILURE;
1694 }
1695
1696 //Get the HDD context.
Kiet Lam3c2ee302014-03-23 23:23:22 -07001697 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 //Get the Adapter context.
1699 pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_INFRA_STATION);
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301700 if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07001701 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05301702 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001703 "%s: Invalid adapter %pK", __func__, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001704 }
1705 else
1706 {
1707 ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
1708 }
1709
1710 kfree_skb((struct sk_buff *)pOsPkt);
1711
1712 //Return the VOS packet resources.
1713 status = vos_pkt_return_packet( pVosPacket );
Agarwal Ashish971c2882013-10-30 20:11:12 +05301714 if (!VOS_IS_STATUS_SUCCESS( status ))
Jeff Johnson295189b2012-06-20 16:38:30 -07001715 {
c_hpothu32490782014-03-14 19:14:34 +05301716 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05301717 "%s: Could not return VOS packet to the pool", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001718 }
1719
1720 return status;
1721}
1722
Katya Nigamf944e5e2015-02-10 15:05:43 +05301723/**============================================================================
1724 @brief hdd_ibss_tx_fetch_packet_cbk() - Callback function invoked by TL to
1725 fetch a packet for transmission.
1726
1727 @param vosContext : [in] pointer to VOS context
1728 @param staId : [in] Station for which TL is requesting a pkt
1729 @param ac : [in] access category requested by TL
1730 @param pVosPacket : [out] pointer to VOS packet packet pointer
1731 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1732
1733 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1734 : VOS_STATUS_E_FAILURE if any errors encountered
1735 : VOS_STATUS_SUCCESS otherwise
1736 ===========================================================================*/
1737VOS_STATUS hdd_ibss_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1738 v_U8_t *pStaId,
1739 WLANTL_ACEnumType ac,
1740 vos_pkt_t **ppVosPacket,
1741 WLANTL_MetaInfoType *pPktMetaInfo )
1742{
1743 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1744 hdd_adapter_t *pAdapter = NULL;
1745 hdd_list_node_t *anchor = NULL;
1746 skb_list_node_t *pktNode = NULL;
1747 struct sk_buff *skb = NULL;
1748 vos_pkt_t *pVosPacket = NULL;
1749 v_MACADDR_t* pDestMacAddress = NULL;
1750 v_TIME_t timestamp;
1751 v_SIZE_t size = 0;
1752 v_U8_t STAId = WLAN_MAX_STA_COUNT;
1753 hdd_context_t *pHddCtx = NULL;
1754 hdd_station_ctx_t *pHddStaCtx = NULL;
1755 hdd_ibss_peer_info_t *pPeerInfo = NULL;
1756 v_U8_t proto_type = 0;
Abhishek Singh99f725a2015-05-15 17:50:26 +05301757 v_U16_t packet_size;
Katya Nigamf944e5e2015-02-10 15:05:43 +05301758
1759 //Sanity check on inputs
1760 if ( ( NULL == vosContext ) ||
1761 ( NULL == pStaId ) ||
1762 ( NULL == ppVosPacket ) ||
1763 ( NULL == pPktMetaInfo ) )
1764 {
1765 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1766 "%s: Null Params being passed", __func__);
1767 return VOS_STATUS_E_FAILURE;
1768 }
1769
1770 //Get the HDD context.
1771 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
1772 if ( NULL == pHddCtx )
1773 {
1774 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1775 "%s: HDD adapter context is Null", __func__);
1776 return VOS_STATUS_E_FAILURE;
1777 }
1778
1779 STAId = *pStaId;
1780 pAdapter = pHddCtx->sta_to_adapter[STAId];
1781 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1782 {
1783 VOS_ASSERT(0);
1784 return VOS_STATUS_E_FAILURE;
1785 }
1786
1787 pHddStaCtx = &pAdapter->sessionCtx.station;
1788 pPeerInfo = &pHddStaCtx->ibss_peer_info;
1789
1790 if (FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed )
1791 {
1792 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1793 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
1794 return VOS_STATUS_E_FAILURE;
1795 }
1796
1797 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
1798
1799 *ppVosPacket = NULL;
1800
1801 //Make sure the AC being asked for is sane
1802 if( ac > WLANTL_MAX_AC || ac < 0)
1803 {
1804 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1805 "%s: Invalid AC %d passed by TL", __func__, ac);
1806 return VOS_STATUS_E_FAILURE;
1807 }
1808
1809 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
1810
Katya Nigamf944e5e2015-02-10 15:05:43 +05301811 //Get the vos packet before so that we are prepare for VOS low reseurce condition
1812 //This simplifies the locking and unlocking of Tx queue
1813 status = vos_pkt_wrap_data_packet( &pVosPacket,
1814 VOS_PKT_TYPE_TX_802_3_DATA,
1815 NULL, //OS Pkt is not being passed
1816 hdd_tx_low_resource_cbk,
1817 pAdapter );
1818
1819 if ((status == VOS_STATUS_E_ALREADY) || (status == VOS_STATUS_E_RESOURCES))
1820 {
1821 //Remember VOS is in a low resource situation
1822 pAdapter->isVosOutOfResource = VOS_TRUE;
1823 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
1824 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
1825 "%s: VOSS in Low Resource scenario", __func__);
1826 //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
1827 return VOS_STATUS_E_FAILURE;
1828 }
1829
1830 /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there.
1831 Do not get next AC as the other branch does.
1832 */
1833 spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
1834 hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &size);
1835
1836 if (0 == size)
1837 {
1838 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
1839 vos_pkt_return_packet(pVosPacket);
1840 return VOS_STATUS_E_EMPTY;
1841 }
1842
1843 status = hdd_list_remove_front( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor );
1844 spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
1845
1846 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1847 "%s: AC %d has packets pending", __func__, ac);
1848
1849 if(VOS_STATUS_SUCCESS == status)
1850 {
1851 //If success then we got a valid packet from some AC
1852 pktNode = list_entry(anchor, skb_list_node_t, anchor);
1853 skb = pktNode->skb;
1854 }
1855 else
1856 {
1857 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1858 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1859 "%s: Error in de-queuing skb from Tx queue status = %d",
1860 __func__, status );
1861 vos_pkt_return_packet(pVosPacket);
1862 return VOS_STATUS_E_FAILURE;
1863 }
1864
1865 //Attach skb to VOS packet.
1866 status = vos_pkt_set_os_packet( pVosPacket, skb );
1867 if (status != VOS_STATUS_SUCCESS)
1868 {
1869 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
1870 "%s: Error attaching skb", __func__);
1871 vos_pkt_return_packet(pVosPacket);
1872 ++pAdapter->stats.tx_dropped;
1873 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
1874 kfree_skb(skb);
1875 return VOS_STATUS_E_FAILURE;
1876 }
1877
1878 //Return VOS packet to TL;
1879 *ppVosPacket = pVosPacket;
1880
1881 //Fill out the meta information needed by TL
1882 vos_pkt_get_timestamp( pVosPacket, &timestamp );
1883 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
1884 if ( 1 < size )
1885 {
1886 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
1887 }
1888 else
1889 {
1890 pPktMetaInfo->bMorePackets = 0;
1891 }
1892
1893 if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE)
1894 pPktMetaInfo->ucIsEapol = 0;
1895 else
1896 pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0;
1897
1898 if ((NULL != pHddCtx) &&
1899 (pHddCtx->cfg_ini->gEnableDebugLog))
1900 {
1901 proto_type = vos_pkt_get_proto_type(skb,
1902 pHddCtx->cfg_ini->gEnableDebugLog);
1903 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
1904 {
1905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1906 "IBSS STA TX EAPOL");
1907 }
1908 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
1909 {
1910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1911 "IBSS STA TX DHCP");
1912 }
Mihir Shete39f7c752015-06-11 15:40:09 +05301913 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
1914 {
1915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1916 "IBSS STA TX ARP");
1917 }
Katya Nigamf944e5e2015-02-10 15:05:43 +05301918 }
1919
Abhishek Singh99f725a2015-05-15 17:50:26 +05301920 vos_pkt_get_packet_length( pVosPacket,&packet_size );
1921 if ( HDD_ETHERTYPE_ARP_SIZE == packet_size )
1922 pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;
1923
Katya Nigamf944e5e2015-02-10 15:05:43 +05301924 pPktMetaInfo->ucUP = pktNode->userPriority;
1925 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
1926 pPktMetaInfo->ucType = 0;
1927
1928 //Extract the destination address from ethernet frame
1929 pDestMacAddress = (v_MACADDR_t*)skb->data;
1930
1931 // we need 802.3 to 802.11 frame translation
1932 // (note that Bcast/Mcast will be translated in SW, unicast in HW)
1933 pPktMetaInfo->ucDisableFrmXtl = 0;
1934 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
1935 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
1936
1937 if ( (pPeerInfo->ibssStaInfo[STAId].txSuspended[ac]) &&
1938 (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
1939 {
1940 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1941 "%s: TX queue re-enabled", __func__);
1942 pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
1943 netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
1944 }
1945
1946 // We're giving the packet to TL so consider it transmitted from
1947 // a statistics perspective. We account for it here instead of
1948 // when the packet is returned for two reasons. First, TL will
1949 // manipulate the skb to the point where the len field is not
1950 // accurate, leading to inaccurate byte counts if we account for
1951 // it later. Second, TL does not provide any feedback as to
1952 // whether or not the packet was successfully sent over the air,
1953 // so the packet counts will be the same regardless of where we
1954 // account for them
1955 pAdapter->stats.tx_bytes += skb->len;
1956 ++pAdapter->stats.tx_packets;
1957 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
1958 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
1959 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
1960
1961 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
1962 "%s: Valid VOS PKT returned to TL", __func__);
1963
1964 return status;
1965}
Jeff Johnson295189b2012-06-20 16:38:30 -07001966
1967/**============================================================================
1968 @brief hdd_tx_fetch_packet_cbk() - Callback function invoked by TL to
1969 fetch a packet for transmission.
1970
1971 @param vosContext : [in] pointer to VOS context
1972 @param staId : [in] Station for which TL is requesting a pkt
1973 @param ac : [in] access category requested by TL
1974 @param pVosPacket : [out] pointer to VOS packet packet pointer
1975 @param pPktMetaInfo : [out] pointer to meta info for the pkt
1976
1977 @return : VOS_STATUS_E_EMPTY if no packets to transmit
1978 : VOS_STATUS_E_FAILURE if any errors encountered
1979 : VOS_STATUS_SUCCESS otherwise
1980 ===========================================================================*/
1981VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext,
1982 v_U8_t *pStaId,
1983 WLANTL_ACEnumType ac,
1984 vos_pkt_t **ppVosPacket,
1985 WLANTL_MetaInfoType *pPktMetaInfo )
1986{
1987 VOS_STATUS status = VOS_STATUS_E_FAILURE;
1988 hdd_adapter_t *pAdapter = NULL;
1989 hdd_context_t *pHddCtx = NULL;
1990 hdd_list_node_t *anchor = NULL;
1991 skb_list_node_t *pktNode = NULL;
1992 struct sk_buff *skb = NULL;
1993 vos_pkt_t *pVosPacket = NULL;
1994 v_MACADDR_t* pDestMacAddress = NULL;
1995 v_TIME_t timestamp;
1996 WLANTL_ACEnumType newAc;
1997 v_SIZE_t size = 0;
Abhishek Singhfa011222014-04-14 10:57:08 +05301998 v_U16_t packet_size;
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 tANI_U8 acAdmitted, i;
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002000 v_U8_t proto_type = 0;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302001 WLANTL_ACEnumType actualAC;
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302002 v_BOOL_t arp_pkt;
Jeff Johnson295189b2012-06-20 16:38:30 -07002003
2004 //Sanity check on inputs
2005 if ( ( NULL == vosContext ) ||
2006 ( NULL == pStaId ) ||
2007 ( NULL == ppVosPacket ) ||
2008 ( NULL == pPktMetaInfo ) )
2009 {
c_hpothu32490782014-03-14 19:14:34 +05302010 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302011 "%s: Null Params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 return VOS_STATUS_E_FAILURE;
2013 }
2014
2015 //Get the HDD context.
Kiet Lam3c2ee302014-03-23 23:23:22 -07002016 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
Jeff Johnson295189b2012-06-20 16:38:30 -07002017 if(pHddCtx == NULL)
2018 {
c_hpothu32490782014-03-14 19:14:34 +05302019 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302020 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002021 return VOS_STATUS_E_FAILURE;
2022 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 pAdapter = pHddCtx->sta_to_adapter[*pStaId];
Jeff Johnsonb156c922013-12-05 17:19:46 -08002024 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Jeff Johnson295189b2012-06-20 16:38:30 -07002025 {
c_hpothu32490782014-03-14 19:14:34 +05302026 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07002027 FL("invalid adapter:%pK for staId:%u"), pAdapter, *pStaId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002028 VOS_ASSERT(0);
2029 return VOS_STATUS_E_FAILURE;
2030 }
2031
2032 ++pAdapter->hdd_stats.hddTxRxStats.txFetched;
2033
2034 *ppVosPacket = NULL;
2035
2036 //Make sure the AC being asked for is sane
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302037 if (ac > WLANTL_AC_HIGH_PRIO || ac < 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002038 {
c_hpothu32490782014-03-14 19:14:34 +05302039 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302040 "%s: Invalid QId %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 return VOS_STATUS_E_FAILURE;
2042 }
2043
2044 ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];
2045
2046#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05302047 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302048 "%s: AC %d passed by TL", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002049#endif // HDD_WMM_DEBUG
2050
Jeff Johnson295189b2012-06-20 16:38:30 -07002051 // do we have any packets pending in this AC?
2052 hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size );
2053 if( size > 0 )
2054 {
2055 // yes, so process it
2056#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05302057 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002058 "%s: AC %d has packets pending", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002059#endif // HDD_WMM_DEBUG
2060 }
2061 else
2062 {
2063 ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty;
2064#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05302065 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002066 "%s: no packets pending", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002067#endif // HDD_WMM_DEBUG
2068 return VOS_STATUS_E_FAILURE;
2069 }
2070
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302071 // Note here that we are not checking "wmmAcAccessAllowed" for packets
2072 // in new queue since there is no one AC associated to the new queue.
2073 // Since there will be either eapol or dhcp pkts in new queue overlooking
2074 // this should be okay from implicit QoS perspective.
2075 if (ac != WLANTL_AC_HIGH_PRIO)
2076 {
2077 // We find an AC with packets
2078 // or we determine we have no more packets to send
2079 // HDD is not allowed to change AC.
2080
2081 // has this AC been admitted? or
2082 // To allow EAPOL packets when not authenticated
2083 if (unlikely((0==pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed) &&
2084 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.uIsAuthenticated))
2085 {
2086 ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty;
2087#ifdef HDD_WMM_DEBUG
2088 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
2089 "%s: no packets pending", __func__);
2090#endif // HDD_WMM_DEBUG
2091 return VOS_STATUS_E_FAILURE;
2092 }
2093 }
2094
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources
2096 //This simplifies the locking and unlocking of Tx queue
2097 status = vos_pkt_wrap_data_packet( &pVosPacket,
2098 VOS_PKT_TYPE_TX_802_3_DATA,
2099 NULL, //OS Pkt is not being passed
2100 hdd_tx_low_resource_cbk,
2101 pAdapter );
2102
2103 if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
2104 {
2105 //Remember VOS is in a low resource situation
2106 pAdapter->isVosOutOfResource = VOS_TRUE;
2107 ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
c_hpothu32490782014-03-14 19:14:34 +05302108 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 -07002109 //TL will now think we have no more packets in this AC
2110 return VOS_STATUS_E_FAILURE;
2111 }
2112
2113 //Remove the packet from the queue
2114 spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock);
2115 status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor );
2116 spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock);
2117
2118 if(VOS_STATUS_SUCCESS == status)
2119 {
2120 //If success then we got a valid packet from some AC
2121 pktNode = list_entry(anchor, skb_list_node_t, anchor);
2122 skb = pktNode->skb;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302123 actualAC = hddWmmUpToAcMap[pktNode->userPriority];
2124 if (actualAC >= WLANTL_MAX_AC)
2125 {
2126 /* To fix klocwork */
2127 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
2128 "%s: Invalid AC for packet:%d", __func__, actualAC);
2129 actualAC = WLANTL_AC_BE;
2130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 }
2132 else
2133 {
2134 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
c_hpothu32490782014-03-14 19:14:34 +05302135 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, "%s: Error in de-queuing "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002136 "skb from Tx queue status = %d", __func__, status );
Jeff Johnson295189b2012-06-20 16:38:30 -07002137 vos_pkt_return_packet(pVosPacket);
2138 return VOS_STATUS_E_FAILURE;
2139 }
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302140 arp_pkt = vos_is_arp_pkt(skb, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07002141 //Attach skb to VOS packet.
2142 status = vos_pkt_set_os_packet( pVosPacket, skb );
2143 if (status != VOS_STATUS_SUCCESS)
2144 {
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302145
2146 if (arp_pkt)
2147 {
2148 ++pAdapter->hdd_stats.hddArpStats.txDropped;
2149 pAdapter->hdd_stats.hddArpStats.reason = HDD_ERROR_ATTACHING_SKB;
2150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2151 "%s :Error attaching skb,ARP packet droped", __func__);
2152 }
2153
c_hpothu32490782014-03-14 19:14:34 +05302154 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: Error attaching skb", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 vos_pkt_return_packet(pVosPacket);
2156 ++pAdapter->stats.tx_dropped;
2157 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
2158 kfree_skb(skb);
2159 return VOS_STATUS_E_FAILURE;
2160 }
2161
2162 //Just being paranoid. To be removed later
2163 if(pVosPacket == NULL)
2164 {
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302165
2166 if (arp_pkt)
2167 {
2168 ++pAdapter->hdd_stats.hddArpStats.txDropped;
2169 pAdapter->hdd_stats.hddArpStats.reason = HDD_VOS_PACKET_RETURNED_BY_VOSS_IS_NULL;
2170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2171 "%s :VOS packet returned by VOSS is NULL,ARP packet droped",
2172 __func__);
2173 }
2174
c_hpothu32490782014-03-14 19:14:34 +05302175 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 -07002176 ++pAdapter->stats.tx_dropped;
2177 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
2178 kfree_skb(skb);
2179 return VOS_STATUS_E_FAILURE;
2180 }
2181
Dino Mycle3b9536d2014-07-09 22:05:24 +05302182#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Srinivas Dasaridab36fe2015-07-21 12:10:56 +05302183 if (vos_is_macaddr_multicast((v_MACADDR_t*)skb->data))
Dino Mycle3b9536d2014-07-09 22:05:24 +05302184 {
Srinivas Dasaridab36fe2015-07-21 12:10:56 +05302185 pAdapter->hdd_stats.hddTxRxStats.txMcast[actualAC]++;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302186 }
2187
2188#endif
2189
Masti, Narayanraddi63d62352015-10-01 12:52:50 +05302190 wlan_hdd_tdls_notify_packet(pAdapter, skb);
Chilam NG571c65a2013-01-19 12:27:36 +05302191
Jeff Johnson295189b2012-06-20 16:38:30 -07002192 //Return VOS packet to TL;
2193 *ppVosPacket = pVosPacket;
2194
2195 //Fill out the meta information needed by TL
2196 //FIXME This timestamp is really the time stamp of wrap_data_packet
2197 vos_pkt_get_timestamp( pVosPacket, &timestamp );
2198 pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
2199
2200 if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE)
2201 pPktMetaInfo->ucIsEapol = 0;
Nirav Shah4f765af2015-01-21 19:51:30 +05302202 else
Jeff Johnson295189b2012-06-20 16:38:30 -07002203 pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0;
2204
Sushant Kaushika8073312015-05-04 17:33:52 +05302205 if (pPktMetaInfo->ucIsEapol)
2206 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
Sachin Ahuja8c65f382014-12-12 15:34:21 +05302207 if ((NULL != pHddCtx) &&
2208 (pHddCtx->cfg_ini->gEnableDebugLog))
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002209 {
2210 proto_type = vos_pkt_get_proto_type(skb,
2211 pHddCtx->cfg_ini->gEnableDebugLog);
2212 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
2213 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07002215 "STA TX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002216 }
2217 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
2218 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002220 "STA TX DHCP");
2221 }
Mihir Shete39f7c752015-06-11 15:40:09 +05302222 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
2223 {
2224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2225 "STA TX ARP");
2226 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002227 }
2228
Abhishek Singhfa011222014-04-14 10:57:08 +05302229 vos_pkt_get_packet_length( pVosPacket,&packet_size );
2230 if( HDD_ETHERTYPE_ARP_SIZE == packet_size )
2231 pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;
2232
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302233 if(pPktMetaInfo->ucIsArp)
2234 {
2235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2236 "%s :STA TX ARP Received in TL ",__func__);
2237 }
2238
Jeff Johnson295189b2012-06-20 16:38:30 -07002239#ifdef FEATURE_WLAN_WAPI
2240 // Override usIsEapol value when its zero for WAPI case
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302241 pPktMetaInfo->ucIsWai = hdd_IsWAIPacket( pVosPacket ) ? 1 : 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002242#endif /* FEATURE_WLAN_WAPI */
2243
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302244 /* 1. Check if ACM is set for this AC
2245 * 2. If set, check if this AC had already admitted
2246 * 3. If not already admitted, downgrade the UP to next best UP
2247 * 4. Allow only when medium time is non zero when Addts accepted
2248 * else downgrade traffic. we opted downgrading over Delts when
2249 * medium time is zero because while doing downgradig driver is not
2250 * clearing the wmm context so consider in subsequent roaming
2251 * if AP (new or same AP) accept the Addts with valid medium time
2252 * no application support is required where if we have opted
2253 * delts Applications have to again do Addts or STA will never
2254 * go for Addts.
2255 */
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302256 pPktMetaInfo->ac = actualAC;
2257 if(!pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcAccessRequired ||
2258 (pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid &&
2259 pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecInfo.medium_time))
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 {
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302261 pPktMetaInfo->ucUP = pktNode->userPriority;
2262 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 }
2264 else
2265 {
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302266 //Downgrade the UP
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302267 acAdmitted = pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid;
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302268 newAc = WLANTL_AC_BK;
Kanchanapally, Vidyullathaed969c62015-02-18 11:39:11 +05302269 for (i=actualAC-1; i>0; i--)
Jeff Johnson295189b2012-06-20 16:38:30 -07002270 {
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302271 if (pAdapter->hddWmmStatus.wmmAcStatus[i].wmmAcAccessRequired == 0)
2272 {
2273 newAc = i;
2274 break;
2275 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002276 }
Agarwal Ashish8b343f12015-01-08 20:06:44 +05302277 pPktMetaInfo->ucUP = hddWmmAcToHighestUp[newAc];
2278 pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
2279 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,
2280 "Downgrading UP %d to UP %d ",
2281 pktNode->userPriority, pPktMetaInfo->ucUP);
Jeff Johnson295189b2012-06-20 16:38:30 -07002282 }
2283
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05302284 if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
2285 {
2286 vos_record_roam_event(e_TL_FIRST_XMIT_TIME, NULL, 0);
2287 }
Mukul Sharma84f27252014-07-14 18:11:42 +05302288
Jeff Johnson295189b2012-06-20 16:38:30 -07002289 pPktMetaInfo->ucType = 0; //FIXME Don't know what this is
2290 pPktMetaInfo->ucDisableFrmXtl = 0; //802.3 frame so we need to xlate
2291 if ( 1 < size )
2292 {
2293 pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
2294 }
2295 else
2296 {
2297 pPktMetaInfo->bMorePackets = 0;
2298 }
2299
2300 //Extract the destination address from ethernet frame
2301 pDestMacAddress = (v_MACADDR_t*)skb->data;
2302 pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
2303 pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;
2304
2305
2306
2307 // if we are in a backpressure situation see if we can turn the hose back on
2308 if ( (pAdapter->isTxSuspended[ac]) &&
2309 (size <= HDD_TX_QUEUE_LOW_WATER_MARK) )
2310 {
2311 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressured;
2312 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressuredAC[ac];
c_hpothu32490782014-03-14 19:14:34 +05302313 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002314 "%s: TX queue[%d] re-enabled", __func__, ac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002315 pAdapter->isTxSuspended[ac] = VOS_FALSE;
2316 netif_tx_wake_queue(netdev_get_tx_queue(pAdapter->dev,
2317 skb_get_queue_mapping(skb) ));
Mihir Shete5d148f12014-12-16 17:54:49 +05302318 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
2319 pAdapter->sessionId, ac));
Jeff Johnson295189b2012-06-20 16:38:30 -07002320 }
2321
2322
2323 // We're giving the packet to TL so consider it transmitted from
2324 // a statistics perspective. We account for it here instead of
2325 // when the packet is returned for two reasons. First, TL will
2326 // manipulate the skb to the point where the len field is not
2327 // accurate, leading to inaccurate byte counts if we account for
2328 // it later. Second, TL does not provide any feedback as to
2329 // whether or not the packet was successfully sent over the air,
2330 // so the packet counts will be the same regardless of where we
2331 // account for them
2332 pAdapter->stats.tx_bytes += skb->len;
2333 ++pAdapter->stats.tx_packets;
2334 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
2335 ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
Mihir Shetef3473692014-06-27 15:13:20 +05302336 pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002337
Leo Chang50bbd252013-04-25 14:58:01 -07002338 if((pHddCtx->cfg_ini->thermalMitigationEnable) &&
2339 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07002340 {
2341 if(mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
2342 {
c_hpothu32490782014-03-14 19:14:34 +05302343 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002344 "%s: Tm Lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002345 return VOS_STATUS_E_FAILURE;
2346 }
2347 if(WLAN_HDD_TM_LEVEL_1 < pHddCtx->tmInfo.currentTmLevel)
2348 {
2349 if(0 == pHddCtx->tmInfo.txFrameCount)
2350 {
2351 /* Just recovered from sleep timeout */
2352 pHddCtx->tmInfo.lastOpenTs = timestamp;
2353 }
2354
Leo Chang50bbd252013-04-25 14:58:01 -07002355 if((VOS_FALSE == pHddCtx->tmInfo.qBlocked) &&
2356 ((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002357 (pHddCtx->tmInfo.txFrameCount >= pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold))
2358 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002359 /* During TX open duration, TX frame count is larger than threshold
2360 * Block TX during Sleep time */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05302361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002362 netif_tx_stop_all_queues(pAdapter->dev);
Leo Chang50bbd252013-04-25 14:58:01 -07002363 pHddCtx->tmInfo.qBlocked = VOS_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002364 pHddCtx->tmInfo.lastblockTs = timestamp;
2365 if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pHddCtx->tmInfo.txSleepTimer))
2366 {
2367 vos_timer_start(&pHddCtx->tmInfo.txSleepTimer, pHddCtx->tmInfo.tmAction.txSleepDuration);
2368 }
2369 }
2370 else if(((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) &&
2371 (pHddCtx->tmInfo.txFrameCount < pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold))
2372 {
2373 /* During TX open duration, TX frame count is less than threshold
2374 * Reset count and timestamp to prepare next cycle */
2375 pHddCtx->tmInfo.lastOpenTs = timestamp;
2376 pHddCtx->tmInfo.txFrameCount = 0;
2377 }
2378 else
2379 {
2380 /* Do Nothing */
2381 }
2382 pHddCtx->tmInfo.txFrameCount++;
2383 }
2384 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
2385 }
2386
2387
2388#ifdef HDD_WMM_DEBUG
c_hpothu32490782014-03-14 19:14:34 +05302389 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 -07002390#endif // HDD_WMM_DEBUG
2391
2392 return status;
2393}
2394
2395
2396/**============================================================================
2397 @brief hdd_tx_low_resource_cbk() - Callback function invoked in the
2398 case where VOS packets are not available at the time of the call to get
2399 packets. This callback function is invoked by VOS when packets are
2400 available.
2401
2402 @param pVosPacket : [in] pointer to VOS packet
2403 @param userData : [in] opaque user data that was passed initially
2404
2405 @return : VOS_STATUS_E_FAILURE if any errors encountered,
2406 : VOS_STATUS_SUCCESS otherwise
2407 =============================================================================*/
2408VOS_STATUS hdd_tx_low_resource_cbk( vos_pkt_t *pVosPacket,
2409 v_VOID_t *userData )
2410{
2411 VOS_STATUS status;
2412 v_SINT_t i = 0;
2413 v_SIZE_t size = 0;
2414 hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
2415
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302416 if (NULL == pAdapter || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
Jeff Johnson295189b2012-06-20 16:38:30 -07002417 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302418 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07002419 FL("Invalid adapter %pK"), pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002420 return VOS_STATUS_E_FAILURE;
2421 }
2422
2423 //Return the packet to VOS. We just needed to know that VOS is out of low resource
2424 //situation. Here we will only signal TL that there is a pending data for a STA.
2425 //VOS packet will be requested (if needed) when TL comes back to fetch data.
2426 vos_pkt_return_packet( pVosPacket );
2427
2428 pAdapter->isVosOutOfResource = VOS_FALSE;
2429
2430 //Indicate to TL that there is pending data if a queue is non empty
2431 for( i=NUM_TX_QUEUES-1; i>=0; --i )
2432 {
2433 size = 0;
2434 hdd_list_size( &pAdapter->wmm_tx_queue[i], &size );
2435 if ( size > 0 )
2436 {
2437 status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2438 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId [0],
2439 (WLANTL_ACEnumType)i );
2440 if( !VOS_IS_STATUS_SUCCESS( status ) )
2441 {
c_hpothu32490782014-03-14 19:14:34 +05302442 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302443 "%s: Failure in indicating pkt to TL for ac=%d", __func__, i);
Jeff Johnson295189b2012-06-20 16:38:30 -07002444 }
2445 }
2446 }
2447
2448 return VOS_STATUS_SUCCESS;
2449}
2450
Katya Nigame7b69a82015-04-28 15:24:06 +05302451static void hdd_mon_add_rx_radiotap_hdr (struct sk_buff *skb,
2452 int rtap_len, v_PVOID_t pRxPacket, hdd_mon_ctx_t *pMonCtx)
2453{
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302454 u8 rtap_temp[28] = {0};
Katya Nigame7b69a82015-04-28 15:24:06 +05302455 struct ieee80211_radiotap_header *rthdr;
2456 unsigned char *pos;
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302457 u32 mac_time;
Katya Nigame7b69a82015-04-28 15:24:06 +05302458 u16 rx_flags = 0;
2459 u16 rateIdx;
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302460 u16 channel_flags = 0;
2461 u8 rfBand;
2462 s8 currentRSSI, currentRSSI0, currentRSSI1;
2463 s8 noise;
Katya Nigame7b69a82015-04-28 15:24:06 +05302464
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302465 mac_time = WDA_GET_RX_TIMESTAMP(pRxPacket);
Katya Nigame7b69a82015-04-28 15:24:06 +05302466 rateIdx = WDA_GET_RX_MAC_RATE_IDX(pRxPacket);
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302467 if( rateIdx >= 210 && rateIdx <= 217)
2468 rateIdx-=202;
2469 if( rateIdx >= 218 && rateIdx <= 225 )
2470 rateIdx-=210;
Abhishek Singh2b055852015-10-07 14:14:13 +05302471
Gupta, Kapil50d757b2016-03-17 19:45:19 +05302472 if(rateIdx >= (sizeof(gRatefromIdx)/ sizeof(int))) {
Abhishek Singh2b055852015-10-07 14:14:13 +05302473 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2474 "%s: invalid rateIdx %d make it 0", __func__, rateIdx);
2475 rateIdx = 0;
2476 }
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302477 rfBand = WDA_GET_RX_RFBAND(pRxPacket);
2478 if (IS_5G_BAND(rfBand))
2479 channel_flags |= IEEE80211_CHAN_5GHZ;
2480 else
2481 channel_flags |= IEEE80211_CHAN_2GHZ;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302482 currentRSSI0 = WDA_GETRSSI0(pRxPacket) - 100;
2483 currentRSSI1 = WDA_GETRSSI1(pRxPacket) - 100;
2484 currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1;
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302485 noise = WDA_GET_RX_SNR(pRxPacket);
Katya Nigame7b69a82015-04-28 15:24:06 +05302486
2487 rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]);
2488
2489 /* radiotap header, set always present flags */
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302490 rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
2491 (1 << IEEE80211_RADIOTAP_FLAGS) |
Katya Nigame7b69a82015-04-28 15:24:06 +05302492 (1 << IEEE80211_RADIOTAP_CHANNEL) |
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302493 (1 << IEEE80211_RADIOTAP_RATE) |
2494 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
2495 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
Katya Nigame7b69a82015-04-28 15:24:06 +05302496 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
2497 rthdr->it_len = cpu_to_le16(rtap_len);
2498
2499 pos = (unsigned char *) (rthdr + 1);
2500
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302501 /* IEEE80211_RADIOTAP_TSFT */
2502 put_unaligned_le64(mac_time, pos);
2503 pos += 8;
2504
Katya Nigame7b69a82015-04-28 15:24:06 +05302505 /* IEEE80211_RADIOTAP_FLAGS */
2506 *pos = 0;
2507 pos++;
2508
2509 /* IEEE80211_RADIOTAP_RATE */
Katya Nigame7b69a82015-04-28 15:24:06 +05302510 *pos = gRatefromIdx[rateIdx]/5;
Katya Nigame7b69a82015-04-28 15:24:06 +05302511 pos++;
2512
2513 /* IEEE80211_RADIOTAP_CHANNEL */
2514 put_unaligned_le16(pMonCtx->ChannelNo, pos);
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302515 pos += 2;
2516 put_unaligned_le16(channel_flags, pos);
2517 pos += 2;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302518
2519 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
2520 *pos = currentRSSI;
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302521 pos++;
2522
2523 /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
2524 *pos = noise;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05302525 pos++;
Katya Nigame7b69a82015-04-28 15:24:06 +05302526
2527 if ((pos - (u8 *)rthdr) & 1)
2528 pos++;
2529 put_unaligned_le16(rx_flags, pos);
2530 pos += 2;
2531
2532 memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len);
2533}
2534
2535
2536VOS_STATUS hdd_rx_packet_monitor_cbk(v_VOID_t *vosContext,vos_pkt_t *pVosPacket, int conversion)
2537{
2538 struct sk_buff *skb = NULL;
2539 VOS_STATUS status = VOS_STATUS_E_FAILURE;
2540 hdd_adapter_t *pAdapter = NULL;
2541 hdd_context_t *pHddCtx = NULL;
2542 hdd_mon_ctx_t *pMonCtx = NULL;
2543 v_PVOID_t pvBDHeader = NULL;
2544 int rxstat;
2545 int needed_headroom = 0;
2546
2547
2548 //Sanity check on inputs
2549 if ( ( NULL == vosContext ) ||
2550 ( NULL == pVosPacket ) )
2551 {
2552 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2553 "%s: Null params being passed", __func__);
2554 return VOS_STATUS_E_FAILURE;
2555 }
2556
2557 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
Abhishek Singh2b055852015-10-07 14:14:13 +05302558
2559 if (NULL == pHddCtx)
2560 {
2561 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2562 FL("Failed to get pHddCtx from vosContext"));
2563 vos_pkt_return_packet( pVosPacket );
2564 return VOS_STATUS_E_FAILURE;
2565 }
2566
Katya Nigame7b69a82015-04-28 15:24:06 +05302567 pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
2568 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
2569 {
2570 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07002571 FL("Invalid adapter %pK for MONITOR MODE"), pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05302572 vos_pkt_return_packet( pVosPacket );
2573 return VOS_STATUS_E_FAILURE;
2574 }
2575
2576 status = WDA_DS_PeekRxPacketInfo( pVosPacket, (v_PVOID_t)&pvBDHeader, 1/*Swap BD*/ );
2577 if ( NULL == pvBDHeader )
2578 {
2579 VOS_TRACE( VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
2580 "Cannot extract BD header");
2581 /* Drop packet */
2582 vos_pkt_return_packet(pVosPacket);
2583 return VOS_STATUS_E_FAILURE;
2584 }
2585
2586 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
2587 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
2588 if(!VOS_IS_STATUS_SUCCESS( status ))
2589 {
2590 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
2591 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2592 "%s: Failure extracting skb from vos pkt", __func__);
2593 vos_pkt_return_packet( pVosPacket );
2594 return VOS_STATUS_E_FAILURE;
2595 }
2596
2597 if(!conversion)
2598 {
2599 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Sravan Kumar Kairam937935b2015-12-28 16:23:04 +05302600 needed_headroom = sizeof(struct ieee80211_radiotap_header) + 18;
Katya Nigame7b69a82015-04-28 15:24:06 +05302601 hdd_mon_add_rx_radiotap_hdr( skb, needed_headroom, pvBDHeader, pMonCtx );
2602 }
2603
2604 skb_reset_mac_header( skb );
2605 skb->dev = pAdapter->dev;
2606 skb->pkt_type = PACKET_OTHERHOST;
2607 skb->protocol = htons(ETH_P_802_2);
2608 skb->ip_summed = CHECKSUM_NONE;
2609 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
2610 ++pAdapter->stats.rx_packets;
2611 pAdapter->stats.rx_bytes += skb->len;
2612
2613 rxstat = netif_rx_ni(skb);
2614 if (NET_RX_SUCCESS == rxstat)
2615 {
2616 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
2617 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
2618 }
2619 else
2620 {
2621 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
2622 }
2623
2624 status = vos_pkt_return_packet( pVosPacket );
2625 if(!VOS_IS_STATUS_SUCCESS( status ))
2626 {
2627 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
2628 }
2629 pAdapter->dev->last_rx = jiffies;
2630
2631return status;
2632}
Jeff Johnson295189b2012-06-20 16:38:30 -07002633
Sravan Kumar Kairamf9f95122017-01-18 20:54:05 +05302634bool hdd_is_duplicate_ip_arp(struct sk_buff *skb)
2635{
2636 struct in_ifaddr **ifap = NULL;
2637 struct in_ifaddr *ifa = NULL;
2638 struct in_device *in_dev;
2639 uint32_t arp_ip,if_ip;
2640
2641 if (NULL == skb)
2642 return false;
2643
2644 arp_ip = hdd_get_arp_src_ip(skb);
2645
2646 if(!skb->dev) return false;
2647
2648 in_dev = __in_dev_get_rtnl(skb->dev);
2649
2650 if (in_dev) {
2651 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
2652 ifap = &ifa->ifa_next) {
2653 if (!strcmp(skb->dev->name, ifa->ifa_label))
2654 break;
2655 }
2656 }
2657 if (ifa && ifa->ifa_local) {
2658
2659 if_ip = ntohl(ifa->ifa_local);
2660 if (if_ip == arp_ip) {
2661 return true;
2662 }
2663 }
2664
2665 return false;
2666}
2667
Jeff Johnson295189b2012-06-20 16:38:30 -07002668/**============================================================================
2669 @brief hdd_rx_packet_cbk() - Receive callback registered with TL.
2670 TL will call this to notify the HDD when one or more packets were
2671 received for a registered STA.
2672
2673 @param vosContext : [in] pointer to VOS context
2674 @param pVosPacketChain : [in] pointer to VOS packet chain
2675 @param staId : [in] Station Id
2676 @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s)
2677
2678 @return : VOS_STATUS_E_FAILURE if any errors encountered,
2679 : VOS_STATUS_SUCCESS otherwise
2680 ===========================================================================*/
2681VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext,
2682 vos_pkt_t *pVosPacketChain,
2683 v_U8_t staId,
2684 WLANTL_RxMetaInfoType* pRxMetaInfo )
2685{
2686 hdd_adapter_t *pAdapter = NULL;
2687 hdd_context_t *pHddCtx = NULL;
2688 VOS_STATUS status = VOS_STATUS_E_FAILURE;
2689 int rxstat;
2690 struct sk_buff *skb = NULL;
2691 vos_pkt_t* pVosPacket;
2692 vos_pkt_t* pNextVosPacket;
c_manjee16126372017-01-16 19:29:30 +05302693 v_U8_t proto_type = 0;
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302694 v_BOOL_t arp_pkt;
Jeff Johnson295189b2012-06-20 16:38:30 -07002695
2696 //Sanity check on inputs
2697 if ( ( NULL == vosContext ) ||
2698 ( NULL == pVosPacketChain ) ||
2699 ( NULL == pRxMetaInfo ) )
2700 {
c_hpothu32490782014-03-14 19:14:34 +05302701 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302702 "%s: Null params being passed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002703 return VOS_STATUS_E_FAILURE;
2704 }
2705
Kiet Lam3c2ee302014-03-23 23:23:22 -07002706 pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
Jeff Johnson295189b2012-06-20 16:38:30 -07002707 if ( NULL == pHddCtx )
2708 {
c_hpothu32490782014-03-14 19:14:34 +05302709 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302710 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002711 return VOS_STATUS_E_FAILURE;
2712 }
2713
2714 pAdapter = pHddCtx->sta_to_adapter[staId];
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302715 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002716 {
Hanumantha Reddy Pothula4ba27c52015-03-12 14:31:10 +05302717 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07002718 FL("Invalid adapter %pK for staId %u"), pAdapter, staId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002719 return VOS_STATUS_E_FAILURE;
2720 }
2721
2722 ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
2723
2724 // walk the chain until all are processed
2725 pVosPacket = pVosPacketChain;
2726 do
2727 {
2728 // get the pointer to the next packet in the chain
2729 // (but don't unlink the packet since we free the entire chain later)
2730 status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);
2731
2732 // both "success" and "empty" are acceptable results
2733 if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
2734 {
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302735
2736 if(hdd_IsARP(pVosPacket))
2737 {
2738 ++pAdapter->hdd_stats.hddArpStats.rxDropped;
2739 pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_WALKING_PACKET_CHAIN;
2740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2741 "%s: ARP packet Drop: Failure walking packet chain", __func__);
2742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002743 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu32490782014-03-14 19:14:34 +05302744 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302745 "%s: Failure walking packet chain", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002746 return VOS_STATUS_E_FAILURE;
2747 }
2748
2749 // Extract the OS packet (skb).
Sushant Kaushikd43987b2015-06-05 12:18:34 +05302750 status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07002751 if(!VOS_IS_STATUS_SUCCESS( status ))
2752 {
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302753
2754 if(hdd_IsARP(pVosPacket))
2755 {
2756 ++pAdapter->hdd_stats.hddArpStats.rxDropped;
2757 pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_EXTRACTING_SKB_FROM_VOS_PKT;
2758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2759 "%s: ARP packet Dropped: Failure extracting skb from vos pkt",
2760 __func__);
2761 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002762 ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
c_hpothu32490782014-03-14 19:14:34 +05302763 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashish971c2882013-10-30 20:11:12 +05302764 "%s: Failure extracting skb from vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002765 return VOS_STATUS_E_FAILURE;
2766 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002767
Sushant Kaushikd43987b2015-06-05 12:18:34 +05302768 if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
2769 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
2770
2771 pVosPacket->pSkb = NULL;
2772
Jeff Johnsone7245742012-09-05 17:12:55 -07002773 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2774 {
c_hpothu32490782014-03-14 19:14:34 +05302775 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsone7245742012-09-05 17:12:55 -07002776 "Magic cookie(%x) for adapter sanity verification is invalid", pAdapter->magic);
2777 return eHAL_STATUS_FAILURE;
2778 }
2779
Chilam Ng1279e232013-01-25 15:06:52 -08002780#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002781 if ((eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) &&
2782 0 != pHddCtx->connected_peer_count)
Chilam Ng1279e232013-01-25 15:06:52 -08002783 {
2784 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
Chilam Ng1279e232013-01-25 15:06:52 -08002785 u8 mac[6];
2786
Ganesh Kondabattinif3ba0972015-08-07 15:58:04 +05302787 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -08002788
Hoonki Lee5fcc4582013-02-05 20:28:26 -08002789 if (vos_is_macaddr_group((v_MACADDR_t *)mac)) {
c_hpothu32490782014-03-14 19:14:34 +05302790 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Chilam Ng1279e232013-01-25 15:06:52 -08002791 "rx broadcast packet, not adding to peer list");
Ganesh Kondabattinif3ba0972015-08-07 15:58:04 +05302792 } else if ((memcmp(pHddStaCtx->conn_info.bssId,
2793 mac, 6) != 0) && (pRxMetaInfo->isStaTdls)) {
2794 wlan_hdd_tdls_update_rx_pkt_cnt_n_rssi(pAdapter, mac,
2795 pRxMetaInfo->rssiAvg);
Chilam Ng1279e232013-01-25 15:06:52 -08002796 } else {
c_hpothu32490782014-03-14 19:14:34 +05302797 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
Chilam Ng1279e232013-01-25 15:06:52 -08002798 "rx packet sa is bssid, not adding to peer list");
2799 }
2800 }
2801#endif
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002802 if (pHddCtx->cfg_ini->gEnableDebugLog)
2803 {
2804 proto_type = vos_pkt_get_proto_type(skb,
2805 pHddCtx->cfg_ini->gEnableDebugLog);
2806 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
2807 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah4b53d4b2015-05-08 05:35:00 -07002809 "STA RX EAPOL");
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002810 }
2811 else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
2812 {
Padma, Santhosh Kumar2d258f72014-12-22 19:55:59 +05302813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002814 "STA RX DHCP");
2815 }
Mihir Shete39f7c752015-06-11 15:40:09 +05302816 else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
2817 {
2818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2819 "STA RX ARP");
2820 }
Tushnim Bhattacharyyaa3ba5a52014-01-30 11:37:33 -08002821 }
2822
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302823 arp_pkt = vos_is_arp_pkt(skb, false);
2824
2825 if (arp_pkt)
2826 {
2827 ++pAdapter->hdd_stats.hddArpStats.rxCount;
2828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2829 "%s :STA RX ARP received",__func__);
2830 }
2831
Sravan Kumar Kairamd9ded562016-11-13 15:21:49 +05302832 if (pHddCtx->rx_wow_dump) {
2833 if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) &&
2834 !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type))
2835 hdd_log_ip_addr(skb);
2836 pHddCtx->rx_wow_dump = false;
2837 }
2838
Girish Gowli8a7bc042015-01-19 16:20:20 +05302839 if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
2840 {
2841 vos_record_roam_event(e_HDD_RX_PKT_CBK_TIME, (void *)skb, 0);
2842 }
Sachin Ahuja8c65f382014-12-12 15:34:21 +05302843 if (( NULL != pHddCtx ) &&
2844 (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
Dino Mycled9b7cc12014-09-04 18:43:07 +05302845 {
2846 hdd_dump_dhcp_pkt(skb, RX_PATH);
2847 }
Mukul Sharma84f27252014-07-14 18:11:42 +05302848
Jeff Johnson295189b2012-06-20 16:38:30 -07002849 skb->dev = pAdapter->dev;
2850 skb->protocol = eth_type_trans(skb, skb->dev);
Madan Mohan Koyyalamudif91902f2012-10-25 11:59:19 -07002851 skb->ip_summed = CHECKSUM_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002852 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
2853 ++pAdapter->stats.rx_packets;
2854 pAdapter->stats.rx_bytes += skb->len;
Sravan Kumar Kairamf9f95122017-01-18 20:54:05 +05302855
2856 if (arp_pkt)
2857 {
2858 pAdapter->dad = hdd_is_duplicate_ip_arp(skb);
2859 if(pAdapter->dad)
2860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2861 "%s :Duplicate IP detected",__func__);
2862 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002863#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Sushant Kaushik83392fa2015-05-05 17:44:40 +05302864 vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
2865 HDD_WAKE_LOCK_DURATION,
2866 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08002867#endif
Bhargav Shah15c8bfc2015-08-04 19:36:12 +05302868 if (pNextVosPacket)
2869 {
2870 rxstat = netif_rx(skb);
2871 }
2872 else
2873 {
2874 rxstat = netif_rx_ni(skb);
2875 }
2876
Jeff Johnson295189b2012-06-20 16:38:30 -07002877 if (NET_RX_SUCCESS == rxstat)
2878 {
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302879
2880 if (arp_pkt)
2881 {
2882 ++pAdapter->hdd_stats.hddArpStats.rxDelivered;
2883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2884 "STA RX ARP packet Delivered to net stack");
2885 }
2886
Jeff Johnson295189b2012-06-20 16:38:30 -07002887 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002888 ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07002889 }
2890 else
2891 {
Asodi T,Venkateswara Reddy9826c872017-01-18 19:08:25 +05302892
2893 if (arp_pkt)
2894 {
2895 ++pAdapter->hdd_stats.hddArpStats.rxRefused;
2896 pAdapter->hdd_stats.hddArpStats.reason = HDD_STA_RX_ARP_PACKET_REFUSED_IN_NET_STACK;
2897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2898 "%s :STA RX ARP packet Refused in net stack", __func__);
2899 }
2900
Jeff Johnson295189b2012-06-20 16:38:30 -07002901 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
2902 }
2903 // now process the next packet in the chain
2904 pVosPacket = pNextVosPacket;
2905
2906 } while (pVosPacket);
2907
2908 //Return the entire VOS packet chain to the resource pool
2909 status = vos_pkt_return_packet( pVosPacketChain );
2910 if(!VOS_IS_STATUS_SUCCESS( status ))
2911 {
c_hpothu32490782014-03-14 19:14:34 +05302912 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002913 }
2914
2915 pAdapter->dev->last_rx = jiffies;
2916
2917 return status;
2918}
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002919/**============================================================================
2920 @brief hdd_tx_rx_pkt_cnt_stat_timer_handler() -
2921 Enable/Disable split scan based on TX and RX traffic.
2922 @param HddContext : [in] pointer to Hdd context
2923 @return : None
2924 ===========================================================================*/
2925void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *phddctx)
2926{
2927 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2928 hdd_adapter_t *pAdapter = NULL;
2929 hdd_station_ctx_t *pHddStaCtx = NULL;
2930 hdd_context_t *pHddCtx = (hdd_context_t *)phddctx;
2931 hdd_config_t *cfg_param = pHddCtx->cfg_ini;
2932 VOS_STATUS status;
2933 v_U8_t staId = 0;
2934 v_U8_t fconnected = 0;
2935
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +05302936 ENTER();
2937 if (0 != (wlan_hdd_validate_context(pHddCtx)))
2938 {
2939 return;
2940 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002941 if (!cfg_param->dynSplitscan)
2942 {
c_hpothu32490782014-03-14 19:14:34 +05302943 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002944 "%s: Error : Dynamic split scan is not Enabled : %d",
2945 __func__, pHddCtx->cfg_ini->dynSplitscan);
2946 return;
2947 }
2948
2949 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2950 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2951 {
2952 pAdapter = pAdapterNode->pAdapter;
2953
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +05302954 if ((NULL != pAdapter) && (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002955 {
c_hpothu32490782014-03-14 19:14:34 +05302956 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002957 "%s: Adapter with device mode %d exists",
2958 __func__, pAdapter->device_mode);
2959
2960 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2961 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
2962 {
2963 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2964 if ((eConnectionState_Associated ==
2965 pHddStaCtx->conn_info.connState) &&
2966 (VOS_TRUE == pHddStaCtx->conn_info.uIsAuthenticated))
2967 {
2968 fconnected = TRUE;
2969 }
2970 }
2971 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
2972 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
2973 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302974 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
2975 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
2976 if(pSapCtx == NULL){
2977 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
2978 FL("psapCtx is NULL"));
2979 return;
2980 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002981 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
2982 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302983 if ((pSapCtx->aStaInfo[staId].isUsed) &&
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002984 (WLANTL_STA_AUTHENTICATED ==
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05302985 pSapCtx->aStaInfo[staId].tlSTAState))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002986 {
2987 fconnected = TRUE;
2988 }
2989 }
2990 }
2991 if ( fconnected )
2992 {
c_hpothu32490782014-03-14 19:14:34 +05302993 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07002994 "%s: One of the interface is connected check for scan",
2995 __func__);
c_hpothu32490782014-03-14 19:14:34 +05302996 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Abhishek Singh90485302014-05-15 16:36:57 +05302997 "%s: pkt_tx_count: %d, pkt_rx_count: %d "
2998 "miracast = %d", __func__,
2999 pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count,
3000 pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count,
3001 pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003002
3003 vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
3004 cfg_param->trafficMntrTmrForSplitScan);
3005 //Check for the previous statistics count
3006 if ((pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count >
3007 cfg_param->txRxThresholdForSplitScan) ||
3008 (pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count >
3009 cfg_param->txRxThresholdForSplitScan) ||
Dundi Ravitejaab9d3092018-04-05 18:24:40 +05303010 pHddCtx->drvr_miracast || pHddCtx->is_vowifi_enabled ||
Abhishek Singh90485302014-05-15 16:36:57 +05303011 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003012 {
3013 pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0;
3014 pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0;
3015
3016 if (!pHddCtx->issplitscan_enabled)
3017 {
3018 pHddCtx->issplitscan_enabled = TRUE;
3019 sme_enable_disable_split_scan(
3020 WLAN_HDD_GET_HAL_CTX(pAdapter),
3021 cfg_param->nNumStaChanCombinedConc,
3022 cfg_param->nNumP2PChanCombinedConc);
3023 }
3024 return;
3025 }
3026 else
3027 {
3028 pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0;
3029 pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0;
3030 }
3031 fconnected = FALSE;
3032 }
3033 }
3034 status = hdd_get_next_adapter( pHddCtx, pAdapterNode, &pNext);
3035 pAdapterNode = pNext;
3036 }
3037
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05303038 /* If TDLSScanCoexistence is enabled, then the TDLS module shall take care
3039 * of disabling the split scan and thus do not disable the same when the
3040 * low TXRX condition is met.
3041 */
3042 if ((pHddCtx->isTdlsScanCoexistence == FALSE) && (pHddCtx->issplitscan_enabled))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003043 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05303044 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003045 "%s: Disable split scan", __func__);
3046 pHddCtx->issplitscan_enabled = FALSE;
3047 sme_enable_disable_split_scan(
3048 pHddCtx->hHal,
3049 SME_DISABLE_SPLIT_SCAN,
3050 SME_DISABLE_SPLIT_SCAN);
3051 }
Mahesh A Saptasagar4534e2b2015-03-05 20:45:41 +05303052 EXIT();
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003053 return;
3054}
Jeff Johnson295189b2012-06-20 16:38:30 -07003055
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +05303056/**
3057 * hdd_rx_fwd_eapol() - forward cached eapol frames
3058 * @vosContext : pointer to vos global context
3059 * @pVosPacket: pointer to vos packet
3060 *
3061 * Return: None
3062 *
3063 */
3064void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket)
3065{
3066 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothulac43a5fc2018-03-12 14:02:32 +05303067 hdd_adapter_t * pAdapter = NULL;
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +05303068 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
3069 struct sk_buff *skb = NULL;
3070 uint8_t proto_type;
3071 uint8_t status;
3072
3073 if ((NULL == vosContext) || (NULL == pVosPacket))
3074 {
3075 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
3076 "%s: Null global context", __func__);
3077 return;
3078 }
3079
3080 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vosContext);
3081 if (NULL == pHddCtx)
3082 {
3083 VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
3084 "%s: HDD adapter context is Null", __func__);
3085 return;
3086 }
3087
3088 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
3089
3090 while ( NULL != pAdapterNode && 0 == status )
3091 {
3092 pAdapter = pAdapterNode->pAdapter;
3093
3094 if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3095 break;
3096
3097 status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
3098 pAdapterNode = pNext;
3099 }
3100
3101 if (NULL == pAdapter)
3102 {
3103 VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
3104 "%s: No adapter", __func__);
3105 return;
3106 }
3107
3108 vos_pkt_get_os_packet(pVosPacket, (v_VOID_t **)&skb, VOS_FALSE);
3109 proto_type = vos_pkt_get_proto_type(skb,
3110 pHddCtx->cfg_ini->gEnableDebugLog);
3111 if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
3112 {
3113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3114 "STA RX EAPOL");
3115 }
3116
3117 skb->dev = pAdapter->dev;
3118 skb->protocol = eth_type_trans(skb, skb->dev);
3119 skb->ip_summed = CHECKSUM_NONE;
3120
3121 netif_rx_ni(skb);
3122}
3123
Sushant Kaushika8073312015-05-04 17:33:52 +05303124#ifdef FEATURE_WLAN_DIAG_SUPPORT
3125/*
3126 * wlan_hdd_get_eapol_params() - Function to extract EAPOL params
3127 * @skb: skb data
3128 * @eapol_params: Pointer to hold the parsed EAPOL params
3129 * @event_type: Event type to indicate Tx/Rx
3130 *
3131 * This function parses the input skb data to get the EAPOL params,if the
3132 * packet is EAPOL and store it in the pointer passed as input
3133 *
3134 */
3135void wlan_hdd_get_eapol_params(struct sk_buff *skb,
3136 struct vos_event_wlan_eapol *eapol_params,
3137 uint8_t event_type)
3138{
3139 uint8_t packet_type=0;
3140
3141 packet_type = (uint8_t)(*(uint8_t *)
3142 (skb->data + HDD_EAPOL_PACKET_TYPE_OFFSET));
3143
3144 /* EAPOL msg type i.e. whether EAPOL-Start or
3145 * EAPOL-Key etc. messages Present at 15 offset.
3146 */
3147 eapol_params->eapol_packet_type = packet_type;
3148
3149 /* This tells if its a M1/M2/M3/M4 packet.
3150 * Present at 19th offset in EAPOL frame.
3151 */
3152 eapol_params->eapol_key_info = (uint16_t)(*(uint16_t *)
3153 (skb->data + HDD_EAPOL_KEY_INFO_OFFSET));
3154 /* This tells if EAPOL packet is in RX or TX
3155 * direction.
3156 */
3157 eapol_params->event_sub_type = event_type;
3158
3159 /* This tells the rate at which EAPOL packet
3160 * is send or received.
3161 */
3162 //TODO fill data rate for rx packet.
3163 eapol_params->eapol_rate = 0;/* As of now, zero */
3164
3165 vos_mem_copy(eapol_params->dest_addr,
3166 (skb->data + HDD_EAPOL_DEST_MAC_OFFSET),
3167 sizeof(eapol_params->dest_addr));
3168 vos_mem_copy(eapol_params->src_addr,
3169 (skb->data + HDD_EAPOL_SRC_MAC_OFFSET),
3170 sizeof(eapol_params->src_addr));
3171 return;
3172}
3173/*
3174 * wlan_hdd_event_eapol_log() - Function to log EAPOL events
3175 * @eapol_params: Structure containing EAPOL params
3176 *
3177 * This function logs the parsed EAPOL params
3178 *
3179 * Return: None
3180 *
3181 */
3182
3183static void wlan_hdd_event_eapol_log(struct vos_event_wlan_eapol eapol_params)
3184{
3185 WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event, struct vos_event_wlan_eapol);
3186
3187 wlan_diag_event.event_sub_type = eapol_params.event_sub_type;
3188 wlan_diag_event.eapol_packet_type = eapol_params.eapol_packet_type;
3189 wlan_diag_event.eapol_key_info = eapol_params.eapol_key_info;
3190 wlan_diag_event.eapol_rate = eapol_params.eapol_rate;
3191 vos_mem_copy(wlan_diag_event.dest_addr,
3192 eapol_params.dest_addr,
3193 sizeof (wlan_diag_event.dest_addr));
3194 vos_mem_copy(wlan_diag_event.src_addr,
3195 eapol_params.src_addr,
3196 sizeof (wlan_diag_event.src_addr));
3197 WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL);
3198}
3199
3200/*
3201 * wlan_hdd_log_eapol() - Function to check and extract EAPOL params
3202 * @skb: skb data
3203 * @event_type: One of enum wifi_connectivity_events to indicate Tx/Rx
3204 *
3205 * This function parses the input skb data to get the EAPOL params,if the
3206 * packet is EAPOL and store it in the pointer passed as input
3207 *
3208 * Return: None
3209 *
3210 */
3211void wlan_hdd_log_eapol(struct sk_buff *skb,
3212 uint8_t event_type)
3213{
3214 struct vos_event_wlan_eapol eapol_params;
3215
3216 wlan_hdd_get_eapol_params(skb, &eapol_params, event_type);
3217 wlan_hdd_event_eapol_log(eapol_params);
Sushant Kaushik9811d8a2015-10-07 15:56:26 +05303218
3219 if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M1_BIT_MASK)
3220 {
3221 hddLog(LOG1, FL("%s: M1 packet"),eapol_params.event_sub_type ==
3222 WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");
3223 }
3224 else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M2_BIT_MASK)
3225 {
3226 hddLog(LOG1, FL("%s: M2 packet"),eapol_params.event_sub_type ==
3227 WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");
3228
3229 }
3230
3231 else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M3_BIT_MASK)
3232 {
3233 hddLog(LOG1, FL("%s: M3 packet"),eapol_params.event_sub_type ==
3234 WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");
3235 }
3236
3237 else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M4_BIT_MASK)
3238 {
3239 hddLog(LOG1, FL("%s: M4 packet"),eapol_params.event_sub_type ==
3240 WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");
3241
3242 }
3243
Sushant Kaushika8073312015-05-04 17:33:52 +05303244}
3245#endif /* FEATURE_WLAN_DIAG_SUPPORT */