blob: faf3fbe53a87080d3948fe242859c28f58acfba4 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Orhan K AKYILDIZ4f20db52015-12-30 12:35:44 -08002 * Copyright (c) 2012-2016 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
28/* Include files */
29#include <linux/semaphore.h>
30#include <wlan_hdd_tx_rx.h>
31#include <wlan_hdd_softap_tx_rx.h>
32#include <linux/netdevice.h>
33#include <linux/skbuff.h>
34#include <linux/etherdevice.h>
Anurag Chouhan6d760662016-02-20 16:05:43 +053035#include <qdf_types.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080036#include <ani_global.h>
Anurag Chouhan6d760662016-02-20 16:05:43 +053037#include <qdf_types.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080038#include <net/ieee80211_radiotap.h>
39#include <cds_sched.h>
40#include <wlan_hdd_napi.h>
Dhanashri Atre182b0272016-02-17 15:35:07 -080041#include <ol_txrx.h>
Dhanashri Atreb08959a2016-03-01 17:28:03 -080042#include <cdp_txrx_peer_ops.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080043
44#ifdef IPA_OFFLOAD
45#include <wlan_hdd_ipa.h>
46#endif
47
48/* Preprocessor definitions and constants */
49#undef QCA_HDD_SAP_DUMP_SK_BUFF
50
51/* Type declarations */
52
53/* Function definitions and documenation */
54#ifdef QCA_HDD_SAP_DUMP_SK_BUFF
55/**
56 * hdd_softap_dump_sk_buff() - Dump an skb
57 * @skb: skb to dump
58 *
59 * Return: None
60 */
61static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
62{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053063 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080064 "%s: head = %p ", __func__, skb->head);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053065 /* QDF_TRACE( QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,"%s: data = %p ", __func__, skb->data); */
66 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067 "%s: tail = %p ", __func__, skb->tail);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053068 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080069 "%s: end = %p ", __func__, skb->end);
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: len = %d ", __func__, skb->len);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053072 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073 "%s: data_len = %d ", __func__, skb->data_len);
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: mac_len = %d", __func__, skb->mac_len);
76
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053077 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080078 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ", skb->data[0],
79 skb->data[1], skb->data[2], skb->data[3], skb->data[4],
80 skb->data[5], skb->data[6], skb->data[7]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053081 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080082 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", skb->data[8],
83 skb->data[9], skb->data[10], skb->data[11], skb->data[12],
84 skb->data[13], skb->data[14], skb->data[15]);
85}
86#else
87static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
88{
89}
90#endif
91
92#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
93/**
94 * hdd_softap_tx_resume_timer_expired_handler() - TX Q resume timer handler
95 * @adapter_context: pointer to vdev adapter
96 *
97 * TX Q resume timer handler for SAP and P2P GO interface. If Blocked
98 * OS Q is not resumed during timeout period, to prevent permanent
99 * stall, resume OS Q forcefully for SAP and P2P GO interface.
100 *
101 * Return: None
102 */
103void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context)
104{
105 hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;
106
107 if (!pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530108 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800109 "%s: INV ARG", __func__);
110 /* INVALID ARG */
111 return;
112 }
113
114 hddLog(LOG1, FL("Enabling queues"));
115 wlan_hdd_netif_queue_control(pAdapter, WLAN_WAKE_ALL_NETIF_QUEUE,
116 WLAN_CONTROL_PATH);
117 return;
118}
119
120/**
121 * hdd_softap_tx_resume_cb() - Resume OS TX Q.
122 * @adapter_context: pointer to vdev apdapter
123 * @tx_resume: TX Q resume trigger
124 *
125 * Q was stopped due to WLAN TX path low resource condition
126 *
127 * Return: None
128 */
129void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume)
130{
131 hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;
132
133 if (!pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530134 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800135 "%s: INV ARG", __func__);
136 /* INVALID ARG */
137 return;
138 }
139
140 /* Resume TX */
141 if (true == tx_resume) {
Anurag Chouhan210db072016-02-22 18:42:15 +0530142 if (QDF_TIMER_STATE_STOPPED !=
143 qdf_mc_timer_get_current_state(&pAdapter->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800144 tx_flow_control_timer)) {
Anurag Chouhan210db072016-02-22 18:42:15 +0530145 qdf_mc_timer_stop(&pAdapter->tx_flow_control_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800146 }
147
148 hddLog(LOG1, FL("Enabling queues"));
149 wlan_hdd_netif_queue_control(pAdapter,
150 WLAN_WAKE_ALL_NETIF_QUEUE,
151 WLAN_DATA_FLOW_CONTROL);
152 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800153 return;
154}
155#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
156
157/**
158 * hdd_softap_hard_start_xmit() - Transmit a frame
159 * @skb: pointer to OS packet (sk_buff)
160 * @dev: pointer to network device
161 *
162 * Function registered with the Linux OS for transmitting
163 * packets. This version of the function directly passes
164 * the packet to Transport Layer.
165 *
166 * Return: Always returns NETDEV_TX_OK
167 */
168int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
169{
170 sme_ac_enum_type ac = SME_AC_BE;
171 hdd_adapter_t *pAdapter = (hdd_adapter_t *) netdev_priv(dev);
172 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530173 struct qdf_mac_addr *pDestMacAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174 uint8_t STAId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800175#ifdef QCA_PKT_PROTO_TRACE
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800176 uint8_t proto_type = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177 hdd_context_t *hddCtxt = (hdd_context_t *) pAdapter->pHddCtx;
178#endif /* QCA_PKT_PROTO_TRACE */
179
180 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
181 /* Prevent this function from being called during SSR since TL
182 * context may not be reinitialized at this time which may
183 * lead to a crash.
184 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800185 if (cds_is_driver_recovering()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530186 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800187 "%s: Recovery in Progress. Ignore!!!", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800188 goto drop_pkt;
189 }
190
191 /*
192 * If the device is operating on a DFS Channel
193 * then check if SAP is in CAC WAIT state and
194 * drop the packets. In CAC WAIT state device
195 * is expected not to transmit any frames.
196 * SAP starts Tx only after the BSS START is
197 * done.
198 */
199 if (pHddApCtx->dfs_cac_block_tx) {
200 goto drop_pkt;
201 }
202
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800203 /*
204 * If a transmit function is not registered, drop packet
205 */
206 if (!pAdapter->tx_fn) {
207 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
208 "%s: TX function not registered by the data path",
209 __func__);
210 goto drop_pkt;
211 }
212
Anurag Chouhan6d760662016-02-20 16:05:43 +0530213 pDestMacAddress = (struct qdf_mac_addr *) skb->data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800214
Anurag Chouhanc5548422016-02-24 18:33:27 +0530215 if (qdf_is_macaddr_broadcast(pDestMacAddress) ||
216 qdf_is_macaddr_group(pDestMacAddress)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800217 /* The BC/MC station ID is assigned during BSS
218 * starting phase. SAP will return the station ID
219 * used for BC/MC traffic.
220 */
221 STAId = pHddApCtx->uBCStaId;
222 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530223 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800224 hdd_softap_get_sta_id(pAdapter,
225 pDestMacAddress, &STAId)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530226 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
227 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 "%s: Failed to find right station", __func__);
229 goto drop_pkt;
230 }
231
232 if (STAId == HDD_WLAN_INVALID_STA_ID) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530233 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
234 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235 "%s: Failed to find right station", __func__);
236 goto drop_pkt;
237 } else if (false == pAdapter->aStaInfo[STAId].isUsed) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530238 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
239 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800240 "%s: STA %d is unregistered", __func__,
241 STAId);
242 goto drop_pkt;
243 }
244
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800245 if ((OL_TXRX_PEER_STATE_CONN !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246 pAdapter->aStaInfo[STAId].tlSTAState)
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800247 && (OL_TXRX_PEER_STATE_AUTH !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800248 pAdapter->aStaInfo[STAId].tlSTAState)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530249 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
250 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251 "%s: Station not connected yet", __func__);
252 goto drop_pkt;
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800253 } else if (OL_TXRX_PEER_STATE_CONN ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800254 pAdapter->aStaInfo[STAId].tlSTAState) {
255 if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530256 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
257 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800258 "%s: NON-EAPOL packet in non-Authenticated state",
259 __func__);
260 goto drop_pkt;
261 }
262 }
263 }
264
265 hdd_get_tx_resource(pAdapter, STAId,
266 WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
267
268 /* Get TL AC corresponding to Qdisc queue index/AC. */
269 ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];
270 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
271
272#if defined (IPA_OFFLOAD)
Nirav Shahcbc6d722016-03-01 16:24:53 +0530273 if (!qdf_nbuf_ipa_owned_get(skb)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800274#endif
275 /* Check if the buffer has enough header room */
276 skb = skb_unshare(skb, GFP_ATOMIC);
277 if (!skb)
Jeff Johnsonedeff232015-11-11 17:19:42 -0800278 goto drop_pkt_accounting;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800279
280 if (skb_headroom(skb) < dev->hard_header_len) {
281 struct sk_buff *tmp;
282 tmp = skb;
283 skb = skb_realloc_headroom(tmp, dev->hard_header_len);
284 dev_kfree_skb(tmp);
285 if (!skb)
Jeff Johnsonedeff232015-11-11 17:19:42 -0800286 goto drop_pkt_accounting;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800287 }
288#if defined (IPA_OFFLOAD)
289 }
290#endif
291
292 wlan_hdd_log_eapol(skb,
293 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
294
295#ifdef QCA_PKT_PROTO_TRACE
296 if ((hddCtxt->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_EAPOL) ||
297 (hddCtxt->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_DHCP)) {
298 /* Proto Trace enabled */
299 proto_type = cds_pkt_get_proto_type(skb,
300 hddCtxt->config->
301 gEnableDebugLog, 0);
302 if (CDS_PKT_TRAC_TYPE_EAPOL & proto_type) {
303 cds_pkt_trace_buf_update("HA:T:EPL");
304 } else if (CDS_PKT_TRAC_TYPE_DHCP & proto_type) {
305 cds_pkt_trace_buf_update("HA:T:DHC");
306 }
307 }
308#endif /* QCA_PKT_PROTO_TRACE */
309 pAdapter->stats.tx_bytes += skb->len;
310 ++pAdapter->stats.tx_packets;
311
312 /* Zero out skb's context buffer for the driver to use */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530313 qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
Nirav Shahcbc6d722016-03-01 16:24:53 +0530314 QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
315 QDF_NBUF_UPDATE_TX_PKT_COUNT(skb, QDF_NBUF_TX_PKT_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800316
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530317 qdf_dp_trace_set_track(skb);
318 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_PACKET_PTR_RECORD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800319 (uint8_t *)skb->data, sizeof(skb->data)));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530320 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_PACKET_RECORD,
Nirav Shahcbc6d722016-03-01 16:24:53 +0530321 (uint8_t *)skb->data, qdf_nbuf_len(skb)));
322 if (qdf_nbuf_len(skb) > QDF_DP_TRACE_RECORD_SIZE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530323 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_PACKET_RECORD,
324 (uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
Nirav Shahcbc6d722016-03-01 16:24:53 +0530325 (qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800327#ifdef QCA_PKT_PROTO_TRACE
328 qdf_nbuf_trace_set_proto_type(skb, proto_type);
329#endif
330 if (pAdapter->tx_fn(ol_txrx_get_vdev_by_sta_id(STAId),
331 (qdf_nbuf_t) skb) != NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530332 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333 "%s: Failed to send packet to txrx for staid:%d",
334 __func__, STAId);
335 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
336 goto drop_pkt;
337 }
338 dev->trans_start = jiffies;
339
340 return NETDEV_TX_OK;
341
342drop_pkt:
343
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530344 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_DROP_PACKET_RECORD,
Nirav Shahcbc6d722016-03-01 16:24:53 +0530345 (uint8_t *)skb->data, qdf_nbuf_len(skb)));
346 if (qdf_nbuf_len(skb) > QDF_DP_TRACE_RECORD_SIZE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530347 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_DROP_PACKET_RECORD,
348 (uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
Nirav Shahcbc6d722016-03-01 16:24:53 +0530349 (qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE)));
Jeff Johnsonedeff232015-11-11 17:19:42 -0800350 kfree_skb(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800351
Jeff Johnsonedeff232015-11-11 17:19:42 -0800352drop_pkt_accounting:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800353 ++pAdapter->stats.tx_dropped;
354 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800355
356 return NETDEV_TX_OK;
357}
358
359/**
360 * __hdd_softap_tx_timeout() - TX timeout handler
361 * @dev: pointer to network device
362 *
363 * This function is registered as a netdev ndo_tx_timeout method, and
364 * is invoked by the kernel if the driver takes too long to transmit a
365 * frame.
366 *
367 * Return: None
368 */
369static void __hdd_softap_tx_timeout(struct net_device *dev)
370{
371 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
372 hdd_context_t *hdd_ctx;
373
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530374 DPTRACE(qdf_dp_trace(NULL, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800375 NULL, 0));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530376 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377 "%s: Transmission timeout occurred", __func__);
378 /* Getting here implies we disabled the TX queues for too
379 * long. Queues are disabled either because of disassociation
380 * or low resource scenarios. In case of disassociation it is
381 * ok to ignore this. But if associated, we have do possible
382 * recovery here
383 */
384 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800385 if (cds_is_driver_recovering()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530386 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800387 "%s: Recovery in Progress. Ignore!!!", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388 return;
389 }
390}
391
392/**
393 * hdd_softap_tx_timeout() - SSR wrapper for __hdd_softap_tx_timeout
394 * @dev: pointer to net_device
395 *
396 * Return: none
397 */
398void hdd_softap_tx_timeout(struct net_device *dev)
399{
400 cds_ssr_protect(__func__);
401 __hdd_softap_tx_timeout(dev);
402 cds_ssr_unprotect(__func__);
403}
404
405/**
406 * @hdd_softap_init_tx_rx() - Initialize Tx/RX module
407 * @pAdapter: pointer to adapter context
408 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530409 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
410 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800411 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530412QDF_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530414 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415
416 uint8_t STAId = 0;
417
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530418 qdf_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800419
420 spin_lock_init(&pAdapter->staInfo_lock);
421
422 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530423 qdf_mem_zero(&pAdapter->aStaInfo[STAId],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424 sizeof(hdd_station_info_t));
425 }
426
427 return status;
428}
429
430/**
431 * @hdd_softap_deinit_tx_rx() - Deinitialize Tx/RX module
432 * @pAdapter: pointer to adapter context
433 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530434 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
435 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530437QDF_STATUS hdd_softap_deinit_tx_rx(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800438{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530439 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440
441 return status;
442}
443
444/**
445 * hdd_softap_init_tx_rx_sta() - Initialize tx/rx for a softap station
446 * @pAdapter: pointer to adapter context
447 * @STAId: Station ID to initialize
448 * @pmacAddrSTA: pointer to the MAC address of the station
449 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530450 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
451 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530453QDF_STATUS hdd_softap_init_tx_rx_sta(hdd_adapter_t *pAdapter, uint8_t STAId,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530454 struct qdf_mac_addr *pmacAddrSTA)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455{
456 spin_lock_bh(&pAdapter->staInfo_lock);
457 if (pAdapter->aStaInfo[STAId].isUsed) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530458 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459 "%s: Reinit station %d", __func__, STAId);
460 spin_unlock_bh(&pAdapter->staInfo_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530461 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 }
463
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530464 qdf_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800465
466 pAdapter->aStaInfo[STAId].isUsed = true;
467 pAdapter->aStaInfo[STAId].isDeauthInProgress = false;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530468 qdf_copy_macaddr(&pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800469
470 spin_unlock_bh(&pAdapter->staInfo_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530471 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800472}
473
474/**
475 * hdd_softap_deinit_tx_rx_sta() - Deinitialize tx/rx for a softap station
476 * @pAdapter: pointer to adapter context
477 * @STAId: Station ID to deinitialize
478 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530479 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
480 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800481 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530482QDF_STATUS hdd_softap_deinit_tx_rx_sta(hdd_adapter_t *pAdapter, uint8_t STAId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800483{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530484 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800485 hdd_hostapd_state_t *pHostapdState;
486
487 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
488
489 spin_lock_bh(&pAdapter->staInfo_lock);
490
491 if (false == pAdapter->aStaInfo[STAId].isUsed) {
492 spin_unlock_bh(&pAdapter->staInfo_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530493 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800494 "%s: Deinit station not inited %d", __func__, STAId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530495 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800496 }
497
498 pAdapter->aStaInfo[STAId].isUsed = false;
499 pAdapter->aStaInfo[STAId].isDeauthInProgress = false;
500
501 spin_unlock_bh(&pAdapter->staInfo_lock);
502 return status;
503}
504
505/**
506 * hdd_softap_rx_packet_cbk() - Receive packet handler
Dhanashri Atre182b0272016-02-17 15:35:07 -0800507 * @context: pointer to HDD context
Nirav Shahcbc6d722016-03-01 16:24:53 +0530508 * @rxBuf: pointer to rx qdf_nbuf
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800509 *
510 * Receive callback registered with TL. TL will call this to notify
511 * the HDD when one or more packets were received for a registered
512 * STA.
513 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530514 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
515 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 */
Dhanashri Atre182b0272016-02-17 15:35:07 -0800517QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518{
519 hdd_adapter_t *pAdapter = NULL;
520 int rxstat;
521 unsigned int cpu_index;
522 struct sk_buff *skb = NULL;
523 hdd_context_t *pHddCtx = NULL;
524#ifdef QCA_PKT_PROTO_TRACE
525 uint8_t proto_type;
526#endif /* QCA_PKT_PROTO_TRACE */
527
528 /* Sanity check on inputs */
Dhanashri Atre182b0272016-02-17 15:35:07 -0800529 if (unlikely((NULL == context) || (NULL == rxBuf))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530530 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800531 "%s: Null params being passed", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530532 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800533 }
534
Dhanashri Atre182b0272016-02-17 15:35:07 -0800535 pAdapter = (hdd_adapter_t *)context;
536 if (unlikely(WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
537 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_FATAL,
538 "Magic cookie(%x) for adapter sanity verification is invalid",
539 pAdapter->magic);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530540 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800541 }
542
Dhanashri Atre182b0272016-02-17 15:35:07 -0800543 pHddCtx = pAdapter->pHddCtx;
544 if (unlikely(NULL == pHddCtx)) {
545 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
546 "%s: HDD context is Null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530547 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548 }
549
550 /* walk the chain until all are processed */
551 skb = (struct sk_buff *)rxBuf;
552
553 hdd_softap_dump_sk_buff(skb);
554
555 skb->dev = pAdapter->dev;
556
Dhanashri Atre182b0272016-02-17 15:35:07 -0800557 if (unlikely(skb->dev == NULL)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530559 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 "%s: ERROR!!Invalid netdevice", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530561 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562 }
563 cpu_index = wlan_hdd_get_cpu();
564 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
565 ++pAdapter->stats.rx_packets;
566 pAdapter->stats.rx_bytes += skb->len;
567
568 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
569
570#ifdef QCA_PKT_PROTO_TRACE
571 if ((pHddCtx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_EAPOL) ||
572 (pHddCtx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_DHCP)) {
573 proto_type = cds_pkt_get_proto_type(skb,
574 pHddCtx->config->
575 gEnableDebugLog, 0);
576 if (CDS_PKT_TRAC_TYPE_EAPOL & proto_type) {
577 cds_pkt_trace_buf_update("HA:R:EPL");
578 } else if (CDS_PKT_TRAC_TYPE_DHCP & proto_type) {
579 cds_pkt_trace_buf_update("HA:R:DHC");
580 }
581 }
582#endif /* QCA_PKT_PROTO_TRACE */
583
584 skb->protocol = eth_type_trans(skb, skb->dev);
585#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530586 qdf_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587 HDD_WAKE_LOCK_DURATION,
588 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
589#endif
590
591 /* Remove SKB from internal tracking table before submitting
592 * it to stack
593 */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530594 qdf_net_buf_debug_release_skb(rxBuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800595
Orhan K AKYILDIZ4f20db52015-12-30 12:35:44 -0800596 if (hdd_napi_enabled(HDD_NAPI_ANY) && !pHddCtx->config->enableRxThread)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597 rxstat = netif_receive_skb(skb);
598 else
599 rxstat = netif_rx_ni(skb);
600 if (NET_RX_SUCCESS == rxstat) {
601 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
602 } else {
603 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
604 }
605
606 pAdapter->dev->last_rx = jiffies;
607
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530608 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800609}
610
611/**
612 * hdd_softap_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
613 * @pAdapter: pointer to adapter context
614 * @staId: Station ID to deregister
615 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530616 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530618QDF_STATUS hdd_softap_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800619{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530620 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621 hdd_context_t *pHddCtx;
622
623 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530624 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800625 "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530626 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800627 }
628
629 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530630 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800631 "%s: Invalid pAdapter magic", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530632 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800633 }
634
635 pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
636 /* Clear station in TL and then update HDD data
637 * structures. This helps to block RX frames from other
638 * station to this station.
639 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530640 qdf_status = ol_txrx_clear_peer(staId);
641 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530642 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800643 "ol_txrx_clear_peer() failed to for staID %d. "
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530644 "Status= %d [0x%08X]", staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800645 }
646
647 if (pAdapter->aStaInfo[staId].isUsed) {
648 spin_lock_bh(&pAdapter->staInfo_lock);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530649 qdf_mem_zero(&pAdapter->aStaInfo[staId],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650 sizeof(hdd_station_info_t));
651 spin_unlock_bh(&pAdapter->staInfo_lock);
652 }
653 pHddCtx->sta_to_adapter[staId] = NULL;
654
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530655 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800656}
657
658/**
659 * hdd_softap_register_sta() - Register a SoftAP STA
660 * @pAdapter: pointer to adapter context
661 * @fAuthRequired: is additional authentication required?
662 * @fPrivacyBit: should 802.11 privacy bit be set?
663 * @staId: station ID assigned to this station
664 * @ucastSig: unicast security signature
665 * @bcastSig: broadcast security signature
666 * @pPeerMacAddress: station MAC address
667 * @fWmmEnabled: is WMM enabled for this STA?
668 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530669 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530671QDF_STATUS hdd_softap_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800672 bool fAuthRequired,
673 bool fPrivacyBit,
674 uint8_t staId,
675 uint8_t ucastSig,
676 uint8_t bcastSig,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530677 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678 bool fWmmEnabled)
679{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530680 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800681 struct ol_txrx_desc_type staDesc = { 0 };
682 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
Dhanashri Atre182b0272016-02-17 15:35:07 -0800683 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800684
685 /*
686 * Clean up old entry if it is not cleaned up properly
687 */
688 if (pAdapter->aStaInfo[staId].isUsed) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530689 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800690 "clean up old entry for STA %d", staId);
691 hdd_softap_deregister_sta(pAdapter, staId);
692 }
693 /* Get the Station ID from the one saved during the assocation. */
694
695 staDesc.sta_id = staId;
696
697 /*Save the pAdapter Pointer for this staId */
698 pHddCtx->sta_to_adapter[staId] = pAdapter;
699
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530700 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701 hdd_softap_init_tx_rx_sta(pAdapter, staId,
702 pPeerMacAddress);
703
704 staDesc.is_qos_enabled = fWmmEnabled;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530705 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800706 "HDD SOFTAP register TL QoS_enabled=%d",
707 staDesc.is_qos_enabled);
708
Dhanashri Atre182b0272016-02-17 15:35:07 -0800709 /* Register the vdev transmit and receive functions */
710 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
711 txrx_ops.rx.rx = hdd_softap_rx_packet_cbk;
712 ol_txrx_vdev_register(
713 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
714 pAdapter, &txrx_ops);
Dhanashri Atre168d2b42016-02-22 14:43:06 -0800715 pAdapter->tx_fn = txrx_ops.tx.tx;
Dhanashri Atre182b0272016-02-17 15:35:07 -0800716
Dhanashri Atre50141c52016-04-07 13:15:29 -0700717 qdf_status = ol_txrx_register_peer(&staDesc);
718 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
719 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
720 "SOFTAP ol_txrx_register_peer() failed to register. Status= %d [0x%08X]",
721 qdf_status, qdf_status);
722 return qdf_status;
723 }
724
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725 /* if ( WPA ), tell TL to go to 'connected' and after keys come to the
726 * driver then go to 'authenticated'. For all other authentication
727 * types (those that do not require upper layer authentication) we can
728 * put TL directly into 'authenticated' state
729 */
730
731 pAdapter->aStaInfo[staId].ucSTAId = staId;
732 pAdapter->aStaInfo[staId].isQosEnabled = fWmmEnabled;
733
734 if (!fAuthRequired) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530735 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800736 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
737 pAdapter->aStaInfo[staId].ucSTAId);
738
739 /* Connections that do not need Upper layer auth,
740 * transition TL directly to 'Authenticated' state.
741 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530742 qdf_status = hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800743 OL_TXRX_PEER_STATE_AUTH, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800744
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800745 pAdapter->aStaInfo[staId].tlSTAState = OL_TXRX_PEER_STATE_AUTH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800746 pAdapter->sessionCtx.ap.uIsAuthenticated = true;
747 } else {
748
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530749 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
751 pAdapter->aStaInfo[staId].ucSTAId);
752
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530753 qdf_status = hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800754 OL_TXRX_PEER_STATE_CONN, false);
755 pAdapter->aStaInfo[staId].tlSTAState = OL_TXRX_PEER_STATE_CONN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756
757 pAdapter->sessionCtx.ap.uIsAuthenticated = false;
758
759 }
760
761 /* Enable Tx queue */
762 hddLog(LOG1, FL("Enabling queues"));
763 wlan_hdd_netif_queue_control(pAdapter,
764 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
765 WLAN_CONTROL_PATH);
766
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530767 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800768}
769
770/**
771 * hdd_softap_register_bc_sta() - Register the SoftAP broadcast STA
772 * @pAdapter: pointer to adapter context
773 * @fPrivacyBit: should 802.11 privacy bit be set?
774 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530775 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800776 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530777QDF_STATUS hdd_softap_register_bc_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 bool fPrivacyBit)
779{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530780 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530782 struct qdf_mac_addr broadcastMacAddr =
783 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 hdd_ap_ctx_t *pHddApCtx;
785
786 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
787
788 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
789#ifdef WLAN_FEATURE_MBSSID
790 pHddCtx->sta_to_adapter[pHddApCtx->uBCStaId] = pAdapter;
791#else
792 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
793#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530794 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 hdd_softap_register_sta(pAdapter, false, fPrivacyBit,
796 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->
797 uBCStaId, 0, 1, &broadcastMacAddr, 0);
798
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530799 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800}
801
802/**
803 * hdd_softap_deregister_bc_sta() - Deregister the SoftAP broadcast STA
804 * @pAdapter: pointer to adapter context
805 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530806 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530808QDF_STATUS hdd_softap_deregister_bc_sta(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800809{
810 return hdd_softap_deregister_sta(pAdapter,
811 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->
812 uBCStaId);
813}
814
815/**
816 * hdd_softap_stop_bss() - Stop the BSS
817 * @pAdapter: pointer to adapter context
818 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530819 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530821QDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530823 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 uint8_t staId = 0;
825 hdd_context_t *pHddCtx;
826 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
827
828 /* bss deregister is not allowed during wlan driver loading or
829 * unloading
830 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800831 if (cds_is_load_or_unload_in_progress()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530832 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800833 "%s: Loading_unloading in Progress, state: 0x%x. Ignore!!!",
834 __func__, cds_get_driver_state());
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530835 return QDF_STATUS_E_PERM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800836 }
837
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530838 qdf_status = hdd_softap_deregister_bc_sta(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800839
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530840 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530841 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 "%s: Failed to deregister BC sta Id %d", __func__,
843 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
844 }
845
846 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
847 /* This excludes BC sta as it is already deregistered */
848 if (pAdapter->aStaInfo[staId].isUsed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530849 qdf_status = hdd_softap_deregister_sta(pAdapter, staId);
850 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530851 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
852 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800853 "%s: Failed to deregister sta Id %d",
854 __func__, staId);
855 }
856 }
857 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530858 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859}
860
861/**
862 * hdd_softap_change_sta_state() - Change the state of a SoftAP station
863 * @pAdapter: pointer to adapter context
864 * @pDestMacAddress: MAC address of the station
865 * @state: new state of the station
866 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530867 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530869QDF_STATUS hdd_softap_change_sta_state(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530870 struct qdf_mac_addr *pDestMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800871 enum ol_txrx_peer_state state)
872{
873 uint8_t ucSTAId = WLAN_MAX_STA_COUNT;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530874 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530876 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 "%s: enter", __func__);
878
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530879 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880 hdd_softap_get_sta_id(pAdapter,
881 pDestMacAddress, &ucSTAId)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530882 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 "%s: Failed to find right station", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530884 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885 }
886
887 if (false ==
Anurag Chouhanc5548422016-02-24 18:33:27 +0530888 qdf_is_macaddr_equal(&pAdapter->aStaInfo[ucSTAId].macAddrSTA,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800889 pDestMacAddress)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530890 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891 "%s: Station MAC address does not matching",
892 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530893 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894 }
895
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530896 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800897 hdd_change_peer_state(pAdapter, ucSTAId, state, false);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530898 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800899 "%s: change station to state %d succeed", __func__, state);
900
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530901 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800902 pAdapter->aStaInfo[ucSTAId].tlSTAState =
Dhanashri Atreb08959a2016-03-01 17:28:03 -0800903 OL_TXRX_PEER_STATE_AUTH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800904 }
905
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530906 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800907 "%s exit", __func__);
908
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530909 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800910}
911
912/*
913 * hdd_softap_get_sta_id() - Find station ID from MAC address
914 * @pAdapter: pointer to adapter context
915 * @pDestMacAddress: MAC address of the destination
916 * @staId: Station ID associated with the MAC address
917 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530918 * Return: QDF_STATUS_SUCCESS if a match was found, in which case
919 * staId is populated, QDF_STATUS_E_FAILURE if a match is
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800920 * not found
921 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530922QDF_STATUS hdd_softap_get_sta_id(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530923 struct qdf_mac_addr *pMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800924 uint8_t *staId)
925{
926 uint8_t i;
927
928 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530929 if (!qdf_mem_cmp
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800930 (&pAdapter->aStaInfo[i].macAddrSTA, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530931 QDF_MAC_ADDR_SIZE) && pAdapter->aStaInfo[i].isUsed) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932 *staId = i;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530933 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800934 }
935 }
936
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530937 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938}