blob: b20c086f0ebde4d5e56baafc2d9e98b167b358e0 [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>
41
42#ifdef IPA_OFFLOAD
43#include <wlan_hdd_ipa.h>
44#endif
45
46/* Preprocessor definitions and constants */
47#undef QCA_HDD_SAP_DUMP_SK_BUFF
48
49/* Type declarations */
50
51/* Function definitions and documenation */
52#ifdef QCA_HDD_SAP_DUMP_SK_BUFF
53/**
54 * hdd_softap_dump_sk_buff() - Dump an skb
55 * @skb: skb to dump
56 *
57 * Return: None
58 */
59static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
60{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053061 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062 "%s: head = %p ", __func__, skb->head);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053063 /* QDF_TRACE( QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,"%s: data = %p ", __func__, skb->data); */
64 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065 "%s: tail = %p ", __func__, skb->tail);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053066 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067 "%s: end = %p ", __func__, skb->end);
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: len = %d ", __func__, skb->len);
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: data_len = %d ", __func__, skb->data_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: mac_len = %d", __func__, skb->mac_len);
74
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053075 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ", skb->data[0],
77 skb->data[1], skb->data[2], skb->data[3], skb->data[4],
78 skb->data[5], skb->data[6], skb->data[7]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053079 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", skb->data[8],
81 skb->data[9], skb->data[10], skb->data[11], skb->data[12],
82 skb->data[13], skb->data[14], skb->data[15]);
83}
84#else
85static void hdd_softap_dump_sk_buff(struct sk_buff *skb)
86{
87}
88#endif
89
90#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
91/**
92 * hdd_softap_tx_resume_timer_expired_handler() - TX Q resume timer handler
93 * @adapter_context: pointer to vdev adapter
94 *
95 * TX Q resume timer handler for SAP and P2P GO interface. If Blocked
96 * OS Q is not resumed during timeout period, to prevent permanent
97 * stall, resume OS Q forcefully for SAP and P2P GO interface.
98 *
99 * Return: None
100 */
101void hdd_softap_tx_resume_timer_expired_handler(void *adapter_context)
102{
103 hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;
104
105 if (!pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530106 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107 "%s: INV ARG", __func__);
108 /* INVALID ARG */
109 return;
110 }
111
112 hddLog(LOG1, FL("Enabling queues"));
113 wlan_hdd_netif_queue_control(pAdapter, WLAN_WAKE_ALL_NETIF_QUEUE,
114 WLAN_CONTROL_PATH);
115 return;
116}
117
118/**
119 * hdd_softap_tx_resume_cb() - Resume OS TX Q.
120 * @adapter_context: pointer to vdev apdapter
121 * @tx_resume: TX Q resume trigger
122 *
123 * Q was stopped due to WLAN TX path low resource condition
124 *
125 * Return: None
126 */
127void hdd_softap_tx_resume_cb(void *adapter_context, bool tx_resume)
128{
129 hdd_adapter_t *pAdapter = (hdd_adapter_t *) adapter_context;
130
131 if (!pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530132 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800133 "%s: INV ARG", __func__);
134 /* INVALID ARG */
135 return;
136 }
137
138 /* Resume TX */
139 if (true == tx_resume) {
Anurag Chouhan210db072016-02-22 18:42:15 +0530140 if (QDF_TIMER_STATE_STOPPED !=
141 qdf_mc_timer_get_current_state(&pAdapter->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800142 tx_flow_control_timer)) {
Anurag Chouhan210db072016-02-22 18:42:15 +0530143 qdf_mc_timer_stop(&pAdapter->tx_flow_control_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800144 }
145
146 hddLog(LOG1, FL("Enabling queues"));
147 wlan_hdd_netif_queue_control(pAdapter,
148 WLAN_WAKE_ALL_NETIF_QUEUE,
149 WLAN_DATA_FLOW_CONTROL);
150 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800151 return;
152}
153#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
154
155/**
156 * hdd_softap_hard_start_xmit() - Transmit a frame
157 * @skb: pointer to OS packet (sk_buff)
158 * @dev: pointer to network device
159 *
160 * Function registered with the Linux OS for transmitting
161 * packets. This version of the function directly passes
162 * the packet to Transport Layer.
163 *
164 * Return: Always returns NETDEV_TX_OK
165 */
166int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
167{
168 sme_ac_enum_type ac = SME_AC_BE;
169 hdd_adapter_t *pAdapter = (hdd_adapter_t *) netdev_priv(dev);
170 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530171 struct qdf_mac_addr *pDestMacAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172 uint8_t STAId;
173 uint8_t proto_type = 0;
174#ifdef QCA_PKT_PROTO_TRACE
175 hdd_context_t *hddCtxt = (hdd_context_t *) pAdapter->pHddCtx;
176#endif /* QCA_PKT_PROTO_TRACE */
177
178 ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
179 /* Prevent this function from being called during SSR since TL
180 * context may not be reinitialized at this time which may
181 * lead to a crash.
182 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800183 if (cds_is_driver_recovering()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530184 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800185 "%s: Recovery in Progress. Ignore!!!", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800186 goto drop_pkt;
187 }
188
189 /*
190 * If the device is operating on a DFS Channel
191 * then check if SAP is in CAC WAIT state and
192 * drop the packets. In CAC WAIT state device
193 * is expected not to transmit any frames.
194 * SAP starts Tx only after the BSS START is
195 * done.
196 */
197 if (pHddApCtx->dfs_cac_block_tx) {
198 goto drop_pkt;
199 }
200
Anurag Chouhan6d760662016-02-20 16:05:43 +0530201 pDestMacAddress = (struct qdf_mac_addr *) skb->data;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202
Anurag Chouhanc5548422016-02-24 18:33:27 +0530203 if (qdf_is_macaddr_broadcast(pDestMacAddress) ||
204 qdf_is_macaddr_group(pDestMacAddress)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800205 /* The BC/MC station ID is assigned during BSS
206 * starting phase. SAP will return the station ID
207 * used for BC/MC traffic.
208 */
209 STAId = pHddApCtx->uBCStaId;
210 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530211 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800212 hdd_softap_get_sta_id(pAdapter,
213 pDestMacAddress, &STAId)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530214 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
215 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800216 "%s: Failed to find right station", __func__);
217 goto drop_pkt;
218 }
219
220 if (STAId == HDD_WLAN_INVALID_STA_ID) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530221 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
222 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800223 "%s: Failed to find right station", __func__);
224 goto drop_pkt;
225 } else if (false == pAdapter->aStaInfo[STAId].isUsed) {
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: STA %d is unregistered", __func__,
229 STAId);
230 goto drop_pkt;
231 }
232
233 if ((ol_txrx_peer_state_conn !=
234 pAdapter->aStaInfo[STAId].tlSTAState)
235 && (ol_txrx_peer_state_auth !=
236 pAdapter->aStaInfo[STAId].tlSTAState)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530237 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
238 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239 "%s: Station not connected yet", __func__);
240 goto drop_pkt;
241 } else if (ol_txrx_peer_state_conn ==
242 pAdapter->aStaInfo[STAId].tlSTAState) {
243 if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530244 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
245 QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246 "%s: NON-EAPOL packet in non-Authenticated state",
247 __func__);
248 goto drop_pkt;
249 }
250 }
251 }
252
253 hdd_get_tx_resource(pAdapter, STAId,
254 WLAN_SAP_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
255
256 /* Get TL AC corresponding to Qdisc queue index/AC. */
257 ac = hdd_qdisc_ac_to_tl_ac[skb->queue_mapping];
258 ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
259
260#if defined (IPA_OFFLOAD)
Nirav Shahcbc6d722016-03-01 16:24:53 +0530261 if (!qdf_nbuf_ipa_owned_get(skb)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262#endif
263 /* Check if the buffer has enough header room */
264 skb = skb_unshare(skb, GFP_ATOMIC);
265 if (!skb)
Jeff Johnsonedeff232015-11-11 17:19:42 -0800266 goto drop_pkt_accounting;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800267
268 if (skb_headroom(skb) < dev->hard_header_len) {
269 struct sk_buff *tmp;
270 tmp = skb;
271 skb = skb_realloc_headroom(tmp, dev->hard_header_len);
272 dev_kfree_skb(tmp);
273 if (!skb)
Jeff Johnsonedeff232015-11-11 17:19:42 -0800274 goto drop_pkt_accounting;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800275 }
276#if defined (IPA_OFFLOAD)
277 }
278#endif
279
280 wlan_hdd_log_eapol(skb,
281 WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
282
283#ifdef QCA_PKT_PROTO_TRACE
284 if ((hddCtxt->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_EAPOL) ||
285 (hddCtxt->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_DHCP)) {
286 /* Proto Trace enabled */
287 proto_type = cds_pkt_get_proto_type(skb,
288 hddCtxt->config->
289 gEnableDebugLog, 0);
290 if (CDS_PKT_TRAC_TYPE_EAPOL & proto_type) {
291 cds_pkt_trace_buf_update("HA:T:EPL");
292 } else if (CDS_PKT_TRAC_TYPE_DHCP & proto_type) {
293 cds_pkt_trace_buf_update("HA:T:DHC");
294 }
295 }
296#endif /* QCA_PKT_PROTO_TRACE */
297 pAdapter->stats.tx_bytes += skb->len;
298 ++pAdapter->stats.tx_packets;
299
300 /* Zero out skb's context buffer for the driver to use */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530301 qdf_mem_set(skb->cb, sizeof(skb->cb), 0);
Nirav Shahcbc6d722016-03-01 16:24:53 +0530302 QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
303 QDF_NBUF_UPDATE_TX_PKT_COUNT(skb, QDF_NBUF_TX_PKT_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800304
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530305 qdf_dp_trace_set_track(skb);
306 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_PACKET_PTR_RECORD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800307 (uint8_t *)skb->data, sizeof(skb->data)));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530308 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_PACKET_RECORD,
Nirav Shahcbc6d722016-03-01 16:24:53 +0530309 (uint8_t *)skb->data, qdf_nbuf_len(skb)));
310 if (qdf_nbuf_len(skb) > QDF_DP_TRACE_RECORD_SIZE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530311 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_HDD_PACKET_RECORD,
312 (uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
Nirav Shahcbc6d722016-03-01 16:24:53 +0530313 (qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800314
315 if (ol_tx_send_data_frame(STAId, skb,
316 proto_type) != NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530317 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800318 "%s: Failed to send packet to txrx for staid:%d",
319 __func__, STAId);
320 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
321 goto drop_pkt;
322 }
323 dev->trans_start = jiffies;
324
325 return NETDEV_TX_OK;
326
327drop_pkt:
328
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530329 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_DROP_PACKET_RECORD,
Nirav Shahcbc6d722016-03-01 16:24:53 +0530330 (uint8_t *)skb->data, qdf_nbuf_len(skb)));
331 if (qdf_nbuf_len(skb) > QDF_DP_TRACE_RECORD_SIZE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530332 DPTRACE(qdf_dp_trace(skb, QDF_DP_TRACE_DROP_PACKET_RECORD,
333 (uint8_t *)&skb->data[QDF_DP_TRACE_RECORD_SIZE],
Nirav Shahcbc6d722016-03-01 16:24:53 +0530334 (qdf_nbuf_len(skb)-QDF_DP_TRACE_RECORD_SIZE)));
Jeff Johnsonedeff232015-11-11 17:19:42 -0800335 kfree_skb(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336
Jeff Johnsonedeff232015-11-11 17:19:42 -0800337drop_pkt_accounting:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800338 ++pAdapter->stats.tx_dropped;
339 ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800340
341 return NETDEV_TX_OK;
342}
343
344/**
345 * __hdd_softap_tx_timeout() - TX timeout handler
346 * @dev: pointer to network device
347 *
348 * This function is registered as a netdev ndo_tx_timeout method, and
349 * is invoked by the kernel if the driver takes too long to transmit a
350 * frame.
351 *
352 * Return: None
353 */
354static void __hdd_softap_tx_timeout(struct net_device *dev)
355{
356 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
357 hdd_context_t *hdd_ctx;
358
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530359 DPTRACE(qdf_dp_trace(NULL, QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800360 NULL, 0));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530361 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362 "%s: Transmission timeout occurred", __func__);
363 /* Getting here implies we disabled the TX queues for too
364 * long. Queues are disabled either because of disassociation
365 * or low resource scenarios. In case of disassociation it is
366 * ok to ignore this. But if associated, we have do possible
367 * recovery here
368 */
369 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800370 if (cds_is_driver_recovering()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530371 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800372 "%s: Recovery in Progress. Ignore!!!", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800373 return;
374 }
375}
376
377/**
378 * hdd_softap_tx_timeout() - SSR wrapper for __hdd_softap_tx_timeout
379 * @dev: pointer to net_device
380 *
381 * Return: none
382 */
383void hdd_softap_tx_timeout(struct net_device *dev)
384{
385 cds_ssr_protect(__func__);
386 __hdd_softap_tx_timeout(dev);
387 cds_ssr_unprotect(__func__);
388}
389
390/**
391 * @hdd_softap_init_tx_rx() - Initialize Tx/RX module
392 * @pAdapter: pointer to adapter context
393 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530394 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
395 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530397QDF_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530399 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400
401 uint8_t STAId = 0;
402
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530403 qdf_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404
405 spin_lock_init(&pAdapter->staInfo_lock);
406
407 for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530408 qdf_mem_zero(&pAdapter->aStaInfo[STAId],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 sizeof(hdd_station_info_t));
410 }
411
412 return status;
413}
414
415/**
416 * @hdd_softap_deinit_tx_rx() - Deinitialize Tx/RX module
417 * @pAdapter: pointer to adapter context
418 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530419 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
420 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530422QDF_STATUS hdd_softap_deinit_tx_rx(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530424 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800425
426 return status;
427}
428
429/**
430 * hdd_softap_init_tx_rx_sta() - Initialize tx/rx for a softap station
431 * @pAdapter: pointer to adapter context
432 * @STAId: Station ID to initialize
433 * @pmacAddrSTA: pointer to the MAC address of the station
434 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530435 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
436 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800437 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530438QDF_STATUS hdd_softap_init_tx_rx_sta(hdd_adapter_t *pAdapter, uint8_t STAId,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530439 struct qdf_mac_addr *pmacAddrSTA)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440{
441 spin_lock_bh(&pAdapter->staInfo_lock);
442 if (pAdapter->aStaInfo[STAId].isUsed) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530443 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444 "%s: Reinit station %d", __func__, STAId);
445 spin_unlock_bh(&pAdapter->staInfo_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530446 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 }
448
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530449 qdf_mem_zero(&pAdapter->aStaInfo[STAId], sizeof(hdd_station_info_t));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800450
451 pAdapter->aStaInfo[STAId].isUsed = true;
452 pAdapter->aStaInfo[STAId].isDeauthInProgress = false;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530453 qdf_copy_macaddr(&pAdapter->aStaInfo[STAId].macAddrSTA, pmacAddrSTA);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454
455 spin_unlock_bh(&pAdapter->staInfo_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530456 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457}
458
459/**
460 * hdd_softap_deinit_tx_rx_sta() - Deinitialize tx/rx for a softap station
461 * @pAdapter: pointer to adapter context
462 * @STAId: Station ID to deinitialize
463 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530464 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
465 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530467QDF_STATUS hdd_softap_deinit_tx_rx_sta(hdd_adapter_t *pAdapter, uint8_t STAId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800468{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530469 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470 hdd_hostapd_state_t *pHostapdState;
471
472 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
473
474 spin_lock_bh(&pAdapter->staInfo_lock);
475
476 if (false == pAdapter->aStaInfo[STAId].isUsed) {
477 spin_unlock_bh(&pAdapter->staInfo_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530478 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800479 "%s: Deinit station not inited %d", __func__, STAId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530480 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800481 }
482
483 pAdapter->aStaInfo[STAId].isUsed = false;
484 pAdapter->aStaInfo[STAId].isDeauthInProgress = false;
485
486 spin_unlock_bh(&pAdapter->staInfo_lock);
487 return status;
488}
489
490/**
491 * hdd_softap_rx_packet_cbk() - Receive packet handler
492 * @cds_context: pointer to CDS context
Nirav Shahcbc6d722016-03-01 16:24:53 +0530493 * @rxBuf: pointer to rx qdf_nbuf
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800494 * @staId: Station Id
495 *
496 * Receive callback registered with TL. TL will call this to notify
497 * the HDD when one or more packets were received for a registered
498 * STA.
499 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530500 * Return: QDF_STATUS_E_FAILURE if any errors encountered,
501 * QDF_STATUS_SUCCESS otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800502 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530503QDF_STATUS hdd_softap_rx_packet_cbk(void *cds_context,
Nirav Shahcbc6d722016-03-01 16:24:53 +0530504 qdf_nbuf_t rxBuf, uint8_t staId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800505{
506 hdd_adapter_t *pAdapter = NULL;
507 int rxstat;
508 unsigned int cpu_index;
509 struct sk_buff *skb = NULL;
510 hdd_context_t *pHddCtx = NULL;
511#ifdef QCA_PKT_PROTO_TRACE
512 uint8_t proto_type;
513#endif /* QCA_PKT_PROTO_TRACE */
514
515 /* Sanity check on inputs */
516 if ((NULL == cds_context) || (NULL == rxBuf)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530517 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518 "%s: Null params being passed", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530519 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 }
521
Anurag Chouhan6d760662016-02-20 16:05:43 +0530522 pHddCtx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800523 if (NULL == pHddCtx) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530524 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800525 "%s: HDD context is Null", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530526 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527 }
528
529 pAdapter = pHddCtx->sta_to_adapter[staId];
530 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
531 hddLog(LOGE,
532 FL("invalid adapter %p or adapter has invalid magic"),
533 pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530534 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535 }
536
537 /* walk the chain until all are processed */
538 skb = (struct sk_buff *)rxBuf;
539
540 hdd_softap_dump_sk_buff(skb);
541
542 skb->dev = pAdapter->dev;
543
544 if (skb->dev == NULL) {
545
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530546 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800547 "%s: ERROR!!Invalid netdevice", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530548 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800549 }
550 cpu_index = wlan_hdd_get_cpu();
551 ++pAdapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
552 ++pAdapter->stats.rx_packets;
553 pAdapter->stats.rx_bytes += skb->len;
554
555 wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
556
557#ifdef QCA_PKT_PROTO_TRACE
558 if ((pHddCtx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_EAPOL) ||
559 (pHddCtx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_DHCP)) {
560 proto_type = cds_pkt_get_proto_type(skb,
561 pHddCtx->config->
562 gEnableDebugLog, 0);
563 if (CDS_PKT_TRAC_TYPE_EAPOL & proto_type) {
564 cds_pkt_trace_buf_update("HA:R:EPL");
565 } else if (CDS_PKT_TRAC_TYPE_DHCP & proto_type) {
566 cds_pkt_trace_buf_update("HA:R:DHC");
567 }
568 }
569#endif /* QCA_PKT_PROTO_TRACE */
570
571 skb->protocol = eth_type_trans(skb, skb->dev);
572#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530573 qdf_wake_lock_timeout_acquire(&pHddCtx->rx_wake_lock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574 HDD_WAKE_LOCK_DURATION,
575 WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
576#endif
577
578 /* Remove SKB from internal tracking table before submitting
579 * it to stack
580 */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530581 qdf_net_buf_debug_release_skb(rxBuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582
Orhan K AKYILDIZ4f20db52015-12-30 12:35:44 -0800583 if (hdd_napi_enabled(HDD_NAPI_ANY) && !pHddCtx->config->enableRxThread)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 rxstat = netif_receive_skb(skb);
585 else
586 rxstat = netif_rx_ni(skb);
587 if (NET_RX_SUCCESS == rxstat) {
588 ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
589 } else {
590 ++pAdapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
591 }
592
593 pAdapter->dev->last_rx = jiffies;
594
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530595 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800596}
597
598/**
599 * hdd_softap_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
600 * @pAdapter: pointer to adapter context
601 * @staId: Station ID to deregister
602 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530603 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530605QDF_STATUS hdd_softap_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800606{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530607 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608 hdd_context_t *pHddCtx;
609
610 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530611 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800612 "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530613 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614 }
615
616 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530617 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800618 "%s: Invalid pAdapter magic", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530619 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800620 }
621
622 pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
623 /* Clear station in TL and then update HDD data
624 * structures. This helps to block RX frames from other
625 * station to this station.
626 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530627 qdf_status = ol_txrx_clear_peer(staId);
628 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530629 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 "ol_txrx_clear_peer() failed to for staID %d. "
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530631 "Status= %d [0x%08X]", staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632 }
633
634 if (pAdapter->aStaInfo[staId].isUsed) {
635 spin_lock_bh(&pAdapter->staInfo_lock);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530636 qdf_mem_zero(&pAdapter->aStaInfo[staId],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800637 sizeof(hdd_station_info_t));
638 spin_unlock_bh(&pAdapter->staInfo_lock);
639 }
640 pHddCtx->sta_to_adapter[staId] = NULL;
641
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530642 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800643}
644
645/**
646 * hdd_softap_register_sta() - Register a SoftAP STA
647 * @pAdapter: pointer to adapter context
648 * @fAuthRequired: is additional authentication required?
649 * @fPrivacyBit: should 802.11 privacy bit be set?
650 * @staId: station ID assigned to this station
651 * @ucastSig: unicast security signature
652 * @bcastSig: broadcast security signature
653 * @pPeerMacAddress: station MAC address
654 * @fWmmEnabled: is WMM enabled for this STA?
655 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530656 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800657 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530658QDF_STATUS hdd_softap_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 bool fAuthRequired,
660 bool fPrivacyBit,
661 uint8_t staId,
662 uint8_t ucastSig,
663 uint8_t bcastSig,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530664 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800665 bool fWmmEnabled)
666{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530667 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800668 struct ol_txrx_desc_type staDesc = { 0 };
669 hdd_context_t *pHddCtx = pAdapter->pHddCtx;
670
671 /*
672 * Clean up old entry if it is not cleaned up properly
673 */
674 if (pAdapter->aStaInfo[staId].isUsed) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530675 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676 "clean up old entry for STA %d", staId);
677 hdd_softap_deregister_sta(pAdapter, staId);
678 }
679 /* Get the Station ID from the one saved during the assocation. */
680
681 staDesc.sta_id = staId;
682
683 /*Save the pAdapter Pointer for this staId */
684 pHddCtx->sta_to_adapter[staId] = pAdapter;
685
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530686 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800687 hdd_softap_init_tx_rx_sta(pAdapter, staId,
688 pPeerMacAddress);
689
690 staDesc.is_qos_enabled = fWmmEnabled;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530691 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 "HDD SOFTAP register TL QoS_enabled=%d",
693 staDesc.is_qos_enabled);
694
695
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530696 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697 ol_txrx_register_peer(hdd_softap_rx_packet_cbk,
698 &staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530699 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530700 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701 "SOFTAP ol_txrx_register_peer() failed to register. Status= %d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530702 qdf_status, qdf_status);
703 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704 }
705
706 /* if ( WPA ), tell TL to go to 'connected' and after keys come to the
707 * driver then go to 'authenticated'. For all other authentication
708 * types (those that do not require upper layer authentication) we can
709 * put TL directly into 'authenticated' state
710 */
711
712 pAdapter->aStaInfo[staId].ucSTAId = staId;
713 pAdapter->aStaInfo[staId].isQosEnabled = fWmmEnabled;
714
715 if (!fAuthRequired) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530716 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
718 pAdapter->aStaInfo[staId].ucSTAId);
719
720 /* Connections that do not need Upper layer auth,
721 * transition TL directly to 'Authenticated' state.
722 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530723 qdf_status = hdd_change_peer_state(pAdapter, staDesc.sta_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800724 ol_txrx_peer_state_auth, false);
725
726 pAdapter->aStaInfo[staId].tlSTAState = ol_txrx_peer_state_auth;
727 pAdapter->sessionCtx.ap.uIsAuthenticated = true;
728 } else {
729
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530730 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
732 pAdapter->aStaInfo[staId].ucSTAId);
733
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530734 qdf_status = hdd_change_peer_state(pAdapter, staDesc.sta_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735 ol_txrx_peer_state_conn, false);
736 pAdapter->aStaInfo[staId].tlSTAState = ol_txrx_peer_state_conn;
737
738 pAdapter->sessionCtx.ap.uIsAuthenticated = false;
739
740 }
741
742 /* Enable Tx queue */
743 hddLog(LOG1, FL("Enabling queues"));
744 wlan_hdd_netif_queue_control(pAdapter,
745 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
746 WLAN_CONTROL_PATH);
747
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530748 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800749}
750
751/**
752 * hdd_softap_register_bc_sta() - Register the SoftAP broadcast STA
753 * @pAdapter: pointer to adapter context
754 * @fPrivacyBit: should 802.11 privacy bit be set?
755 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530756 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530758QDF_STATUS hdd_softap_register_bc_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 bool fPrivacyBit)
760{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530761 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530763 struct qdf_mac_addr broadcastMacAddr =
764 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800765 hdd_ap_ctx_t *pHddApCtx;
766
767 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
768
769 pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter;
770#ifdef WLAN_FEATURE_MBSSID
771 pHddCtx->sta_to_adapter[pHddApCtx->uBCStaId] = pAdapter;
772#else
773 pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter;
774#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530775 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800776 hdd_softap_register_sta(pAdapter, false, fPrivacyBit,
777 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->
778 uBCStaId, 0, 1, &broadcastMacAddr, 0);
779
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530780 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781}
782
783/**
784 * hdd_softap_deregister_bc_sta() - Deregister the SoftAP broadcast STA
785 * @pAdapter: pointer to adapter context
786 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530787 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530789QDF_STATUS hdd_softap_deregister_bc_sta(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790{
791 return hdd_softap_deregister_sta(pAdapter,
792 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->
793 uBCStaId);
794}
795
796/**
797 * hdd_softap_stop_bss() - Stop the BSS
798 * @pAdapter: pointer to adapter context
799 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530800 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530802QDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530804 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805 uint8_t staId = 0;
806 hdd_context_t *pHddCtx;
807 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
808
809 /* bss deregister is not allowed during wlan driver loading or
810 * unloading
811 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800812 if (cds_is_load_or_unload_in_progress()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530813 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800814 "%s: Loading_unloading in Progress, state: 0x%x. Ignore!!!",
815 __func__, cds_get_driver_state());
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530816 return QDF_STATUS_E_PERM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 }
818
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530819 qdf_status = hdd_softap_deregister_bc_sta(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530821 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530822 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823 "%s: Failed to deregister BC sta Id %d", __func__,
824 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId);
825 }
826
827 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
828 /* This excludes BC sta as it is already deregistered */
829 if (pAdapter->aStaInfo[staId].isUsed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530830 qdf_status = hdd_softap_deregister_sta(pAdapter, staId);
831 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530832 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
833 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834 "%s: Failed to deregister sta Id %d",
835 __func__, staId);
836 }
837 }
838 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530839 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800840}
841
842/**
843 * hdd_softap_change_sta_state() - Change the state of a SoftAP station
844 * @pAdapter: pointer to adapter context
845 * @pDestMacAddress: MAC address of the station
846 * @state: new state of the station
847 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530848 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800849 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530850QDF_STATUS hdd_softap_change_sta_state(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530851 struct qdf_mac_addr *pDestMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 enum ol_txrx_peer_state state)
853{
854 uint8_t ucSTAId = WLAN_MAX_STA_COUNT;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530855 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800856
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530857 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800858 "%s: enter", __func__);
859
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530860 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861 hdd_softap_get_sta_id(pAdapter,
862 pDestMacAddress, &ucSTAId)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530863 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864 "%s: Failed to find right station", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530865 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 }
867
868 if (false ==
Anurag Chouhanc5548422016-02-24 18:33:27 +0530869 qdf_is_macaddr_equal(&pAdapter->aStaInfo[ucSTAId].macAddrSTA,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870 pDestMacAddress)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530871 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872 "%s: Station MAC address does not matching",
873 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530874 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875 }
876
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530877 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878 hdd_change_peer_state(pAdapter, ucSTAId, state, false);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530879 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880 "%s: change station to state %d succeed", __func__, state);
881
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530882 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 pAdapter->aStaInfo[ucSTAId].tlSTAState =
884 ol_txrx_peer_state_auth;
885 }
886
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530887 QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 "%s exit", __func__);
889
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530890 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891}
892
893/*
894 * hdd_softap_get_sta_id() - Find station ID from MAC address
895 * @pAdapter: pointer to adapter context
896 * @pDestMacAddress: MAC address of the destination
897 * @staId: Station ID associated with the MAC address
898 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530899 * Return: QDF_STATUS_SUCCESS if a match was found, in which case
900 * staId is populated, QDF_STATUS_E_FAILURE if a match is
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901 * not found
902 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530903QDF_STATUS hdd_softap_get_sta_id(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530904 struct qdf_mac_addr *pMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 uint8_t *staId)
906{
907 uint8_t i;
908
909 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530910 if (!qdf_mem_cmp
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800911 (&pAdapter->aStaInfo[i].macAddrSTA, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530912 QDF_MAC_ADDR_SIZE) && pAdapter->aStaInfo[i].isUsed) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800913 *staId = i;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530914 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800915 }
916 }
917
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530918 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919}