blob: f592adb932a9c339a907b876315cbf06865e4f08 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Jeff Johnson4fca3b52017-01-12 08:44:18 -08002 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
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 Johnsond5bd6fd2016-12-05 12:29:21 -080028/* denote that this file does not allow legacy hddLog */
29#define HDD_DISALLOW_LEGACY_HDDLOG 1
30
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080031/* Include files */
32#include <linux/semaphore.h>
33#include <wlan_hdd_tx_rx.h>
34#include <wlan_hdd_softap_tx_rx.h>
35#include <linux/netdevice.h>
36#include <linux/skbuff.h>
37#include <linux/etherdevice.h>
Anurag Chouhan6d760662016-02-20 16:05:43 +053038#include <qdf_types.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080039#include <ani_global.h>
Anurag Chouhan6d760662016-02-20 16:05:43 +053040#include <qdf_types.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080041#include <net/ieee80211_radiotap.h>
42#include <cds_sched.h>
43#include <wlan_hdd_napi.h>
Leo Changfdb45c32016-10-28 11:09:23 -070044#include <cdp_txrx_cmn.h>
Dhanashri Atreb08959a2016-03-01 17:28:03 -080045#include <cdp_txrx_peer_ops.h>
Manjunathappa Prakash779e4862016-09-12 17:00:11 -070046#include <cds_utils.h>
Leo Changfdb45c32016-10-28 11:09:23 -070047#include <cdp_txrx_flow_ctrl_v2.h>
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080048#include <cdp_txrx_handle.h>
Abhishek Singh07c627e2017-03-20 17:56:34 +053049#include <wlan_hdd_object_manager.h>
Rachit Kankane2487f8f2017-04-19 14:30:19 +053050#include "wlan_p2p_ucfg_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051#ifdef IPA_OFFLOAD
52#include <wlan_hdd_ipa.h>
53#endif
54
55/* Preprocessor definitions and constants */
56#undef QCA_HDD_SAP_DUMP_SK_BUFF
57
58/* Type declarations */
59
60/* Function definitions and documenation */
61#ifdef QCA_HDD_SAP_DUMP_SK_BUFF
62/**
63 * hdd_softap_dump_sk_buff() - Dump an skb
64 * @skb: skb to dump
65 *
66 * Return: None
67 */
68static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
69{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053070 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080071 "%s: head = %p ", __func__, skb->head);
Srinivas Girigowdae806a822017-03-25 11:25:30 -070072 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073 "%s: tail = %p ", __func__, skb->tail);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053074 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075 "%s: end = %p ", __func__, skb->end);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053076 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077 "%s: len = %d ", __func__, skb->len);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053078 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079 "%s: data_len = %d ", __func__, skb->data_len);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053080 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081 "%s: mac_len = %d", __func__, skb->mac_len);
82
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053083 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ", skb->data[0],
85 skb->data[1], skb->data[2], skb->data[3], skb->data[4],
86 skb->data[5], skb->data[6], skb->data[7]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053087 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", skb->data[8],
89 skb->data[9], skb->data[10], skb->data[11], skb->data[12],
90 skb->data[13], skb->data[14], skb->data[15]);
91}
92#else
93static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
94{
95}
96#endif
97
98#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
99/**
100 * hdd_softap_tx_resume_timer_expired_handler() - TX Q resume timer handler
101 * @adapter_context: pointer to vdev adapter
102 *
103 * TX Q resume timer handler for SAP and P2P GO interface. If Blocked
104 * OS Q is not resumed during timeout period, to prevent permanent
105 * stall, resume OS Q forcefully for SAP and P2P GO interface.
106 *
107 * Return: None
108 */
109void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context)
110{
111 hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;
112
113 if (!pAdapter) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800114 hdd_err("NULL adapter");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 return;
116 }
117
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700118 hdd_debug("Enabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800119 wlan_hdd_netif_queue_control(pAdapter, WLAN_WAKE_ALL_NETIF_QUEUE,
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800120 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800121}
122
Poddar, Siddarthb61cf642016-04-28 16:02:39 +0530123#if defined(CONFIG_PER_VDEV_TX_DESC_POOL)
124
125/**
126 * hdd_softap_tx_resume_false() - Resume OS TX Q false leads to queue disabling
127 * @pAdapter: pointer to hdd adapter
128 * @tx_resume: TX Q resume trigger
129 *
130 *
131 * Return: None
132 */
133static void
134hdd_softap_tx_resume_false(hdd_adapter_t *pAdapter, bool tx_resume)
135{
136 if (true == tx_resume)
137 return;
138
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700139 hdd_debug("Disabling queues");
Poddar, Siddarthb61cf642016-04-28 16:02:39 +0530140 wlan_hdd_netif_queue_control(pAdapter, WLAN_STOP_ALL_NETIF_QUEUE,
141 WLAN_DATA_FLOW_CONTROL);
142
143 if (QDF_TIMER_STATE_STOPPED ==
144 qdf_mc_timer_get_current_state(&pAdapter->
145 tx_flow_control_timer)) {
146 QDF_STATUS status;
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700147
Poddar, Siddarthb61cf642016-04-28 16:02:39 +0530148 status = qdf_mc_timer_start(&pAdapter->tx_flow_control_timer,
149 WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
150
151 if (!QDF_IS_STATUS_SUCCESS(status))
152 hdd_err("Failed to start tx_flow_control_timer");
153 else
154 pAdapter->hdd_stats.hddTxRxStats.txflow_timer_cnt++;
155 }
Poddar, Siddarthb61cf642016-04-28 16:02:39 +0530156}
157#else
158
159static inline void
160hdd_softap_tx_resume_false(hdd_adapter_t *pAdapter, bool tx_resume)
161{
Poddar, Siddarthb61cf642016-04-28 16:02:39 +0530162}
163#endif
164
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800165/**
166 * hdd_softap_tx_resume_cb() - Resume OS TX Q.
167 * @adapter_context: pointer to vdev apdapter
168 * @tx_resume: TX Q resume trigger
169 *
170 * Q was stopped due to WLAN TX path low resource condition
171 *
172 * Return: None
173 */
174void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume)
175{
176 hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;
177
178 if (!pAdapter) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800179 hdd_err("NULL adapter");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800180 return;
181 }
182
183 /* Resume TX */
184 if (true == tx_resume) {
Anurag Chouhan210db072016-02-22 18:42:15 +0530185 if (QDF_TIMER_STATE_STOPPED !=
186 qdf_mc_timer_get_current_state(&pAdapter->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800187 tx_flow_control_timer)) {
Anurag Chouhan210db072016-02-22 18:42:15 +0530188 qdf_mc_timer_stop(&pAdapter->tx_flow_control_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189 }
190
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700191 hdd_debug("Enabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800192 wlan_hdd_netif_queue_control(pAdapter,
193 WLAN_WAKE_ALL_NETIF_QUEUE,
194 WLAN_DATA_FLOW_CONTROL);
195 }
Poddar, Siddarthb61cf642016-04-28 16:02:39 +0530196 hdd_softap_tx_resume_false(pAdapter, tx_resume);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800197}
gbianec670c592016-11-24 11:21:30 +0800198
199static inline struct sk_buff *hdd_skb_orphan(hdd_adapter_t *pAdapter,
200 struct sk_buff *skb)
201{
202 if (pAdapter->tx_flow_low_watermark > 0)
203 skb_orphan(skb);
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700204 else
gbianec670c592016-11-24 11:21:30 +0800205 skb = skb_unshare(skb, GFP_ATOMIC);
gbianec670c592016-11-24 11:21:30 +0800206
207 return skb;
208}
209
210#else
Mohit Khannad0b63f52017-02-18 18:05:52 -0800211/**
212 * hdd_skb_orphan() - skb_unshare a cloned packed else skb_orphan
213 * @pAdapter: pointer to HDD adapter
214 * @skb: pointer to skb data packet
215 *
216 * Return: pointer to skb structure
217 */
Mohit Khannaebf4ca32017-03-14 22:02:35 -0700218static inline struct sk_buff *hdd_skb_orphan(hdd_adapter_t *pAdapter,
Mohit Khannad0b63f52017-02-18 18:05:52 -0800219 struct sk_buff *skb) {
gbianec670c592016-11-24 11:21:30 +0800220
Mohit Khannad0b63f52017-02-18 18:05:52 -0800221 struct sk_buff *nskb;
Manjunathappa Prakashdab74fa2017-06-19 12:11:03 -0700222 hdd_context_t *hdd_ctx = pAdapter->pHddCtx;
Mohit Khannad0b63f52017-02-18 18:05:52 -0800223
Manjunathappa Prakashdab74fa2017-06-19 12:11:03 -0700224 nskb = skb_unshare(skb, GFP_ATOMIC);
225 if (unlikely(hdd_ctx->config->tx_orphan_enable) && (nskb == skb)) {
Mohit Khannad0b63f52017-02-18 18:05:52 -0800226 /*
227 * For UDP packets we want to orphan the packet to allow the app
228 * to send more packets. The flow would ultimately be controlled
229 * by the limited number of tx descriptors for the vdev.
230 */
231 ++pAdapter->hdd_stats.hddTxRxStats.txXmitOrphaned;
232 skb_orphan(skb);
233 }
234 return nskb;
gbianec670c592016-11-24 11:21:30 +0800235}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800236#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
237
238/**
Mukul Sharmac4de4ef2016-09-12 15:39:00 +0530239 * __hdd_softap_hard_start_xmit() - Transmit a frame
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800240 * @skb: pointer to OS packet (sk_buff)
241 * @dev: pointer to network device
242 *
243 * Function registered with the Linux OS for transmitting
244 * packets. This version of the function directly passes
245 * the packet to Transport Layer.
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530246 * In case of any packet drop or error, log the error with
247 * INFO HIGH/LOW/MEDIUM to avoid excessive logging in kmsg.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800248 *
249 * Return: Always returns NETDEV_TX_OK
250 */
Jeff Johnson6376abe2016-10-05 16:24:56 -0700251static int __hdd_softap_hard_start_xmit(struct sk_buff *skb,
252 struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800253{
254 sme_ac_enum_type ac = SME_AC_BE;
255 hdd_adapter_t *pAdapter = (hdd_adapter_t *) netdev_priv(dev);
256 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530257 struct qdf_mac_addr *pDestMacAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800258 uint8_t STAId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800259
260 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
261 /* Prevent this function from being called during SSR since TL
262 * context may not be reinitialized at this time which may
263 * lead to a crash.
264 */
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530265 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530266 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800267 "%s: Recovery in Progress. Ignore!!!", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800268 goto drop_pkt;
269 }
270
271 /*
272 * If the device is operating on a DFS Channel
273 * then check if SAP is in CAC WAIT state and
274 * drop the packets. In CAC WAIT state device
275 * is expected not to transmit any frames.
276 * SAP starts Tx only after the BSS START is
277 * done.
278 */
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700279 if (pHddApCtx->dfs_cac_block_tx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800280 goto drop_pkt;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800281
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800282 /*
Jeff Johnson4fca3b52017-01-12 08:44:18 -0800283 * If a transmit function is not registered, drop packet
284 */
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800285 if (!pAdapter->tx_fn) {
286 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
287 "%s: TX function not registered by the data path",
288 __func__);
289 goto drop_pkt;
290 }
291
Nirav Shah5e74bb82016-07-20 16:01:27 +0530292 wlan_hdd_classify_pkt(skb);
293
Anurag Chouhan6d760662016-02-20 16:05:43 +0530294 pDestMacAddress = (struct qdf_mac_addr *) skb->data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295
Nirav Shah5e74bb82016-07-20 16:01:27 +0530296 if (QDF_NBUF_CB_GET_IS_BCAST(skb) ||
297 QDF_NBUF_CB_GET_IS_MCAST(skb)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298 /* The BC/MC station ID is assigned during BSS
299 * starting phase. SAP will return the station ID
300 * used for BC/MC traffic.
301 */
302 STAId = pHddApCtx->uBCStaId;
303 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530304 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305 hdd_softap_get_sta_id(pAdapter,
306 pDestMacAddress, &STAId)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530307 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530308 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309 "%s: Failed to find right station", __func__);
310 goto drop_pkt;
311 }
312
Prakash Dhavali3107b752016-11-28 14:35:06 +0530313 if (STAId >= WLAN_MAX_STA_COUNT) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530314 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530315 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800316 "%s: Failed to find right station", __func__);
317 goto drop_pkt;
318 } else if (false == pAdapter->aStaInfo[STAId].isUsed) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530319 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530320 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800321 "%s: STA %d is unregistered", __func__,
322 STAId);
323 goto drop_pkt;
Poddar, Siddartha5075462017-03-16 19:20:09 +0530324 } else if (true == pAdapter->aStaInfo[STAId].
325 isDeauthInProgress) {
326 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530327 QDF_TRACE_LEVEL_INFO_HIGH,
Poddar, Siddartha5075462017-03-16 19:20:09 +0530328 "%s: STA %d deauth in progress", __func__,
329 STAId);
330 goto drop_pkt;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331 }
332
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800333 if ((OL_TXRX_PEER_STATE_CONN !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800334 pAdapter->aStaInfo[STAId].tlSTAState)
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800335 && (OL_TXRX_PEER_STATE_AUTH !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336 pAdapter->aStaInfo[STAId].tlSTAState)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530337 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530338 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800339 "%s: Station not connected yet", __func__);
340 goto drop_pkt;
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800341 } else if (OL_TXRX_PEER_STATE_CONN ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800342 pAdapter->aStaInfo[STAId].tlSTAState) {
343 if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530344 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530345 QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346 "%s: NON-EAPOL packet in non-Authenticated state",
347 __func__);
348 goto drop_pkt;
349 }
350 }
351 }
352
353 hdd_get_tx_resource(pAdapter, STAId,
354 WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
355
356 /* Get TL AC corresponding to Qdisc queue index/AC. */
357 ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];
358 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
359
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700360#if defined(IPA_OFFLOAD)
Nirav Shahcbc6d722016-03-01 16:24:53 +0530361 if (!qdf_nbuf_ipa_owned_get(skb)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362#endif
gbianec670c592016-11-24 11:21:30 +0800363
364#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 19, 0))
365 /*
Jeff Johnson4fca3b52017-01-12 08:44:18 -0800366 * The TCP TX throttling logic is changed a little after
367 * 3.19-rc1 kernel, the TCP sending limit will be smaller,
368 * which will throttle the TCP packets to the host driver.
369 * The TCP UP LINK throughput will drop heavily. In order to
370 * fix this issue, need to orphan the socket buffer asap, which
371 * will call skb's destructor to notify the TCP stack that the
372 * SKB buffer is unowned. And then the TCP stack will pump more
373 * packets to host driver.
374 *
375 * The TX packets might be dropped for UDP case in the iperf
376 * testing. So need to be protected by follow control.
377 */
gbianec670c592016-11-24 11:21:30 +0800378 skb = hdd_skb_orphan(pAdapter, skb);
379#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380 /* Check if the buffer has enough header room */
381 skb = skb_unshare(skb, GFP_ATOMIC);
gbianec670c592016-11-24 11:21:30 +0800382#endif
383
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 if (!skb)
Jeff Johnsonedeff232015-11-11 17:19:42 -0800385 goto drop_pkt_accounting;
gbianec670c592016-11-24 11:21:30 +0800386
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700387#if defined(IPA_OFFLOAD)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388 }
389#endif
390
Himanshu Agarwal53298d12017-02-20 19:14:17 +0530391 /*
392 * Add SKB to internal tracking table before further processing
393 * in WLAN driver.
394 */
395 qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
396
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800397 pAdapter->stats.tx_bytes += skb->len;
Mohit Khannab1dd1e82017-02-04 15:14:38 -0800398
399 if (qdf_nbuf_is_tso(skb))
400 pAdapter->stats.tx_packets += qdf_nbuf_get_tso_num_seg(skb);
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700401 else
Mohit Khannab1dd1e82017-02-04 15:14:38 -0800402 ++pAdapter->stats.tx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403
Nirav Shah5e74bb82016-07-20 16:01:27 +0530404 hdd_event_eapol_log(skb, QDF_TX);
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700405 qdf_dp_trace_log_pkt(pAdapter->sessionId, skb, QDF_TX,
406 QDF_TRACE_DEFAULT_PDEV_ID);
Nirav Shahcbc6d722016-03-01 16:24:53 +0530407 QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
408 QDF_NBUF_UPDATE_TX_PKT_COUNT(skb, QDF_NBUF_TX_PKT_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409
Nirav Shah0d58a7e2016-04-26 22:54:12 +0530410 qdf_dp_trace_set_track(skb, QDF_TX);
411 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700412 QDF_TRACE_DEFAULT_PDEV_ID, qdf_nbuf_data_addr(skb),
413 sizeof(qdf_nbuf_data(skb)),
Himanshu Agarwalee3411a2017-01-31 12:56:47 +0530414 QDF_TX));
Nirav Shah0d58a7e2016-04-26 22:54:12 +0530415 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_TX_PACKET_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700416 QDF_TRACE_DEFAULT_PDEV_ID, (uint8_t *)skb->data,
417 qdf_nbuf_len(skb), QDF_TX));
Nirav Shahcbc6d722016-03-01 16:24:53 +0530418 if (qdf_nbuf_len(skb) > QDF_DP_TRACE_RECORD_SIZE)
Nirav Shah0d58a7e2016-04-26 22:54:12 +0530419 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_TX_PACKET_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700420 QDF_TRACE_DEFAULT_PDEV_ID,
Nirav Shah0d58a7e2016-04-26 22:54:12 +0530421 (uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
422 (qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE), QDF_TX));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423
Leo Changfdb45c32016-10-28 11:09:23 -0700424 if (pAdapter->tx_fn(pAdapter->txrx_vdev,
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800425 (qdf_nbuf_t) skb) != NULL) {
Poddar, Siddarth31b9b8b2017-04-07 12:04:55 +0530426 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 "%s: Failed to send packet to txrx for staid:%d",
428 __func__, STAId);
429 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
Himanshu Agarwal53298d12017-02-20 19:14:17 +0530430 goto drop_pkt_and_release_skb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 }
Dustin Browne0024fa2016-10-14 16:29:21 -0700432 netif_trans_update(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800433
434 return NETDEV_TX_OK;
435
Himanshu Agarwal53298d12017-02-20 19:14:17 +0530436drop_pkt_and_release_skb:
437 qdf_net_buf_debug_release_skb(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800438drop_pkt:
439
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530440 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_DROP_PACKET_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700441 QDF_TRACE_DEFAULT_PDEV_ID, (uint8_t *)skb->data,
442 qdf_nbuf_len(skb), QDF_TX));
Nirav Shahcbc6d722016-03-01 16:24:53 +0530443 if (qdf_nbuf_len(skb) > QDF_DP_TRACE_RECORD_SIZE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530444 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_DROP_PACKET_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700445 QDF_TRACE_DEFAULT_PDEV_ID,
Nirav Shah0d58a7e2016-04-26 22:54:12 +0530446 (uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
447 (qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE), QDF_TX));
Jeff Johnsonedeff232015-11-11 17:19:42 -0800448 kfree_skb(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449
Jeff Johnsonedeff232015-11-11 17:19:42 -0800450drop_pkt_accounting:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 ++pAdapter->stats.tx_dropped;
452 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453
454 return NETDEV_TX_OK;
455}
456
457/**
Mukul Sharmac4de4ef2016-09-12 15:39:00 +0530458 * hdd_softap_hard_start_xmit() - Wrapper function to protect
459 * __hdd_softap_hard_start_xmit from SSR
460 * @skb: pointer to OS packet
461 * @dev: pointer to net_device structure
462 *
463 * Function called by OS if any packet needs to transmit.
464 *
465 * Return: Always returns NETDEV_TX_OK
466 */
467int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
468{
469 int ret;
470
471 cds_ssr_protect(__func__);
472 ret = __hdd_softap_hard_start_xmit(skb, dev);
473 cds_ssr_unprotect(__func__);
474
475 return ret;
476}
477
Sen, Devendra154b3c42017-02-13 20:44:15 +0530478#ifdef FEATURE_WLAN_DIAG_SUPPORT
479/**
480 * hdd_wlan_datastall_sap_event()- Send SAP datastall information
481 *
482 * This Function send send SAP datastall diag event
483 *
484 * Return: void.
485 */
486static void hdd_wlan_datastall_sap_event(void)
487{
488 WLAN_HOST_DIAG_EVENT_DEF(sap_data_stall,
489 struct host_event_wlan_datastall);
490 qdf_mem_zero(&sap_data_stall, sizeof(sap_data_stall));
491 sap_data_stall.reason = SOFTAP_TX_TIMEOUT;
492 WLAN_HOST_DIAG_EVENT_REPORT(&sap_data_stall,
493 EVENT_WLAN_SOFTAP_DATASTALL);
494}
495#else
496static inline void hdd_wlan_datastall_sap_event(void)
497{
498
499}
500#endif
501
Mukul Sharmac4de4ef2016-09-12 15:39:00 +0530502/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800503 * __hdd_softap_tx_timeout() - TX timeout handler
504 * @dev: pointer to network device
505 *
506 * This function is registered as a netdev ndo_tx_timeout method, and
507 * is invoked by the kernel if the driver takes too long to transmit a
508 * frame.
509 *
510 * Return: None
511 */
512static void __hdd_softap_tx_timeout(struct net_device *dev)
513{
514 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
515 hdd_context_t *hdd_ctx;
Nirav Shah89223f72016-03-01 18:10:38 +0530516 struct netdev_queue *txq;
517 int i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530519 DPTRACE(qdf_dp_trace(NULL, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700520 QDF_TRACE_DEFAULT_PDEV_ID,
521 NULL, 0, QDF_TX));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522 /* Getting here implies we disabled the TX queues for too
523 * long. Queues are disabled either because of disassociation
524 * or low resource scenarios. In case of disassociation it is
525 * ok to ignore this. But if associated, we have do possible
526 * recovery here
527 */
528 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +0530529 if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530530 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800531 "%s: Recovery in Progress. Ignore!!!", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532 return;
533 }
Nirav Shah89223f72016-03-01 18:10:38 +0530534
Dustin Browne0024fa2016-10-14 16:29:21 -0700535 TX_TIMEOUT_TRACE(dev, QDF_MODULE_ID_HDD_SAP_DATA);
Nirav Shah89223f72016-03-01 18:10:38 +0530536
537 for (i = 0; i < NUM_TX_QUEUES; i++) {
538 txq = netdev_get_tx_queue(dev, i);
539 QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
Srinivas Girigowda028c4482017-03-09 18:52:02 -0800540 QDF_TRACE_LEVEL_DEBUG,
541 "Queue: %d status: %d txq->trans_start: %lu",
Nirav Shah89223f72016-03-01 18:10:38 +0530542 i, netif_tx_queue_stopped(txq), txq->trans_start);
543 }
544
545 wlan_hdd_display_netif_queue_history(hdd_ctx);
Leo Changfdb45c32016-10-28 11:09:23 -0700546 cdp_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC));
Srinivas Girigowda028c4482017-03-09 18:52:02 -0800547 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Nirav Shah89223f72016-03-01 18:10:38 +0530548 "carrier state: %d", netif_carrier_ok(dev));
Sen, Devendra154b3c42017-02-13 20:44:15 +0530549 hdd_wlan_datastall_sap_event();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800550}
551
552/**
553 * hdd_softap_tx_timeout() - SSR wrapper for __hdd_softap_tx_timeout
554 * @dev: pointer to net_device
555 *
556 * Return: none
557 */
558void hdd_softap_tx_timeout(struct net_device *dev)
559{
560 cds_ssr_protect(__func__);
561 __hdd_softap_tx_timeout(dev);
562 cds_ssr_unprotect(__func__);
563}
564
565/**
566 * @hdd_softap_init_tx_rx() - Initialize Tx/RX module
567 * @pAdapter: pointer to adapter context
568 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530569 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
570 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530572QDF_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800573{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530574 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800575
576 uint8_t STAId = 0;
577
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530578 qdf_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579
580 spin_lock_init(&pAdapter->staInfo_lock);
581
582 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530583 qdf_mem_zero(&pAdapter->aStaInfo[STAId],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 sizeof(hdd_station_info_t));
585 }
586
587 return status;
588}
589
590/**
591 * @hdd_softap_deinit_tx_rx() - Deinitialize Tx/RX module
592 * @pAdapter: pointer to adapter context
593 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530594 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
595 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530597QDF_STATUS hdd_softap_deinit_tx_rx(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598{
Dhanashri Atreed3bf512017-02-21 12:25:53 -0800599 if (pAdapter == NULL) {
600 hdd_err("Called with pAdapter = NULL.");
601 return QDF_STATUS_E_FAILURE;
602 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800603
Dhanashri Atreed3bf512017-02-21 12:25:53 -0800604 pAdapter->txrx_vdev = NULL;
605 pAdapter->tx_fn = NULL;
606 hdd_info("Deregistering TX function hook !");
607 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608}
609
610/**
611 * hdd_softap_init_tx_rx_sta() - Initialize tx/rx for a softap station
612 * @pAdapter: pointer to adapter context
613 * @STAId: Station ID to initialize
614 * @pmacAddrSTA: pointer to the MAC address of the station
615 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530616 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
617 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530619QDF_STATUS hdd_softap_init_tx_rx_sta(hdd_adapter_t *pAdapter, uint8_t STAId,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530620 struct qdf_mac_addr *pmacAddrSTA)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621{
622 spin_lock_bh(&pAdapter->staInfo_lock);
623 if (pAdapter->aStaInfo[STAId].isUsed) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624 spin_unlock_bh(&pAdapter->staInfo_lock);
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800625 hdd_err("Reinit of in use station %d", STAId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530626 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800627 }
628
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530629 qdf_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630
631 pAdapter->aStaInfo[STAId].isUsed = true;
632 pAdapter->aStaInfo[STAId].isDeauthInProgress = false;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530633 qdf_copy_macaddr(&pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800634
635 spin_unlock_bh(&pAdapter->staInfo_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530636 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800637}
638
639/**
640 * hdd_softap_deinit_tx_rx_sta() - Deinitialize tx/rx for a softap station
641 * @pAdapter: pointer to adapter context
642 * @STAId: Station ID to deinitialize
643 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530644 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
645 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530647QDF_STATUS hdd_softap_deinit_tx_rx_sta(hdd_adapter_t *pAdapter, uint8_t STAId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800648{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530649 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650 hdd_hostapd_state_t *pHostapdState;
651
652 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
653
654 spin_lock_bh(&pAdapter->staInfo_lock);
655
656 if (false == pAdapter->aStaInfo[STAId].isUsed) {
657 spin_unlock_bh(&pAdapter->staInfo_lock);
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800658 hdd_err("Deinit station not inited %d", STAId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530659 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800660 }
661
662 pAdapter->aStaInfo[STAId].isUsed = false;
663 pAdapter->aStaInfo[STAId].isDeauthInProgress = false;
664
665 spin_unlock_bh(&pAdapter->staInfo_lock);
666 return status;
667}
668
669/**
670 * hdd_softap_rx_packet_cbk() - Receive packet handler
Dhanashri Atre182b0272016-02-17 15:35:07 -0800671 * @context: pointer to HDD context
Nirav Shahcbc6d722016-03-01 16:24:53 +0530672 * @rxBuf: pointer to rx qdf_nbuf
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800673 *
674 * Receive callback registered with TL. TL will call this to notify
675 * the HDD when one or more packets were received for a registered
676 * STA.
677 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530678 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
679 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800680 */
Dhanashri Atre182b0272016-02-17 15:35:07 -0800681QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682{
683 hdd_adapter_t *pAdapter = NULL;
684 int rxstat;
685 unsigned int cpu_index;
686 struct sk_buff *skb = NULL;
Dhanashri Atrecefa8802017-02-02 16:17:14 -0800687 struct sk_buff *next = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800688 hdd_context_t *pHddCtx = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800689
690 /* Sanity check on inputs */
Dhanashri Atre182b0272016-02-17 15:35:07 -0800691 if (unlikely((NULL == context) || (NULL == rxBuf))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530692 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 "%s: Null params being passed", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530694 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695 }
696
Dhanashri Atre182b0272016-02-17 15:35:07 -0800697 pAdapter = (hdd_adapter_t *)context;
698 if (unlikely(WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
Srinivas Girigowda028c4482017-03-09 18:52:02 -0800699 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
Dhanashri Atre182b0272016-02-17 15:35:07 -0800700 "Magic cookie(%x) for adapter sanity verification is invalid",
701 pAdapter->magic);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530702 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800703 }
704
Dhanashri Atre182b0272016-02-17 15:35:07 -0800705 pHddCtx = pAdapter->pHddCtx;
706 if (unlikely(NULL == pHddCtx)) {
707 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
708 "%s: HDD context is Null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530709 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800710 }
711
712 /* walk the chain until all are processed */
Dhanashri Atrecefa8802017-02-02 16:17:14 -0800713 next = (struct sk_buff *)rxBuf;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800714
Dhanashri Atrecefa8802017-02-02 16:17:14 -0800715 while (next) {
716 skb = next;
717 next = skb->next;
Dhanashri Atre63d98022017-01-24 18:22:09 -0800718 skb->next = NULL;
Dhanashri Atrecefa8802017-02-02 16:17:14 -0800719
720#ifdef QCA_WIFI_NAPIER_EMULATION /* Debug code, remove later */
Venkata Sharath Chandra Manchalacc789172017-07-25 23:28:45 -0700721 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO,
Dhanashri Atrecefa8802017-02-02 16:17:14 -0800722 "%s: skb %p skb->len %d\n", __func__, skb, skb->len);
723#endif
724
Dhanashri Atre63d98022017-01-24 18:22:09 -0800725 hdd_softap_dump_sk_buff(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800726
Dhanashri Atre63d98022017-01-24 18:22:09 -0800727 skb->dev = pAdapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728
Dhanashri Atre63d98022017-01-24 18:22:09 -0800729 if (unlikely(skb->dev == NULL)) {
730
731 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
732 "%s: ERROR!!Invalid netdevice", __func__);
Dhanashri Atrecefa8802017-02-02 16:17:14 -0800733 continue;
Dhanashri Atre63d98022017-01-24 18:22:09 -0800734 }
735 cpu_index = wlan_hdd_get_cpu();
736 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
737 ++pAdapter->stats.rx_packets;
738 pAdapter->stats.rx_bytes += skb->len;
739
740 hdd_event_eapol_log(skb, QDF_RX);
Himanshu Agarwalee3411a2017-01-31 12:56:47 +0530741 DPTRACE(qdf_dp_trace(skb,
Dhanashri Atre63d98022017-01-24 18:22:09 -0800742 QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700743 QDF_TRACE_DEFAULT_PDEV_ID,
Himanshu Agarwalee3411a2017-01-31 12:56:47 +0530744 qdf_nbuf_data_addr(skb),
745 sizeof(qdf_nbuf_data(skb)), QDF_RX));
746 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_RX_PACKET_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700747 QDF_TRACE_DEFAULT_PDEV_ID,
748 (uint8_t *)skb->data, qdf_nbuf_len(skb),
749 QDF_RX));
Himanshu Agarwalee3411a2017-01-31 12:56:47 +0530750 if (qdf_nbuf_len(skb) > QDF_DP_TRACE_RECORD_SIZE)
751 DPTRACE(qdf_dp_trace(skb,
752 QDF_DP_TRACE_HDD_RX_PACKET_RECORD,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -0700753 QDF_TRACE_DEFAULT_PDEV_ID,
Himanshu Agarwalee3411a2017-01-31 12:56:47 +0530754 (uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
755 (qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE),
756 QDF_RX));
Dhanashri Atre63d98022017-01-24 18:22:09 -0800757
758 skb->protocol = eth_type_trans(skb, skb->dev);
759
760 /* hold configurable wakelock for unicast traffic */
761 if (pHddCtx->config->rx_wakelock_timeout &&
762 skb->pkt_type != PACKET_BROADCAST &&
763 skb->pkt_type != PACKET_MULTICAST) {
764 cds_host_diag_log_work(&pHddCtx->rx_wake_lock,
765 pHddCtx->config->rx_wakelock_timeout,
766 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
767 qdf_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock,
768 pHddCtx->config->
769 rx_wakelock_timeout);
770 }
771
772 /* Remove SKB from internal tracking table before submitting
773 * it to stack
774 */
Manjunathappa Prakash17c07bd2017-04-27 21:24:28 -0700775 qdf_net_buf_debug_release_skb(skb);
Dhanashri Atre63d98022017-01-24 18:22:09 -0800776 if (hdd_napi_enabled(HDD_NAPI_ANY) &&
777 !pHddCtx->enableRxThread)
778 rxstat = netif_receive_skb(skb);
779 else
780 rxstat = netif_rx_ni(skb);
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700781 if (NET_RX_SUCCESS == rxstat)
Dhanashri Atre63d98022017-01-24 18:22:09 -0800782 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
Srinivas Girigowdae806a822017-03-25 11:25:30 -0700783 else
Dhanashri Atre63d98022017-01-24 18:22:09 -0800784 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
Dhanashri Atre63d98022017-01-24 18:22:09 -0800785
786 pAdapter->dev->last_rx = jiffies;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530789 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790}
791
792/**
793 * hdd_softap_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
794 * @pAdapter: pointer to adapter context
795 * @staId: Station ID to deregister
796 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530797 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800798 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530799QDF_STATUS hdd_softap_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530801 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800802 hdd_context_t *pHddCtx;
Abhishek Singh07c627e2017-03-20 17:56:34 +0530803 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804
805 if (NULL == pAdapter) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800806 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530807 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808 }
809
810 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800811 hdd_err("Invalid adapter magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530812 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800813 }
814
815 pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
816 /* Clear station in TL and then update HDD data
817 * structures. This helps to block RX frames from other
818 * station to this station.
819 */
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -0800820 qdf_status = cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800821 (struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
822 staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530823 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -0800824 hdd_err("cdp_clear_peer failed for staID %d, Status=%d [0x%08X]",
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800825 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 }
827
Dustin Brown7d043f62017-03-27 12:07:36 -0700828 ret = hdd_objmgr_remove_peer_object(pAdapter->hdd_vdev,
829 pAdapter->aStaInfo[staId].
830 macAddrSTA.bytes);
Abhishek Singh07c627e2017-03-20 17:56:34 +0530831 if (ret)
832 hdd_err("Peer obj %pM delete fails",
833 pAdapter->aStaInfo[staId].macAddrSTA.bytes);
834
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835 if (pAdapter->aStaInfo[staId].isUsed) {
836 spin_lock_bh(&pAdapter->staInfo_lock);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530837 qdf_mem_zero(&pAdapter->aStaInfo[staId],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800838 sizeof(hdd_station_info_t));
839 spin_unlock_bh(&pAdapter->staInfo_lock);
840 }
Abhishek Singh07c627e2017-03-20 17:56:34 +0530841
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 pHddCtx->sta_to_adapter[staId] = NULL;
843
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530844 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845}
846
847/**
848 * hdd_softap_register_sta() - Register a SoftAP STA
849 * @pAdapter: pointer to adapter context
850 * @fAuthRequired: is additional authentication required?
851 * @fPrivacyBit: should 802.11 privacy bit be set?
852 * @staId: station ID assigned to this station
853 * @ucastSig: unicast security signature
854 * @bcastSig: broadcast security signature
855 * @pPeerMacAddress: station MAC address
856 * @fWmmEnabled: is WMM enabled for this STA?
857 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530858 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530860QDF_STATUS hdd_softap_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861 bool fAuthRequired,
862 bool fPrivacyBit,
863 uint8_t staId,
864 uint8_t ucastSig,
865 uint8_t bcastSig,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530866 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800867 bool fWmmEnabled)
868{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530869 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870 struct ol_txrx_desc_type staDesc = { 0 };
871 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
Dhanashri Atre182b0272016-02-17 15:35:07 -0800872 struct ol_txrx_ops txrx_ops;
Leo Changfdb45c32016-10-28 11:09:23 -0700873 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
874 void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800876 hdd_info("STA:%u, Auth:%u, Priv:%u, WMM:%u",
877 staId, fAuthRequired, fPrivacyBit, fWmmEnabled);
878
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800879 /*
880 * Clean up old entry if it is not cleaned up properly
881 */
882 if (pAdapter->aStaInfo[staId].isUsed) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800883 hdd_info("clean up old entry for STA %d", staId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 hdd_softap_deregister_sta(pAdapter, staId);
885 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800887 /* Get the Station ID from the one saved during the assocation. */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 staDesc.sta_id = staId;
889
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800890 /* Save the pAdapter Pointer for this staId */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891 pHddCtx->sta_to_adapter[staId] = pAdapter;
892
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530893 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894 hdd_softap_init_tx_rx_sta(pAdapter, staId,
895 pPeerMacAddress);
896
897 staDesc.is_qos_enabled = fWmmEnabled;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898
Dhanashri Atre182b0272016-02-17 15:35:07 -0800899 /* Register the vdev transmit and receive functions */
900 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
901 txrx_ops.rx.rx = hdd_softap_rx_packet_cbk;
Leo Changfdb45c32016-10-28 11:09:23 -0700902 cdp_vdev_register(soc,
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800903 (struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
904 (struct cdp_pdev *)pdev, pAdapter->sessionId),
905 pAdapter, &txrx_ops);
906 pAdapter->txrx_vdev = (void *)cdp_get_vdev_from_vdev_id(soc,
907 (struct cdp_pdev *)pdev,
Leo Changfdb45c32016-10-28 11:09:23 -0700908 pAdapter->sessionId);
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800909 pAdapter->tx_fn = txrx_ops.tx.tx;
Dhanashri Atre182b0272016-02-17 15:35:07 -0800910
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800911 qdf_status = cdp_peer_register(soc,
912 (struct cdp_pdev *)pdev, &staDesc);
Dhanashri Atre50141c52016-04-07 13:15:29 -0700913 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800914 hdd_err("cdp_peer_register() failed to register. Status = %d [0x%08X]",
915 qdf_status, qdf_status);
Dhanashri Atre50141c52016-04-07 13:15:29 -0700916 return qdf_status;
917 }
918
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919 /* if ( WPA ), tell TL to go to 'connected' and after keys come to the
920 * driver then go to 'authenticated'. For all other authentication
921 * types (those that do not require upper layer authentication) we can
922 * put TL directly into 'authenticated' state
923 */
924
925 pAdapter->aStaInfo[staId].ucSTAId = staId;
926 pAdapter->aStaInfo[staId].isQosEnabled = fWmmEnabled;
927
928 if (!fAuthRequired) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800929 hdd_info("open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
930 pAdapter->aStaInfo[staId].ucSTAId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800931
932 /* Connections that do not need Upper layer auth,
933 * transition TL directly to 'Authenticated' state.
934 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530935 qdf_status = hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800936 OL_TXRX_PEER_STATE_AUTH, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800938 pAdapter->aStaInfo[staId].tlSTAState = OL_TXRX_PEER_STATE_AUTH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939 pAdapter->sessionCtx.ap.uIsAuthenticated = true;
940 } else {
941
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -0800942 hdd_info("ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
943 pAdapter->aStaInfo[staId].ucSTAId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530945 qdf_status = hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800946 OL_TXRX_PEER_STATE_CONN, false);
947 pAdapter->aStaInfo[staId].tlSTAState = OL_TXRX_PEER_STATE_CONN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800948
949 pAdapter->sessionCtx.ap.uIsAuthenticated = false;
950
951 }
952
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700953 hdd_debug("Enabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800954 wlan_hdd_netif_queue_control(pAdapter,
955 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
956 WLAN_CONTROL_PATH);
957
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530958 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800959}
960
961/**
962 * hdd_softap_register_bc_sta() - Register the SoftAP broadcast STA
963 * @pAdapter: pointer to adapter context
964 * @fPrivacyBit: should 802.11 privacy bit be set?
965 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530966 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800967 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530968QDF_STATUS hdd_softap_register_bc_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969 bool fPrivacyBit)
970{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530971 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800972 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530973 struct qdf_mac_addr broadcastMacAddr =
974 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800975 hdd_ap_ctx_t *pHddApCtx;
976
977 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
978
979 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800980 pHddCtx->sta_to_adapter[pHddApCtx->uBCStaId] = pAdapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530981 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800982 hdd_softap_register_sta(pAdapter, false, fPrivacyBit,
983 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->
984 uBCStaId, 0, 1, &broadcastMacAddr, 0);
985
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530986 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987}
988
989/**
990 * hdd_softap_deregister_bc_sta() - Deregister the SoftAP broadcast STA
991 * @pAdapter: pointer to adapter context
992 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530993 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800994 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530995QDF_STATUS hdd_softap_deregister_bc_sta(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996{
997 return hdd_softap_deregister_sta(pAdapter,
998 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->
999 uBCStaId);
1000}
1001
1002/**
1003 * hdd_softap_stop_bss() - Stop the BSS
1004 * @pAdapter: pointer to adapter context
1005 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301006 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301008QDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001009{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301010 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001011 uint8_t staId = 0;
1012 hdd_context_t *pHddCtx;
Srinivas Girigowdae806a822017-03-25 11:25:30 -07001013
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001014 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1015
1016 /* bss deregister is not allowed during wlan driver loading or
1017 * unloading
1018 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001019 if (cds_is_load_or_unload_in_progress()) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001020 hdd_err("Loading_unloading in Progress, state: 0x%x. Ignore!!!",
1021 cds_get_driver_state());
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301022 return QDF_STATUS_E_PERM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023 }
1024
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301025 qdf_status = hdd_softap_deregister_bc_sta(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001026
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301027 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001028 hdd_err("Failed to deregister BC sta Id %d",
1029 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001030 }
1031
1032 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
1033 /* This excludes BC sta as it is already deregistered */
1034 if (pAdapter->aStaInfo[staId].isUsed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301035 qdf_status = hdd_softap_deregister_sta(pAdapter, staId);
1036 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001037 hdd_err("Failed to deregister sta Id %d",
1038 staId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001039 }
1040 }
1041 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301042 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043}
1044
1045/**
1046 * hdd_softap_change_sta_state() - Change the state of a SoftAP station
1047 * @pAdapter: pointer to adapter context
1048 * @pDestMacAddress: MAC address of the station
1049 * @state: new state of the station
1050 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301051 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301053QDF_STATUS hdd_softap_change_sta_state(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301054 struct qdf_mac_addr *pDestMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055 enum ol_txrx_peer_state state)
1056{
1057 uint8_t ucSTAId = WLAN_MAX_STA_COUNT;
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001058 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001059
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001060 ENTER_DEV(pAdapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001061
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001062 qdf_status = hdd_softap_get_sta_id(pAdapter, pDestMacAddress, &ucSTAId);
1063 if (QDF_STATUS_SUCCESS != qdf_status) {
1064 hdd_err("Failed to find right station");
1065 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001066 }
1067
1068 if (false ==
Anurag Chouhanc5548422016-02-24 18:33:27 +05301069 qdf_is_macaddr_equal(&pAdapter->aStaInfo[ucSTAId].macAddrSTA,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001070 pDestMacAddress)) {
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001071 hdd_err("Station %u MAC address not matching", ucSTAId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301072 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001073 }
1074
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301075 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001076 hdd_change_peer_state(pAdapter, ucSTAId, state, false);
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001077 hdd_info("Station %u changed to state %d", ucSTAId, state);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001078
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301079 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001080 pAdapter->aStaInfo[ucSTAId].tlSTAState =
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001081 OL_TXRX_PEER_STATE_AUTH;
Rachit Kankane2487f8f2017-04-19 14:30:19 +05301082 p2p_peer_authorized(pAdapter->hdd_vdev, pDestMacAddress->bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001083 }
1084
Jeff Johnsond5bd6fd2016-12-05 12:29:21 -08001085 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301086 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001087}
1088
1089/*
1090 * hdd_softap_get_sta_id() - Find station ID from MAC address
1091 * @pAdapter: pointer to adapter context
1092 * @pDestMacAddress: MAC address of the destination
1093 * @staId: Station ID associated with the MAC address
1094 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301095 * Return: QDF_STATUS_SUCCESS if a match was found, in which case
1096 * staId is populated, QDF_STATUS_E_FAILURE if a match is
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001097 * not found
1098 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301099QDF_STATUS hdd_softap_get_sta_id(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301100 struct qdf_mac_addr *pMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001101 uint8_t *staId)
1102{
1103 uint8_t i;
1104
1105 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301106 if (!qdf_mem_cmp
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001107 (&pAdapter->aStaInfo[i].macAddrSTA, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301108 QDF_MAC_ADDR_SIZE) && pAdapter->aStaInfo[i].isUsed) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001109 *staId = i;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301110 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001111 }
1112 }
1113
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301114 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001115}