blob: 7fb25cb74d9acb0f29ad6350a60cd136aa9b25f4 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302 * Copyright (c) 2011-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
28/**
29 * \file lim_send_management_frames.c
30 *
31 * \brief Code for preparing and sending 802.11 Management frames
32 *
33 *
34 */
35
36#include "sir_api.h"
37#include "ani_global.h"
38#include "sir_mac_prot_def.h"
39#include "cfg_api.h"
40#include "utils_api.h"
41#include "lim_types.h"
42#include "lim_utils.h"
43#include "lim_security_utils.h"
44#include "lim_prop_exts_utils.h"
45#include "dot11f.h"
46#include "lim_sta_hash_api.h"
47#include "sch_api.h"
48#include "lim_send_messages.h"
49#include "lim_assoc_utils.h"
50#include "lim_ft.h"
51#ifdef WLAN_FEATURE_11W
52#include "wni_cfg.h"
53#endif
54
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080055#include "lim_ft_defs.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080056#include "lim_session.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053057#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053058#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059#include "cds_utils.h"
60#include "sme_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#include "rrm_api.h"
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +053062#include "qdf_crypto.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063
64#include "wma_types.h"
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -080065#include <cdp_txrx_cmn.h>
Tushnim Bhattacharyya45ed04f2017-03-15 10:15:05 -070066#include <cdp_txrx_peer_ops.h>
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053067#include "lim_process_fils.h"
Naveen Rawat08db88f2017-09-08 15:07:48 -070068#include "wlan_utility.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080069
70/**
71 *
72 * \brief This function is called to add the sequence number to the
73 * management frames
74 *
75 * \param pMac Pointer to Global MAC structure
76 *
77 * \param pMacHdr Pointer to MAC management header
78 *
79 * The pMacHdr argument points to the MAC management header. The
80 * sequence number stored in the pMac structure will be incremented
81 * and updated to the MAC management header. The start sequence
82 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
83 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
84 * number will roll over.
85 *
86 */
Jeff Johnson38112a32016-10-07 07:30:50 -070087static void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088{
89 if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
90 pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
91 }
92
93 pMac->mgmtSeqNum++;
94
95 pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
96 pMacHdr->seqControl.seqNumHi =
97 ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
98}
99
100/**
101 *
102 * \brief This function is called before sending a p2p action frame
103 * inorder to add sequence numbers to action packets
104 *
105 * \param pMac Pointer to Global MAC structure
106 *
107 * \param pBD Pointer to the frame buffer that needs to be populate
108 *
109 * The pMacHdr argument points to the MAC management header. The
110 * sequence number stored in the pMac structure will be incremented
111 * and updated to the MAC management header. The start sequence
112 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
113 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
114 * number will roll over.
115 *
116 */
117void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
118{
119 tpSirMacMgmtHdr pMacHdr;
120
121 /* / Prepare MAC management header */
122 pMacHdr = (tpSirMacMgmtHdr) (pBD);
123
124 /* Prepare sequence number */
125 lim_add_mgmt_seq_num(pMac, pMacHdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700126 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800127 pMacHdr->seqControl.seqNumLo,
128 pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
129}
130
131/**
132 * lim_populate_mac_header() - Fill in 802.11 header of frame
133 *
134 * @mac_ctx: Pointer to Global MAC structure
135 * @buf: Pointer to the frame buffer that needs to be populate
136 * @type: 802.11 Type of the frame
137 * @sub_type: 802.11 Subtype of the frame
138 * @peer_addr: dst address
139 * @self_mac_addr: local mac address
140 *
141 * This function is called by various LIM modules to prepare the
142 * 802.11 frame MAC header
143 *
144 * The buf argument points to the beginning of the frame buffer to
145 * which - a) The 802.11 MAC header is set b) Following this MAC header
146 * will be the MGMT frame payload The payload itself is populated by the
147 * caller API
148 *
149 * Return: None
150 */
151
152void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
153 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
154 tSirMacAddr self_mac_addr)
155{
156 tpSirMacMgmtHdr mac_hdr;
157
158 /* Prepare MAC management header */
159 mac_hdr = (tpSirMacMgmtHdr) (buf);
160
161 /* Prepare FC */
162 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
163 mac_hdr->fc.type = type;
164 mac_hdr->fc.subType = sub_type;
165
166 /* Prepare Address 1 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530167 qdf_mem_copy((uint8_t *) mac_hdr->da,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800168 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
169
170 /* Prepare Address 2 */
171 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
172
173 /* Prepare Address 3 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530174 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800175 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
176
177 /* Prepare sequence number */
178 lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700179 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800180 mac_hdr->seqControl.seqNumLo,
181 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
182}
183
184/**
185 * lim_send_probe_req_mgmt_frame() - send probe request management frame
186 * @mac_ctx: Pointer to Global MAC structure
187 * @ssid: SSID to be sent in Probe Request frame
188 * @bssid: BSSID to be sent in Probe Request frame
189 * @channel: Channel # on which the Probe Request is going out
190 * @self_macaddr: self MAC address
191 * @dot11mode: self dotllmode
192 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
193 * frame
194 * @additional_ie: if additional_ielen is non zero, include this field in the
195 * Probe Request frame
196 *
197 * This function is called by various LIM modules to send Probe Request frame
198 * during active scan/learn phase.
199 * Probe request is sent out in the following scenarios:
200 * --heartbeat failure: session needed
201 * --join req: session needed
202 * --foreground scan: no session
203 * --background scan: no session
204 * --sch_beacon_processing: to get EDCA parameters: session needed
205 *
206 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
207 */
208tSirRetStatus
209lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
210 tSirMacSSid *ssid,
211 tSirMacAddr bssid,
212 uint8_t channel,
213 tSirMacAddr self_macaddr,
214 uint32_t dot11mode,
215 uint32_t additional_ielen, uint8_t *additional_ie)
216{
217 tDot11fProbeRequest pr;
218 uint32_t status, bytes, payload;
219 uint8_t *frame;
220 void *packet;
Kapil Guptac03eb072016-08-09 14:01:36 +0530221 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800222 tpPESession pesession;
223 uint8_t sessionid;
Naveen Rawat08db88f2017-09-08 15:07:48 -0700224 const uint8_t *p2pie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800225 uint8_t txflag = 0;
226 uint8_t sme_sessionid = 0;
227 bool is_vht_enabled = false;
228 uint8_t txPower;
229 uint16_t addn_ielen = additional_ielen;
Kapil Guptac03eb072016-08-09 14:01:36 +0530230 bool extracted_ext_cap_flag = false;
231 tDot11fIEExtCap extracted_ext_cap;
232 tSirRetStatus sir_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800233
234 /* The probe req should not send 11ac capabilieties if band is 2.4GHz,
235 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
236 * is false and dot11mode is 11ac set it to 11n.
237 */
238 if (channel <= SIR_11B_CHANNEL_END &&
239 (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
240 (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
241 WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
242 dot11mode = WNI_CFG_DOT11_MODE_11N;
243 /*
244 * session context may or may not be present, when probe request needs
245 * to be sent out. Following cases exist:
246 * --heartbeat failure: session needed
247 * --join req: session needed
248 * --foreground scan: no session
249 * --background scan: no session
250 * --sch_beacon_processing: to get EDCA parameters: session needed
251 * If session context does not exist, some IEs will be populated from
252 * CFGs, e.g. Supported and Extended rate set IEs
253 */
254 pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
255
256 if (pesession != NULL)
257 sme_sessionid = pesession->smeSessionId;
258
259 /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
260 /* and then hand it off to 'dot11f_pack_probe_request' (for */
261 /* serialization). We start by zero-initializing the structure: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530262 qdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800263
264 /* & delegating to assorted helpers: */
265 populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
266
267 if (addn_ielen && additional_ie)
268 p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
269
270 /*
271 * Don't include 11b rate if it is a P2P serach or probe request is
272 * sent by P2P Client
273 */
274 if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
275 (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
276 mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
277 ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530278 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800279 )
280 ) {
281 /*
282 * In the below API pass channel number > 14, do that it fills
283 * only 11a rates in supported rates
284 */
285 populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
286 pesession);
287 } else {
288 populate_dot11f_supp_rates(mac_ctx, channel,
289 &pr.SuppRates, pesession);
290
291 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
292 populate_dot11f_ext_supp_rates1(mac_ctx, channel,
293 &pr.ExtSuppRates);
294 }
295 }
296
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800297 /*
298 * Table 7-14 in IEEE Std. 802.11k-2008 says
299 * DS params "can" be present in RRM is disabled and "is" present if
300 * RRM is enabled. It should be ok even if we add it into probe req when
301 * RRM is not enabled.
302 */
303 populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
304 /* Call RRM module to get the tx power for management used. */
305 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
306 populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
307
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800308
309 if (pesession != NULL) {
310 pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
311 /* Include HT Capability IE */
312 if (pesession->htCapability)
313 populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
314 } else { /* pesession == NULL */
315 if (IS_DOT11_MODE_HT(dot11mode))
316 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
317 }
318
319 /*
320 * Set channelbonding information as "disabled" when tunned to a
321 * 2.4 GHz channel
322 */
323 if (channel <= SIR_11B_CHANNEL_END) {
324 if (mac_ctx->roam.configParam.channelBondingMode24GHz
325 == PHY_SINGLE_CHANNEL_CENTERED) {
326 pr.HTCaps.supportedChannelWidthSet =
327 eHT_CHANNEL_WIDTH_20MHZ;
328 pr.HTCaps.shortGI40MHz = 0;
329 } else {
330 pr.HTCaps.supportedChannelWidthSet =
331 eHT_CHANNEL_WIDTH_40MHZ;
332 }
333 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800334 if (pesession != NULL) {
335 pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
336 /* Include VHT Capability IE */
337 if (pesession->vhtCapability) {
338 populate_dot11f_vht_caps(mac_ctx, pesession,
339 &pr.VHTCaps);
340 is_vht_enabled = true;
341 }
342 } else {
343 if (IS_DOT11_MODE_VHT(dot11mode)) {
344 populate_dot11f_vht_caps(mac_ctx, pesession,
345 &pr.VHTCaps);
346 is_vht_enabled = true;
347 }
348 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800349 if (pesession != NULL)
350 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
351 pesession);
352
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +0530353 if (mac_ctx->roam.configParam.qcn_ie_support)
354 populate_dot11f_qcn_ie(&pr.QCN_IE);
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +0530355
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800356 if (IS_DOT11_MODE_HE(dot11mode) && NULL != pesession)
357 lim_update_session_he_capable(mac_ctx, pesession);
358
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700359 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800360 populate_dot11f_he_caps(mac_ctx, pesession, &pr.vendor_he_cap);
361
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362 if (addn_ielen) {
Kapil Guptac03eb072016-08-09 14:01:36 +0530363 qdf_mem_zero((uint8_t *)&extracted_ext_cap,
364 sizeof(tDot11fIEExtCap));
365 sir_status = lim_strip_extcap_update_struct(mac_ctx,
366 additional_ie,
367 &addn_ielen,
368 &extracted_ext_cap);
369 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700370 pe_debug("Unable to Stripoff ExtCap IE from Probe Req");
Kapil Guptac03eb072016-08-09 14:01:36 +0530371 } else {
372 struct s_ext_cap *p_ext_cap =
373 (struct s_ext_cap *)
374 extracted_ext_cap.bytes;
375 if (p_ext_cap->interworking_service)
376 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +0800377 extracted_ext_cap.num_bytes =
378 lim_compute_ext_cap_ie_length
379 (&extracted_ext_cap);
Kapil Guptac03eb072016-08-09 14:01:36 +0530380 extracted_ext_cap_flag =
Hu Wang411e0cc2016-10-28 14:56:01 +0800381 (extracted_ext_cap.num_bytes > 0);
Kapil Guptac03eb072016-08-09 14:01:36 +0530382 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800383 }
384
Hu Wang411e0cc2016-10-28 14:56:01 +0800385 /*
386 * Extcap IE now support variable length, merge Extcap IE from addn_ie
387 * may change the frame size. Therefore, MUST merge ExtCap IE before
388 * dot11f get packed payload size.
389 */
390 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800391 lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800392
393 /* That's it-- now we pack it. First, how much space are we going to */
394 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
395 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700396 pe_err("Failed to calculate the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800397 status);
398 /* We'll fall back on the worst case scenario: */
399 payload = sizeof(tDot11fProbeRequest);
400 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700401 pe_warn("There were warnings while calculating the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800402 status);
403 }
404
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800405 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
406
407 /* Ok-- try to allocate some memory: */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530408 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530410 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700411 pe_err("Failed to allocate %d bytes for a Probe Request", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412 return eSIR_MEM_ALLOC_FAILED;
413 }
414 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530415 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800416
417 /* Next, we fill out the buffer descriptor: */
418 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
419 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
420
421 /* That done, pack the Probe Request: */
422 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
423 sizeof(tSirMacMgmtHdr),
424 payload, &payload);
425 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700426 pe_err("Failed to pack a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800427 cds_packet_free((void *)packet);
428 return eSIR_FAILURE; /* allocated! */
429 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700430 pe_warn("There were warnings while packing a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 }
432 /* Append any AddIE if present. */
433 if (addn_ielen) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530434 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800435 additional_ie, addn_ielen);
436 payload += addn_ielen;
437 }
438
439 /* If this probe request is sent during P2P Search State, then we need
440 * to send it at OFDM rate.
441 */
442 if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
443 || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
444 mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
445 /*
446 * For unicast probe req mgmt from Join function we don't set
447 * above variables. So we need to add one more check whether it
448 * is pePersona is P2P_CLIENT or not
449 */
450 || ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530451 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 ) {
453 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
454 }
455
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530456 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457 wma_tx_frame(mac_ctx, packet,
458 (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
459 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
460 lim_tx_complete, frame, txflag, sme_sessionid,
Naveen Rawat296a5182017-09-25 14:02:48 -0700461 0, RATEID_DEFAULT);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530462 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700463 pe_err("could not send Probe Request frame!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464 /* Pkt will be freed up by the callback */
465 return eSIR_FAILURE;
466 }
467
468 return eSIR_SUCCESS;
469} /* End lim_send_probe_req_mgmt_frame. */
470
Jeff Johnson38112a32016-10-07 07:30:50 -0700471static tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800472 uint8_t *addIE, uint16_t *addnIELen,
473 uint8_t probeReqP2pIe)
474{
475 /* If Probe request doesn't have P2P IE, then take out P2P IE
476 from additional IE */
477 if (!probeReqP2pIe) {
478 uint8_t *tempbuf = NULL;
479 uint16_t tempLen = 0;
480 int left = *addnIELen;
481 uint8_t *ptr = addIE;
482 uint8_t elem_id, elem_len;
483
484 if (NULL == addIE) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700485 pe_err("NULL addIE pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800486 return eSIR_FAILURE;
487 }
488
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530489 tempbuf = qdf_mem_malloc(left);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 if (NULL == tempbuf) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700491 pe_err("Unable to allocate memory to store addn IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800492 return eSIR_MEM_ALLOC_FAILED;
493 }
494
495 while (left >= 2) {
496 elem_id = ptr[0];
497 elem_len = ptr[1];
498 left -= 2;
499 if (elem_len > left) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700500 pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800501 elem_id, elem_len, left);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530502 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800503 return eSIR_FAILURE;
504 }
505 if (!((SIR_MAC_EID_VENDOR == elem_id) &&
506 (memcmp
507 (&ptr[2], SIR_MAC_P2P_OUI,
508 SIR_MAC_P2P_OUI_SIZE) == 0))) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530509 qdf_mem_copy(tempbuf + tempLen, &ptr[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510 elem_len + 2);
511 tempLen += (elem_len + 2);
512 }
513 left -= elem_len;
514 ptr += (elem_len + 2);
515 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530516 qdf_mem_copy(addIE, tempbuf, tempLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517 *addnIELen = tempLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530518 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519 }
520 return eSIR_SUCCESS;
521}
522
523/**
524 * lim_send_probe_rsp_mgmt_frame() - Send probe response
525 *
526 * @mac_ctx: Handle for mac context
527 * @peer_macaddr: Mac address of requesting peer
528 * @ssid: SSID for response
529 * @n_staid: Station ID, currently unused.
530 * @pe_session: PE session id
531 * @keepalive: Keep alive flag. Currently unused.
532 * @preq_p2pie: P2P IE in incoming probe request
533 *
534 * Builds and sends probe response frame to the requesting peer
535 *
536 * Return: void
537 */
538
539void
540lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
541 tSirMacAddr peer_macaddr,
542 tpAniSSID ssid,
543 short n_staid,
544 uint8_t keepalive,
545 tpPESession pe_session, uint8_t preq_p2pie)
546{
547 tDot11fProbeResponse *frm;
548 tSirRetStatus sir_status;
Hu Wang411e0cc2016-10-28 14:56:01 +0800549 uint32_t cfg, payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800550 tpSirMacMgmtHdr mac_hdr;
551 uint8_t *frame;
Arif Hussainfbf50682016-06-15 12:57:43 -0700552 void *packet = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530553 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800554 uint32_t addn_ie_present = false;
555
556 uint16_t addn_ie_len = 0;
557 uint32_t wps_ap = 0, tmp;
558 uint8_t tx_flag = 0;
559 uint8_t *add_ie = NULL;
Naveen Rawat08db88f2017-09-08 15:07:48 -0700560 const uint8_t *p2p_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800561 uint8_t noalen = 0;
562 uint8_t total_noalen = 0;
563 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
564 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
565 uint8_t sme_sessionid = 0;
566 bool is_vht_enabled = false;
Padma, Santhosh Kumar92234472017-04-19 18:20:02 +0530567 tDot11fIEExtCap extracted_ext_cap = {0};
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530568 bool extracted_ext_cap_flag = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800569
570 /* We don't answer requests in this case*/
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700571 if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 return;
573
574 if (NULL == pe_session)
575 return;
576
577 /*
578 * In case when cac timer is running for this SAP session then
579 * avoid sending probe rsp out. It is violation of dfs specification.
580 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530581 if (((pe_session->pePersona == QDF_SAP_MODE) ||
582 (pe_session->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800583 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530584 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800585 FL("CAC timer is running, probe response dropped"));
586 return;
587 }
588 sme_sessionid = pe_session->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530589 frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700591 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 return;
593 }
594
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800595 /*
596 * Fill out 'frm', after which we'll just hand the struct off to
597 * 'dot11f_pack_probe_response'.
598 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530599 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800600
601 /*
602 * Timestamp to be updated by TFP, below.
603 *
604 * Beacon Interval:
605 */
606 if (LIM_IS_AP_ROLE(pe_session)) {
607 frm->BeaconInterval.interval =
608 mac_ctx->sch.schObject.gSchBeaconInterval;
609 } else {
610 sir_status = wlan_cfg_get_int(mac_ctx,
611 WNI_CFG_BEACON_INTERVAL, &cfg);
612 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700613 pe_err("Failed to get WNI_CFG_BEACON_INTERVAL (%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800614 sir_status);
615 goto err_ret;
616 }
617 frm->BeaconInterval.interval = (uint16_t) cfg;
618 }
619
620 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
621 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
622 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
623 &frm->SuppRates, pe_session);
624
625 populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
626 pe_session->currentOperChannel);
627 populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
628
629 if (LIM_IS_AP_ROLE(pe_session)) {
630 if (pe_session->wps_state != SAP_WPS_DISABLED)
631 populate_dot11f_probe_res_wpsi_es(mac_ctx,
632 &frm->WscProbeRes,
633 pe_session);
634 } else {
635 if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
636 &tmp) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700637 pe_err("Failed to cfg get id %d", WNI_CFG_WPS_ENABLE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638
639 wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
640
641 if (wps_ap)
642 populate_dot11f_wsc_in_probe_res(mac_ctx,
643 &frm->WscProbeRes);
644
645 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
646 eLIM_WSC_ENROLL_BEGIN) {
647 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
648 &frm->WscProbeRes);
649 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
650 eLIM_WSC_ENROLL_IN_PROGRESS;
651 }
652
653 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
654 eLIM_WSC_ENROLL_END) {
655 de_populate_dot11f_wsc_registrar_info_in_probe_res(
656 mac_ctx, &frm->WscProbeRes);
657 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
658 eLIM_WSC_ENROLL_NOOP;
659 }
660 }
661
662 populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
663 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
664
665 if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
666 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
667
668 populate_dot11f_ext_supp_rates(mac_ctx,
669 POPULATE_DOT11F_RATES_OPERATIONAL,
670 &frm->ExtSuppRates, pe_session);
671
672 /* Populate HT IEs, when operating in 11n */
673 if (pe_session->htCapability) {
674 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
675 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
676 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677 if (pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700678 pe_debug("Populate VHT IE in Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800679 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
680 populate_dot11f_vht_operation(mac_ctx, pe_session,
681 &frm->VHTOperation);
682 /*
683 * we do not support multi users yet.
684 * populate_dot11f_vht_ext_bss_load( mac_ctx,
685 * &frm.VHTExtBssLoad );
686 */
687 is_vht_enabled = true;
688 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800689
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800690 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700691 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800692 populate_dot11f_he_caps(mac_ctx, pe_session,
693 &frm->vendor_he_cap);
694 populate_dot11f_he_operation(mac_ctx, pe_session,
695 &frm->vendor_he_op);
696 }
697
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
699 pe_session);
700
701 if (pe_session->pLimStartBssReq) {
702 populate_dot11f_wpa(mac_ctx,
703 &(pe_session->pLimStartBssReq->rsnIE),
704 &frm->WPA);
705 populate_dot11f_rsn_opaque(mac_ctx,
706 &(pe_session->pLimStartBssReq->rsnIE),
707 &frm->RSNOpaque);
708 }
709
710 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
711 &frm->WMMCaps, pe_session);
712
713#if defined(FEATURE_WLAN_WAPI)
714 if (pe_session->pLimStartBssReq)
715 populate_dot11f_wapi(mac_ctx,
716 &(pe_session->pLimStartBssReq->rsnIE),
717 &frm->WAPI);
718#endif /* defined(FEATURE_WLAN_WAPI) */
719
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800720 if (mac_ctx->lim.gpLimRemainOnChanReq)
721 bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
722 sizeof(tSirRemainOnChnReq));
723 else
724 /*
725 * Only use CFG for non-listen mode. This CFG is not working for
726 * concurrency. In listening mode, probe rsp IEs is passed in
727 * the message from SME to PE.
728 */
729 addn_ie_present =
730 (pe_session->addIeParams.probeRespDataLen != 0);
731
732 if (addn_ie_present) {
733
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530734 add_ie = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735 pe_session->addIeParams.probeRespDataLen);
736 if (NULL == add_ie) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700737 pe_err("add_ie allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738 goto err_ret;
739 }
740
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530741 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800742 pe_session->addIeParams.probeRespData_buff,
743 pe_session->addIeParams.probeRespDataLen);
744 addn_ie_len = pe_session->addIeParams.probeRespDataLen;
745
746 if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
747 add_ie, &addn_ie_len, preq_p2pie)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700748 pe_err("Unable to get addn_ie");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800749 goto err_ret;
750 }
751
752 sir_status = lim_strip_extcap_update_struct(mac_ctx,
753 add_ie, &addn_ie_len,
754 &extracted_ext_cap);
755 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700756 pe_debug("Unable to strip off ExtCap IE");
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530757 } else {
758 extracted_ext_cap_flag = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 }
760
761 bytes = bytes + addn_ie_len;
762
763 if (preq_p2pie)
764 p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
765 addn_ie_len);
766
767 if (p2p_ie != NULL) {
768 /* get NoA attribute stream P2P IE */
769 noalen = lim_get_noa_attr_stream(mac_ctx,
770 noa_stream, pe_session);
771 if (noalen != 0) {
772 total_noalen =
773 lim_build_p2p_ie(mac_ctx, &noa_ie[0],
774 &noa_stream[0], noalen);
775 bytes = bytes + total_noalen;
776 }
777 }
778 }
779
Hu Wang411e0cc2016-10-28 14:56:01 +0800780 /*
781 * Extcap IE now support variable length, merge Extcap IE from addn_ie
782 * may change the frame size. Therefore, MUST merge ExtCap IE before
783 * dot11f get packed payload size.
784 */
785 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800786 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
787 true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800788
789 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
790 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700791 pe_err("Probe Response size error (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800792 status);
793 /* We'll fall back on the worst case scenario: */
794 payload = sizeof(tDot11fProbeResponse);
795 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700796 pe_warn("Probe Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800797 status);
798 }
799
800 bytes += payload + sizeof(tSirMacMgmtHdr);
801
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530802 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530804 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700805 pe_err("Probe Response allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806 goto err_ret;
807 }
808 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530809 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800810
811 /* Next, we fill out the buffer descriptor: */
812 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
813 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
814 pe_session->selfMacAddr);
815
816 mac_hdr = (tpSirMacMgmtHdr) frame;
817
818 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
819
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820 /* That done, pack the Probe Response: */
821 status =
822 dot11f_pack_probe_response(mac_ctx, frm,
823 frame + sizeof(tSirMacMgmtHdr),
824 payload, &payload);
825 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700826 pe_err("Probe Response pack failure (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 status);
828 goto err_ret;
829 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700830 pe_warn("Probe Response pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800831 }
832
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700833 pe_debug("Sending Probe Response frame to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +0530834 lim_print_mac_addr(mac_ctx, peer_macaddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800836 if (mac_ctx->lim.gpLimRemainOnChanReq)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530837 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800838 mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
839 (mac_ctx->lim.gpLimRemainOnChanReq->length -
840 sizeof(tSirRemainOnChnReq)));
841
842 if (addn_ie_present)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530843 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800844 &add_ie[0], addn_ie_len);
845
846 if (noalen != 0) {
847 if (total_noalen >
848 (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700849 pe_err("Not able to insert NoA, total len=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800850 total_noalen);
851 goto err_ret;
852 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530853 qdf_mem_copy(&frame[bytes - (total_noalen)],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800854 &noa_ie[0], total_noalen);
855 }
856 }
857
858 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +0530859 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
860 (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861 )
862 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
863
864 /* Queue Probe Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530865 qdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 (uint16_t) bytes,
867 TXRX_FRM_802_11_MGMT,
868 ANI_TXDIR_TODS,
869 7, lim_tx_complete, frame, tx_flag,
Naveen Rawat296a5182017-09-25 14:02:48 -0700870 sme_sessionid, 0, RATEID_DEFAULT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800871
872 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530873 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700874 pe_err("Could not send Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875
876 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530877 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530879 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880 return;
881
882err_ret:
883 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530884 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885 if (frm != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530886 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887 if (packet != NULL)
888 cds_packet_free((void *)packet);
889 return;
890
891} /* End lim_send_probe_rsp_mgmt_frame. */
892
893void
894lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
895 tSirMacAddr peerMacAddr,
896 tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
897{
898 uint16_t i;
899 uint8_t *pFrame;
900 tDot11fAddTSRequest AddTSReq;
901 tDot11fWMMAddTSRequest WMMAddTSReq;
902 uint32_t nPayload, nBytes, nStatus;
903 tpSirMacMgmtHdr pMacHdr;
904 void *pPacket;
905#ifdef FEATURE_WLAN_ESE
906 uint32_t phyMode;
907#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530908 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 uint8_t txFlag = 0;
910 uint8_t smeSessionId = 0;
911
912 if (NULL == psessionEntry) {
913 return;
914 }
915
916 smeSessionId = psessionEntry->smeSessionId;
917
918 if (!pAddTS->wmeTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530919 qdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800920
921 AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
922 AddTSReq.DialogToken.token = pAddTS->dialogToken;
923 AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
924 if (pAddTS->lleTspecPresent) {
925 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
926 } else {
927 populate_dot11f_wmmtspec(&pAddTS->tspec,
928 &AddTSReq.WMMTSPEC);
929 }
930
931 if (pAddTS->lleTspecPresent) {
932 AddTSReq.num_WMMTCLAS = 0;
933 AddTSReq.num_TCLAS = pAddTS->numTclas;
934 for (i = 0; i < pAddTS->numTclas; ++i) {
935 populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
936 &AddTSReq.TCLAS[i]);
937 }
938 } else {
939 AddTSReq.num_TCLAS = 0;
940 AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
941 for (i = 0; i < pAddTS->numTclas; ++i) {
942 populate_dot11f_wmmtclas(pMac,
943 &pAddTS->tclasInfo[i],
944 &AddTSReq.WMMTCLAS[i]);
945 }
946 }
947
948 if (pAddTS->tclasProcPresent) {
949 if (pAddTS->lleTspecPresent) {
950 AddTSReq.TCLASSPROC.processing =
951 pAddTS->tclasProc;
952 AddTSReq.TCLASSPROC.present = 1;
953 } else {
954 AddTSReq.WMMTCLASPROC.version = 1;
955 AddTSReq.WMMTCLASPROC.processing =
956 pAddTS->tclasProc;
957 AddTSReq.WMMTCLASPROC.present = 1;
958 }
959 }
960
961 nStatus =
962 dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
963 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700964 pe_err("Failed to calculate the packed size for an Add TS Request (0x%08x)",
965 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966 /* We'll fall back on the worst case scenario: */
967 nPayload = sizeof(tDot11fAddTSRequest);
968 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700969 pe_warn("There were warnings while calculating the packed size for an Add TS Request (0x%08x)",
970 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971 }
972 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530973 qdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800974
975 WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
976 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
977 WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
978
979 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
980 WMMAddTSReq.StatusCode.statusCode = 0;
981
982 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
983#ifdef FEATURE_WLAN_ESE
984 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
985
986 if (phyMode == WNI_CFG_PHY_MODE_11G
987 || phyMode == WNI_CFG_PHY_MODE_11A) {
988 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
989 } else {
990 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
991 }
992 populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
993 &WMMAddTSReq.ESETrafStrmRateSet,
994 sizeof(uint8_t));
995#endif
996 /* fillWmeTspecIE */
997
998 nStatus =
999 dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
1000 &nPayload);
1001 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001002 pe_err("Failed to calculate the packed size for a WMM Add TS Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001003 nStatus);
1004 /* We'll fall back on the worst case scenario: */
1005 nPayload = sizeof(tDot11fAddTSRequest);
1006 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001007 pe_warn("There were warnings while calculating the packed size for a WMM Add TS Request (0x%08x)",
1008 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001009 }
1010 }
1011
1012 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1013
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301014 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001015 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301016 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001017 pe_err("Failed to allocate %d bytes for an Add TS Request",
1018 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001019 return;
1020 }
1021 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301022 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001023
1024 /* Next, we fill out the buffer descriptor: */
1025 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1026 SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
1027 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1028
1029 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1030
1031#ifdef WLAN_FEATURE_11W
1032 lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
1033#endif
1034
1035 /* That done, pack the struct: */
1036 if (!pAddTS->wmeTspecPresent) {
1037 nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
1038 pFrame +
1039 sizeof(tSirMacMgmtHdr),
1040 nPayload, &nPayload);
1041 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001042 pe_err("Failed to pack an Add TS Request "
1043 "(0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044 cds_packet_free((void *)pPacket);
1045 return; /* allocated! */
1046 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001047 pe_warn("There were warnings while packing an Add TS Request (0x%08x)",
1048 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049 }
1050 } else {
1051 nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
1052 pFrame +
1053 sizeof(tSirMacMgmtHdr),
1054 nPayload, &nPayload);
1055 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001056 pe_err("Failed to pack a WMM Add TS Request (0x%08x)",
1057 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001058 cds_packet_free((void *)pPacket);
1059 return; /* allocated! */
1060 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001061 pe_warn("There were warnings while packing a WMM Add TS Request (0x%08x)",
1062 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001063 }
1064 }
1065
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001066 pe_debug("Sending an Add TS Request frame to");
1067 lim_print_mac_addr(pMac, peerMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001068
1069 if ((SIR_BAND_5_GHZ ==
1070 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301071 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1072 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001073 ) {
1074 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1075 }
1076
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301077 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001078 psessionEntry->peSessionId, pMacHdr->fc.subType));
1079
1080 /* Queue Addts Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301081 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001082 TXRX_FRM_802_11_MGMT,
1083 ANI_TXDIR_TODS,
1084 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07001085 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301086 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301087 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001088
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001089 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1090 pe_err("Could not send an Add TS Request (%X",
1091 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001092} /* End lim_send_addts_req_action_frame. */
1093
1094/**
1095 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
1096 * @mac_ctx: Handle for mac context
1097 * @status_code: Status code for assoc response frame
1098 * @aid: Association ID
1099 * @peer_addr: Mac address of requesting peer
1100 * @subtype: Assoc/Reassoc
1101 * @sta: Pointer to station node
1102 * @pe_session: PE session id.
1103 *
1104 * Builds and sends association response frame to the requesting peer.
1105 *
1106 * Return: void
1107 */
1108
1109void
1110lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
1111 uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
1112 uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
1113{
1114 static tDot11fAssocResponse frm;
1115 uint8_t *frame;
1116 tpSirMacMgmtHdr mac_hdr;
1117 tSirRetStatus sir_status;
1118 uint8_t lle_mode = 0, addts;
1119 tHalBitVal qos_mode, wme_mode;
Hu Wang411e0cc2016-10-28 14:56:01 +08001120 uint32_t payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301122 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001123 tUpdateBeaconParams beacon_params;
1124 uint8_t tx_flag = 0;
1125 uint32_t addn_ie_len = 0;
1126 uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
1127 tpSirAssocReq assoc_req = NULL;
1128 uint8_t sme_session = 0;
1129 bool is_vht = false;
1130 uint16_t stripoff_len = 0;
1131 tDot11fIEExtCap extracted_ext_cap;
1132 bool extracted_flag = false;
1133#ifdef WLAN_FEATURE_11W
1134 uint32_t retry_int;
1135 uint32_t max_retries;
1136#endif
1137
1138 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001139 pe_err("pe_session is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001140 return;
1141 }
1142
1143 sme_session = pe_session->smeSessionId;
1144
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301145 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001146
1147 limGetQosMode(pe_session, &qos_mode);
1148 limGetWmeMode(pe_session, &wme_mode);
1149
1150 /*
1151 * An Add TS IE is added only if the AP supports it and
1152 * the requesting STA sent a traffic spec.
1153 */
1154 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
1155
1156 frm.Status.status = status_code;
1157
1158 frm.AID.associd = aid | LIM_AID_MASK;
1159
1160 if (NULL == sta) {
1161 populate_dot11f_supp_rates(mac_ctx,
1162 POPULATE_DOT11F_RATES_OPERATIONAL,
1163 &frm.SuppRates, pe_session);
1164 populate_dot11f_ext_supp_rates(mac_ctx,
1165 POPULATE_DOT11F_RATES_OPERATIONAL,
1166 &frm.ExtSuppRates, pe_session);
1167 } else {
1168 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
1169 &frm.ExtSuppRates,
1170 sta->supportedRates.llbRates,
1171 sta->supportedRates.llaRates);
1172 }
1173
1174 if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
1175 eSIR_SUCCESS == status_code) {
1176 assoc_req = (tpSirAssocReq)
1177 pe_session->parsedAssocReq[sta->assocId];
1178 /*
1179 * populate P2P IE in AssocRsp when assocReq from the peer
1180 * includes P2P IE
1181 */
1182 if (assoc_req != NULL && assoc_req->addIEPresent)
1183 populate_dot11_assoc_res_p2p_ie(mac_ctx,
1184 &frm.P2PAssocRes,
1185 assoc_req);
1186 }
1187
1188 if (NULL != sta) {
1189 if (eHAL_SET == qos_mode) {
1190 if (sta->lleEnabled) {
1191 lle_mode = 1;
1192 populate_dot11f_edca_param_set(mac_ctx,
1193 &frm.EDCAParamSet, pe_session);
1194 }
1195 }
1196
1197 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
1198 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
1199 pe_session);
1200
1201 if (sta->wsmEnabled)
1202 populate_dot11f_wmm_caps(&frm.WMMCaps);
1203 }
1204
1205 if (sta->mlmStaContext.htCapability &&
1206 pe_session->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001207 pe_debug("Populate HT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001208 populate_dot11f_ht_caps(mac_ctx, pe_session,
1209 &frm.HTCaps);
Krunal Sonief3294b2015-06-12 15:12:19 -07001210 /*
1211 * Check the STA capability and
1212 * update the HTCaps accordingly
1213 */
1214 frm.HTCaps.supportedChannelWidthSet = (
1215 sta->htSupportedChannelWidthSet <
1216 pe_session->htSupportedChannelWidthSet) ?
1217 sta->htSupportedChannelWidthSet :
1218 pe_session->htSupportedChannelWidthSet;
1219 if (!frm.HTCaps.supportedChannelWidthSet)
1220 frm.HTCaps.shortGI40MHz = 0;
1221
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001222 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1223 pe_session);
1224 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001225 pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x",
Agrawal Ashishc38e58d2015-09-16 17:17:29 +05301226 frm.HTCaps.supportedChannelWidthSet,
1227 frm.HTCaps.mimoPowerSave,
1228 frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
1229 frm.HTCaps.shortGI40MHz,
1230 frm.HTCaps.dsssCckMode40MHz,
1231 frm.HTCaps.maxRxAMPDUFactor);
1232
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233 if (sta->mlmStaContext.vhtCapability &&
1234 pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001235 pe_debug("Populate VHT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001236 populate_dot11f_vht_caps(mac_ctx, pe_session,
1237 &frm.VHTCaps);
1238 populate_dot11f_vht_operation(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301239 &frm.VHTOperation);
1240 is_vht = true;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301241 } else {
Tushnim Bhattacharyya3d17def2017-06-19 11:13:43 -07001242 /*
1243 * 2G-AS platform: SAP associates with HT (11n)clients
1244 * as 2x1 in 2G and 2X2 in 5G
1245 * Non-2G-AS platform: SAP associates with HT (11n)
1246 * clients as 2X2 in 2G and 5G
1247 * 5G-AS: DonÂ’t care
1248 */
1249 if (!policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc) &&
1250 frm.HTCaps.present && mac_ctx->hw_dbs_capable &&
1251 mac_ctx->lteCoexAntShare &&
1252 IS_24G_CH(pe_session->currentOperChannel))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301253 frm.HTCaps.supportedMCSSet[1] = 0;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301254 }
1255 if (pe_session->vhtCapability &&
1256 pe_session->vendor_vht_sap &&
1257 (assoc_req != NULL) &&
1258 assoc_req->vendor_vht_ie.VHTCaps.present) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001259 pe_debug("Populate Vendor VHT IEs in Assoc Rsponse");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301260 frm.vendor_vht_ie.present = 1;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301261 frm.vendor_vht_ie.VHTCaps.present = 1;
1262 populate_dot11f_vht_caps(mac_ctx, pe_session,
1263 &frm.vendor_vht_ie.VHTCaps);
Kiran Kumar Lokerecc448682017-07-20 18:08:01 -07001264 populate_dot11f_vht_operation(mac_ctx, pe_session,
1265 &frm.vendor_vht_ie.VHTOperation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 is_vht = true;
1267 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1269 pe_session);
1270
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001271 if (lim_is_sta_he_capable(sta) &&
1272 lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001273 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001274 populate_dot11f_he_caps(mac_ctx, pe_session,
1275 &frm.vendor_he_cap);
1276 populate_dot11f_he_operation(mac_ctx, pe_session,
1277 &frm.vendor_he_op);
1278 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279#ifdef WLAN_FEATURE_11W
1280 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1281 if (wlan_cfg_get_int
1282 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1283 &max_retries) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001284 pe_err("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285 else if (wlan_cfg_get_int
1286 (mac_ctx,
1287 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1288 &retry_int) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001289 pe_err("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 else
1291 populate_dot11f_timeout_interval(mac_ctx,
1292 &frm.TimeoutInterval,
1293 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1294 (max_retries -
1295 sta->pmfSaQueryRetryCount)
1296 * retry_int);
1297 }
1298#endif
Arif Hussain0c816922017-04-06 15:04:44 -07001299
1300 if (LIM_IS_AP_ROLE(pe_session) && sta->non_ecsa_capable)
1301 pe_session->lim_non_ecsa_cap_num++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302 }
1303
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301304 qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305
1306 if (LIM_IS_AP_ROLE(pe_session) &&
1307 (pe_session->gLimProtectionControl !=
1308 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1309 lim_decide_ap_protection(mac_ctx, peer_addr,
1310 &beacon_params, pe_session);
1311
1312 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1313 pe_session);
1314 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1315 pe_session);
1316
1317 /*
1318 * Populate Do11capabilities after updating session with
1319 * Assos req details
1320 */
1321 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1322
1323 beacon_params.bssIdx = pe_session->bssIdx;
1324
1325 /* Send message to HAL about beacon parameter change. */
1326 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1327 && beacon_params.paramChangeBitmap) {
1328 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1329 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331
1332 if (assoc_req != NULL) {
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001333 addn_ie_len = pe_session->addIeParams.assocRespDataLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334
1335 /* Nonzero length indicates Assoc rsp IE available */
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001336 if (addn_ie_len > 0 &&
1337 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
1338 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301339 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 pe_session->addIeParams.assocRespData_buff,
1341 pe_session->addIeParams.assocRespDataLen);
1342
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301343 qdf_mem_set((uint8_t *) &extracted_ext_cap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 sizeof(extracted_ext_cap), 0);
1345
1346 stripoff_len = addn_ie_len;
1347 sir_status =
1348 lim_strip_extcap_update_struct
1349 (mac_ctx, &add_ie[0], &stripoff_len,
1350 &extracted_ext_cap);
1351 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001352 pe_debug("strip off extcap IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 } else {
1354 addn_ie_len = stripoff_len;
1355 extracted_flag = true;
1356 }
1357 bytes = bytes + addn_ie_len;
1358 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001359 pe_debug("addn_ie_len: %d for Assoc Resp: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 addn_ie_len, assoc_req->addIEPresent);
1361 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001362
1363 /*
1364 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1365 * may change the frame size. Therefore, MUST merge ExtCap IE before
1366 * dot11f get packed payload size.
1367 */
1368 if (extracted_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001369 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
1370 true);
Hu Wang411e0cc2016-10-28 14:56:01 +08001371
1372 /* Allocate a buffer for this frame: */
1373 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1374 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001375 pe_err("get Association Response size failure (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001376 status);
1377 return;
1378 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001379 pe_warn("get Association Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001380 status);
1381 }
1382
1383 bytes += sizeof(tSirMacMgmtHdr) + payload;
1384
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301385 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301387 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001388 pe_err("cds_packet_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001389 return;
1390 }
1391 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301392 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393
1394 /* Next, we fill out the buffer descriptor: */
1395 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1396 (LIM_ASSOC == subtype) ?
1397 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1398 peer_addr,
1399 pe_session->selfMacAddr);
1400 mac_hdr = (tpSirMacMgmtHdr) frame;
1401
1402 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001404 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1405 frame + sizeof(tSirMacMgmtHdr),
1406 payload, &payload);
1407 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001408 pe_err("Association Response pack failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001409 status);
1410 cds_packet_free((void *)packet);
1411 return;
1412 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001413 pe_warn("Association Response pack warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001414 status);
1415 }
1416
1417 if (subtype == LIM_ASSOC)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001418 pe_debug("*** Sending Assoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419 status_code, aid);
1420 else
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001421 pe_debug("*** Sending ReAssoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422 status_code, aid);
1423
Abhishek Singh5d8d7332017-08-10 15:15:24 +05301424 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425
1426 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301427 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 &add_ie[0], addn_ie_len);
1429
1430 if ((SIR_BAND_5_GHZ ==
1431 lim_get_rf_band(pe_session->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05301432 (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
1433 (pe_session->pePersona == QDF_P2P_GO_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001434 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1435
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301436 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437 pe_session->peSessionId, mac_hdr->fc.subType));
1438 /* Queue Association Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301439 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 TXRX_FRM_802_11_MGMT,
1441 ANI_TXDIR_TODS,
1442 7, lim_tx_complete, frame, tx_flag,
Naveen Rawat296a5182017-09-25 14:02:48 -07001443 sme_session, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301444 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301445 pe_session->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446
1447 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301448 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001449 pe_err("Could not Send Re/AssocRsp, retCode=%X",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301450 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451
1452 /*
1453 * update the ANI peer station count.
1454 * FIXME_PROTECTION : take care of different type of station
1455 * counter inside this function.
1456 */
1457 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1458
1459}
1460
1461void
1462lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1463 tSirMacAddr peer,
1464 uint8_t wmmTspecPresent,
1465 tSirMacTSInfo *pTsinfo,
1466 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1467{
1468 uint8_t *pFrame;
1469 tpSirMacMgmtHdr pMacHdr;
1470 tDot11fDelTS DelTS;
1471 tDot11fWMMDelTS WMMDelTS;
1472 uint32_t nBytes, nPayload, nStatus;
1473 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301474 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475 uint8_t txFlag = 0;
1476 uint8_t smeSessionId = 0;
1477
1478 if (NULL == psessionEntry) {
1479 return;
1480 }
1481
1482 smeSessionId = psessionEntry->smeSessionId;
1483
1484 if (!wmmTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301485 qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001486
1487 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1488 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1489 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1490
1491 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1492 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001493 pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494 /* We'll fall back on the worst case scenario: */
1495 nPayload = sizeof(tDot11fDelTS);
1496 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001497 pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)",
1498 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 }
1500 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301501 qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001502
1503 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1504 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1505 WMMDelTS.DialogToken.token = 0;
1506 WMMDelTS.StatusCode.statusCode = 0;
1507 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1508 nStatus =
1509 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1510 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001511 pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 /* We'll fall back on the worst case scenario: */
1513 nPayload = sizeof(tDot11fDelTS);
1514 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001515 pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)",
1516 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001517 }
1518 }
1519
1520 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1521
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301522 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1524 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301525 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001526 pe_err("Failed to allocate %d bytes for an Add TS Response",
1527 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 return;
1529 }
1530 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301531 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532
1533 /* Next, we fill out the buffer descriptor: */
1534 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1535 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1536 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1537
1538 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1539
1540#ifdef WLAN_FEATURE_11W
1541 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1542#endif
1543
1544 /* That done, pack the struct: */
1545 if (!wmmTspecPresent) {
1546 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1547 pFrame + sizeof(tSirMacMgmtHdr),
1548 nPayload, &nPayload);
1549 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001550 pe_err("Failed to pack a Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 nStatus);
1552 cds_packet_free((void *)pPacket);
1553 return; /* allocated! */
1554 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001555 pe_warn("There were warnings while packing a Del TS frame (0x%08x)",
1556 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 }
1558 } else {
1559 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1560 pFrame + sizeof(tSirMacMgmtHdr),
1561 nPayload, &nPayload);
1562 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001563 pe_err("Failed to pack a WMM Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001564 nStatus);
1565 cds_packet_free((void *)pPacket);
1566 return; /* allocated! */
1567 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001568 pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)",
1569 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 }
1571 }
1572
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001573 pe_debug("Sending DELTS REQ (size %d) to ", nBytes);
1574 lim_print_mac_addr(pMac, pMacHdr->da, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001575
1576 if ((SIR_BAND_5_GHZ ==
1577 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301578 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1579 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580 ) {
1581 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1582 }
1583
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301584 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301586 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 TXRX_FRM_802_11_MGMT,
1588 ANI_TXDIR_TODS,
1589 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07001590 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301591 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301592 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001593 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301594 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001595 pe_err("Failed to send Del TS (%X)!", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001596
1597} /* End lim_send_delts_req_action_frame. */
1598
1599/**
Abhishek Singhdd2cb572017-08-11 11:10:19 +05301600 * lim_assoc_tx_complete_cnf()- Confirmation for assoc sent over the air
1601 * @context: pointer to global mac
1602 * @buf: buffer
1603 * @tx_complete : Sent status
1604 * @params; tx completion params
1605 *
1606 * Return: This returns QDF_STATUS
1607 */
1608
1609static QDF_STATUS lim_assoc_tx_complete_cnf(void *context,
1610 qdf_nbuf_t buf,
1611 uint32_t tx_complete,
1612 void *params)
1613{
1614 uint16_t assoc_ack_status;
1615 uint16_t reason_code;
1616 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
1617
1618 pe_debug("tx_complete= %d", tx_complete);
1619 if (tx_complete) {
1620 assoc_ack_status = ACKED;
1621 reason_code = eSIR_SUCCESS;
1622 } else {
1623 assoc_ack_status = NOT_ACKED;
1624 reason_code = eSIR_FAILURE;
1625 }
1626 if (buf)
1627 qdf_nbuf_free(buf);
1628
1629 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_ACK_EVENT,
1630 NULL, assoc_ack_status, reason_code);
1631 return QDF_STATUS_SUCCESS;
1632}
1633
1634/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 * lim_send_assoc_req_mgmt_frame() - Send association request
1636 * @mac_ctx: Handle to MAC context
1637 * @mlm_assoc_req: Association request information
1638 * @pe_session: PE session information
1639 *
1640 * Builds and transmits association request frame to AP.
1641 *
1642 * Return: Void
1643 */
1644
1645void
1646lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1647 tLimMlmAssocReq *mlm_assoc_req,
1648 tpPESession pe_session)
1649{
1650 tDot11fAssocRequest *frm;
1651 uint16_t caps;
1652 uint8_t *frame;
1653 tSirRetStatus sir_status;
1654 tLimMlmAssocCnf assoc_cnf;
Hu Wang411e0cc2016-10-28 14:56:01 +08001655 uint32_t bytes = 0, payload, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001656 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1657 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301658 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659 uint16_t add_ie_len;
1660 uint8_t *add_ie;
Naveen Rawat08db88f2017-09-08 15:07:48 -07001661 const uint8_t *wps_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 uint8_t power_caps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001663 uint8_t tx_flag = 0;
1664 uint8_t sme_sessionid = 0;
1665 bool vht_enabled = false;
1666 tDot11fIEExtCap extr_ext_cap;
1667 bool extr_ext_flag = true;
1668 tpSirMacMgmtHdr mac_hdr;
Hu Wangfbd279d2016-10-31 18:24:34 +08001669 uint32_t ie_offset = 0;
1670 uint8_t *p_ext_cap = NULL;
1671 tDot11fIEExtCap bcn_ext_cap;
1672 uint8_t *bcn_ie = NULL;
1673 uint32_t bcn_ie_len = 0;
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05301674 uint32_t aes_block_size_len = 0;
Naveen Rawat296a5182017-09-25 14:02:48 -07001675 enum rateid min_rid = RATEID_DEFAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676
1677 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001678 pe_err("pe_session is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301679 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 return;
1681 }
1682
1683 sme_sessionid = pe_session->smeSessionId;
1684
1685 /* check this early to avoid unncessary operation */
1686 if (NULL == pe_session->pLimJoinReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001687 pe_err("pe_session->pLimJoinReq is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301688 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689 return;
1690 }
1691 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1692 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1693
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301694 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001696 pe_err("Unable to allocate memory");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301697 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001698 return;
1699 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001700 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001701
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301702 if (add_ie_len && pe_session->is_ext_caps_present) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301703 qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001704 0);
1705 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1706 add_ie, &add_ie_len, &extr_ext_cap);
1707 if (eSIR_SUCCESS != sir_status) {
1708 extr_ext_flag = false;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001709 pe_debug("Unable to Stripoff ExtCap IE from Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001710 } else {
1711 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1712 extr_ext_cap.bytes;
1713
1714 if (p_ext_cap->interworking_service)
1715 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +08001716 extr_ext_cap.num_bytes =
1717 lim_compute_ext_cap_ie_length(&extr_ext_cap);
1718 extr_ext_flag = (extr_ext_cap.num_bytes > 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 }
1720 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001721 pe_debug("No addn IE or peer dosen't support addnIE for Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001722 extr_ext_flag = false;
1723 }
1724
1725 caps = mlm_assoc_req->capabilityInfo;
1726#if defined(FEATURE_WLAN_WAPI)
1727 /*
1728 * According to WAPI standard:
1729 * 7.3.1.4 Capability Information field
1730 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1731 * in transmitted Association or Reassociation management frames.
1732 * APs ignore the Privacy subfield within received Association and
1733 * Reassociation management frames.
1734 */
1735 if (pe_session->encryptType == eSIR_ED_WPI)
1736 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1737#endif
1738 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1739
1740 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1741 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1742 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1743 &frm->SuppRates, pe_session);
1744
1745 qos_enabled = (pe_session->limQosEnabled) &&
1746 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1747
1748 wme_enabled = (pe_session->limWmeEnabled) &&
1749 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1750
1751 /* We prefer .11e asociations: */
1752 if (qos_enabled)
1753 wme_enabled = false;
1754
1755 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1756 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1757
1758 if (pe_session->lim11hEnable &&
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07001759 pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760 power_caps = true;
1761
1762 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1763 LIM_ASSOC, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1765 LIM_ASSOC, pe_session);
1766
1767 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001768 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1769 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1770 if (power_caps == false) {
1771 power_caps = true;
1772 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1773 LIM_ASSOC, pe_session);
1774 }
1775 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776 if (qos_enabled)
Naveen Rawatcd118312016-11-22 10:46:21 -08001777 populate_dot11f_qos_caps_station(mac_ctx, pe_session,
1778 &frm->QOSCapsStation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001779
1780 populate_dot11f_ext_supp_rates(mac_ctx,
1781 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1782 pe_session);
1783
Gupta, Kapil54a16992016-01-13 19:34:02 +05301784 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1785 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1787 pe_session);
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08001788
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001789 /*
1790 * The join request *should* contain zero or one of the WPA and RSN
1791 * IEs. The payload send along with the request is a
1792 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1793 * typedef struct sSirRSNie
1794 * {
1795 * uint16_t length;
1796 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1797 * } tSirRSNie, *tpSirRSNie;
1798 * So, we should be able to make the following two calls harmlessly,
1799 * since they do nothing if they don't find the given IE in the
1800 * bytestream with which they're provided.
1801 * The net effect of this will be to faithfully transmit whatever
1802 * security IE is in the join request.
1803 * However, if we're associating for the purpose of WPS
1804 * enrollment, and we've been configured to indicate that by
1805 * eliding the WPA or RSN IE, we just skip this:
1806 */
1807 if (add_ie_len && add_ie)
1808 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1809
1810 if (NULL == wps_ie) {
1811 populate_dot11f_rsn_opaque(mac_ctx,
1812 &(pe_session->pLimJoinReq->rsnIE),
1813 &frm->RSNOpaque);
1814 populate_dot11f_wpa_opaque(mac_ctx,
1815 &(pe_session->pLimJoinReq->rsnIE),
1816 &frm->WPAOpaque);
1817#if defined(FEATURE_WLAN_WAPI)
1818 populate_dot11f_wapi_opaque(mac_ctx,
1819 &(pe_session->pLimJoinReq->rsnIE),
1820 &frm->WAPIOpaque);
1821#endif /* defined(FEATURE_WLAN_WAPI) */
1822 }
1823 /* include WME EDCA IE as well */
1824 if (wme_enabled) {
1825 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1826 pe_session, &frm->WMMInfoStation);
1827
1828 if (wsm_enabled)
1829 populate_dot11f_wmm_caps(&frm->WMMCaps);
1830 }
1831
1832 /*
1833 * Populate HT IEs, when operating in 11n and
1834 * when AP is also operating in 11n mode
1835 */
1836 if (pe_session->htCapability &&
1837 mac_ctx->lim.htCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001838 pe_debug("Populate HT Caps in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001839 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001840 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1841 &frm->HTCaps, sizeof(frm->HTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001842 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001843 pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x",
Agrawal Ashishc38e58d2015-09-16 17:17:29 +05301844 frm->HTCaps.supportedChannelWidthSet,
1845 frm->HTCaps.mimoPowerSave,
1846 frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
1847 frm->HTCaps.shortGI40MHz,
1848 frm->HTCaps.dsssCckMode40MHz,
1849 frm->HTCaps.maxRxAMPDUFactor);
1850
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851 if (pe_session->vhtCapability &&
1852 pe_session->vhtCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001853 pe_debug("Populate VHT IEs in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001854 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001855 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1856 &frm->VHTCaps, sizeof(frm->VHTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857 vht_enabled = true;
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001858 if (pe_session->enableHtSmps &&
1859 !pe_session->supported_nss_1x1) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001860 pe_err("VHT OP mode IE in Assoc Req");
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001861 populate_dot11f_operating_mode(mac_ctx,
1862 &frm->OperatingMode, pe_session);
1863 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864 }
1865 if (!vht_enabled &&
1866 pe_session->is_vendor_specific_vhtcaps) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001867 pe_debug("Populate Vendor VHT IEs in Assoc Request");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301868 frm->vendor_vht_ie.present = 1;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301869 frm->vendor_vht_ie.VHTCaps.present = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001870 populate_dot11f_vht_caps(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301871 &frm->vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001872 vht_enabled = true;
1873 }
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301874 if (pe_session->is_ext_caps_present)
1875 populate_dot11f_ext_cap(mac_ctx, vht_enabled,
1876 &frm->ExtCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001877
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +05301878 if (mac_ctx->roam.configParam.qcn_ie_support)
1879 populate_dot11f_qcn_ie(&frm->QCN_IE);
1880
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001881 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001882 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001883 populate_dot11f_he_caps(mac_ctx, pe_session,
1884 &frm->vendor_he_cap);
1885 }
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301886
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887 if (pe_session->pLimJoinReq->is11Rconnection) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001888 tSirBssDescription *bssdescr;
1889
1890 bssdescr = &pe_session->pLimJoinReq->bssDescription;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001891 pe_debug("mdie = %02x %02x %02x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001892 (unsigned int) bssdescr->mdie[0],
1893 (unsigned int) bssdescr->mdie[1],
1894 (unsigned int) bssdescr->mdie[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001895 populate_mdie(mac_ctx, &frm->MobilityDomain,
1896 pe_session->pLimJoinReq->bssDescription.mdie);
1897 } else {
1898 /* No 11r IEs dont send any MDIE */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001899 pe_debug("MDIE not present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001900 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001901
1902#ifdef FEATURE_WLAN_ESE
1903 /*
1904 * ESE Version IE will be included in association request
1905 * when ESE is enabled on DUT through ini and it is also
1906 * advertised by the peer AP to which we are trying to
1907 * associate to.
1908 */
1909 if (pe_session->is_ese_version_ie_present &&
1910 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1911 populate_dot11f_ese_version(&frm->ESEVersion);
1912 /* For ESE Associations fill the ESE IEs */
1913 if (pe_session->isESEconnection &&
1914 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1915#ifndef FEATURE_DISABLE_RM
1916 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1917#endif
1918 }
1919#endif
1920
Hu Wang411e0cc2016-10-28 14:56:01 +08001921 /*
1922 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1923 * may change the frame size. Therefore, MUST merge ExtCap IE before
1924 * dot11f get packed payload size.
1925 */
1926 if (extr_ext_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001927 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
1928
1929 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
1930 if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
1931 ie_offset = DOT11F_FF_TIMESTAMP_LEN +
1932 DOT11F_FF_BEACONINTERVAL_LEN +
1933 DOT11F_FF_CAPABILITIES_LEN;
1934
1935 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
1936 if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
1937 bcn_ie = pe_session->beacon + ie_offset;
1938 bcn_ie_len = pe_session->bcnLen - ie_offset;
Naveen Rawat08db88f2017-09-08 15:07:48 -07001939 p_ext_cap = (uint8_t *)wlan_get_ie_ptr_from_eid(
Hu Wangfbd279d2016-10-31 18:24:34 +08001940 DOT11F_EID_EXTCAP,
Naveen Rawat08db88f2017-09-08 15:07:48 -07001941 bcn_ie, bcn_ie_len);
Hu Wangfbd279d2016-10-31 18:24:34 +08001942 lim_update_extcap_struct(mac_ctx, p_ext_cap,
1943 &bcn_ext_cap);
1944 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
1945 false);
1946 }
1947 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001948
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001949 if (eSIR_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
1950 add_ie, &add_ie_len, &frm->SuppOperatingClasses))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001951 pe_debug("Unable to Stripoff supp op classes IE from Assoc Req");
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001952
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05301953 if (lim_is_fils_connection(pe_session)) {
1954 populate_dot11f_fils_params(mac_ctx, frm, pe_session);
1955 aes_block_size_len = AES_BLOCK_SIZE;
1956 }
1957
1958 /*
1959 * Do unpack to populate the add_ie buffer to frm structure
1960 * before packing the frm structure. In this way, the IE ordering
1961 * which the latest 802.11 spec mandates is maintained.
1962 */
1963 if (add_ie_len)
1964 dot11f_unpack_assoc_request(mac_ctx, add_ie,
1965 add_ie_len, frm, true);
1966
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1968 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001969 pe_err("Association Request packet size failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 status);
1971 /* We'll fall back on the worst case scenario: */
1972 payload = sizeof(tDot11fAssocRequest);
1973 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001974 pe_warn("Association request packet size warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001975 status);
1976 }
1977
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05301978 bytes = payload + sizeof(tSirMacMgmtHdr) +
1979 aes_block_size_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001980
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301981 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001982 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301983 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001984 pe_err("Failed to allocate %d bytes", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985
1986 pe_session->limMlmState = pe_session->limPrevMlmState;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301987 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001988 pe_session->peSessionId,
1989 pe_session->limMlmState));
1990
1991 /* Update PE session id */
1992 assoc_cnf.sessionId = pe_session->peSessionId;
1993
1994 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1995
1996 cds_packet_free((void *)packet);
1997
1998 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1999 (uint32_t *) &assoc_cnf);
2000
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05302001 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002 }
2003 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302004 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002005
2006 /* Next, we fill out the buffer descriptor: */
2007 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2008 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
2009 pe_session->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010 /* That done, pack the Assoc Request: */
2011 status = dot11f_pack_assoc_request(mac_ctx, frm,
2012 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
2013 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002014 pe_err("Assoc request pack failure (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002015 cds_packet_free((void *)packet);
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05302016 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002017 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002018 pe_warn("Assoc request pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019 }
2020
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002021 if (pe_session->assocReq != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302022 qdf_mem_free(pe_session->assocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002023 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002024 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002025 }
2026
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05302027 if (lim_is_fils_connection(pe_session)) {
2028 qdf_status = aead_encrypt_assoc_req(mac_ctx, pe_session,
2029 frame, &payload);
2030 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
2031 cds_packet_free((void *)packet);
2032 qdf_mem_free(frm);
2033 return;
2034 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002035 }
2036
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302037 pe_session->assocReq = qdf_mem_malloc(payload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002038 if (NULL == pe_session->assocReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002039 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040 } else {
2041 /*
2042 * Store the Assoc request. This is sent to csr/hdd in
2043 * join cnf response.
2044 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302045 qdf_mem_copy(pe_session->assocReq,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046 frame + sizeof(tSirMacMgmtHdr), payload);
2047 pe_session->assocReqLen = payload;
2048 }
2049
2050 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302051 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
2052 || (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002053 )
2054 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2055
Anurag Chouhan6d760662016-02-20 16:05:43 +05302056 if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
2057 pe_session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002058 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2059
2060#ifdef FEATURE_WLAN_DIAG_SUPPORT
2061 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
2062 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2063#endif
2064 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302065 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 pe_session->peSessionId, mac_hdr->fc.subType));
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05302067
2068 pe_debug("Sending Association Request length %d to ", bytes);
Naveen Rawat296a5182017-09-25 14:02:48 -07002069 min_rid = lim_get_min_session_txrate(pe_session);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302070 qdf_status =
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302071 wma_tx_frameWithTxComplete(mac_ctx, packet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002072 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
2073 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302074 lim_tx_complete, frame, lim_assoc_tx_complete_cnf,
Naveen Rawat296a5182017-09-25 14:02:48 -07002075 tx_flag, sme_sessionid, false, 0, min_rid);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302076 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302077 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302078 pe_session->peSessionId, qdf_status));
Naveen Rawat296a5182017-09-25 14:02:48 -07002079
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302080 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002081 pe_err("Failed to send Association Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302082 qdf_status);
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302083 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_ACK_EVENT,
2084 pe_session, SENT_FAIL, eSIR_FAILURE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002085 /* Pkt will be freed up by the callback */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086 }
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05302087end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002088 /* Free up buffer allocated for mlm_assoc_req */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302089 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090 mlm_assoc_req = NULL;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302091 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002092 return;
2093}
2094
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095/**
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302096 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302097 * @context: pointer to global mac
2098 * @buf: buffer
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302099 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302100 * @params; tx completion params
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302101 *
2102 * Return: This returns QDF_STATUS
2103 */
2104
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302105static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
2106 qdf_nbuf_t buf,
2107 uint32_t tx_complete,
2108 void *params)
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302109{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302110 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302111 uint16_t auth_ack_status;
2112 uint16_t reason_code;
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302113
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002114 pe_debug("tx_complete= %d", tx_complete);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302115 if (tx_complete) {
2116 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302117 auth_ack_status = ACKED;
2118 reason_code = eSIR_SUCCESS;
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302119 /* 'Change' timer for future activations */
2120 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2121 } else {
2122 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302123 auth_ack_status = NOT_ACKED;
2124 reason_code = eSIR_FAILURE;
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302125 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302126
2127 if (buf)
2128 qdf_nbuf_free(buf);
2129
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302130 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT,
2131 NULL, auth_ack_status, reason_code);
2132
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302133 return QDF_STATUS_SUCCESS;
2134}
2135
2136/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002137 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2138 *
2139 * @mac_ctx: Pointer to Global MAC structure
2140 * @auth_frame: Pointer to Authentication frame structure
2141 * @peer_addr: MAC address of destination peer
2142 * @wep_bit: wep bit in frame control for Authentication frame3
2143 * @session: PE session information
2144 *
2145 * This function is called by lim_process_mlm_messages(). Authentication frame
2146 * is formatted and sent when this function is called.
2147 *
2148 * Return: void
2149 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150void
2151lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2152 tpSirMacAuthFrameBody auth_frame,
2153 tSirMacAddr peer_addr,
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302154 uint8_t wep_challenge_len,
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302155 tpPESession session)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002156{
2157 uint8_t *frame, *body;
2158 uint32_t frame_len = 0, body_len = 0;
2159 tpSirMacMgmtHdr mac_hdr;
2160 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302161 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002162 uint8_t tx_flag = 0;
2163 uint8_t sme_sessionid = 0;
2164 uint16_t ft_ies_length = 0;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002165 bool challenge_req = false;
Naveen Rawat296a5182017-09-25 14:02:48 -07002166 enum rateid min_rid = RATEID_DEFAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002167
2168 if (NULL == session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002169 pe_err("Error: psession Entry is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002170 return;
2171 }
2172
2173 sme_sessionid = session->smeSessionId;
2174
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302175 if (wep_challenge_len) {
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002176 /*
2177 * Auth frame3 to be sent with encrypted framebody
2178 *
2179 * Allocate buffer for Authenticaton frame of size
2180 * equal to management frame header length plus 2 bytes
2181 * each for auth algorithm number, transaction number,
2182 * status code, 128 bytes for challenge text and
2183 * 4 bytes each for IV & ICV.
2184 */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002185 pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
2186 MAC_ADDR_ARRAY(peer_addr));
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002187
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302188 body_len = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002189 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002190
2191 goto alloc_packet;
2192 }
2193
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302194 pe_info("Sending Auth seq# %d status %d (%d) to "
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002195 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 auth_frame->authTransactionSeqNumber,
2197 auth_frame->authStatusCode,
2198 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
2199 MAC_ADDR_ARRAY(peer_addr));
2200
2201 switch (auth_frame->authTransactionSeqNumber) {
2202 case SIR_MAC_AUTH_FRAME_1:
2203 /*
2204 * Allocate buffer for Authenticaton frame of size
2205 * equal to management frame header length plus 2 bytes
2206 * each for auth algorithm number, transaction number
2207 * and status code.
2208 */
2209
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002210 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2211 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002212
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05302213 frame_len += lim_create_fils_auth_data(mac_ctx,
2214 auth_frame, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2216 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2217 0 != session->ftPEContext.pFTPreAuthReq->
2218 ft_ies_length) {
2219 ft_ies_length = session->ftPEContext.
2220 pFTPreAuthReq->ft_ies_length;
2221 frame_len += ft_ies_length;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002222 pe_debug("Auth frame, FTIES length added=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223 ft_ies_length);
2224 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002225 pe_debug("Auth frame, Does not contain FTIES!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002226 frame_len += (2 + SIR_MDIE_SIZE);
2227 }
2228 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002229 break;
2230
2231 case SIR_MAC_AUTH_FRAME_2:
2232 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2233 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2234 (auth_frame->authStatusCode !=
2235 eSIR_MAC_SUCCESS_STATUS))) {
2236 /*
2237 * Allocate buffer for Authenticaton frame of size
2238 * equal to management frame header length plus
2239 * 2 bytes each for auth algorithm number,
2240 * transaction number and status code.
2241 */
2242
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002243 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2244 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002245 } else {
2246 /*
2247 * Shared Key algorithm with challenge text
2248 * to be sent.
2249 *
2250 * Allocate buffer for Authenticaton frame of size
2251 * equal to management frame header length plus
2252 * 2 bytes each for auth algorithm number,
2253 * transaction number, status code and 128 bytes
2254 * for challenge text.
2255 */
2256
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002257 challenge_req = true;
2258 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
yeshwanth sriram guntuka5c71a292017-08-24 15:51:19 +05302259 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH +
2260 SIR_MAC_CHALLENGE_ID_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002261 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002262 }
2263 break;
2264
2265 case SIR_MAC_AUTH_FRAME_3:
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002266 /*
2267 * Auth frame3 to be sent without encrypted framebody
2268 *
2269 * Allocate buffer for Authenticaton frame of size equal
2270 * to management frame header length plus 2 bytes each
2271 * for auth algorithm number, transaction number and
2272 * status code.
2273 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002274
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002275 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2276 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002277 break;
2278
2279 case SIR_MAC_AUTH_FRAME_4:
2280 /*
2281 * Allocate buffer for Authenticaton frame of size equal
2282 * to management frame header length plus 2 bytes each
2283 * for auth algorithm number, transaction number and
2284 * status code.
2285 */
2286
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002287 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2288 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002289
2290 break;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002291 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002292 pe_err("Invalid auth transaction seq num");
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002293 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002294 } /* switch (auth_frame->authTransactionSeqNumber) */
2295
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002296alloc_packet:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302297 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002298 (void **)&packet);
2299
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302300 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002301 pe_err("call to bufAlloc failed for AUTH frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002302 return;
2303 }
2304
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302305 qdf_mem_zero(frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002306
2307 /* Prepare BD */
2308 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2309 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2310 mac_hdr = (tpSirMacMgmtHdr) frame;
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302311 if (wep_challenge_len)
2312 mac_hdr->fc.wep = LIM_WEP_IN_FC;
2313 else
2314 mac_hdr->fc.wep = LIM_NO_WEP_IN_FC;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002315
2316 /* Prepare BSSId */
Rajeev Kumarcf835a02016-04-15 15:01:31 -07002317 if (LIM_IS_AP_ROLE(session))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302318 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002319 (uint8_t *) session->bssId,
2320 sizeof(tSirMacAddr));
2321
2322 /* Prepare Authentication frame body */
2323 body = frame + sizeof(tSirMacMgmtHdr);
2324
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302325 if (wep_challenge_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302326 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002327
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002328 pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329 MAC_ADDR_ARRAY(mac_hdr->da));
2330
2331 } else {
2332 *((uint16_t *) (body)) =
2333 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2334 body += sizeof(uint16_t);
2335 body_len -= sizeof(uint16_t);
2336
2337 *((uint16_t *) (body)) =
2338 sir_swap_u16if_needed(
2339 auth_frame->authTransactionSeqNumber);
2340 body += sizeof(uint16_t);
2341 body_len -= sizeof(uint16_t);
2342
2343 *((uint16_t *) (body)) =
2344 sir_swap_u16if_needed(auth_frame->authStatusCode);
2345 body += sizeof(uint16_t);
2346 body_len -= sizeof(uint16_t);
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002347
2348 if (challenge_req) {
2349 if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
Himanshu Agarwalc422ca72017-09-19 11:07:36 +05302350 /* copy challenge IE id, len, challenge text */
2351 *body = auth_frame->type;
2352 body++;
2353 body_len -= sizeof(uint8_t);
2354 *body = auth_frame->length;
2355 body++;
2356 body_len -= sizeof(uint8_t);
2357 qdf_mem_copy(body, auth_frame->challengeText,
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002358 body_len);
2359 pe_err("Incomplete challenge info: length: %d, expected: %d",
2360 body_len,
2361 SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
2362 body += body_len;
2363 body_len = 0;
2364 } else {
2365 /* copy challenge IE id, len, challenge text */
2366 *body = auth_frame->type;
2367 body++;
2368 *body = auth_frame->length;
2369 body++;
2370 qdf_mem_copy(body, auth_frame->challengeText,
yeshwanth sriram guntuka5c71a292017-08-24 15:51:19 +05302371 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
2372 body += SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002373
yeshwanth sriram guntuka5c71a292017-08-24 15:51:19 +05302374 body_len -= SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH +
2375 SIR_MAC_CHALLENGE_ID_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002376 }
2377 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002379 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2380 (auth_frame->authTransactionSeqNumber ==
2381 SIR_MAC_AUTH_FRAME_1) &&
2382 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2383
2384 if (ft_ies_length > 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302385 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002386 session->ftPEContext.
2387 pFTPreAuthReq->ft_ies,
2388 ft_ies_length);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002389 pe_debug("Auth1 Frame FTIE is: ");
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002390 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2391 QDF_TRACE_LEVEL_DEBUG,
2392 (uint8_t *) body,
2393 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002394 } else if (NULL != session->ftPEContext.
2395 pFTPreAuthReq->pbssDescription) {
2396 /* MDID attr is 54 */
2397 *body = SIR_MDIE_ELEMENT_ID;
2398 body++;
2399 *body = SIR_MDIE_SIZE;
2400 body++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302401 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002402 &session->ftPEContext.pFTPreAuthReq->
2403 pbssDescription->mdie[0],
2404 SIR_MDIE_SIZE);
2405 }
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05302406 } else if (auth_frame->authAlgoNumber ==
2407 eSIR_FILS_SK_WITHOUT_PFS) {
2408 /* TODO MDIE */
2409 pe_debug("appending fils Auth data");
2410 lim_add_fils_data_to_auth_frame(session, body);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002411 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002412
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002413 pe_debug("*** Sending Auth seq# %d status %d (%d) to "
2414 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002415 auth_frame->authTransactionSeqNumber,
2416 auth_frame->authStatusCode,
2417 (auth_frame->authStatusCode ==
2418 eSIR_MAC_SUCCESS_STATUS),
2419 MAC_ADDR_ARRAY(mac_hdr->da));
2420 }
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002421 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2422 QDF_TRACE_LEVEL_DEBUG,
2423 frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002424
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302425 if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
2426 (SIR_BAND_5_GHZ == lim_get_rf_band(
2427 session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002428 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302429 else if ((SIR_BAND_5_GHZ ==
2430 lim_get_rf_band(session->currentOperChannel))
2431 || (session->pePersona == QDF_P2P_CLIENT_MODE)
2432 || (session->pePersona == QDF_P2P_GO_MODE))
2433 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002434
Anurag Chouhan6d760662016-02-20 16:05:43 +05302435 if (session->pePersona == QDF_P2P_CLIENT_MODE ||
2436 session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002437 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2438
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302439 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002440 session->peSessionId, mac_hdr->fc.subType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002441
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302442 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
Naveen Rawat296a5182017-09-25 14:02:48 -07002443 min_rid = lim_get_min_session_txrate(session);
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302444 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
2445 (uint16_t)frame_len,
2446 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2447 7, lim_tx_complete, frame,
2448 lim_auth_tx_complete_cnf,
Naveen Rawat296a5182017-09-25 14:02:48 -07002449 tx_flag, sme_sessionid, false, 0, min_rid);
Abhishek Singhdd2cb572017-08-11 11:10:19 +05302450 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2451 session->peSessionId, qdf_status));
2452 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
2453 pe_err("*** Could not send Auth frame, retCode=%X ***",
2454 qdf_status);
2455 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2456 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_ACK_EVENT,
2457 session, SENT_FAIL, eSIR_FAILURE);
2458 /* Pkt will be freed up by the callback */
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302459 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002460 return;
2461}
2462
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302463QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002464{
2465 uint16_t aid;
2466 tpDphHashNode pStaDs;
2467 tLimMlmDeauthReq *pMlmDeauthReq;
2468 tLimMlmDeauthCnf mlmDeauthCnf;
2469 tpPESession psessionEntry;
2470
2471 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
2472 if (pMlmDeauthReq) {
2473 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
2474 lim_deactivate_and_change_timer(pMac,
2475 eLIM_DEAUTH_ACK_TIMER);
2476 }
2477
2478 psessionEntry = pe_find_session_by_session_id(pMac,
2479 pMlmDeauthReq->sessionId);
2480 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002481 pe_err("session does not exist for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002482 mlmDeauthCnf.resultCode =
2483 eSIR_SME_INVALID_PARAMETERS;
2484 goto end;
2485 }
2486
2487 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002488 dph_lookup_hash_entry(pMac,
2489 pMlmDeauthReq->peer_macaddr.bytes,
2490 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002491 &psessionEntry->dph.dphHashTable);
2492 if (pStaDs == NULL) {
2493 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2494 goto end;
2495 }
2496
2497 /* / Receive path cleanup with dummy packet */
2498 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2499 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002500 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
2501 (
Abhishek Singhe0680852015-12-16 14:28:48 +05302502#ifdef FEATURE_WLAN_ESE
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002503 (psessionEntry->isESEconnection) ||
Abhishek Singhe0680852015-12-16 14:28:48 +05302504#endif
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002505 (psessionEntry->isFastRoamIniFeatureEnabled) ||
2506 (psessionEntry->is11Rconnection))) {
Jeff Johnson11bd4f32017-09-18 08:15:17 -07002507 pe_debug("FT Preauth (%pK,%d) Deauth rc %d src = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002508 psessionEntry,
2509 psessionEntry->peSessionId,
2510 pMlmDeauthReq->reasonCode,
2511 pMlmDeauthReq->deauthTrigger);
2512 lim_ft_cleanup(pMac, psessionEntry);
2513 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002514 pe_debug("No FT Preauth Session Cleanup in role %d"
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002515#ifdef FEATURE_WLAN_ESE
2516 " isESE %d"
2517#endif
2518 " isLFR %d"
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002519 " is11r %d, Deauth reason %d Trigger = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002520 psessionEntry->limSystemRole,
2521#ifdef FEATURE_WLAN_ESE
2522 psessionEntry->isESEconnection,
2523#endif
2524 psessionEntry->isFastRoamIniFeatureEnabled,
2525 psessionEntry->is11Rconnection,
Abhishek Singhe0680852015-12-16 14:28:48 +05302526 pMlmDeauthReq->reasonCode,
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002527 pMlmDeauthReq->deauthTrigger);
2528 }
2529 /* Free up buffer allocated for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302530 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002531 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
2532 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302533 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534end:
Anurag Chouhanc5548422016-02-24 18:33:27 +05302535 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002536 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002537 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
2538 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
2539 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
2540
2541 /* Free up buffer allocated */
2542 /* for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302543 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002544
2545 lim_post_sme_message(pMac,
2546 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302547 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002548}
2549
2550/**
2551 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
2552 *
2553 * @mac_ctx: Handle to MAC context
2554 *
2555 * Sends disassoc confirmation to SME. Removes disassoc request stored
2556 * in lim.
2557 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302558 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002559 */
2560
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302561QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002562{
2563 uint16_t aid;
2564 tpDphHashNode sta_ds;
2565 tLimMlmDisassocCnf disassoc_cnf;
2566 tpPESession pe_session;
2567 tLimMlmDisassocReq *disassoc_req;
2568
2569 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
2570 if (disassoc_req) {
2571 if (tx_timer_running(
2572 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
2573 lim_deactivate_and_change_timer(mac_ctx,
2574 eLIM_DISASSOC_ACK_TIMER);
2575
2576 pe_session = pe_find_session_by_session_id(
2577 mac_ctx, disassoc_req->sessionId);
2578 if (pe_session == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002579 pe_err("No session for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002580 disassoc_cnf.resultCode =
2581 eSIR_SME_INVALID_PARAMETERS;
2582 goto end;
2583 }
2584
2585 sta_ds = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002586 disassoc_req->peer_macaddr.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002587 &pe_session->dph.dphHashTable);
2588 if (sta_ds == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002589 pe_err("StaDs Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002590 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2591 goto end;
2592 }
2593 /* Receive path cleanup with dummy packet */
2594 if (eSIR_SUCCESS !=
2595 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
2596 disassoc_cnf.resultCode =
2597 eSIR_SME_RESOURCES_UNAVAILABLE;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002598 pe_err("cleanup_rx_path error");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002599 goto end;
2600 }
Deepak Dhamdhere57c95ff2016-09-30 16:44:44 -07002601 if (LIM_IS_STA_ROLE(pe_session) &&
2602 (disassoc_req->reasonCode !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002603 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Jeff Johnson11bd4f32017-09-18 08:15:17 -07002604 pe_debug("FT Preauth Session (%pK %d) Clean up",
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002605 pe_session, pe_session->peSessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002606
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002607 /* Delete FT session if there exists one */
2608 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002609 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002610 /* Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302611 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002612 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302613 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302615 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 }
2617end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302618 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002619 (uint8_t *) disassoc_req->peer_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302620 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002621 disassoc_cnf.aid = disassoc_req->aid;
2622 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
2623
2624 /* Update PE session ID */
2625 disassoc_cnf.sessionId = disassoc_req->sessionId;
2626
2627 if (disassoc_req != NULL) {
2628 /* / Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302629 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002630 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
2631 }
2632
2633 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
2634 (uint32_t *) &disassoc_cnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302635 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002636}
2637
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302638QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
2639 qdf_nbuf_t buf,
2640 uint32_t txCompleteSuccess,
2641 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002642{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302643 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2644
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002645 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302646
2647 if (buf)
2648 qdf_nbuf_free(buf);
2649
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002650 return lim_send_disassoc_cnf(pMac);
2651}
2652
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302653QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
2654 qdf_nbuf_t buf,
2655 uint32_t txCompleteSuccess,
2656 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002657{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302658 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2659
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002660 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302661
2662 if (buf)
2663 qdf_nbuf_free(buf);
2664
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002665 return lim_send_deauth_cnf(pMac);
2666}
2667
2668/**
2669 * \brief This function is called to send Disassociate frame.
2670 *
2671 *
2672 * \param pMac Pointer to Global MAC structure
2673 *
2674 * \param nReason Indicates the reason that need to be sent in
2675 * Disassociation frame
2676 *
2677 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
2678 * sent
2679 *
2680 *
2681 */
2682
2683void
2684lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
2685 uint16_t nReason,
2686 tSirMacAddr peer,
2687 tpPESession psessionEntry, bool waitForAck)
2688{
2689 tDot11fDisassociation frm;
2690 uint8_t *pFrame;
2691 tpSirMacMgmtHdr pMacHdr;
2692 uint32_t nBytes, nPayload, nStatus;
2693 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302694 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695 uint8_t txFlag = 0;
2696 uint32_t val = 0;
2697 uint8_t smeSessionId = 0;
2698 if (NULL == psessionEntry) {
2699 return;
2700 }
2701
2702 /*
2703 * In case when cac timer is running for this SAP session then
2704 * avoid sending disassoc out. It is violation of dfs specification.
2705 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302706 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2707 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002708 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302709 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002710 FL
2711 ("CAC timer is running, drop disassoc from going out"));
2712 return;
2713 }
2714 smeSessionId = psessionEntry->smeSessionId;
2715
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302716 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002717
2718 frm.Reason.code = nReason;
2719
2720 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
2721 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002722 pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002723 nStatus);
2724 /* We'll fall back on the worst case scenario: */
2725 nPayload = sizeof(tDot11fDisassociation);
2726 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002727 pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)",
2728 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 }
2730
2731 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2732
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302733 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002734 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302735 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002736 pe_err("Failed to allocate %d bytes for a Disassociation",
2737 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002738 return;
2739 }
2740 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302741 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002742
2743 /* Next, we fill out the buffer descriptor: */
2744 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2745 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
2746 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2747
2748 /* Prepare the BSSID */
2749 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2750
2751#ifdef WLAN_FEATURE_11W
2752 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2753#endif
2754
2755 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
2756 sizeof(tSirMacMgmtHdr),
2757 nPayload, &nPayload);
2758 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002759 pe_err("Failed to pack a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002760 nStatus);
2761 cds_packet_free((void *)pPacket);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002762 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002763 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002764 pe_warn("There were warnings while packing a Disassociation (0x%08x)",
2765 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002766 }
2767
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002768 pe_debug("***Sessionid %d Sending Disassociation frame with "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002769 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002770 MAC_ADDRESS_STR, psessionEntry->peSessionId, nReason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002771 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
2772 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2773
2774 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302775 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2776 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002777 ) {
2778 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2779 }
2780
Sushant Kaushik46556062015-12-02 16:57:47 +05302781 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002782
2783 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302784 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002785 psessionEntry->peSessionId,
2786 pMacHdr->fc.subType));
2787 /* Queue Disassociation frame in high priority WQ */
2788 /* get the duration from the request */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302789 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002790 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2791 TXRX_FRM_802_11_MGMT,
2792 ANI_TXDIR_TODS, 7, lim_tx_complete,
2793 pFrame, lim_disassoc_tx_complete_cnf,
Naveen Rawat296a5182017-09-25 14:02:48 -07002794 txFlag, smeSessionId, false, 0,
2795 RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302796 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302797 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302798 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799
2800 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2801
2802 if (tx_timer_change
2803 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
2804 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002805 pe_err("Unable to change Disassoc ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002806 return;
2807 } else if (TX_SUCCESS !=
2808 tx_timer_activate(&pMac->lim.limTimers.
2809 gLimDisassocAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002810 pe_err("Unable to activate Disassoc ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 lim_deactivate_and_change_timer(pMac,
2812 eLIM_DISASSOC_ACK_TIMER);
2813 return;
2814 }
2815 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302816 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002817 psessionEntry->peSessionId,
2818 pMacHdr->fc.subType));
2819 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302820 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002821 TXRX_FRM_802_11_MGMT,
2822 ANI_TXDIR_TODS,
2823 7,
2824 lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07002825 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302826 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302827 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302828 psessionEntry->peSessionId, qdf_status));
2829 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002830 pe_err("Failed to send Disassociation (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302831 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002832 /* Pkt will be freed up by the callback */
2833 }
2834 }
2835} /* End lim_send_disassoc_mgmt_frame. */
2836
2837/**
2838 * \brief This function is called to send a Deauthenticate frame
2839 *
2840 *
2841 * \param pMac Pointer to global MAC structure
2842 *
2843 * \param nReason Indicates the reason that need to be sent in the
2844 * Deauthenticate frame
2845 *
2846 * \param peeer address of the STA to which the frame is to be sent
2847 *
2848 *
2849 */
2850
2851void
2852lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
2853 uint16_t nReason,
2854 tSirMacAddr peer,
2855 tpPESession psessionEntry, bool waitForAck)
2856{
2857 tDot11fDeAuth frm;
2858 uint8_t *pFrame;
2859 tpSirMacMgmtHdr pMacHdr;
2860 uint32_t nBytes, nPayload, nStatus;
2861 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302862 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002863 uint8_t txFlag = 0;
2864 uint32_t val = 0;
2865#ifdef FEATURE_WLAN_TDLS
2866 uint16_t aid;
2867 tpDphHashNode pStaDs;
2868#endif
2869 uint8_t smeSessionId = 0;
2870
2871 if (NULL == psessionEntry) {
2872 return;
2873 }
2874
2875 /*
2876 * In case when cac timer is running for this SAP session then
2877 * avoid deauth frame out. It is violation of dfs specification.
2878 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302879 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2880 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002881 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302882 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002883 FL
2884 ("CAC timer is running, drop the deauth from going out"));
2885 return;
2886 }
2887 smeSessionId = psessionEntry->smeSessionId;
2888
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302889 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002890
2891 frm.Reason.code = nReason;
2892
2893 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
2894 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002895 pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896 nStatus);
2897 /* We'll fall back on the worst case scenario: */
2898 nPayload = sizeof(tDot11fDeAuth);
2899 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002900 pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)",
2901 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002902 }
2903
2904 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2905
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302906 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302908 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002909 pe_err("Failed to allocate %d bytes for a De-Authentication",
2910 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911 return;
2912 }
2913 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302914 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002915
2916 /* Next, we fill out the buffer descriptor: */
2917 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2918 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
2919 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2920
2921 /* Prepare the BSSID */
2922 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2923
2924#ifdef WLAN_FEATURE_11W
2925 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2926#endif
2927
2928 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
2929 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
2930 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002931 pe_err("Failed to pack a DeAuthentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002932 nStatus);
2933 cds_packet_free((void *)pPacket);
2934 return;
2935 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002936 pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
2937 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002938 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002939 pe_debug("***Sessionid %d Sending Deauth frame with "
2940 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
2941 " ,From " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002942 psessionEntry->peSessionId, nReason, waitForAck,
2943 MAC_ADDR_ARRAY(pMacHdr->da),
2944 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2945
2946 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302947 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2948 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002949 ) {
2950 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2951 }
2952
Sushant Kaushik46556062015-12-02 16:57:47 +05302953 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002954#ifdef FEATURE_WLAN_TDLS
2955 pStaDs =
2956 dph_lookup_hash_entry(pMac, peer, &aid,
2957 &psessionEntry->dph.dphHashTable);
2958#endif
2959
2960 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302961 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002962 psessionEntry->peSessionId,
2963 pMacHdr->fc.subType));
2964 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302965 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002966 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2967 TXRX_FRM_802_11_MGMT,
2968 ANI_TXDIR_TODS, 7, lim_tx_complete,
2969 pFrame, lim_deauth_tx_complete_cnf,
Naveen Rawat296a5182017-09-25 14:02:48 -07002970 txFlag, smeSessionId, false, 0,
2971 RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302972 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302973 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302974 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002975 /* Pkt will be freed up by the callback lim_tx_complete */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302976 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002977 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302978 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002979
2980 /* Call lim_process_deauth_ack_timeout which will send
2981 * DeauthCnf for this frame
2982 */
2983 lim_process_deauth_ack_timeout(pMac);
2984 return;
2985 }
2986
2987 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2988
2989 if (tx_timer_change
2990 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
2991 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002992 pe_err("Unable to change Deauth ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002993 return;
2994 } else if (TX_SUCCESS !=
2995 tx_timer_activate(&pMac->lim.limTimers.
2996 gLimDeauthAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002997 pe_err("Unable to activate Deauth ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002998 lim_deactivate_and_change_timer(pMac,
2999 eLIM_DEAUTH_ACK_TIMER);
3000 return;
3001 }
3002 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303003 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003004 psessionEntry->peSessionId,
3005 pMacHdr->fc.subType));
3006#ifdef FEATURE_WLAN_TDLS
3007 if ((NULL != pStaDs)
3008 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
3009 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303010 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003011 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3012 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
3013 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07003014 smeSessionId, 0, RATEID_DEFAULT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003015 } else {
3016#endif
3017 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303018 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003019 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3020 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3021 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07003022 smeSessionId, 0, RATEID_DEFAULT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003023#ifdef FEATURE_WLAN_TDLS
3024 }
3025#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303026 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303027 psessionEntry->peSessionId, qdf_status));
3028 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003029 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303030 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003031 /* Pkt will be freed up by the callback */
3032 }
3033 }
3034
3035} /* End lim_send_deauth_mgmt_frame. */
3036
3037#ifdef ANI_SUPPORT_11H
3038/**
3039 * \brief Send a Measurement Report Action frame
3040 *
3041 *
3042 * \param pMac Pointer to the global MAC structure
3043 *
3044 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
3045 *
3046 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3047 *
3048 *
3049 */
3050
3051tSirRetStatus
3052lim_send_meas_report_frame(tpAniSirGlobal pMac,
3053 tpSirMacMeasReqActionFrame pMeasReqFrame,
3054 tSirMacAddr peer, tpPESession psessionEntry)
3055{
3056 tDot11fMeasurementReport frm;
3057 uint8_t *pFrame;
3058 tSirRetStatus nSirStatus;
3059 tpSirMacMgmtHdr pMacHdr;
3060 uint32_t nBytes, nPayload, nStatus;
3061 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303062 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303064 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065
3066 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3067 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3068 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3069
3070 switch (pMeasReqFrame->measReqIE.measType) {
3071 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3072 nSirStatus =
3073 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3074 &frm.MeasurementReport);
3075 break;
3076 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3077 nSirStatus =
3078 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3079 &frm.MeasurementReport);
3080 break;
3081 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3082 nSirStatus =
3083 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3084 &frm.MeasurementReport);
3085 break;
3086 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003087 pe_err("Unknown measurement type %d in limSen"
3088 "dMeasReportFrame",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003089 pMeasReqFrame->measReqIE.measType);
3090 return eSIR_FAILURE;
3091 }
3092
3093 if (eSIR_SUCCESS != nSirStatus)
3094 return eSIR_FAILURE;
3095
3096 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3097 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003098 pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003099 nStatus);
3100 /* We'll fall back on the worst case scenario: */
3101 nPayload = sizeof(tDot11fMeasurementReport);
3102 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003103 pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)",
3104 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003105 }
3106
3107 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3108
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303109 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003110 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3111 (uint16_t) nBytes, (void **)&pFrame,
3112 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303113 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003114 pe_err("Failed to allocate %d bytes for a "
3115 "De-Authentication", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003116 return eSIR_FAILURE;
3117 }
3118 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303119 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003120
3121 /* Next, we fill out the buffer descriptor: */
3122 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3123 SIR_MAC_MGMT_ACTION, peer);
3124 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3125
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303126 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003127
3128#ifdef WLAN_FEATURE_11W
3129 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3130#endif
3131
3132 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3133 sizeof(tSirMacMgmtHdr),
3134 nPayload, &nPayload);
3135 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003136 pe_err("Failed to pack a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003137 nStatus);
3138 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3139 (void *)pFrame, (void *)pPacket);
3140 return eSIR_FAILURE; /* allocated! */
3141 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003142 pe_warn("There were warnings while packing a Measurement Report (0x%08x)",
3143 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003144 }
3145
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303146 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003147 ((psessionEntry) ? psessionEntry->
3148 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303149 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003150 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3151 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
Naveen Rawat296a5182017-09-25 14:02:48 -07003152 lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303153 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303154 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003155 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303156 qdf_status));
3157 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003158 pe_err("Failed to send a Measurement Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303159 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003160 /* Pkt will be freed up by the callback */
3161 return eSIR_FAILURE; /* just allocated... */
3162 }
3163
3164 return eSIR_SUCCESS;
3165
3166} /* End lim_send_meas_report_frame. */
3167
3168/**
3169 * \brief Send a TPC Request Action frame
3170 *
3171 *
3172 * \param pMac Pointer to the global MAC datastructure
3173 *
3174 * \param peer MAC address to which the frame should be sent
3175 *
3176 *
3177 */
3178
3179void
3180lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3181 tSirMacAddr peer, tpPESession psessionEntry)
3182{
3183 tDot11fTPCRequest frm;
3184 uint8_t *pFrame;
3185 tpSirMacMgmtHdr pMacHdr;
3186 uint32_t nBytes, nPayload, nStatus;
3187 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303188 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003189
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303190 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003191
3192 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3193 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3194 frm.DialogToken.token = 1;
3195 frm.TPCRequest.present = 1;
3196
3197 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3198 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003199 pe_err("Failed to calculate the packed size for a TPC Request (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003200 /* We'll fall back on the worst case scenario: */
3201 nPayload = sizeof(tDot11fTPCRequest);
3202 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003203 pe_warn("There were warnings while calculating the packed size for a TPC Request (0x%08x)",
3204 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003205 }
3206
3207 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3208
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303209 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003210 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3211 (uint16_t) nBytes, (void **)&pFrame,
3212 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303213 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003214 pe_err("Failed to allocate %d bytes for a TPC"
3215 " Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003216 return;
3217 }
3218 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303219 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003220
3221 /* Next, we fill out the buffer descriptor: */
3222 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3223 SIR_MAC_MGMT_ACTION, peer);
3224 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3225
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303226 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003227
3228#ifdef WLAN_FEATURE_11W
3229 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3230#endif
3231
3232 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3233 sizeof(tSirMacMgmtHdr),
3234 nPayload, &nPayload);
3235 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003236 pe_err("Failed to pack a TPC Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003237 nStatus);
3238 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3239 (void *)pFrame, (void *)pPacket);
3240 return; /* allocated! */
3241 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003242 pe_warn("There were warnings while packing a TPC Request (0x%08x)",
3243 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003244 }
3245
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303246 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003247 ((psessionEntry) ? psessionEntry->
3248 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303249 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003250 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3251 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
Naveen Rawat296a5182017-09-25 14:02:48 -07003252 lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303253 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303254 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003255 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303256 qdf_status));
3257 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003258 pe_err("Failed to send a TPC Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303259 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003260 /* Pkt will be freed up by the callback */
3261 }
3262
3263} /* End lim_send_tpc_request_frame. */
3264
3265/**
3266 * \brief Send a TPC Report Action frame
3267 *
3268 *
3269 * \param pMac Pointer to the global MAC datastructure
3270 *
3271 * \param pTpcReqFrame Pointer to the received TPC Request
3272 *
3273 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3274 *
3275 *
3276 */
3277
3278tSirRetStatus
3279lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3280 tpSirMacTpcReqActionFrame pTpcReqFrame,
3281 tSirMacAddr peer, tpPESession psessionEntry)
3282{
3283 tDot11fTPCReport frm;
3284 uint8_t *pFrame;
3285 tpSirMacMgmtHdr pMacHdr;
3286 uint32_t nBytes, nPayload, nStatus;
3287 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303288 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003289
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303290 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003291
3292 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3293 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3294 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3295
3296 frm.TPCReport.tx_power = 0;
3297 frm.TPCReport.link_margin = 0;
3298 frm.TPCReport.present = 1;
3299
3300 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3301 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003302 pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003303 /* We'll fall back on the worst case scenario: */
3304 nPayload = sizeof(tDot11fTPCReport);
3305 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003306 pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)",
3307 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003308 }
3309
3310 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3311
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303312 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003313 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3314 (uint16_t) nBytes, (void **)&pFrame,
3315 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303316 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003317 pe_err("Failed to allocate %d bytes for a TPC"
3318 " Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003319 return eSIR_FAILURE;
3320 }
3321 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303322 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003323
3324 /* Next, we fill out the buffer descriptor: */
3325 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3326 SIR_MAC_MGMT_ACTION, peer);
3327
3328 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3329
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303330 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003331
3332#ifdef WLAN_FEATURE_11W
3333 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3334#endif
3335
3336 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3337 sizeof(tSirMacMgmtHdr),
3338 nPayload, &nPayload);
3339 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003340 pe_err("Failed to pack a TPC Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003341 nStatus);
3342 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3343 (void *)pFrame, (void *)pPacket);
3344 return eSIR_FAILURE; /* allocated! */
3345 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003346 pe_warn("There were warnings while packing a TPC Report (0x%08x)",
3347 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003348
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303349 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003350 ((psessionEntry) ? psessionEntry->
3351 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303352 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003353 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3354 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
Naveen Rawat296a5182017-09-25 14:02:48 -07003355 lim_tx_complete, pFrame, 0, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303356 MTRACE(qdf_trace
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003357 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3358 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3359 qdf_status));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303360 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003361 pe_err("Failed to send a TPC Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303362 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003363 /* Pkt will be freed up by the callback */
3364 return eSIR_FAILURE; /* just allocated... */
3365 }
3366
3367 return eSIR_SUCCESS;
3368
3369} /* End lim_send_tpc_report_frame. */
3370#endif /* ANI_SUPPORT_11H */
3371
3372/**
3373 * \brief Send a Channel Switch Announcement
3374 *
3375 *
3376 * \param pMac Pointer to the global MAC datastructure
3377 *
3378 * \param peer MAC address to which this frame will be sent
3379 *
3380 * \param nMode
3381 *
3382 * \param nNewChannel
3383 *
3384 * \param nCount
3385 *
3386 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3387 *
3388 *
3389 */
3390
3391tSirRetStatus
3392lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3393 tSirMacAddr peer,
3394 uint8_t nMode,
3395 uint8_t nNewChannel,
3396 uint8_t nCount, tpPESession psessionEntry)
3397{
3398 tDot11fChannelSwitch frm;
3399 uint8_t *pFrame;
3400 tpSirMacMgmtHdr pMacHdr;
3401 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3402 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303403 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003404 uint8_t txFlag = 0;
3405
3406 uint8_t smeSessionId = 0;
3407
3408 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003409 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410 return eSIR_FAILURE;
3411 }
3412 smeSessionId = psessionEntry->smeSessionId;
3413
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303414 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003415
3416 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3417 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
3418 frm.ChanSwitchAnn.switchMode = nMode;
3419 frm.ChanSwitchAnn.newChannel = nNewChannel;
3420 frm.ChanSwitchAnn.switchCount = nCount;
3421 frm.ChanSwitchAnn.present = 1;
3422
3423 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
3424 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003425 pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003426 nStatus);
3427 /* We'll fall back on the worst case scenario: */
3428 nPayload = sizeof(tDot11fChannelSwitch);
3429 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003430 pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)",
3431 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003432 }
3433
3434 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3435
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303436 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003437 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3438 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303439 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003440 pe_err("Failed to allocate %d bytes for a TPC Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003441 return eSIR_FAILURE;
3442 }
3443 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303444 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003445
3446 /* Next, we fill out the buffer descriptor: */
3447 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3448 SIR_MAC_MGMT_ACTION, peer,
3449 psessionEntry->selfMacAddr);
3450 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303451 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003452 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3453
3454#ifdef WLAN_FEATURE_11W
3455 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3456#endif
3457
3458 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
3459 sizeof(tSirMacMgmtHdr),
3460 nPayload, &nPayload);
3461 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003462 pe_err("Failed to pack a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003463 nStatus);
3464 cds_packet_free((void *)pPacket);
3465 return eSIR_FAILURE; /* allocated! */
3466 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003467 pe_warn("There were warnings while packing a Channel Switch (0x%08x)",
3468 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003469 }
3470
3471 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303472 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3473 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003474 ) {
3475 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3476 }
3477
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303478 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003479 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303480 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003481 TXRX_FRM_802_11_MGMT,
3482 ANI_TXDIR_TODS,
3483 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07003484 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303485 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303486 psessionEntry->peSessionId, qdf_status));
3487 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003488 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303489 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003490 /* Pkt will be freed up by the callback */
3491 return eSIR_FAILURE;
3492 }
3493
3494 return eSIR_SUCCESS;
3495
3496} /* End lim_send_channel_switch_mgmt_frame. */
3497
Abhishek Singh518323d2015-10-19 17:42:01 +05303498/**
3499 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
3500 * action frame over the air .
3501 * @mac_ctx: pointer to global mac structure
3502 * @peer: Destination mac.
3503 * @mode: channel switch mode
3504 * @new_op_class: new op class
3505 * @new_channel: new channel to switch
3506 * @count: channel switch count
3507 *
3508 * This function is called to send ECSA frame.
3509 *
3510 * Return: success if frame is sent else return failure
3511 */
3512
3513tSirRetStatus
3514lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
3515 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
3516 uint8_t new_channel, uint8_t count, tpPESession session_entry)
3517{
3518 tDot11fext_channel_switch_action_frame frm;
3519 uint8_t *frame;
3520 tpSirMacMgmtHdr mac_hdr;
3521 uint32_t num_bytes, n_payload, status;
3522 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303523 QDF_STATUS qdf_status;
Abhishek Singh518323d2015-10-19 17:42:01 +05303524 uint8_t txFlag = 0;
3525 uint8_t sme_session_id = 0;
3526
3527 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003528 pe_err("Session entry is NULL!!!");
Abhishek Singh518323d2015-10-19 17:42:01 +05303529 return eSIR_FAILURE;
3530 }
3531
3532 sme_session_id = session_entry->smeSessionId;
3533
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303534 qdf_mem_set(&frm, sizeof(frm), 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303535
3536 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
3537 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
3538
3539 frm.ext_chan_switch_ann_action.switch_mode = mode;
3540 frm.ext_chan_switch_ann_action.op_class = new_op_class;
3541 frm.ext_chan_switch_ann_action.new_channel = new_channel;
3542 frm.ext_chan_switch_ann_action.switch_count = count;
3543
3544
3545 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
3546 &frm, &n_payload);
3547 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003548 pe_err("Failed to get packed size for Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303549 status);
3550 /* We'll fall back on the worst case scenario*/
3551 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
3552 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003553 pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)",
Abhishek Singh518323d2015-10-19 17:42:01 +05303554 status);
3555 }
3556
3557 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3558
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303559 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303560 (void **) &frame, (void **) &packet);
3561
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303562 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003563 pe_err("Failed to allocate %d bytes for a Ext Channel Switch",
Abhishek Singh518323d2015-10-19 17:42:01 +05303564 num_bytes);
3565 return eSIR_FAILURE;
3566 }
3567
3568 /* Paranoia*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303569 qdf_mem_set(frame, num_bytes, 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303570
3571 /* Next, we fill out the buffer descriptor */
3572 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3573 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3574 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303575 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Abhishek Singh518323d2015-10-19 17:42:01 +05303576 (uint8_t *) session_entry->bssId,
3577 sizeof(tSirMacAddr));
3578
3579 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
3580 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3581 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003582 pe_err("Failed to pack a Channel Switch 0x%08x", status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303583 cds_packet_free((void *)packet);
3584 return eSIR_FAILURE;
3585 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003586 pe_warn("There were warnings while packing a Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303587 status);
3588 }
3589
3590 if ((SIR_BAND_5_GHZ ==
3591 lim_get_rf_band(session_entry->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05303592 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3593 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303594 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3595 }
3596
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003597 pe_debug("Send Ext channel Switch to :"MAC_ADDRESS_STR" with swcount %d, swmode %d , newchannel %d newops %d",
Abhishek Singh518323d2015-10-19 17:42:01 +05303598 MAC_ADDR_ARRAY(mac_hdr->da),
3599 frm.ext_chan_switch_ann_action.switch_count,
3600 frm.ext_chan_switch_ann_action.switch_mode,
3601 frm.ext_chan_switch_ann_action.new_channel,
3602 frm.ext_chan_switch_ann_action.op_class);
3603
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303604 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Abhishek Singh518323d2015-10-19 17:42:01 +05303605 session_entry->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303606 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303607 TXRX_FRM_802_11_MGMT,
3608 ANI_TXDIR_TODS,
3609 7,
3610 lim_tx_complete, frame,
Naveen Rawat296a5182017-09-25 14:02:48 -07003611 txFlag, sme_session_id, 0,
3612 RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303613 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303614 session_entry->peSessionId, qdf_status));
3615 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003616 pe_err("Failed to send a Ext Channel Switch %X!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303617 qdf_status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303618 /* Pkt will be freed up by the callback */
3619 return eSIR_FAILURE;
3620 }
3621 return eSIR_SUCCESS;
3622} /* End lim_send_extended_chan_switch_action_frame */
3623
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303624
3625/**
3626 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
3627 * sent over the air
3628 *
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303629 * @context: pointer to global mac
3630 * @buf: buffer
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303631 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303632 * @params: tx completion params
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303633 *
3634 * Return: This returns QDF_STATUS
3635 */
3636
3637static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303638 void *context,
3639 qdf_nbuf_t buf,
3640 uint32_t tx_complete,
3641 void *params)
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303642{
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003643 pe_debug("tx_complete: %d", tx_complete);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303644 return QDF_STATUS_SUCCESS;
3645}
3646
3647/**
3648 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
3649 * p2p oper chan change confirm action frame
3650 * @mac_ctx: pointer to global mac structure
3651 * @peer: Destination mac.
3652 * @session_entry: session entry
3653 *
3654 * This function is called to send p2p oper chan change confirm action frame.
3655 *
3656 * Return: success if frame is sent else return failure
3657 */
3658
3659tSirRetStatus
3660lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
3661 tSirMacAddr peer, tpPESession session_entry)
3662{
3663 tDot11fp2p_oper_chan_change_confirm frm;
3664 uint8_t *frame;
3665 tpSirMacMgmtHdr mac_hdr;
3666 uint32_t num_bytes, n_payload, status;
3667 void *packet;
3668 QDF_STATUS qdf_status;
3669 uint8_t tx_flag = 0;
3670 uint8_t sme_session_id = 0;
3671
3672 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003673 pe_err("Session entry is NULL!!!");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303674 return eSIR_FAILURE;
3675 }
3676
3677 sme_session_id = session_entry->smeSessionId;
3678
3679 qdf_mem_set(&frm, sizeof(frm), 0);
3680
3681 frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
3682
3683 qdf_mem_copy(frm.p2p_action_oui.oui_data,
3684 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
3685 frm.p2p_action_subtype.subtype = 0x04;
3686 frm.DialogToken.token = 0x0;
3687
3688 if (session_entry->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003689 pe_debug("Populate HT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303690 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
3691 }
3692
3693 if (session_entry->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003694 pe_debug("Populate VHT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303695 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
3696 populate_dot11f_operating_mode(mac_ctx,
3697 &frm.OperatingMode, session_entry);
3698 }
3699
3700 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
3701 &frm, &n_payload);
3702 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003703 pe_err("Failed to get packed size 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303704 /* We'll fall back on the worst case scenario*/
3705 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
3706 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003707 pe_warn("There were warnings while calculating the packed size (0x%08x)",
3708 status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303709 }
3710
3711 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3712
3713 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
3714 (void **) &frame, (void **) &packet);
3715
3716 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003717 pe_err("Failed to allocate %d bytes", num_bytes);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303718 return eSIR_FAILURE;
3719 }
3720
3721 qdf_mem_set(frame, num_bytes, 0);
3722
3723 /* Next, fill out the buffer descriptor */
3724 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3725 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3726 mac_hdr = (tpSirMacMgmtHdr) frame;
3727 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
3728 (uint8_t *) session_entry->bssId,
3729 sizeof(tSirMacAddr));
3730
3731 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
3732 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3733 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003734 pe_err("Failed to pack 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303735 cds_packet_free((void *)packet);
3736 return eSIR_FAILURE;
3737 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003738 pe_warn("There were warnings while packing 0x%08x",
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303739 status);
3740 }
3741
3742 if ((SIR_BAND_5_GHZ ==
3743 lim_get_rf_band(session_entry->currentOperChannel)) ||
3744 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3745 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
3746 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3747 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003748 pe_debug("Send frame on channel %d to mac "
3749 MAC_ADDRESS_STR, session_entry->currentOperChannel,
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303750 MAC_ADDR_ARRAY(peer));
3751
3752 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3753 session_entry->peSessionId, mac_hdr->fc.subType));
3754
3755 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
3756 (uint16_t)num_bytes,
3757 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3758 7, lim_tx_complete, frame,
3759 lim_oper_chan_change_confirm_tx_complete_cnf,
Naveen Rawat296a5182017-09-25 14:02:48 -07003760 tx_flag, sme_session_id, false, 0, RATEID_DEFAULT);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303761
3762 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3763 session_entry->peSessionId, qdf_status));
3764 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003765 pe_err("Failed to send status %X!", qdf_status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303766 /* Pkt will be freed up by the callback */
3767 return eSIR_FAILURE;
3768 }
3769 return eSIR_SUCCESS;
3770}
3771
3772
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003773tSirRetStatus
3774lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
3775 tSirMacAddr peer,
3776 uint8_t nMode, tpPESession psessionEntry)
3777{
3778 tDot11fOperatingMode frm;
3779 uint8_t *pFrame;
3780 tpSirMacMgmtHdr pMacHdr;
3781 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
3782 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303783 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003784 uint8_t txFlag = 0;
3785
3786 uint8_t smeSessionId = 0;
3787
3788 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003789 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003790 return eSIR_FAILURE;
3791 }
3792 smeSessionId = psessionEntry->smeSessionId;
3793
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303794 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003795
3796 frm.Category.category = SIR_MAC_ACTION_VHT;
3797 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
3798 frm.OperatingMode.chanWidth = nMode;
3799 frm.OperatingMode.rxNSS = 0;
3800 frm.OperatingMode.rxNSSType = 0;
3801
3802 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
3803 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003804 pe_err("Failed to calculate the packed size for a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003805 nStatus);
3806 /* We'll fall back on the worst case scenario: */
3807 nPayload = sizeof(tDot11fOperatingMode);
3808 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003809 pe_warn("There were warnings while calculating the packed size for a Operating Mode (0x%08x)",
3810 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003811 }
3812
3813 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3814
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303815 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003816 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3817 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303818 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003819 pe_err("Failed to allocate %d bytes for a Operating Mode Report",
3820 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003821 return eSIR_FAILURE;
3822 }
3823 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303824 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003825
3826 /* Next, we fill out the buffer descriptor: */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303827 if (psessionEntry->pePersona == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003828 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3829 SIR_MAC_MGMT_ACTION, peer,
3830 psessionEntry->selfMacAddr);
3831 else
3832 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3833 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
3834 psessionEntry->selfMacAddr);
3835 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303836 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003837 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3838 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
3839 sizeof(tSirMacMgmtHdr),
3840 nPayload, &nPayload);
3841 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003842 pe_err("Failed to pack a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003843 nStatus);
3844 cds_packet_free((void *)pPacket);
3845 return eSIR_FAILURE; /* allocated! */
3846 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003847 pe_warn("There were warnings while packing a Operating Mode (0x%08x)",
3848 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003849 }
3850 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303851 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3852 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003853 ) {
3854 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3855 }
3856
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303857 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003858 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303859 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003860 TXRX_FRM_802_11_MGMT,
3861 ANI_TXDIR_TODS,
3862 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07003863 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303864 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303865 psessionEntry->peSessionId, qdf_status));
3866 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003867 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303868 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003869 /* Pkt will be freed up by the callback */
3870 return eSIR_FAILURE;
3871 }
3872
3873 return eSIR_SUCCESS;
3874}
3875
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003876/**
3877 * \brief Send a Neighbor Report Request Action frame
3878 *
3879 *
3880 * \param pMac Pointer to the global MAC structure
3881 *
3882 * \param pNeighborReq Address of a tSirMacNeighborReportReq
3883 *
3884 * \param peer mac address of peer station.
3885 *
3886 * \param psessionEntry address of session entry.
3887 *
3888 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3889 *
3890 *
3891 */
3892
3893tSirRetStatus
3894lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
3895 tpSirMacNeighborReportReq pNeighborReq,
3896 tSirMacAddr peer, tpPESession psessionEntry)
3897{
3898 tSirRetStatus statusCode = eSIR_SUCCESS;
3899 tDot11fNeighborReportRequest frm;
3900 uint8_t *pFrame;
3901 tpSirMacMgmtHdr pMacHdr;
3902 uint32_t nBytes, nPayload, nStatus;
3903 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303904 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905 uint8_t txFlag = 0;
3906 uint8_t smeSessionId = 0;
3907
3908 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003909 pe_err("(psession == NULL) in Request to send Neighbor Report request action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003910 return eSIR_FAILURE;
3911 }
3912 smeSessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303913 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003914
3915 frm.Category.category = SIR_MAC_ACTION_RRM;
3916 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
3917 frm.DialogToken.token = pNeighborReq->dialogToken;
3918
3919 if (pNeighborReq->ssid_present) {
3920 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
3921 }
3922
3923 nStatus =
3924 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
3925 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003926 pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003927 nStatus);
3928 /* We'll fall back on the worst case scenario: */
3929 nPayload = sizeof(tDot11fNeighborReportRequest);
3930 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003931 pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)",
3932 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003933 }
3934
3935 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3936
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303937 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003938 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3939 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303940 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003941 pe_err("Failed to allocate %d bytes for a Neighbor "
3942 "Report Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003943 return eSIR_FAILURE;
3944 }
3945 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303946 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003947
3948 /* Copy necessary info to BD */
3949 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3950 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
3951
3952 /* Update A3 with the BSSID */
3953 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3954
3955 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3956
3957#ifdef WLAN_FEATURE_11W
3958 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3959#endif
3960
3961 /* Now, we're ready to "pack" the frames */
3962 nStatus = dot11f_pack_neighbor_report_request(pMac,
3963 &frm,
3964 pFrame +
3965 sizeof(tSirMacMgmtHdr),
3966 nPayload, &nPayload);
3967
3968 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003969 pe_err("Failed to pack an Neighbor Report Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003970 nStatus);
3971
3972 /* FIXME - Need to convert to tSirRetStatus */
3973 statusCode = eSIR_FAILURE;
3974 goto returnAfterError;
3975 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003976 pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)",
3977 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003978 }
3979
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003980 pe_debug("Sending a Neighbor Report Request to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +05303981 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003982
3983 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303984 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3985 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003986 ) {
3987 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3988 }
3989
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303990 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003991 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303992 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003993 pPacket,
3994 (uint16_t) nBytes,
3995 TXRX_FRM_802_11_MGMT,
3996 ANI_TXDIR_TODS,
3997 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07003998 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303999 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304000 psessionEntry->peSessionId, qdf_status));
4001 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004002 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004003 statusCode = eSIR_FAILURE;
4004 /* Pkt will be freed up by the callback */
4005 return statusCode;
4006 } else
4007 return eSIR_SUCCESS;
4008
4009returnAfterError:
4010 cds_packet_free((void *)pPacket);
4011
4012 return statusCode;
4013} /* End lim_send_neighbor_report_request_frame. */
4014
4015/**
4016 * \brief Send a Link Report Action frame
4017 *
4018 *
4019 * \param pMac Pointer to the global MAC structure
4020 *
4021 * \param pLinkReport Address of a tSirMacLinkReport
4022 *
4023 * \param peer mac address of peer station.
4024 *
4025 * \param psessionEntry address of session entry.
4026 *
4027 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4028 *
4029 *
4030 */
4031
4032tSirRetStatus
4033lim_send_link_report_action_frame(tpAniSirGlobal pMac,
4034 tpSirMacLinkReport pLinkReport,
4035 tSirMacAddr peer, tpPESession psessionEntry)
4036{
4037 tSirRetStatus statusCode = eSIR_SUCCESS;
4038 tDot11fLinkMeasurementReport frm;
4039 uint8_t *pFrame;
4040 tpSirMacMgmtHdr pMacHdr;
4041 uint32_t nBytes, nPayload, nStatus;
4042 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304043 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004044 uint8_t txFlag = 0;
4045 uint8_t smeSessionId = 0;
4046
4047 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004048 pe_err("(psession == NULL) in Request to send Link Report action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004049 return eSIR_FAILURE;
4050 }
4051
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304052 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004053
4054 frm.Category.category = SIR_MAC_ACTION_RRM;
4055 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
4056 frm.DialogToken.token = pLinkReport->dialogToken;
4057
4058 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
4059 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
4060 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
4061 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
4062 /* such case this way than changing the frame parser. */
4063 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
4064 frm.TPCEleLen.TPCLen = 2;
4065 frm.TxPower.txPower = pLinkReport->txPower;
4066 frm.LinkMargin.linkMargin = 0;
4067
4068 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4069 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4070 frm.RCPI.rcpi = pLinkReport->rcpi;
4071 frm.RSNI.rsni = pLinkReport->rsni;
4072
4073 nStatus =
4074 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4075 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004076 pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004077 /* We'll fall back on the worst case scenario: */
4078 nPayload = sizeof(tDot11fLinkMeasurementReport);
4079 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004080 pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)",
4081 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082 }
4083
4084 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4085
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304086 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004087 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4088 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304089 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004090 pe_err("Failed to allocate %d bytes for a Link "
4091 "Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004092 return eSIR_FAILURE;
4093 }
4094 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304095 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004096
4097 /* Copy necessary info to BD */
4098 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4099 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4100
4101 /* Update A3 with the BSSID */
4102 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4103
4104 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4105
4106#ifdef WLAN_FEATURE_11W
4107 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4108#endif
4109
4110 /* Now, we're ready to "pack" the frames */
4111 nStatus = dot11f_pack_link_measurement_report(pMac,
4112 &frm,
4113 pFrame +
4114 sizeof(tSirMacMgmtHdr),
4115 nPayload, &nPayload);
4116
4117 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004118 pe_err("Failed to pack an Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004119
4120 /* FIXME - Need to convert to tSirRetStatus */
4121 statusCode = eSIR_FAILURE;
4122 goto returnAfterError;
4123 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004124 pe_warn("There were warnings while packing Link Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004125 nStatus);
4126 }
4127
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004128 pe_warn("Sending a Link Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004129 lim_print_mac_addr(pMac, peer, LOGW);
4130
4131 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304132 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4133 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004134 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4135 }
4136
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304137 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004138 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304139 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004140 pPacket,
4141 (uint16_t) nBytes,
4142 TXRX_FRM_802_11_MGMT,
4143 ANI_TXDIR_TODS,
4144 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07004145 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304146 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304147 psessionEntry->peSessionId, qdf_status));
4148 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004149 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004150 statusCode = eSIR_FAILURE;
4151 /* Pkt will be freed up by the callback */
4152 return statusCode;
4153 } else
4154 return eSIR_SUCCESS;
4155
4156returnAfterError:
4157 cds_packet_free((void *)pPacket);
4158
4159 return statusCode;
4160} /* End lim_send_link_report_action_frame. */
4161
4162/**
4163 * \brief Send a Beacon Report Action frame
4164 *
4165 *
4166 * \param pMac Pointer to the global MAC structure
4167 *
4168 * \param dialog_token dialog token to be used in the action frame.
4169 *
4170 * \param num_report number of reports in pRRMReport.
4171 *
4172 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4173 *
4174 * \param peer mac address of peer station.
4175 *
4176 * \param psessionEntry address of session entry.
4177 *
4178 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4179 *
4180 *
4181 */
4182
4183tSirRetStatus
4184lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4185 uint8_t dialog_token,
4186 uint8_t num_report,
4187 tpSirMacRadioMeasureReport pRRMReport,
4188 tSirMacAddr peer,
4189 tpPESession psessionEntry)
4190{
4191 tSirRetStatus statusCode = eSIR_SUCCESS;
4192 uint8_t *pFrame;
4193 tpSirMacMgmtHdr pMacHdr;
4194 uint32_t nBytes, nPayload, nStatus;
4195 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304196 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004197 uint8_t i;
4198 uint8_t txFlag = 0;
4199 uint8_t smeSessionId = 0;
4200
4201 tDot11fRadioMeasurementReport *frm =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304202 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004203 if (!frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004204 pe_err("Not enough memory to allocate tDot11fRadioMeasurementReport");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004205 return eSIR_MEM_ALLOC_FAILED;
4206 }
4207
4208 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004209 pe_err("(psession == NULL) in Request to send Beacon Report action frame");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304210 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004211 return eSIR_FAILURE;
4212 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004213
Deepak Dhamdhere6a021482017-04-20 17:59:58 -07004214 smeSessionId = psessionEntry->smeSessionId;
4215
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004216 pe_debug("dialog_token %d num_report %d",
Padma, Santhosh Kumar93ec7d22016-12-26 15:58:37 +05304217 dialog_token, num_report);
4218
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004219 frm->Category.category = SIR_MAC_ACTION_RRM;
4220 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4221 frm->DialogToken.token = dialog_token;
4222
4223 frm->num_MeasurementReport =
4224 (num_report >
4225 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4226 num_report;
4227
4228 for (i = 0; i < frm->num_MeasurementReport; i++) {
4229 frm->MeasurementReport[i].type = pRRMReport[i].type;
4230 frm->MeasurementReport[i].token = pRRMReport[i].token;
4231 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4232 switch (pRRMReport[i].type) {
4233 case SIR_MAC_RRM_BEACON_TYPE:
4234 populate_dot11f_beacon_report(pMac,
4235 &frm->MeasurementReport[i],
4236 &pRRMReport[i].report.
4237 beaconReport);
4238 frm->MeasurementReport[i].incapable =
4239 pRRMReport[i].incapable;
4240 frm->MeasurementReport[i].refused =
4241 pRRMReport[i].refused;
4242 frm->MeasurementReport[i].present = 1;
4243 break;
4244 default:
4245 frm->MeasurementReport[i].incapable =
4246 pRRMReport[i].incapable;
4247 frm->MeasurementReport[i].refused =
4248 pRRMReport[i].refused;
4249 frm->MeasurementReport[i].present = 1;
4250 break;
4251 }
4252 }
4253
4254 nStatus =
4255 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4256 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004257 pe_err("Failed to calculate the packed size for a Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004258 nStatus);
4259 /* We'll fall back on the worst case scenario: */
4260 nPayload = sizeof(tDot11fLinkMeasurementReport);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304261 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004262 return eSIR_FAILURE;
4263 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004264 pe_warn("There were warnings while calculating the packed size for a Radio Measure Report (0x%08x)",
4265 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004266 }
4267
4268 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4269
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304270 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004271 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4272 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304273 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004274 pe_err("Failed to allocate %d bytes for a Radio Measure "
4275 "Report", nBytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304276 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277 return eSIR_FAILURE;
4278 }
4279 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304280 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004281
4282 /* Copy necessary info to BD */
4283 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4284 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4285
4286 /* Update A3 with the BSSID */
4287 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4288
4289 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4290
4291#ifdef WLAN_FEATURE_11W
4292 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4293#endif
4294
4295 /* Now, we're ready to "pack" the frames */
4296 nStatus = dot11f_pack_radio_measurement_report(pMac,
4297 frm,
4298 pFrame +
4299 sizeof(tSirMacMgmtHdr),
4300 nPayload, &nPayload);
4301
4302 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004303 pe_err("Failed to pack an Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004304 nStatus);
4305
4306 /* FIXME - Need to convert to tSirRetStatus */
4307 statusCode = eSIR_FAILURE;
4308 goto returnAfterError;
4309 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004310 pe_warn("There were warnings while packing Radio Measure Report (0x%08x)",
4311 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004312 }
4313
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004314 pe_warn("Sending a Radio Measure Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004315 lim_print_mac_addr(pMac, peer, LOGW);
4316
4317 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304318 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4319 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004320 ) {
4321 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4322 }
4323
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304324 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004325 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304326 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004327 pPacket,
4328 (uint16_t) nBytes,
4329 TXRX_FRM_802_11_MGMT,
4330 ANI_TXDIR_TODS,
4331 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07004332 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304333 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304334 psessionEntry->peSessionId, qdf_status));
4335 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004336 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004337 statusCode = eSIR_FAILURE;
4338 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304339 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004340 return statusCode;
4341 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304342 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004343 return eSIR_SUCCESS;
4344 }
4345
4346returnAfterError:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304347 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004348 cds_packet_free((void *)pPacket);
4349 return statusCode;
4350}
4351
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004352#ifdef WLAN_FEATURE_11W
4353/**
4354 * \brief Send SA query request action frame to peer
4355 *
4356 * \sa lim_send_sa_query_request_frame
4357 *
4358 *
4359 * \param pMac The global tpAniSirGlobal object
4360 *
4361 * \param transId Transaction identifier
4362 *
4363 * \param peer The Mac address of the station to which this action frame is addressed
4364 *
4365 * \param psessionEntry The PE session entry
4366 *
4367 * \return eSIR_SUCCESS if setup completes successfully
4368 * eSIR_FAILURE is some problem is encountered
4369 */
4370
4371tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4372 tSirMacAddr peer,
4373 tpPESession psessionEntry)
4374{
4375
4376 tDot11fSaQueryReq frm; /* SA query request action frame */
4377 uint8_t *pFrame;
4378 tSirRetStatus nSirStatus;
4379 tpSirMacMgmtHdr pMacHdr;
4380 uint32_t nBytes, nPayload, nStatus;
4381 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304382 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004383 uint8_t txFlag = 0;
4384 uint8_t smeSessionId = 0;
4385
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304386 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004387 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4388 /* 11w action field is :
4389 action: 0 --> SA Query Request action frame
4390 action: 1 --> SA Query Response action frame */
4391 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4392 /* 11w SA Query Request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304393 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004394
4395 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4396 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004397 pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004398 nStatus);
4399 /* We'll fall back on the worst case scenario: */
4400 nPayload = sizeof(tDot11fSaQueryReq);
4401 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004402 pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)",
4403 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004404 }
4405
4406 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304407 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004408 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304409 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004410 pe_err("Failed to allocate %d bytes for a SA Query Request "
4411 "action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004412 return eSIR_FAILURE;
4413 }
4414 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304415 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004416
4417 /* Copy necessary info to BD */
4418 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4419 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4420
4421 /* Update A3 with the BSSID */
4422 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4423
4424 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4425
4426 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4427 /* in the FC */
4428 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4429
4430 /* Pack 11w SA Query Request frame */
4431 nStatus = dot11f_pack_sa_query_req(pMac,
4432 &frm,
4433 pFrame + sizeof(tSirMacMgmtHdr),
4434 nPayload, &nPayload);
4435
4436 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004437 pe_err("Failed to pack an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004438 nStatus);
4439 /* FIXME - Need to convert to tSirRetStatus */
4440 nSirStatus = eSIR_FAILURE;
4441 goto returnAfterError;
4442 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004443 pe_warn("There were warnings while packing SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004444 nStatus);
4445 }
4446
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004447 pe_debug("Sending an SA Query Request to");
4448 lim_print_mac_addr(pMac, peer, LOGD);
4449 pe_debug("Sending an SA Query Request from ");
4450 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451
4452 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4453#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304454 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4455 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004456#endif
4457 ) {
4458 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4459 }
4460 smeSessionId = psessionEntry->smeSessionId;
4461
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304462 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004463 pPacket,
4464 (uint16_t) nBytes,
4465 TXRX_FRM_802_11_MGMT,
4466 ANI_TXDIR_TODS,
4467 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07004468 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304469 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004470 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004471 nSirStatus = eSIR_FAILURE;
4472 /* Pkt will be freed up by the callback */
4473 return nSirStatus;
4474 } else {
4475 return eSIR_SUCCESS;
4476 }
4477
4478returnAfterError:
4479 cds_packet_free((void *)pPacket);
4480 return nSirStatus;
4481} /* End lim_send_sa_query_request_frame */
4482
4483/**
4484 * \brief Send SA query response action frame to peer
4485 *
4486 * \sa lim_send_sa_query_response_frame
4487 *
4488 *
4489 * \param pMac The global tpAniSirGlobal object
4490 *
4491 * \param transId Transaction identifier received in SA query request action frame
4492 *
4493 * \param peer The Mac address of the AP to which this action frame is addressed
4494 *
4495 * \param psessionEntry The PE session entry
4496 *
4497 * \return eSIR_SUCCESS if setup completes successfully
4498 * eSIR_FAILURE is some problem is encountered
4499 */
4500
4501tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
4502 uint8_t *transId, tSirMacAddr peer,
4503 tpPESession psessionEntry)
4504{
4505
4506 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
4507 uint8_t *pFrame;
4508 tSirRetStatus nSirStatus;
4509 tpSirMacMgmtHdr pMacHdr;
4510 uint32_t nBytes, nPayload, nStatus;
4511 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304512 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004513 uint8_t txFlag = 0;
4514 uint8_t smeSessionId = 0;
4515
4516 smeSessionId = psessionEntry->smeSessionId;
4517
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304518 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004519 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4520 /*11w action field is :
4521 action: 0 --> SA query request action frame
4522 action: 1 --> SA query response action frame */
4523 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
4524 /*11w SA query response transId is same as
4525 SA query request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304526 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004527
4528 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
4529 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004530 pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004531 nStatus);
4532 /* We'll fall back on the worst case scenario: */
4533 nPayload = sizeof(tDot11fSaQueryRsp);
4534 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004535 pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)",
4536 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004537 }
4538
4539 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304540 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004541 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304542 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004543 pe_err("Failed to allocate %d bytes for a SA query response"
4544 " action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004545 return eSIR_FAILURE;
4546 }
4547 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304548 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004549
4550 /* Copy necessary info to BD */
4551 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4552 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4553
4554 /* Update A3 with the BSSID */
4555 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4556
4557 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4558
4559 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
4560 /* in the FC */
4561 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4562
4563 /* Pack 11w SA query response frame */
4564 nStatus = dot11f_pack_sa_query_rsp(pMac,
4565 &frm,
4566 pFrame + sizeof(tSirMacMgmtHdr),
4567 nPayload, &nPayload);
4568
4569 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004570 pe_err("Failed to pack an SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004571 nStatus);
4572 /* FIXME - Need to convert to tSirRetStatus */
4573 nSirStatus = eSIR_FAILURE;
4574 goto returnAfterError;
4575 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004576 pe_warn("There were warnings while packing SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004577 nStatus);
4578 }
4579
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004580 pe_debug("Sending a SA Query Response to");
Srinivas Girigowdaf936d822017-03-19 23:23:59 -07004581 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004582
4583 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4584#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304585 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4586 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004587#endif
4588 ) {
4589 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4590 }
4591
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304592 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004593 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304594 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004595 pPacket,
4596 (uint16_t) nBytes,
4597 TXRX_FRM_802_11_MGMT,
4598 ANI_TXDIR_TODS,
4599 7, lim_tx_complete, pFrame, txFlag,
Naveen Rawat296a5182017-09-25 14:02:48 -07004600 smeSessionId, 0, RATEID_DEFAULT);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304601 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304602 psessionEntry->peSessionId, qdf_status));
4603 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004604 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004605 nSirStatus = eSIR_FAILURE;
4606 /* Pkt will be freed up by the callback */
4607 return nSirStatus;
4608 } else {
4609 return eSIR_SUCCESS;
4610 }
4611
4612returnAfterError:
4613 cds_packet_free((void *)pPacket);
4614 return nSirStatus;
4615} /* End lim_send_sa_query_response_frame */
4616#endif
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004617
4618/**
4619 * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
4620 * @mac_ctx: mac context
4621 * @peer_mac: Peer MAC address
4622 * @tid: TID for which addba response is being sent
4623 * @session: PE session entry
4624 *
4625 * This function is called when ADDBA request is successful. ADDBA response is
4626 * setup by calling addba_response_setup API and frame is then sent out OTA.
4627 *
4628 * Return: QDF_STATUS
4629 */
4630QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
4631 tSirMacAddr peer_mac, uint16_t tid, tpPESession session)
4632{
4633
4634 tDot11faddba_rsp frm;
4635 uint8_t *frame_ptr;
4636 tpSirMacMgmtHdr mgmt_hdr;
4637 uint32_t num_bytes, payload_size, status;
4638 void *pkt_ptr;
4639 QDF_STATUS qdf_status;
4640 uint8_t tx_flag = 0;
4641 uint8_t sme_sessionid = 0;
4642 uint16_t buff_size, status_code, batimeout;
4643 uint8_t peer_id, dialog_token;
4644 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4645 void *peer, *pdev;
4646
4647 sme_sessionid = session->smeSessionId;
4648
4649 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4650 if (!pdev) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004651 pe_err("pdev is NULL");
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004652 return QDF_STATUS_E_FAILURE;
4653 }
4654
4655 peer = cdp_peer_find_by_addr(soc, pdev, peer_mac, &peer_id);
4656 if (!peer) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004657 pe_err("PEER [%pM] not found", peer_mac);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004658 return QDF_STATUS_E_FAILURE;
4659 }
4660
4661 cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
4662 &status_code, &buff_size, &batimeout);
4663
4664 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4665 frm.Category.category = SIR_MAC_ACTION_BLKACK;
4666 frm.Action.action = SIR_MAC_ADDBA_RSP;
4667
4668 frm.DialogToken.token = dialog_token;
4669 frm.Status.status = status_code;
4670 frm.addba_param_set.tid = tid;
4671 frm.addba_param_set.buff_size = buff_size;
4672 frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE;
4673 frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED;
4674 frm.ba_timeout.timeout = batimeout;
4675
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004676 pe_debug("Sending a ADDBA Response from %pM to %pM",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004677 session->selfMacAddr, peer_mac);
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004678 pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004679 tid, frm.DialogToken.token, frm.Status.status,
4680 frm.addba_param_set.buff_size);
4681
4682 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
4683 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004684 pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004685 status);
4686 /* We'll fall back on the worst case scenario: */
4687 payload_size = sizeof(tDot11faddba_rsp);
4688 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004689 pe_warn("There were warnings while calculating the packed size for a ADDBA Response (0x%08x).", status);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004690 }
4691
4692 num_bytes = payload_size + sizeof(*mgmt_hdr);
4693 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
4694 (void **)&pkt_ptr);
4695 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004696 pe_err("Failed to allocate %d bytes for a ADDBA response action frame",
4697 num_bytes);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004698 return QDF_STATUS_E_FAILURE;
4699 }
4700 qdf_mem_set(frame_ptr, num_bytes, 0);
4701
4702 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
4703 SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
4704
4705 /* Update A3 with the BSSID */
4706 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
4707 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
4708
4709 /* ADDBA Response is a robust mgmt action frame,
4710 * set the "protect" (aka WEP) bit in the FC
4711 */
4712 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
4713
4714 status = dot11f_pack_addba_rsp(mac_ctx, &frm,
4715 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
4716 &payload_size);
4717
4718 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004719 pe_err("Failed to pack a ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004720 status);
4721 qdf_status = QDF_STATUS_E_FAILURE;
4722 goto error_addba_rsp;
4723 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004724 pe_warn("There were warnings while packing ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004725 status);
4726 }
4727
4728
4729 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
4730#ifdef WLAN_FEATURE_P2P
4731 || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
4732 (session->pePersona == QDF_P2P_GO_MODE)
4733#endif
4734 ) {
4735 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4736 }
4737
4738 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4739 session->peSessionId, mgmt_hdr->fc.subType));
4740 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
4741 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
Naveen Rawat296a5182017-09-25 14:02:48 -07004742 lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0,
4743 RATEID_DEFAULT);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004744 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4745 session->peSessionId, qdf_status));
4746 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004747 pe_err("wma_tx_frame FAILED! Status [%d]",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004748 qdf_status);
4749 qdf_status = QDF_STATUS_E_FAILURE;
4750 /*
4751 * wma_tx_frame free memory in certain cases, free pkt_ptr
4752 * only if not freed already.
4753 */
4754 if (pkt_ptr)
4755 cds_packet_free((void *)pkt_ptr);
4756 return qdf_status;
4757 } else {
4758 return eSIR_SUCCESS;
4759 }
4760
4761error_addba_rsp:
4762 cds_packet_free((void *)pkt_ptr);
4763 return qdf_status;
4764}