blob: f9cbf7a239df0b1cf020f6c703c2bef7e5245fa5 [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"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
63#include "wma_types.h"
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -080064#include <cdp_txrx_cmn.h>
Tushnim Bhattacharyya45ed04f2017-03-15 10:15:05 -070065#include <cdp_txrx_peer_ops.h>
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053066#include "lim_process_fils.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067
68/**
69 *
70 * \brief This function is called to add the sequence number to the
71 * management frames
72 *
73 * \param pMac Pointer to Global MAC structure
74 *
75 * \param pMacHdr Pointer to MAC management header
76 *
77 * The pMacHdr argument points to the MAC management header. The
78 * sequence number stored in the pMac structure will be incremented
79 * and updated to the MAC management header. The start sequence
80 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
81 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
82 * number will roll over.
83 *
84 */
Jeff Johnson38112a32016-10-07 07:30:50 -070085static void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080086{
87 if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
88 pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
89 }
90
91 pMac->mgmtSeqNum++;
92
93 pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
94 pMacHdr->seqControl.seqNumHi =
95 ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
96}
97
98/**
99 *
100 * \brief This function is called before sending a p2p action frame
101 * inorder to add sequence numbers to action packets
102 *
103 * \param pMac Pointer to Global MAC structure
104 *
105 * \param pBD Pointer to the frame buffer that needs to be populate
106 *
107 * The pMacHdr argument points to the MAC management header. The
108 * sequence number stored in the pMac structure will be incremented
109 * and updated to the MAC management header. The start sequence
110 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
111 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
112 * number will roll over.
113 *
114 */
115void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
116{
117 tpSirMacMgmtHdr pMacHdr;
118
119 /* / Prepare MAC management header */
120 pMacHdr = (tpSirMacMgmtHdr) (pBD);
121
122 /* Prepare sequence number */
123 lim_add_mgmt_seq_num(pMac, pMacHdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700124 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800125 pMacHdr->seqControl.seqNumLo,
126 pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
127}
128
129/**
130 * lim_populate_mac_header() - Fill in 802.11 header of frame
131 *
132 * @mac_ctx: Pointer to Global MAC structure
133 * @buf: Pointer to the frame buffer that needs to be populate
134 * @type: 802.11 Type of the frame
135 * @sub_type: 802.11 Subtype of the frame
136 * @peer_addr: dst address
137 * @self_mac_addr: local mac address
138 *
139 * This function is called by various LIM modules to prepare the
140 * 802.11 frame MAC header
141 *
142 * The buf argument points to the beginning of the frame buffer to
143 * which - a) The 802.11 MAC header is set b) Following this MAC header
144 * will be the MGMT frame payload The payload itself is populated by the
145 * caller API
146 *
147 * Return: None
148 */
149
150void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
151 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
152 tSirMacAddr self_mac_addr)
153{
154 tpSirMacMgmtHdr mac_hdr;
155
156 /* Prepare MAC management header */
157 mac_hdr = (tpSirMacMgmtHdr) (buf);
158
159 /* Prepare FC */
160 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
161 mac_hdr->fc.type = type;
162 mac_hdr->fc.subType = sub_type;
163
164 /* Prepare Address 1 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530165 qdf_mem_copy((uint8_t *) mac_hdr->da,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800166 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
167
168 /* Prepare Address 2 */
169 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
170
171 /* Prepare Address 3 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530172 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800173 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
174
175 /* Prepare sequence number */
176 lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700177 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800178 mac_hdr->seqControl.seqNumLo,
179 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
180}
181
182/**
183 * lim_send_probe_req_mgmt_frame() - send probe request management frame
184 * @mac_ctx: Pointer to Global MAC structure
185 * @ssid: SSID to be sent in Probe Request frame
186 * @bssid: BSSID to be sent in Probe Request frame
187 * @channel: Channel # on which the Probe Request is going out
188 * @self_macaddr: self MAC address
189 * @dot11mode: self dotllmode
190 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
191 * frame
192 * @additional_ie: if additional_ielen is non zero, include this field in the
193 * Probe Request frame
194 *
195 * This function is called by various LIM modules to send Probe Request frame
196 * during active scan/learn phase.
197 * Probe request is sent out in the following scenarios:
198 * --heartbeat failure: session needed
199 * --join req: session needed
200 * --foreground scan: no session
201 * --background scan: no session
202 * --sch_beacon_processing: to get EDCA parameters: session needed
203 *
204 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
205 */
206tSirRetStatus
207lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
208 tSirMacSSid *ssid,
209 tSirMacAddr bssid,
210 uint8_t channel,
211 tSirMacAddr self_macaddr,
212 uint32_t dot11mode,
213 uint32_t additional_ielen, uint8_t *additional_ie)
214{
215 tDot11fProbeRequest pr;
216 uint32_t status, bytes, payload;
217 uint8_t *frame;
218 void *packet;
Kapil Guptac03eb072016-08-09 14:01:36 +0530219 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800220 tpPESession pesession;
221 uint8_t sessionid;
222 uint8_t *p2pie = NULL;
223 uint8_t txflag = 0;
224 uint8_t sme_sessionid = 0;
225 bool is_vht_enabled = false;
226 uint8_t txPower;
227 uint16_t addn_ielen = additional_ielen;
Kapil Guptac03eb072016-08-09 14:01:36 +0530228 bool extracted_ext_cap_flag = false;
229 tDot11fIEExtCap extracted_ext_cap;
230 tSirRetStatus sir_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231
232 /* The probe req should not send 11ac capabilieties if band is 2.4GHz,
233 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
234 * is false and dot11mode is 11ac set it to 11n.
235 */
236 if (channel <= SIR_11B_CHANNEL_END &&
237 (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
238 (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
239 WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
240 dot11mode = WNI_CFG_DOT11_MODE_11N;
241 /*
242 * session context may or may not be present, when probe request needs
243 * to be sent out. Following cases exist:
244 * --heartbeat failure: session needed
245 * --join req: session needed
246 * --foreground scan: no session
247 * --background scan: no session
248 * --sch_beacon_processing: to get EDCA parameters: session needed
249 * If session context does not exist, some IEs will be populated from
250 * CFGs, e.g. Supported and Extended rate set IEs
251 */
252 pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
253
254 if (pesession != NULL)
255 sme_sessionid = pesession->smeSessionId;
256
257 /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
258 /* and then hand it off to 'dot11f_pack_probe_request' (for */
259 /* serialization). We start by zero-initializing the structure: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530260 qdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800261
262 /* & delegating to assorted helpers: */
263 populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
264
265 if (addn_ielen && additional_ie)
266 p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
267
268 /*
269 * Don't include 11b rate if it is a P2P serach or probe request is
270 * sent by P2P Client
271 */
272 if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
273 (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
274 mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
275 ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530276 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800277 )
278 ) {
279 /*
280 * In the below API pass channel number > 14, do that it fills
281 * only 11a rates in supported rates
282 */
283 populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
284 pesession);
285 } else {
286 populate_dot11f_supp_rates(mac_ctx, channel,
287 &pr.SuppRates, pesession);
288
289 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
290 populate_dot11f_ext_supp_rates1(mac_ctx, channel,
291 &pr.ExtSuppRates);
292 }
293 }
294
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800295 /*
296 * Table 7-14 in IEEE Std. 802.11k-2008 says
297 * DS params "can" be present in RRM is disabled and "is" present if
298 * RRM is enabled. It should be ok even if we add it into probe req when
299 * RRM is not enabled.
300 */
301 populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
302 /* Call RRM module to get the tx power for management used. */
303 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
304 populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
305
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800306
307 if (pesession != NULL) {
308 pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
309 /* Include HT Capability IE */
310 if (pesession->htCapability)
311 populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
312 } else { /* pesession == NULL */
313 if (IS_DOT11_MODE_HT(dot11mode))
314 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
315 }
316
317 /*
318 * Set channelbonding information as "disabled" when tunned to a
319 * 2.4 GHz channel
320 */
321 if (channel <= SIR_11B_CHANNEL_END) {
322 if (mac_ctx->roam.configParam.channelBondingMode24GHz
323 == PHY_SINGLE_CHANNEL_CENTERED) {
324 pr.HTCaps.supportedChannelWidthSet =
325 eHT_CHANNEL_WIDTH_20MHZ;
326 pr.HTCaps.shortGI40MHz = 0;
327 } else {
328 pr.HTCaps.supportedChannelWidthSet =
329 eHT_CHANNEL_WIDTH_40MHZ;
330 }
331 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800332 if (pesession != NULL) {
333 pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
334 /* Include VHT Capability IE */
335 if (pesession->vhtCapability) {
336 populate_dot11f_vht_caps(mac_ctx, pesession,
337 &pr.VHTCaps);
338 is_vht_enabled = true;
339 }
340 } else {
341 if (IS_DOT11_MODE_VHT(dot11mode)) {
342 populate_dot11f_vht_caps(mac_ctx, pesession,
343 &pr.VHTCaps);
344 is_vht_enabled = true;
345 }
346 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800347 if (pesession != NULL)
348 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
349 pesession);
350
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +0530351 if (mac_ctx->roam.configParam.qcn_ie_support)
352 populate_dot11f_qcn_ie(&pr.QCN_IE);
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +0530353
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800354 if (IS_DOT11_MODE_HE(dot11mode) && NULL != pesession)
355 lim_update_session_he_capable(mac_ctx, pesession);
356
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700357 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800358 populate_dot11f_he_caps(mac_ctx, pesession, &pr.vendor_he_cap);
359
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800360 if (addn_ielen) {
Kapil Guptac03eb072016-08-09 14:01:36 +0530361 qdf_mem_zero((uint8_t *)&extracted_ext_cap,
362 sizeof(tDot11fIEExtCap));
363 sir_status = lim_strip_extcap_update_struct(mac_ctx,
364 additional_ie,
365 &addn_ielen,
366 &extracted_ext_cap);
367 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700368 pe_debug("Unable to Stripoff ExtCap IE from Probe Req");
Kapil Guptac03eb072016-08-09 14:01:36 +0530369 } else {
370 struct s_ext_cap *p_ext_cap =
371 (struct s_ext_cap *)
372 extracted_ext_cap.bytes;
373 if (p_ext_cap->interworking_service)
374 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +0800375 extracted_ext_cap.num_bytes =
376 lim_compute_ext_cap_ie_length
377 (&extracted_ext_cap);
Kapil Guptac03eb072016-08-09 14:01:36 +0530378 extracted_ext_cap_flag =
Hu Wang411e0cc2016-10-28 14:56:01 +0800379 (extracted_ext_cap.num_bytes > 0);
Kapil Guptac03eb072016-08-09 14:01:36 +0530380 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800381 }
382
Hu Wang411e0cc2016-10-28 14:56:01 +0800383 /*
384 * Extcap IE now support variable length, merge Extcap IE from addn_ie
385 * may change the frame size. Therefore, MUST merge ExtCap IE before
386 * dot11f get packed payload size.
387 */
388 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800389 lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800390
391 /* That's it-- now we pack it. First, how much space are we going to */
392 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
393 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700394 pe_err("Failed to calculate the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800395 status);
396 /* We'll fall back on the worst case scenario: */
397 payload = sizeof(tDot11fProbeRequest);
398 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700399 pe_warn("There were warnings while calculating the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800400 status);
401 }
402
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
404
405 /* Ok-- try to allocate some memory: */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530406 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800407 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530408 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700409 pe_err("Failed to allocate %d bytes for a Probe Request", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410 return eSIR_MEM_ALLOC_FAILED;
411 }
412 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530413 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414
415 /* Next, we fill out the buffer descriptor: */
416 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
417 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
418
419 /* That done, pack the Probe Request: */
420 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
421 sizeof(tSirMacMgmtHdr),
422 payload, &payload);
423 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700424 pe_err("Failed to pack a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800425 cds_packet_free((void *)packet);
426 return eSIR_FAILURE; /* allocated! */
427 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700428 pe_warn("There were warnings while packing a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 }
430 /* Append any AddIE if present. */
431 if (addn_ielen) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530432 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800433 additional_ie, addn_ielen);
434 payload += addn_ielen;
435 }
436
437 /* If this probe request is sent during P2P Search State, then we need
438 * to send it at OFDM rate.
439 */
440 if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
441 || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
442 mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
443 /*
444 * For unicast probe req mgmt from Join function we don't set
445 * above variables. So we need to add one more check whether it
446 * is pePersona is P2P_CLIENT or not
447 */
448 || ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530449 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800450 ) {
451 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
452 }
453
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530454 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 wma_tx_frame(mac_ctx, packet,
456 (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
457 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
458 lim_tx_complete, frame, txflag, sme_sessionid,
459 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530460 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700461 pe_err("could not send Probe Request frame!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 /* Pkt will be freed up by the callback */
463 return eSIR_FAILURE;
464 }
465
466 return eSIR_SUCCESS;
467} /* End lim_send_probe_req_mgmt_frame. */
468
Jeff Johnson38112a32016-10-07 07:30:50 -0700469static tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470 uint8_t *addIE, uint16_t *addnIELen,
471 uint8_t probeReqP2pIe)
472{
473 /* If Probe request doesn't have P2P IE, then take out P2P IE
474 from additional IE */
475 if (!probeReqP2pIe) {
476 uint8_t *tempbuf = NULL;
477 uint16_t tempLen = 0;
478 int left = *addnIELen;
479 uint8_t *ptr = addIE;
480 uint8_t elem_id, elem_len;
481
482 if (NULL == addIE) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700483 pe_err("NULL addIE pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 return eSIR_FAILURE;
485 }
486
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530487 tempbuf = qdf_mem_malloc(left);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800488 if (NULL == tempbuf) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700489 pe_err("Unable to allocate memory to store addn IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 return eSIR_MEM_ALLOC_FAILED;
491 }
492
493 while (left >= 2) {
494 elem_id = ptr[0];
495 elem_len = ptr[1];
496 left -= 2;
497 if (elem_len > left) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700498 pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800499 elem_id, elem_len, left);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530500 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800501 return eSIR_FAILURE;
502 }
503 if (!((SIR_MAC_EID_VENDOR == elem_id) &&
504 (memcmp
505 (&ptr[2], SIR_MAC_P2P_OUI,
506 SIR_MAC_P2P_OUI_SIZE) == 0))) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530507 qdf_mem_copy(tempbuf + tempLen, &ptr[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508 elem_len + 2);
509 tempLen += (elem_len + 2);
510 }
511 left -= elem_len;
512 ptr += (elem_len + 2);
513 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530514 qdf_mem_copy(addIE, tempbuf, tempLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800515 *addnIELen = tempLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530516 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517 }
518 return eSIR_SUCCESS;
519}
520
521/**
522 * lim_send_probe_rsp_mgmt_frame() - Send probe response
523 *
524 * @mac_ctx: Handle for mac context
525 * @peer_macaddr: Mac address of requesting peer
526 * @ssid: SSID for response
527 * @n_staid: Station ID, currently unused.
528 * @pe_session: PE session id
529 * @keepalive: Keep alive flag. Currently unused.
530 * @preq_p2pie: P2P IE in incoming probe request
531 *
532 * Builds and sends probe response frame to the requesting peer
533 *
534 * Return: void
535 */
536
537void
538lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
539 tSirMacAddr peer_macaddr,
540 tpAniSSID ssid,
541 short n_staid,
542 uint8_t keepalive,
543 tpPESession pe_session, uint8_t preq_p2pie)
544{
545 tDot11fProbeResponse *frm;
546 tSirRetStatus sir_status;
Hu Wang411e0cc2016-10-28 14:56:01 +0800547 uint32_t cfg, payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800548 tpSirMacMgmtHdr mac_hdr;
549 uint8_t *frame;
Arif Hussainfbf50682016-06-15 12:57:43 -0700550 void *packet = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530551 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800552 uint32_t addn_ie_present = false;
553
554 uint16_t addn_ie_len = 0;
555 uint32_t wps_ap = 0, tmp;
556 uint8_t tx_flag = 0;
557 uint8_t *add_ie = NULL;
558 uint8_t *p2p_ie = NULL;
559 uint8_t noalen = 0;
560 uint8_t total_noalen = 0;
561 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
562 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
563 uint8_t sme_sessionid = 0;
564 bool is_vht_enabled = false;
Padma, Santhosh Kumar92234472017-04-19 18:20:02 +0530565 tDot11fIEExtCap extracted_ext_cap = {0};
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530566 bool extracted_ext_cap_flag = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567
568 /* We don't answer requests in this case*/
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700569 if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 return;
571
572 if (NULL == pe_session)
573 return;
574
575 /*
576 * In case when cac timer is running for this SAP session then
577 * avoid sending probe rsp out. It is violation of dfs specification.
578 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530579 if (((pe_session->pePersona == QDF_SAP_MODE) ||
580 (pe_session->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800581 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530582 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800583 FL("CAC timer is running, probe response dropped"));
584 return;
585 }
586 sme_sessionid = pe_session->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530587 frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800588 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700589 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 return;
591 }
592
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800593 /*
594 * Fill out 'frm', after which we'll just hand the struct off to
595 * 'dot11f_pack_probe_response'.
596 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530597 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598
599 /*
600 * Timestamp to be updated by TFP, below.
601 *
602 * Beacon Interval:
603 */
604 if (LIM_IS_AP_ROLE(pe_session)) {
605 frm->BeaconInterval.interval =
606 mac_ctx->sch.schObject.gSchBeaconInterval;
607 } else {
608 sir_status = wlan_cfg_get_int(mac_ctx,
609 WNI_CFG_BEACON_INTERVAL, &cfg);
610 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700611 pe_err("Failed to get WNI_CFG_BEACON_INTERVAL (%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800612 sir_status);
613 goto err_ret;
614 }
615 frm->BeaconInterval.interval = (uint16_t) cfg;
616 }
617
618 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
619 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
620 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
621 &frm->SuppRates, pe_session);
622
623 populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
624 pe_session->currentOperChannel);
625 populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
626
627 if (LIM_IS_AP_ROLE(pe_session)) {
628 if (pe_session->wps_state != SAP_WPS_DISABLED)
629 populate_dot11f_probe_res_wpsi_es(mac_ctx,
630 &frm->WscProbeRes,
631 pe_session);
632 } else {
633 if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
634 &tmp) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700635 pe_err("Failed to cfg get id %d", WNI_CFG_WPS_ENABLE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636
637 wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
638
639 if (wps_ap)
640 populate_dot11f_wsc_in_probe_res(mac_ctx,
641 &frm->WscProbeRes);
642
643 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
644 eLIM_WSC_ENROLL_BEGIN) {
645 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
646 &frm->WscProbeRes);
647 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
648 eLIM_WSC_ENROLL_IN_PROGRESS;
649 }
650
651 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
652 eLIM_WSC_ENROLL_END) {
653 de_populate_dot11f_wsc_registrar_info_in_probe_res(
654 mac_ctx, &frm->WscProbeRes);
655 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
656 eLIM_WSC_ENROLL_NOOP;
657 }
658 }
659
660 populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
661 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
662
663 if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
664 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
665
666 populate_dot11f_ext_supp_rates(mac_ctx,
667 POPULATE_DOT11F_RATES_OPERATIONAL,
668 &frm->ExtSuppRates, pe_session);
669
670 /* Populate HT IEs, when operating in 11n */
671 if (pe_session->htCapability) {
672 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
673 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
674 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800675 if (pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700676 pe_debug("Populate VHT IE in Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800677 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
678 populate_dot11f_vht_operation(mac_ctx, pe_session,
679 &frm->VHTOperation);
680 /*
681 * we do not support multi users yet.
682 * populate_dot11f_vht_ext_bss_load( mac_ctx,
683 * &frm.VHTExtBssLoad );
684 */
685 is_vht_enabled = true;
686 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800687
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800688 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700689 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800690 populate_dot11f_he_caps(mac_ctx, pe_session,
691 &frm->vendor_he_cap);
692 populate_dot11f_he_operation(mac_ctx, pe_session,
693 &frm->vendor_he_op);
694 }
695
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
697 pe_session);
698
699 if (pe_session->pLimStartBssReq) {
700 populate_dot11f_wpa(mac_ctx,
701 &(pe_session->pLimStartBssReq->rsnIE),
702 &frm->WPA);
703 populate_dot11f_rsn_opaque(mac_ctx,
704 &(pe_session->pLimStartBssReq->rsnIE),
705 &frm->RSNOpaque);
706 }
707
708 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
709 &frm->WMMCaps, pe_session);
710
711#if defined(FEATURE_WLAN_WAPI)
712 if (pe_session->pLimStartBssReq)
713 populate_dot11f_wapi(mac_ctx,
714 &(pe_session->pLimStartBssReq->rsnIE),
715 &frm->WAPI);
716#endif /* defined(FEATURE_WLAN_WAPI) */
717
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800718 if (mac_ctx->lim.gpLimRemainOnChanReq)
719 bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
720 sizeof(tSirRemainOnChnReq));
721 else
722 /*
723 * Only use CFG for non-listen mode. This CFG is not working for
724 * concurrency. In listening mode, probe rsp IEs is passed in
725 * the message from SME to PE.
726 */
727 addn_ie_present =
728 (pe_session->addIeParams.probeRespDataLen != 0);
729
730 if (addn_ie_present) {
731
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530732 add_ie = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800733 pe_session->addIeParams.probeRespDataLen);
734 if (NULL == add_ie) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700735 pe_err("add_ie allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800736 goto err_ret;
737 }
738
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530739 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800740 pe_session->addIeParams.probeRespData_buff,
741 pe_session->addIeParams.probeRespDataLen);
742 addn_ie_len = pe_session->addIeParams.probeRespDataLen;
743
744 if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
745 add_ie, &addn_ie_len, preq_p2pie)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700746 pe_err("Unable to get addn_ie");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 goto err_ret;
748 }
749
750 sir_status = lim_strip_extcap_update_struct(mac_ctx,
751 add_ie, &addn_ie_len,
752 &extracted_ext_cap);
753 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700754 pe_debug("Unable to strip off ExtCap IE");
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530755 } else {
756 extracted_ext_cap_flag = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757 }
758
759 bytes = bytes + addn_ie_len;
760
761 if (preq_p2pie)
762 p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
763 addn_ie_len);
764
765 if (p2p_ie != NULL) {
766 /* get NoA attribute stream P2P IE */
767 noalen = lim_get_noa_attr_stream(mac_ctx,
768 noa_stream, pe_session);
769 if (noalen != 0) {
770 total_noalen =
771 lim_build_p2p_ie(mac_ctx, &noa_ie[0],
772 &noa_stream[0], noalen);
773 bytes = bytes + total_noalen;
774 }
775 }
776 }
777
Hu Wang411e0cc2016-10-28 14:56:01 +0800778 /*
779 * Extcap IE now support variable length, merge Extcap IE from addn_ie
780 * may change the frame size. Therefore, MUST merge ExtCap IE before
781 * dot11f get packed payload size.
782 */
783 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800784 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
785 true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800786
787 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
788 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700789 pe_err("Probe Response size error (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800790 status);
791 /* We'll fall back on the worst case scenario: */
792 payload = sizeof(tDot11fProbeResponse);
793 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700794 pe_warn("Probe Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800795 status);
796 }
797
798 bytes += payload + sizeof(tSirMacMgmtHdr);
799
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530800 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530802 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700803 pe_err("Probe Response allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804 goto err_ret;
805 }
806 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530807 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808
809 /* Next, we fill out the buffer descriptor: */
810 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
811 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
812 pe_session->selfMacAddr);
813
814 mac_hdr = (tpSirMacMgmtHdr) frame;
815
816 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
817
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800818 /* That done, pack the Probe Response: */
819 status =
820 dot11f_pack_probe_response(mac_ctx, frm,
821 frame + sizeof(tSirMacMgmtHdr),
822 payload, &payload);
823 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700824 pe_err("Probe Response pack failure (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800825 status);
826 goto err_ret;
827 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700828 pe_warn("Probe Response pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800829 }
830
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700831 pe_debug("Sending Probe Response frame to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +0530832 lim_print_mac_addr(mac_ctx, peer_macaddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800833
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834 if (mac_ctx->lim.gpLimRemainOnChanReq)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530835 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800836 mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
837 (mac_ctx->lim.gpLimRemainOnChanReq->length -
838 sizeof(tSirRemainOnChnReq)));
839
840 if (addn_ie_present)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530841 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800842 &add_ie[0], addn_ie_len);
843
844 if (noalen != 0) {
845 if (total_noalen >
846 (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700847 pe_err("Not able to insert NoA, total len=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800848 total_noalen);
849 goto err_ret;
850 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530851 qdf_mem_copy(&frame[bytes - (total_noalen)],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 &noa_ie[0], total_noalen);
853 }
854 }
855
856 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +0530857 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
858 (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859 )
860 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
861
862 /* Queue Probe Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530863 qdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864 (uint16_t) bytes,
865 TXRX_FRM_802_11_MGMT,
866 ANI_TXDIR_TODS,
867 7, lim_tx_complete, frame, tx_flag,
868 sme_sessionid, 0);
869
870 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530871 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700872 pe_err("Could not send Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873
874 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530875 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800876
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530877 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878 return;
879
880err_ret:
881 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530882 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 if (frm != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530884 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885 if (packet != NULL)
886 cds_packet_free((void *)packet);
887 return;
888
889} /* End lim_send_probe_rsp_mgmt_frame. */
890
891void
892lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
893 tSirMacAddr peerMacAddr,
894 tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
895{
896 uint16_t i;
897 uint8_t *pFrame;
898 tDot11fAddTSRequest AddTSReq;
899 tDot11fWMMAddTSRequest WMMAddTSReq;
900 uint32_t nPayload, nBytes, nStatus;
901 tpSirMacMgmtHdr pMacHdr;
902 void *pPacket;
903#ifdef FEATURE_WLAN_ESE
904 uint32_t phyMode;
905#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530906 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800907 uint8_t txFlag = 0;
908 uint8_t smeSessionId = 0;
909
910 if (NULL == psessionEntry) {
911 return;
912 }
913
914 smeSessionId = psessionEntry->smeSessionId;
915
916 if (!pAddTS->wmeTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530917 qdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800918
919 AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
920 AddTSReq.DialogToken.token = pAddTS->dialogToken;
921 AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
922 if (pAddTS->lleTspecPresent) {
923 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
924 } else {
925 populate_dot11f_wmmtspec(&pAddTS->tspec,
926 &AddTSReq.WMMTSPEC);
927 }
928
929 if (pAddTS->lleTspecPresent) {
930 AddTSReq.num_WMMTCLAS = 0;
931 AddTSReq.num_TCLAS = pAddTS->numTclas;
932 for (i = 0; i < pAddTS->numTclas; ++i) {
933 populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
934 &AddTSReq.TCLAS[i]);
935 }
936 } else {
937 AddTSReq.num_TCLAS = 0;
938 AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
939 for (i = 0; i < pAddTS->numTclas; ++i) {
940 populate_dot11f_wmmtclas(pMac,
941 &pAddTS->tclasInfo[i],
942 &AddTSReq.WMMTCLAS[i]);
943 }
944 }
945
946 if (pAddTS->tclasProcPresent) {
947 if (pAddTS->lleTspecPresent) {
948 AddTSReq.TCLASSPROC.processing =
949 pAddTS->tclasProc;
950 AddTSReq.TCLASSPROC.present = 1;
951 } else {
952 AddTSReq.WMMTCLASPROC.version = 1;
953 AddTSReq.WMMTCLASPROC.processing =
954 pAddTS->tclasProc;
955 AddTSReq.WMMTCLASPROC.present = 1;
956 }
957 }
958
959 nStatus =
960 dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
961 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700962 pe_err("Failed to calculate the packed size for an Add TS Request (0x%08x)",
963 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800964 /* We'll fall back on the worst case scenario: */
965 nPayload = sizeof(tDot11fAddTSRequest);
966 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700967 pe_warn("There were warnings while calculating the packed size for an Add TS Request (0x%08x)",
968 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969 }
970 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530971 qdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800972
973 WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
974 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
975 WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
976
977 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
978 WMMAddTSReq.StatusCode.statusCode = 0;
979
980 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
981#ifdef FEATURE_WLAN_ESE
982 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
983
984 if (phyMode == WNI_CFG_PHY_MODE_11G
985 || phyMode == WNI_CFG_PHY_MODE_11A) {
986 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
987 } else {
988 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
989 }
990 populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
991 &WMMAddTSReq.ESETrafStrmRateSet,
992 sizeof(uint8_t));
993#endif
994 /* fillWmeTspecIE */
995
996 nStatus =
997 dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
998 &nPayload);
999 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001000 pe_err("Failed to calculate the packed size for a WMM Add TS Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001001 nStatus);
1002 /* We'll fall back on the worst case scenario: */
1003 nPayload = sizeof(tDot11fAddTSRequest);
1004 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001005 pe_warn("There were warnings while calculating the packed size for a WMM Add TS Request (0x%08x)",
1006 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 }
1008 }
1009
1010 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1011
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301012 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301014 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001015 pe_err("Failed to allocate %d bytes for an Add TS Request",
1016 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001017 return;
1018 }
1019 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301020 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021
1022 /* Next, we fill out the buffer descriptor: */
1023 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1024 SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
1025 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1026
1027 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1028
1029#ifdef WLAN_FEATURE_11W
1030 lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
1031#endif
1032
1033 /* That done, pack the struct: */
1034 if (!pAddTS->wmeTspecPresent) {
1035 nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
1036 pFrame +
1037 sizeof(tSirMacMgmtHdr),
1038 nPayload, &nPayload);
1039 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001040 pe_err("Failed to pack an Add TS Request "
1041 "(0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042 cds_packet_free((void *)pPacket);
1043 return; /* allocated! */
1044 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001045 pe_warn("There were warnings while packing an Add TS Request (0x%08x)",
1046 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001047 }
1048 } else {
1049 nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
1050 pFrame +
1051 sizeof(tSirMacMgmtHdr),
1052 nPayload, &nPayload);
1053 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001054 pe_err("Failed to pack a WMM Add TS Request (0x%08x)",
1055 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001056 cds_packet_free((void *)pPacket);
1057 return; /* allocated! */
1058 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001059 pe_warn("There were warnings while packing a WMM Add TS Request (0x%08x)",
1060 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001061 }
1062 }
1063
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001064 pe_debug("Sending an Add TS Request frame to");
1065 lim_print_mac_addr(pMac, peerMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001066
1067 if ((SIR_BAND_5_GHZ ==
1068 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301069 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1070 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001071 ) {
1072 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1073 }
1074
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301075 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001076 psessionEntry->peSessionId, pMacHdr->fc.subType));
1077
1078 /* Queue Addts Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301079 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001080 TXRX_FRM_802_11_MGMT,
1081 ANI_TXDIR_TODS,
1082 7, lim_tx_complete, pFrame, txFlag,
1083 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301084 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301085 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001086
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001087 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1088 pe_err("Could not send an Add TS Request (%X",
1089 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001090} /* End lim_send_addts_req_action_frame. */
1091
1092/**
1093 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
1094 * @mac_ctx: Handle for mac context
1095 * @status_code: Status code for assoc response frame
1096 * @aid: Association ID
1097 * @peer_addr: Mac address of requesting peer
1098 * @subtype: Assoc/Reassoc
1099 * @sta: Pointer to station node
1100 * @pe_session: PE session id.
1101 *
1102 * Builds and sends association response frame to the requesting peer.
1103 *
1104 * Return: void
1105 */
1106
1107void
1108lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
1109 uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
1110 uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
1111{
1112 static tDot11fAssocResponse frm;
1113 uint8_t *frame;
1114 tpSirMacMgmtHdr mac_hdr;
1115 tSirRetStatus sir_status;
1116 uint8_t lle_mode = 0, addts;
1117 tHalBitVal qos_mode, wme_mode;
Hu Wang411e0cc2016-10-28 14:56:01 +08001118 uint32_t payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001119 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301120 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 tUpdateBeaconParams beacon_params;
1122 uint8_t tx_flag = 0;
1123 uint32_t addn_ie_len = 0;
1124 uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
1125 tpSirAssocReq assoc_req = NULL;
1126 uint8_t sme_session = 0;
1127 bool is_vht = false;
1128 uint16_t stripoff_len = 0;
1129 tDot11fIEExtCap extracted_ext_cap;
1130 bool extracted_flag = false;
1131#ifdef WLAN_FEATURE_11W
1132 uint32_t retry_int;
1133 uint32_t max_retries;
1134#endif
1135
1136 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001137 pe_err("pe_session is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001138 return;
1139 }
1140
1141 sme_session = pe_session->smeSessionId;
1142
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301143 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001144
1145 limGetQosMode(pe_session, &qos_mode);
1146 limGetWmeMode(pe_session, &wme_mode);
1147
1148 /*
1149 * An Add TS IE is added only if the AP supports it and
1150 * the requesting STA sent a traffic spec.
1151 */
1152 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
1153
1154 frm.Status.status = status_code;
1155
1156 frm.AID.associd = aid | LIM_AID_MASK;
1157
1158 if (NULL == sta) {
1159 populate_dot11f_supp_rates(mac_ctx,
1160 POPULATE_DOT11F_RATES_OPERATIONAL,
1161 &frm.SuppRates, pe_session);
1162 populate_dot11f_ext_supp_rates(mac_ctx,
1163 POPULATE_DOT11F_RATES_OPERATIONAL,
1164 &frm.ExtSuppRates, pe_session);
1165 } else {
1166 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
1167 &frm.ExtSuppRates,
1168 sta->supportedRates.llbRates,
1169 sta->supportedRates.llaRates);
1170 }
1171
1172 if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
1173 eSIR_SUCCESS == status_code) {
1174 assoc_req = (tpSirAssocReq)
1175 pe_session->parsedAssocReq[sta->assocId];
1176 /*
1177 * populate P2P IE in AssocRsp when assocReq from the peer
1178 * includes P2P IE
1179 */
1180 if (assoc_req != NULL && assoc_req->addIEPresent)
1181 populate_dot11_assoc_res_p2p_ie(mac_ctx,
1182 &frm.P2PAssocRes,
1183 assoc_req);
1184 }
1185
1186 if (NULL != sta) {
1187 if (eHAL_SET == qos_mode) {
1188 if (sta->lleEnabled) {
1189 lle_mode = 1;
1190 populate_dot11f_edca_param_set(mac_ctx,
1191 &frm.EDCAParamSet, pe_session);
1192 }
1193 }
1194
1195 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
1196 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
1197 pe_session);
1198
1199 if (sta->wsmEnabled)
1200 populate_dot11f_wmm_caps(&frm.WMMCaps);
1201 }
1202
1203 if (sta->mlmStaContext.htCapability &&
1204 pe_session->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001205 pe_debug("Populate HT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001206 populate_dot11f_ht_caps(mac_ctx, pe_session,
1207 &frm.HTCaps);
Krunal Sonief3294b2015-06-12 15:12:19 -07001208 /*
1209 * Check the STA capability and
1210 * update the HTCaps accordingly
1211 */
1212 frm.HTCaps.supportedChannelWidthSet = (
1213 sta->htSupportedChannelWidthSet <
1214 pe_session->htSupportedChannelWidthSet) ?
1215 sta->htSupportedChannelWidthSet :
1216 pe_session->htSupportedChannelWidthSet;
1217 if (!frm.HTCaps.supportedChannelWidthSet)
1218 frm.HTCaps.shortGI40MHz = 0;
1219
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001220 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1221 pe_session);
1222 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001223 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 +05301224 frm.HTCaps.supportedChannelWidthSet,
1225 frm.HTCaps.mimoPowerSave,
1226 frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
1227 frm.HTCaps.shortGI40MHz,
1228 frm.HTCaps.dsssCckMode40MHz,
1229 frm.HTCaps.maxRxAMPDUFactor);
1230
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001231 if (sta->mlmStaContext.vhtCapability &&
1232 pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001233 pe_debug("Populate VHT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234 populate_dot11f_vht_caps(mac_ctx, pe_session,
1235 &frm.VHTCaps);
1236 populate_dot11f_vht_operation(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301237 &frm.VHTOperation);
1238 is_vht = true;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301239 } else {
Tushnim Bhattacharyya3d17def2017-06-19 11:13:43 -07001240 /*
1241 * 2G-AS platform: SAP associates with HT (11n)clients
1242 * as 2x1 in 2G and 2X2 in 5G
1243 * Non-2G-AS platform: SAP associates with HT (11n)
1244 * clients as 2X2 in 2G and 5G
1245 * 5G-AS: DonÂ’t care
1246 */
1247 if (!policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc) &&
1248 frm.HTCaps.present && mac_ctx->hw_dbs_capable &&
1249 mac_ctx->lteCoexAntShare &&
1250 IS_24G_CH(pe_session->currentOperChannel))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301251 frm.HTCaps.supportedMCSSet[1] = 0;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301252 }
1253 if (pe_session->vhtCapability &&
1254 pe_session->vendor_vht_sap &&
1255 (assoc_req != NULL) &&
1256 assoc_req->vendor_vht_ie.VHTCaps.present) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001257 pe_debug("Populate Vendor VHT IEs in Assoc Rsponse");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301258 frm.vendor_vht_ie.present = 1;
1259 frm.vendor_vht_ie.type =
1260 pe_session->vendor_specific_vht_ie_type;
1261 frm.vendor_vht_ie.sub_type =
1262 pe_session->vendor_specific_vht_ie_sub_type;
1263
1264 frm.vendor_vht_ie.VHTCaps.present = 1;
1265 populate_dot11f_vht_caps(mac_ctx, pe_session,
1266 &frm.vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267 is_vht = true;
1268 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1270 pe_session);
1271
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001272 if (lim_is_sta_he_capable(sta) &&
1273 lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001274 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001275 populate_dot11f_he_caps(mac_ctx, pe_session,
1276 &frm.vendor_he_cap);
1277 populate_dot11f_he_operation(mac_ctx, pe_session,
1278 &frm.vendor_he_op);
1279 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280#ifdef WLAN_FEATURE_11W
1281 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1282 if (wlan_cfg_get_int
1283 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1284 &max_retries) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001285 pe_err("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001286 else if (wlan_cfg_get_int
1287 (mac_ctx,
1288 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1289 &retry_int) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001290 pe_err("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001291 else
1292 populate_dot11f_timeout_interval(mac_ctx,
1293 &frm.TimeoutInterval,
1294 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1295 (max_retries -
1296 sta->pmfSaQueryRetryCount)
1297 * retry_int);
1298 }
1299#endif
Arif Hussain0c816922017-04-06 15:04:44 -07001300
1301 if (LIM_IS_AP_ROLE(pe_session) && sta->non_ecsa_capable)
1302 pe_session->lim_non_ecsa_cap_num++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001303 }
1304
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301305 qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001306
1307 if (LIM_IS_AP_ROLE(pe_session) &&
1308 (pe_session->gLimProtectionControl !=
1309 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1310 lim_decide_ap_protection(mac_ctx, peer_addr,
1311 &beacon_params, pe_session);
1312
1313 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1314 pe_session);
1315 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1316 pe_session);
1317
1318 /*
1319 * Populate Do11capabilities after updating session with
1320 * Assos req details
1321 */
1322 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1323
1324 beacon_params.bssIdx = pe_session->bssIdx;
1325
1326 /* Send message to HAL about beacon parameter change. */
1327 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1328 && beacon_params.paramChangeBitmap) {
1329 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1330 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1331 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001332
1333 if (assoc_req != NULL) {
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001334 addn_ie_len = pe_session->addIeParams.assocRespDataLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335
1336 /* Nonzero length indicates Assoc rsp IE available */
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001337 if (addn_ie_len > 0 &&
1338 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
1339 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301340 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001341 pe_session->addIeParams.assocRespData_buff,
1342 pe_session->addIeParams.assocRespDataLen);
1343
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301344 qdf_mem_set((uint8_t *) &extracted_ext_cap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001345 sizeof(extracted_ext_cap), 0);
1346
1347 stripoff_len = addn_ie_len;
1348 sir_status =
1349 lim_strip_extcap_update_struct
1350 (mac_ctx, &add_ie[0], &stripoff_len,
1351 &extracted_ext_cap);
1352 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001353 pe_debug("strip off extcap IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354 } else {
1355 addn_ie_len = stripoff_len;
1356 extracted_flag = true;
1357 }
1358 bytes = bytes + addn_ie_len;
1359 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001360 pe_debug("addn_ie_len: %d for Assoc Resp: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001361 addn_ie_len, assoc_req->addIEPresent);
1362 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001363
1364 /*
1365 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1366 * may change the frame size. Therefore, MUST merge ExtCap IE before
1367 * dot11f get packed payload size.
1368 */
1369 if (extracted_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001370 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
1371 true);
Hu Wang411e0cc2016-10-28 14:56:01 +08001372
1373 /* Allocate a buffer for this frame: */
1374 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1375 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001376 pe_err("get Association Response size failure (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001377 status);
1378 return;
1379 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001380 pe_warn("get Association Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001381 status);
1382 }
1383
1384 bytes += sizeof(tSirMacMgmtHdr) + payload;
1385
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301386 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301388 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001389 pe_err("cds_packet_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390 return;
1391 }
1392 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301393 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001394
1395 /* Next, we fill out the buffer descriptor: */
1396 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1397 (LIM_ASSOC == subtype) ?
1398 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1399 peer_addr,
1400 pe_session->selfMacAddr);
1401 mac_hdr = (tpSirMacMgmtHdr) frame;
1402
1403 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1404
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001405 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1406 frame + sizeof(tSirMacMgmtHdr),
1407 payload, &payload);
1408 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001409 pe_err("Association Response pack failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001410 status);
1411 cds_packet_free((void *)packet);
1412 return;
1413 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001414 pe_warn("Association Response pack warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415 status);
1416 }
1417
1418 if (subtype == LIM_ASSOC)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001419 pe_debug("*** Sending Assoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001420 status_code, aid);
1421 else
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001422 pe_debug("*** Sending ReAssoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001423 status_code, aid);
1424
1425 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1426
1427 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301428 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001429 &add_ie[0], addn_ie_len);
1430
1431 if ((SIR_BAND_5_GHZ ==
1432 lim_get_rf_band(pe_session->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05301433 (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
1434 (pe_session->pePersona == QDF_P2P_GO_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001435 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1436
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301437 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001438 pe_session->peSessionId, mac_hdr->fc.subType));
1439 /* Queue Association Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301440 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441 TXRX_FRM_802_11_MGMT,
1442 ANI_TXDIR_TODS,
1443 7, lim_tx_complete, frame, tx_flag,
1444 sme_session, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301445 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301446 pe_session->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447
1448 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301449 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001450 pe_err("Could not Send Re/AssocRsp, retCode=%X",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301451 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452
1453 /*
1454 * update the ANI peer station count.
1455 * FIXME_PROTECTION : take care of different type of station
1456 * counter inside this function.
1457 */
1458 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1459
1460}
1461
1462void
1463lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1464 tSirMacAddr peer,
1465 uint8_t wmmTspecPresent,
1466 tSirMacTSInfo *pTsinfo,
1467 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1468{
1469 uint8_t *pFrame;
1470 tpSirMacMgmtHdr pMacHdr;
1471 tDot11fDelTS DelTS;
1472 tDot11fWMMDelTS WMMDelTS;
1473 uint32_t nBytes, nPayload, nStatus;
1474 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301475 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 uint8_t txFlag = 0;
1477 uint8_t smeSessionId = 0;
1478
1479 if (NULL == psessionEntry) {
1480 return;
1481 }
1482
1483 smeSessionId = psessionEntry->smeSessionId;
1484
1485 if (!wmmTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301486 qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487
1488 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1489 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1490 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1491
1492 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1493 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001494 pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001495 /* We'll fall back on the worst case scenario: */
1496 nPayload = sizeof(tDot11fDelTS);
1497 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001498 pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)",
1499 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500 }
1501 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301502 qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001503
1504 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1505 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1506 WMMDelTS.DialogToken.token = 0;
1507 WMMDelTS.StatusCode.statusCode = 0;
1508 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1509 nStatus =
1510 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1511 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001512 pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001513 /* We'll fall back on the worst case scenario: */
1514 nPayload = sizeof(tDot11fDelTS);
1515 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001516 pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)",
1517 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518 }
1519 }
1520
1521 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1522
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301523 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1525 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301526 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001527 pe_err("Failed to allocate %d bytes for an Add TS Response",
1528 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529 return;
1530 }
1531 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301532 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533
1534 /* Next, we fill out the buffer descriptor: */
1535 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1536 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1537 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1538
1539 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1540
1541#ifdef WLAN_FEATURE_11W
1542 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1543#endif
1544
1545 /* That done, pack the struct: */
1546 if (!wmmTspecPresent) {
1547 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1548 pFrame + sizeof(tSirMacMgmtHdr),
1549 nPayload, &nPayload);
1550 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001551 pe_err("Failed to pack a Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001552 nStatus);
1553 cds_packet_free((void *)pPacket);
1554 return; /* allocated! */
1555 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001556 pe_warn("There were warnings while packing a Del TS frame (0x%08x)",
1557 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001558 }
1559 } else {
1560 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1561 pFrame + sizeof(tSirMacMgmtHdr),
1562 nPayload, &nPayload);
1563 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001564 pe_err("Failed to pack a WMM Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565 nStatus);
1566 cds_packet_free((void *)pPacket);
1567 return; /* allocated! */
1568 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001569 pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)",
1570 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001571 }
1572 }
1573
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001574 pe_debug("Sending DELTS REQ (size %d) to ", nBytes);
1575 lim_print_mac_addr(pMac, pMacHdr->da, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576
1577 if ((SIR_BAND_5_GHZ ==
1578 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301579 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1580 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001581 ) {
1582 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1583 }
1584
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301585 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001586 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301587 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001588 TXRX_FRM_802_11_MGMT,
1589 ANI_TXDIR_TODS,
1590 7, lim_tx_complete, pFrame, txFlag,
1591 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301592 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301593 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001594 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301595 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001596 pe_err("Failed to send Del TS (%X)!", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597
1598} /* End lim_send_delts_req_action_frame. */
1599
1600/**
1601 * lim_send_assoc_req_mgmt_frame() - Send association request
1602 * @mac_ctx: Handle to MAC context
1603 * @mlm_assoc_req: Association request information
1604 * @pe_session: PE session information
1605 *
1606 * Builds and transmits association request frame to AP.
1607 *
1608 * Return: Void
1609 */
1610
1611void
1612lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1613 tLimMlmAssocReq *mlm_assoc_req,
1614 tpPESession pe_session)
1615{
1616 tDot11fAssocRequest *frm;
1617 uint16_t caps;
1618 uint8_t *frame;
1619 tSirRetStatus sir_status;
1620 tLimMlmAssocCnf assoc_cnf;
Hu Wang411e0cc2016-10-28 14:56:01 +08001621 uint32_t bytes = 0, payload, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001622 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1623 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301624 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001625 uint16_t add_ie_len;
1626 uint8_t *add_ie;
1627 uint8_t *wps_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628 uint8_t power_caps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 uint8_t tx_flag = 0;
1630 uint8_t sme_sessionid = 0;
1631 bool vht_enabled = false;
1632 tDot11fIEExtCap extr_ext_cap;
1633 bool extr_ext_flag = true;
1634 tpSirMacMgmtHdr mac_hdr;
Hu Wangfbd279d2016-10-31 18:24:34 +08001635 uint32_t ie_offset = 0;
1636 uint8_t *p_ext_cap = NULL;
1637 tDot11fIEExtCap bcn_ext_cap;
1638 uint8_t *bcn_ie = NULL;
1639 uint32_t bcn_ie_len = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640
1641 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001642 pe_err("pe_session is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301643 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001644 return;
1645 }
1646
1647 sme_sessionid = pe_session->smeSessionId;
1648
1649 /* check this early to avoid unncessary operation */
1650 if (NULL == pe_session->pLimJoinReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001651 pe_err("pe_session->pLimJoinReq is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301652 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001653 return;
1654 }
1655 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1656 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1657
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301658 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001660 pe_err("Unable to allocate memory");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301661 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 return;
1663 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001664 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301666 if (add_ie_len && pe_session->is_ext_caps_present) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301667 qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 0);
1669 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1670 add_ie, &add_ie_len, &extr_ext_cap);
1671 if (eSIR_SUCCESS != sir_status) {
1672 extr_ext_flag = false;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001673 pe_debug("Unable to Stripoff ExtCap IE from Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674 } else {
1675 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1676 extr_ext_cap.bytes;
1677
1678 if (p_ext_cap->interworking_service)
1679 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +08001680 extr_ext_cap.num_bytes =
1681 lim_compute_ext_cap_ie_length(&extr_ext_cap);
1682 extr_ext_flag = (extr_ext_cap.num_bytes > 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001683 }
1684 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001685 pe_debug("No addn IE or peer dosen't support addnIE for Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001686 extr_ext_flag = false;
1687 }
1688
1689 caps = mlm_assoc_req->capabilityInfo;
1690#if defined(FEATURE_WLAN_WAPI)
1691 /*
1692 * According to WAPI standard:
1693 * 7.3.1.4 Capability Information field
1694 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1695 * in transmitted Association or Reassociation management frames.
1696 * APs ignore the Privacy subfield within received Association and
1697 * Reassociation management frames.
1698 */
1699 if (pe_session->encryptType == eSIR_ED_WPI)
1700 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1701#endif
1702 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1703
1704 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1705 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1706 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1707 &frm->SuppRates, pe_session);
1708
1709 qos_enabled = (pe_session->limQosEnabled) &&
1710 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1711
1712 wme_enabled = (pe_session->limWmeEnabled) &&
1713 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1714
1715 /* We prefer .11e asociations: */
1716 if (qos_enabled)
1717 wme_enabled = false;
1718
1719 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1720 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1721
1722 if (pe_session->lim11hEnable &&
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07001723 pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 power_caps = true;
1725
1726 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1727 LIM_ASSOC, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1729 LIM_ASSOC, pe_session);
1730
1731 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1733 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1734 if (power_caps == false) {
1735 power_caps = true;
1736 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1737 LIM_ASSOC, pe_session);
1738 }
1739 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740 if (qos_enabled)
Naveen Rawatcd118312016-11-22 10:46:21 -08001741 populate_dot11f_qos_caps_station(mac_ctx, pe_session,
1742 &frm->QOSCapsStation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001743
1744 populate_dot11f_ext_supp_rates(mac_ctx,
1745 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1746 pe_session);
1747
Gupta, Kapil54a16992016-01-13 19:34:02 +05301748 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1749 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001750 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1751 pe_session);
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08001752
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 /*
1754 * The join request *should* contain zero or one of the WPA and RSN
1755 * IEs. The payload send along with the request is a
1756 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1757 * typedef struct sSirRSNie
1758 * {
1759 * uint16_t length;
1760 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1761 * } tSirRSNie, *tpSirRSNie;
1762 * So, we should be able to make the following two calls harmlessly,
1763 * since they do nothing if they don't find the given IE in the
1764 * bytestream with which they're provided.
1765 * The net effect of this will be to faithfully transmit whatever
1766 * security IE is in the join request.
1767 * However, if we're associating for the purpose of WPS
1768 * enrollment, and we've been configured to indicate that by
1769 * eliding the WPA or RSN IE, we just skip this:
1770 */
1771 if (add_ie_len && add_ie)
1772 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1773
1774 if (NULL == wps_ie) {
1775 populate_dot11f_rsn_opaque(mac_ctx,
1776 &(pe_session->pLimJoinReq->rsnIE),
1777 &frm->RSNOpaque);
1778 populate_dot11f_wpa_opaque(mac_ctx,
1779 &(pe_session->pLimJoinReq->rsnIE),
1780 &frm->WPAOpaque);
1781#if defined(FEATURE_WLAN_WAPI)
1782 populate_dot11f_wapi_opaque(mac_ctx,
1783 &(pe_session->pLimJoinReq->rsnIE),
1784 &frm->WAPIOpaque);
1785#endif /* defined(FEATURE_WLAN_WAPI) */
1786 }
1787 /* include WME EDCA IE as well */
1788 if (wme_enabled) {
1789 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1790 pe_session, &frm->WMMInfoStation);
1791
1792 if (wsm_enabled)
1793 populate_dot11f_wmm_caps(&frm->WMMCaps);
1794 }
1795
1796 /*
1797 * Populate HT IEs, when operating in 11n and
1798 * when AP is also operating in 11n mode
1799 */
1800 if (pe_session->htCapability &&
1801 mac_ctx->lim.htCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001802 pe_debug("Populate HT Caps in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001803 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001804 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1805 &frm->HTCaps, sizeof(frm->HTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001807 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 +05301808 frm->HTCaps.supportedChannelWidthSet,
1809 frm->HTCaps.mimoPowerSave,
1810 frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
1811 frm->HTCaps.shortGI40MHz,
1812 frm->HTCaps.dsssCckMode40MHz,
1813 frm->HTCaps.maxRxAMPDUFactor);
1814
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815 if (pe_session->vhtCapability &&
1816 pe_session->vhtCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001817 pe_debug("Populate VHT IEs in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001819 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1820 &frm->VHTCaps, sizeof(frm->VHTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001821 vht_enabled = true;
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001822 if (pe_session->enableHtSmps &&
1823 !pe_session->supported_nss_1x1) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001824 pe_err("VHT OP mode IE in Assoc Req");
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001825 populate_dot11f_operating_mode(mac_ctx,
1826 &frm->OperatingMode, pe_session);
1827 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001828 }
1829 if (!vht_enabled &&
1830 pe_session->is_vendor_specific_vhtcaps) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001831 pe_debug("Populate Vendor VHT IEs in Assoc Request");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301832 frm->vendor_vht_ie.present = 1;
1833 frm->vendor_vht_ie.type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001834 pe_session->vendor_specific_vht_ie_type;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301835 frm->vendor_vht_ie.sub_type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001836 pe_session->vendor_specific_vht_ie_sub_type;
1837
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301838 frm->vendor_vht_ie.VHTCaps.present = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001839 populate_dot11f_vht_caps(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301840 &frm->vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 vht_enabled = true;
1842 }
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301843 if (pe_session->is_ext_caps_present)
1844 populate_dot11f_ext_cap(mac_ctx, vht_enabled,
1845 &frm->ExtCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001846
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +05301847 if (mac_ctx->roam.configParam.qcn_ie_support)
1848 populate_dot11f_qcn_ie(&frm->QCN_IE);
1849
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001850 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001851 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001852 populate_dot11f_he_caps(mac_ctx, pe_session,
1853 &frm->vendor_he_cap);
1854 }
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301855
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001856 if (pe_session->pLimJoinReq->is11Rconnection) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857 tSirBssDescription *bssdescr;
1858
1859 bssdescr = &pe_session->pLimJoinReq->bssDescription;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001860 pe_debug("mdie = %02x %02x %02x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001861 (unsigned int) bssdescr->mdie[0],
1862 (unsigned int) bssdescr->mdie[1],
1863 (unsigned int) bssdescr->mdie[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864 populate_mdie(mac_ctx, &frm->MobilityDomain,
1865 pe_session->pLimJoinReq->bssDescription.mdie);
1866 } else {
1867 /* No 11r IEs dont send any MDIE */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001868 pe_debug("MDIE not present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001869 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001870
1871#ifdef FEATURE_WLAN_ESE
1872 /*
1873 * ESE Version IE will be included in association request
1874 * when ESE is enabled on DUT through ini and it is also
1875 * advertised by the peer AP to which we are trying to
1876 * associate to.
1877 */
1878 if (pe_session->is_ese_version_ie_present &&
1879 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1880 populate_dot11f_ese_version(&frm->ESEVersion);
1881 /* For ESE Associations fill the ESE IEs */
1882 if (pe_session->isESEconnection &&
1883 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1884#ifndef FEATURE_DISABLE_RM
1885 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1886#endif
1887 }
1888#endif
1889
Hu Wang411e0cc2016-10-28 14:56:01 +08001890 /*
1891 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1892 * may change the frame size. Therefore, MUST merge ExtCap IE before
1893 * dot11f get packed payload size.
1894 */
1895 if (extr_ext_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001896 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
1897
1898 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
1899 if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
1900 ie_offset = DOT11F_FF_TIMESTAMP_LEN +
1901 DOT11F_FF_BEACONINTERVAL_LEN +
1902 DOT11F_FF_CAPABILITIES_LEN;
1903
1904 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
1905 if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
1906 bcn_ie = pe_session->beacon + ie_offset;
1907 bcn_ie_len = pe_session->bcnLen - ie_offset;
1908 p_ext_cap = lim_get_ie_ptr_new(mac_ctx,
1909 bcn_ie,
1910 bcn_ie_len,
1911 DOT11F_EID_EXTCAP,
1912 ONE_BYTE);
1913 lim_update_extcap_struct(mac_ctx, p_ext_cap,
1914 &bcn_ext_cap);
1915 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
1916 false);
1917 }
1918 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001919
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001920 if (eSIR_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
1921 add_ie, &add_ie_len, &frm->SuppOperatingClasses))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001922 pe_debug("Unable to Stripoff supp op classes IE from Assoc Req");
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001923
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001924 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1925 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001926 pe_err("Association Request packet size failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001927 status);
1928 /* We'll fall back on the worst case scenario: */
1929 payload = sizeof(tDot11fAssocRequest);
1930 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001931 pe_warn("Association request packet size warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001932 status);
1933 }
1934
1935 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1936
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301937 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001938 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301939 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001940 pe_err("Failed to allocate %d bytes", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001941
1942 pe_session->limMlmState = pe_session->limPrevMlmState;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301943 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001944 pe_session->peSessionId,
1945 pe_session->limMlmState));
1946
1947 /* Update PE session id */
1948 assoc_cnf.sessionId = pe_session->peSessionId;
1949
1950 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1951
1952 cds_packet_free((void *)packet);
1953
1954 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1955 (uint32_t *) &assoc_cnf);
1956
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301957 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001958 }
1959 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301960 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961
1962 /* Next, we fill out the buffer descriptor: */
1963 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1964 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1965 pe_session->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966 /* That done, pack the Assoc Request: */
1967 status = dot11f_pack_assoc_request(mac_ctx, frm,
1968 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1969 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001970 pe_err("Assoc request pack failure (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001971 cds_packet_free((void *)packet);
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301972 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001974 pe_warn("Assoc request pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001975 }
1976
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001977 pe_debug("Sending Association Request length %d to ", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001978 if (pe_session->assocReq != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301979 qdf_mem_free(pe_session->assocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001980 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001981 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001982 }
1983
1984 if (add_ie_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301985 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001986 add_ie, add_ie_len);
1987 payload += add_ie_len;
1988 }
1989
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301990 pe_session->assocReq = qdf_mem_malloc(payload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001991 if (NULL == pe_session->assocReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001992 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001993 } else {
1994 /*
1995 * Store the Assoc request. This is sent to csr/hdd in
1996 * join cnf response.
1997 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301998 qdf_mem_copy(pe_session->assocReq,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999 frame + sizeof(tSirMacMgmtHdr), payload);
2000 pe_session->assocReqLen = payload;
2001 }
2002
2003 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302004 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
2005 || (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002006 )
2007 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2008
Anurag Chouhan6d760662016-02-20 16:05:43 +05302009 if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
2010 pe_session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2012
2013#ifdef FEATURE_WLAN_DIAG_SUPPORT
2014 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
2015 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2016#endif
2017 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302018 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019 pe_session->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302020 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002021 wma_tx_frame(mac_ctx, packet,
2022 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
2023 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2024 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302025 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302026 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302027 pe_session->peSessionId, qdf_status));
2028 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002029 pe_err("Failed to send Association Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302030 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031 /* Pkt will be freed up by the callback */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002032 }
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05302033end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002034 /* Free up buffer allocated for mlm_assoc_req */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302035 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002036 mlm_assoc_req = NULL;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302037 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002038 return;
2039}
2040
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002041/**
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302042 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302043 * @context: pointer to global mac
2044 * @buf: buffer
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302045 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302046 * @params; tx completion params
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302047 *
2048 * Return: This returns QDF_STATUS
2049 */
2050
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302051static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
2052 qdf_nbuf_t buf,
2053 uint32_t tx_complete,
2054 void *params)
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302055{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302056 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
2057
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002058 pe_debug("tx_complete= %d", tx_complete);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302059 if (tx_complete) {
2060 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
2061 /* 'Change' timer for future activations */
2062 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2063 } else {
2064 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2065 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302066
2067 if (buf)
2068 qdf_nbuf_free(buf);
2069
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302070 return QDF_STATUS_SUCCESS;
2071}
2072
2073/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002074 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2075 *
2076 * @mac_ctx: Pointer to Global MAC structure
2077 * @auth_frame: Pointer to Authentication frame structure
2078 * @peer_addr: MAC address of destination peer
2079 * @wep_bit: wep bit in frame control for Authentication frame3
2080 * @session: PE session information
2081 *
2082 * This function is called by lim_process_mlm_messages(). Authentication frame
2083 * is formatted and sent when this function is called.
2084 *
2085 * Return: void
2086 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087void
2088lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2089 tpSirMacAuthFrameBody auth_frame,
2090 tSirMacAddr peer_addr,
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302091 uint8_t wep_challenge_len,
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302092 tpPESession session, bool wait_for_ack)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002093{
2094 uint8_t *frame, *body;
2095 uint32_t frame_len = 0, body_len = 0;
2096 tpSirMacMgmtHdr mac_hdr;
2097 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302098 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 uint8_t tx_flag = 0;
2100 uint8_t sme_sessionid = 0;
2101 uint16_t ft_ies_length = 0;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002102 bool challenge_req = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103
2104 if (NULL == session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002105 pe_err("Error: psession Entry is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106 return;
2107 }
2108
2109 sme_sessionid = session->smeSessionId;
2110
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302111 if (wep_challenge_len) {
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002112 /*
2113 * Auth frame3 to be sent with encrypted framebody
2114 *
2115 * Allocate buffer for Authenticaton frame of size
2116 * equal to management frame header length plus 2 bytes
2117 * each for auth algorithm number, transaction number,
2118 * status code, 128 bytes for challenge text and
2119 * 4 bytes each for IV & ICV.
2120 */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002121 pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
2122 MAC_ADDR_ARRAY(peer_addr));
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002123
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302124 body_len = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002125 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002126
2127 goto alloc_packet;
2128 }
2129
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002130 pe_info("Sending Auth seq# %d status %d (%d) wait_for_ack %d to "
2131 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002132 auth_frame->authTransactionSeqNumber,
2133 auth_frame->authStatusCode,
2134 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302135 wait_for_ack,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002136 MAC_ADDR_ARRAY(peer_addr));
2137
2138 switch (auth_frame->authTransactionSeqNumber) {
2139 case SIR_MAC_AUTH_FRAME_1:
2140 /*
2141 * Allocate buffer for Authenticaton frame of size
2142 * equal to management frame header length plus 2 bytes
2143 * each for auth algorithm number, transaction number
2144 * and status code.
2145 */
2146
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002147 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2148 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05302150 frame_len += lim_create_fils_auth_data(mac_ctx,
2151 auth_frame, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2153 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2154 0 != session->ftPEContext.pFTPreAuthReq->
2155 ft_ies_length) {
2156 ft_ies_length = session->ftPEContext.
2157 pFTPreAuthReq->ft_ies_length;
2158 frame_len += ft_ies_length;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002159 pe_debug("Auth frame, FTIES length added=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160 ft_ies_length);
2161 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002162 pe_debug("Auth frame, Does not contain FTIES!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002163 frame_len += (2 + SIR_MDIE_SIZE);
2164 }
2165 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002166 break;
2167
2168 case SIR_MAC_AUTH_FRAME_2:
2169 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2170 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2171 (auth_frame->authStatusCode !=
2172 eSIR_MAC_SUCCESS_STATUS))) {
2173 /*
2174 * Allocate buffer for Authenticaton frame of size
2175 * equal to management frame header length plus
2176 * 2 bytes each for auth algorithm number,
2177 * transaction number and status code.
2178 */
2179
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002180 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2181 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182 } else {
2183 /*
2184 * Shared Key algorithm with challenge text
2185 * to be sent.
2186 *
2187 * Allocate buffer for Authenticaton frame of size
2188 * equal to management frame header length plus
2189 * 2 bytes each for auth algorithm number,
2190 * transaction number, status code and 128 bytes
2191 * for challenge text.
2192 */
2193
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002194 challenge_req = true;
2195 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
2196 SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2197 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002198 }
2199 break;
2200
2201 case SIR_MAC_AUTH_FRAME_3:
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002202 /*
2203 * Auth frame3 to be sent without encrypted framebody
2204 *
2205 * Allocate buffer for Authenticaton frame of size equal
2206 * to management frame header length plus 2 bytes each
2207 * for auth algorithm number, transaction number and
2208 * status code.
2209 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002210
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002211 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2212 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002213 break;
2214
2215 case SIR_MAC_AUTH_FRAME_4:
2216 /*
2217 * Allocate buffer for Authenticaton frame of size equal
2218 * to management frame header length plus 2 bytes each
2219 * for auth algorithm number, transaction number and
2220 * status code.
2221 */
2222
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002223 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2224 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002225
2226 break;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002227 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002228 pe_err("Invalid auth transaction seq num");
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002229 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002230 } /* switch (auth_frame->authTransactionSeqNumber) */
2231
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002232alloc_packet:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302233 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002234 (void **)&packet);
2235
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302236 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002237 pe_err("call to bufAlloc failed for AUTH frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002238 return;
2239 }
2240
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302241 qdf_mem_zero(frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002242
2243 /* Prepare BD */
2244 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2245 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2246 mac_hdr = (tpSirMacMgmtHdr) frame;
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302247 if (wep_challenge_len)
2248 mac_hdr->fc.wep = LIM_WEP_IN_FC;
2249 else
2250 mac_hdr->fc.wep = LIM_NO_WEP_IN_FC;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002251
2252 /* Prepare BSSId */
Rajeev Kumarcf835a02016-04-15 15:01:31 -07002253 if (LIM_IS_AP_ROLE(session))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302254 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002255 (uint8_t *) session->bssId,
2256 sizeof(tSirMacAddr));
2257
2258 /* Prepare Authentication frame body */
2259 body = frame + sizeof(tSirMacMgmtHdr);
2260
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302261 if (wep_challenge_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302262 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002263
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002264 pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002265 MAC_ADDR_ARRAY(mac_hdr->da));
2266
2267 } else {
2268 *((uint16_t *) (body)) =
2269 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2270 body += sizeof(uint16_t);
2271 body_len -= sizeof(uint16_t);
2272
2273 *((uint16_t *) (body)) =
2274 sir_swap_u16if_needed(
2275 auth_frame->authTransactionSeqNumber);
2276 body += sizeof(uint16_t);
2277 body_len -= sizeof(uint16_t);
2278
2279 *((uint16_t *) (body)) =
2280 sir_swap_u16if_needed(auth_frame->authStatusCode);
2281 body += sizeof(uint16_t);
2282 body_len -= sizeof(uint16_t);
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002283
2284 if (challenge_req) {
2285 if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
2286 qdf_mem_copy(body, (uint8_t *)&auth_frame->type,
2287 body_len);
2288 pe_err("Incomplete challenge info: length: %d, expected: %d",
2289 body_len,
2290 SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
2291 body += body_len;
2292 body_len = 0;
2293 } else {
2294 /* copy challenge IE id, len, challenge text */
2295 *body = auth_frame->type;
2296 body++;
2297 *body = auth_frame->length;
2298 body++;
2299 qdf_mem_copy(body, auth_frame->challengeText,
2300 SIR_MAC_AUTH_CHALLENGE_LENGTH);
2301 body += SIR_MAC_AUTH_CHALLENGE_LENGTH;
2302
2303 body_len -= SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2304 }
2305 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002306
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002307 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2308 (auth_frame->authTransactionSeqNumber ==
2309 SIR_MAC_AUTH_FRAME_1) &&
2310 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2311
2312 if (ft_ies_length > 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302313 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002314 session->ftPEContext.
2315 pFTPreAuthReq->ft_ies,
2316 ft_ies_length);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002317 pe_debug("Auth1 Frame FTIE is: ");
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002318 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2319 QDF_TRACE_LEVEL_DEBUG,
2320 (uint8_t *) body,
2321 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002322 } else if (NULL != session->ftPEContext.
2323 pFTPreAuthReq->pbssDescription) {
2324 /* MDID attr is 54 */
2325 *body = SIR_MDIE_ELEMENT_ID;
2326 body++;
2327 *body = SIR_MDIE_SIZE;
2328 body++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302329 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002330 &session->ftPEContext.pFTPreAuthReq->
2331 pbssDescription->mdie[0],
2332 SIR_MDIE_SIZE);
2333 }
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05302334 } else if (auth_frame->authAlgoNumber ==
2335 eSIR_FILS_SK_WITHOUT_PFS) {
2336 /* TODO MDIE */
2337 pe_debug("appending fils Auth data");
2338 lim_add_fils_data_to_auth_frame(session, body);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002339 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002340
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002341 pe_debug("*** Sending Auth seq# %d status %d (%d) to "
2342 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343 auth_frame->authTransactionSeqNumber,
2344 auth_frame->authStatusCode,
2345 (auth_frame->authStatusCode ==
2346 eSIR_MAC_SUCCESS_STATUS),
2347 MAC_ADDR_ARRAY(mac_hdr->da));
2348 }
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002349 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2350 QDF_TRACE_LEVEL_DEBUG,
2351 frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302353 if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
2354 (SIR_BAND_5_GHZ == lim_get_rf_band(
2355 session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002356 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302357 else if ((SIR_BAND_5_GHZ ==
2358 lim_get_rf_band(session->currentOperChannel))
2359 || (session->pePersona == QDF_P2P_CLIENT_MODE)
2360 || (session->pePersona == QDF_P2P_GO_MODE))
2361 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002362
Anurag Chouhan6d760662016-02-20 16:05:43 +05302363 if (session->pePersona == QDF_P2P_CLIENT_MODE ||
2364 session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002365 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2366
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302367 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002368 session->peSessionId, mac_hdr->fc.subType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002369
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302370 if (wait_for_ack) {
2371 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
2372 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
2373 (uint16_t)frame_len,
2374 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2375 7, lim_tx_complete, frame,
2376 lim_auth_tx_complete_cnf,
2377 tx_flag, sme_sessionid, false, 0);
2378 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2379 session->peSessionId, qdf_status));
2380 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002381 pe_err("*** Could not send Auth frame, retCode=%X ***",
2382 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302383 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2384 /* Pkt will be freed up by the callback */
2385 }
2386 } else {
2387 /* Queue Authentication frame in high priority WQ */
2388 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
2389 TXRX_FRM_802_11_MGMT,
2390 ANI_TXDIR_TODS, 7, lim_tx_complete,
2391 frame, tx_flag, sme_sessionid, 0);
2392 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2393 session->peSessionId, qdf_status));
2394 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002395 pe_err("*** Could not send Auth frame, retCode=%X ***",
2396 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302397 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002398 return;
2399}
2400
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302401QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002402{
2403 uint16_t aid;
2404 tpDphHashNode pStaDs;
2405 tLimMlmDeauthReq *pMlmDeauthReq;
2406 tLimMlmDeauthCnf mlmDeauthCnf;
2407 tpPESession psessionEntry;
2408
2409 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
2410 if (pMlmDeauthReq) {
2411 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
2412 lim_deactivate_and_change_timer(pMac,
2413 eLIM_DEAUTH_ACK_TIMER);
2414 }
2415
2416 psessionEntry = pe_find_session_by_session_id(pMac,
2417 pMlmDeauthReq->sessionId);
2418 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002419 pe_err("session does not exist for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002420 mlmDeauthCnf.resultCode =
2421 eSIR_SME_INVALID_PARAMETERS;
2422 goto end;
2423 }
2424
2425 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002426 dph_lookup_hash_entry(pMac,
2427 pMlmDeauthReq->peer_macaddr.bytes,
2428 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002429 &psessionEntry->dph.dphHashTable);
2430 if (pStaDs == NULL) {
2431 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2432 goto end;
2433 }
2434
2435 /* / Receive path cleanup with dummy packet */
2436 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2437 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002438 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
2439 (
Abhishek Singhe0680852015-12-16 14:28:48 +05302440#ifdef FEATURE_WLAN_ESE
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002441 (psessionEntry->isESEconnection) ||
Abhishek Singhe0680852015-12-16 14:28:48 +05302442#endif
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002443 (psessionEntry->isFastRoamIniFeatureEnabled) ||
2444 (psessionEntry->is11Rconnection))) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002445 pe_debug("FT Preauth (%p,%d) Deauth rc %d src = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002446 psessionEntry,
2447 psessionEntry->peSessionId,
2448 pMlmDeauthReq->reasonCode,
2449 pMlmDeauthReq->deauthTrigger);
2450 lim_ft_cleanup(pMac, psessionEntry);
2451 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002452 pe_debug("No FT Preauth Session Cleanup in role %d"
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002453#ifdef FEATURE_WLAN_ESE
2454 " isESE %d"
2455#endif
2456 " isLFR %d"
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002457 " is11r %d, Deauth reason %d Trigger = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002458 psessionEntry->limSystemRole,
2459#ifdef FEATURE_WLAN_ESE
2460 psessionEntry->isESEconnection,
2461#endif
2462 psessionEntry->isFastRoamIniFeatureEnabled,
2463 psessionEntry->is11Rconnection,
Abhishek Singhe0680852015-12-16 14:28:48 +05302464 pMlmDeauthReq->reasonCode,
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002465 pMlmDeauthReq->deauthTrigger);
2466 }
2467 /* Free up buffer allocated for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302468 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
2470 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302471 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472end:
Anurag Chouhanc5548422016-02-24 18:33:27 +05302473 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002474 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002475 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
2476 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
2477 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
2478
2479 /* Free up buffer allocated */
2480 /* for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302481 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002482
2483 lim_post_sme_message(pMac,
2484 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302485 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002486}
2487
2488/**
2489 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
2490 *
2491 * @mac_ctx: Handle to MAC context
2492 *
2493 * Sends disassoc confirmation to SME. Removes disassoc request stored
2494 * in lim.
2495 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302496 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002497 */
2498
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302499QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500{
2501 uint16_t aid;
2502 tpDphHashNode sta_ds;
2503 tLimMlmDisassocCnf disassoc_cnf;
2504 tpPESession pe_session;
2505 tLimMlmDisassocReq *disassoc_req;
2506
2507 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
2508 if (disassoc_req) {
2509 if (tx_timer_running(
2510 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
2511 lim_deactivate_and_change_timer(mac_ctx,
2512 eLIM_DISASSOC_ACK_TIMER);
2513
2514 pe_session = pe_find_session_by_session_id(
2515 mac_ctx, disassoc_req->sessionId);
2516 if (pe_session == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002517 pe_err("No session for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002518 disassoc_cnf.resultCode =
2519 eSIR_SME_INVALID_PARAMETERS;
2520 goto end;
2521 }
2522
2523 sta_ds = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002524 disassoc_req->peer_macaddr.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002525 &pe_session->dph.dphHashTable);
2526 if (sta_ds == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002527 pe_err("StaDs Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2529 goto end;
2530 }
2531 /* Receive path cleanup with dummy packet */
2532 if (eSIR_SUCCESS !=
2533 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
2534 disassoc_cnf.resultCode =
2535 eSIR_SME_RESOURCES_UNAVAILABLE;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002536 pe_err("cleanup_rx_path error");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002537 goto end;
2538 }
Deepak Dhamdhere57c95ff2016-09-30 16:44:44 -07002539 if (LIM_IS_STA_ROLE(pe_session) &&
2540 (disassoc_req->reasonCode !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002541 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002542 pe_debug("FT Preauth Session (%p %d) Clean up",
2543 pe_session, pe_session->peSessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002544
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002545 /* Delete FT session if there exists one */
2546 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002548 /* Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302549 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002550 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302551 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002552 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302553 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002554 }
2555end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302556 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002557 (uint8_t *) disassoc_req->peer_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302558 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002559 disassoc_cnf.aid = disassoc_req->aid;
2560 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
2561
2562 /* Update PE session ID */
2563 disassoc_cnf.sessionId = disassoc_req->sessionId;
2564
2565 if (disassoc_req != NULL) {
2566 /* / Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302567 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
2569 }
2570
2571 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
2572 (uint32_t *) &disassoc_cnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302573 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002574}
2575
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302576QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
2577 qdf_nbuf_t buf,
2578 uint32_t txCompleteSuccess,
2579 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002580{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302581 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2582
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002583 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302584
2585 if (buf)
2586 qdf_nbuf_free(buf);
2587
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002588 return lim_send_disassoc_cnf(pMac);
2589}
2590
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302591QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
2592 qdf_nbuf_t buf,
2593 uint32_t txCompleteSuccess,
2594 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002595{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302596 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2597
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002598 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302599
2600 if (buf)
2601 qdf_nbuf_free(buf);
2602
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002603 return lim_send_deauth_cnf(pMac);
2604}
2605
2606/**
2607 * \brief This function is called to send Disassociate frame.
2608 *
2609 *
2610 * \param pMac Pointer to Global MAC structure
2611 *
2612 * \param nReason Indicates the reason that need to be sent in
2613 * Disassociation frame
2614 *
2615 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
2616 * sent
2617 *
2618 *
2619 */
2620
2621void
2622lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
2623 uint16_t nReason,
2624 tSirMacAddr peer,
2625 tpPESession psessionEntry, bool waitForAck)
2626{
2627 tDot11fDisassociation frm;
2628 uint8_t *pFrame;
2629 tpSirMacMgmtHdr pMacHdr;
2630 uint32_t nBytes, nPayload, nStatus;
2631 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302632 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002633 uint8_t txFlag = 0;
2634 uint32_t val = 0;
2635 uint8_t smeSessionId = 0;
2636 if (NULL == psessionEntry) {
2637 return;
2638 }
2639
2640 /*
2641 * In case when cac timer is running for this SAP session then
2642 * avoid sending disassoc out. It is violation of dfs specification.
2643 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302644 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2645 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002646 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302647 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648 FL
2649 ("CAC timer is running, drop disassoc from going out"));
2650 return;
2651 }
2652 smeSessionId = psessionEntry->smeSessionId;
2653
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302654 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002655
2656 frm.Reason.code = nReason;
2657
2658 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
2659 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002660 pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002661 nStatus);
2662 /* We'll fall back on the worst case scenario: */
2663 nPayload = sizeof(tDot11fDisassociation);
2664 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002665 pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)",
2666 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667 }
2668
2669 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2670
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302671 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002672 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302673 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002674 pe_err("Failed to allocate %d bytes for a Disassociation",
2675 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002676 return;
2677 }
2678 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302679 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680
2681 /* Next, we fill out the buffer descriptor: */
2682 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2683 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
2684 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2685
2686 /* Prepare the BSSID */
2687 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2688
2689#ifdef WLAN_FEATURE_11W
2690 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2691#endif
2692
2693 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
2694 sizeof(tSirMacMgmtHdr),
2695 nPayload, &nPayload);
2696 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002697 pe_err("Failed to pack a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698 nStatus);
2699 cds_packet_free((void *)pPacket);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002700 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002702 pe_warn("There were warnings while packing a Disassociation (0x%08x)",
2703 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002704 }
2705
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002706 pe_debug("***Sessionid %d Sending Disassociation frame with "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002707 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002708 MAC_ADDRESS_STR, psessionEntry->peSessionId, nReason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002709 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
2710 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2711
2712 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302713 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2714 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002715 ) {
2716 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2717 }
2718
Sushant Kaushik46556062015-12-02 16:57:47 +05302719 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720
2721 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302722 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002723 psessionEntry->peSessionId,
2724 pMacHdr->fc.subType));
2725 /* Queue Disassociation frame in high priority WQ */
2726 /* get the duration from the request */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302727 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2729 TXRX_FRM_802_11_MGMT,
2730 ANI_TXDIR_TODS, 7, lim_tx_complete,
2731 pFrame, lim_disassoc_tx_complete_cnf,
2732 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302733 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302734 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302735 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002736
2737 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2738
2739 if (tx_timer_change
2740 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
2741 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002742 pe_err("Unable to change Disassoc ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743 return;
2744 } else if (TX_SUCCESS !=
2745 tx_timer_activate(&pMac->lim.limTimers.
2746 gLimDisassocAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002747 pe_err("Unable to activate Disassoc ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002748 lim_deactivate_and_change_timer(pMac,
2749 eLIM_DISASSOC_ACK_TIMER);
2750 return;
2751 }
2752 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302753 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002754 psessionEntry->peSessionId,
2755 pMacHdr->fc.subType));
2756 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302757 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002758 TXRX_FRM_802_11_MGMT,
2759 ANI_TXDIR_TODS,
2760 7,
2761 lim_tx_complete, pFrame, txFlag,
2762 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302763 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302764 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302765 psessionEntry->peSessionId, qdf_status));
2766 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002767 pe_err("Failed to send Disassociation (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302768 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002769 /* Pkt will be freed up by the callback */
2770 }
2771 }
2772} /* End lim_send_disassoc_mgmt_frame. */
2773
2774/**
2775 * \brief This function is called to send a Deauthenticate frame
2776 *
2777 *
2778 * \param pMac Pointer to global MAC structure
2779 *
2780 * \param nReason Indicates the reason that need to be sent in the
2781 * Deauthenticate frame
2782 *
2783 * \param peeer address of the STA to which the frame is to be sent
2784 *
2785 *
2786 */
2787
2788void
2789lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
2790 uint16_t nReason,
2791 tSirMacAddr peer,
2792 tpPESession psessionEntry, bool waitForAck)
2793{
2794 tDot11fDeAuth frm;
2795 uint8_t *pFrame;
2796 tpSirMacMgmtHdr pMacHdr;
2797 uint32_t nBytes, nPayload, nStatus;
2798 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302799 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002800 uint8_t txFlag = 0;
2801 uint32_t val = 0;
2802#ifdef FEATURE_WLAN_TDLS
2803 uint16_t aid;
2804 tpDphHashNode pStaDs;
2805#endif
2806 uint8_t smeSessionId = 0;
2807
2808 if (NULL == psessionEntry) {
2809 return;
2810 }
2811
2812 /*
2813 * In case when cac timer is running for this SAP session then
2814 * avoid deauth frame out. It is violation of dfs specification.
2815 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302816 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2817 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002818 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302819 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002820 FL
2821 ("CAC timer is running, drop the deauth from going out"));
2822 return;
2823 }
2824 smeSessionId = psessionEntry->smeSessionId;
2825
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302826 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002827
2828 frm.Reason.code = nReason;
2829
2830 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
2831 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002832 pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002833 nStatus);
2834 /* We'll fall back on the worst case scenario: */
2835 nPayload = sizeof(tDot11fDeAuth);
2836 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002837 pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)",
2838 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002839 }
2840
2841 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2842
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302843 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002844 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302845 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002846 pe_err("Failed to allocate %d bytes for a De-Authentication",
2847 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002848 return;
2849 }
2850 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302851 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002852
2853 /* Next, we fill out the buffer descriptor: */
2854 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2855 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
2856 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2857
2858 /* Prepare the BSSID */
2859 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2860
2861#ifdef WLAN_FEATURE_11W
2862 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2863#endif
2864
2865 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
2866 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
2867 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002868 pe_err("Failed to pack a DeAuthentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002869 nStatus);
2870 cds_packet_free((void *)pPacket);
2871 return;
2872 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002873 pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
2874 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002875 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002876 pe_debug("***Sessionid %d Sending Deauth frame with "
2877 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
2878 " ,From " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002879 psessionEntry->peSessionId, nReason, waitForAck,
2880 MAC_ADDR_ARRAY(pMacHdr->da),
2881 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2882
2883 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302884 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2885 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002886 ) {
2887 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2888 }
2889
Sushant Kaushik46556062015-12-02 16:57:47 +05302890 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002891#ifdef FEATURE_WLAN_TDLS
2892 pStaDs =
2893 dph_lookup_hash_entry(pMac, peer, &aid,
2894 &psessionEntry->dph.dphHashTable);
2895#endif
2896
2897 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302898 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002899 psessionEntry->peSessionId,
2900 pMacHdr->fc.subType));
2901 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302902 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002903 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2904 TXRX_FRM_802_11_MGMT,
2905 ANI_TXDIR_TODS, 7, lim_tx_complete,
2906 pFrame, lim_deauth_tx_complete_cnf,
2907 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302908 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302909 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302910 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911 /* Pkt will be freed up by the callback lim_tx_complete */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302912 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002913 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302914 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002915
2916 /* Call lim_process_deauth_ack_timeout which will send
2917 * DeauthCnf for this frame
2918 */
2919 lim_process_deauth_ack_timeout(pMac);
2920 return;
2921 }
2922
2923 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2924
2925 if (tx_timer_change
2926 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
2927 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002928 pe_err("Unable to change Deauth ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002929 return;
2930 } else if (TX_SUCCESS !=
2931 tx_timer_activate(&pMac->lim.limTimers.
2932 gLimDeauthAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002933 pe_err("Unable to activate Deauth ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002934 lim_deactivate_and_change_timer(pMac,
2935 eLIM_DEAUTH_ACK_TIMER);
2936 return;
2937 }
2938 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302939 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002940 psessionEntry->peSessionId,
2941 pMacHdr->fc.subType));
2942#ifdef FEATURE_WLAN_TDLS
2943 if ((NULL != pStaDs)
2944 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
2945 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302946 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002947 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2948 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
2949 7, lim_tx_complete, pFrame, txFlag,
2950 smeSessionId, 0);
2951 } else {
2952#endif
2953 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302954 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002955 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2956 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2957 7, lim_tx_complete, pFrame, txFlag,
2958 smeSessionId, 0);
2959#ifdef FEATURE_WLAN_TDLS
2960 }
2961#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302962 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302963 psessionEntry->peSessionId, qdf_status));
2964 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002965 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302966 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002967 /* Pkt will be freed up by the callback */
2968 }
2969 }
2970
2971} /* End lim_send_deauth_mgmt_frame. */
2972
2973#ifdef ANI_SUPPORT_11H
2974/**
2975 * \brief Send a Measurement Report Action frame
2976 *
2977 *
2978 * \param pMac Pointer to the global MAC structure
2979 *
2980 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
2981 *
2982 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
2983 *
2984 *
2985 */
2986
2987tSirRetStatus
2988lim_send_meas_report_frame(tpAniSirGlobal pMac,
2989 tpSirMacMeasReqActionFrame pMeasReqFrame,
2990 tSirMacAddr peer, tpPESession psessionEntry)
2991{
2992 tDot11fMeasurementReport frm;
2993 uint8_t *pFrame;
2994 tSirRetStatus nSirStatus;
2995 tpSirMacMgmtHdr pMacHdr;
2996 uint32_t nBytes, nPayload, nStatus;
2997 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302998 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002999
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303000 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003001
3002 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3003 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3004 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3005
3006 switch (pMeasReqFrame->measReqIE.measType) {
3007 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3008 nSirStatus =
3009 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3010 &frm.MeasurementReport);
3011 break;
3012 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3013 nSirStatus =
3014 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3015 &frm.MeasurementReport);
3016 break;
3017 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3018 nSirStatus =
3019 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3020 &frm.MeasurementReport);
3021 break;
3022 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003023 pe_err("Unknown measurement type %d in limSen"
3024 "dMeasReportFrame",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003025 pMeasReqFrame->measReqIE.measType);
3026 return eSIR_FAILURE;
3027 }
3028
3029 if (eSIR_SUCCESS != nSirStatus)
3030 return eSIR_FAILURE;
3031
3032 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3033 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003034 pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003035 nStatus);
3036 /* We'll fall back on the worst case scenario: */
3037 nPayload = sizeof(tDot11fMeasurementReport);
3038 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003039 pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)",
3040 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003041 }
3042
3043 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3044
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303045 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003046 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3047 (uint16_t) nBytes, (void **)&pFrame,
3048 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303049 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003050 pe_err("Failed to allocate %d bytes for a "
3051 "De-Authentication", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003052 return eSIR_FAILURE;
3053 }
3054 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303055 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003056
3057 /* Next, we fill out the buffer descriptor: */
3058 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3059 SIR_MAC_MGMT_ACTION, peer);
3060 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3061
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303062 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063
3064#ifdef WLAN_FEATURE_11W
3065 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3066#endif
3067
3068 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3069 sizeof(tSirMacMgmtHdr),
3070 nPayload, &nPayload);
3071 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003072 pe_err("Failed to pack a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003073 nStatus);
3074 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3075 (void *)pFrame, (void *)pPacket);
3076 return eSIR_FAILURE; /* allocated! */
3077 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003078 pe_warn("There were warnings while packing a Measurement Report (0x%08x)",
3079 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003080 }
3081
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303082 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003083 ((psessionEntry) ? psessionEntry->
3084 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303085 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003086 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3087 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3088 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303089 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303090 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003091 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303092 qdf_status));
3093 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003094 pe_err("Failed to send a Measurement Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303095 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003096 /* Pkt will be freed up by the callback */
3097 return eSIR_FAILURE; /* just allocated... */
3098 }
3099
3100 return eSIR_SUCCESS;
3101
3102} /* End lim_send_meas_report_frame. */
3103
3104/**
3105 * \brief Send a TPC Request Action frame
3106 *
3107 *
3108 * \param pMac Pointer to the global MAC datastructure
3109 *
3110 * \param peer MAC address to which the frame should be sent
3111 *
3112 *
3113 */
3114
3115void
3116lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3117 tSirMacAddr peer, tpPESession psessionEntry)
3118{
3119 tDot11fTPCRequest frm;
3120 uint8_t *pFrame;
3121 tpSirMacMgmtHdr pMacHdr;
3122 uint32_t nBytes, nPayload, nStatus;
3123 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303124 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003125
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303126 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003127
3128 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3129 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3130 frm.DialogToken.token = 1;
3131 frm.TPCRequest.present = 1;
3132
3133 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3134 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003135 pe_err("Failed to calculate the packed size for a TPC Request (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003136 /* We'll fall back on the worst case scenario: */
3137 nPayload = sizeof(tDot11fTPCRequest);
3138 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003139 pe_warn("There were warnings while calculating the packed size for a TPC Request (0x%08x)",
3140 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003141 }
3142
3143 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3144
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303145 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003146 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3147 (uint16_t) nBytes, (void **)&pFrame,
3148 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303149 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003150 pe_err("Failed to allocate %d bytes for a TPC"
3151 " Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003152 return;
3153 }
3154 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303155 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003156
3157 /* Next, we fill out the buffer descriptor: */
3158 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3159 SIR_MAC_MGMT_ACTION, peer);
3160 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3161
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303162 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003163
3164#ifdef WLAN_FEATURE_11W
3165 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3166#endif
3167
3168 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3169 sizeof(tSirMacMgmtHdr),
3170 nPayload, &nPayload);
3171 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003172 pe_err("Failed to pack a TPC Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003173 nStatus);
3174 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3175 (void *)pFrame, (void *)pPacket);
3176 return; /* allocated! */
3177 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003178 pe_warn("There were warnings while packing a TPC Request (0x%08x)",
3179 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003180 }
3181
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303182 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003183 ((psessionEntry) ? psessionEntry->
3184 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303185 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003186 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3187 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3188 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303189 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303190 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003191 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303192 qdf_status));
3193 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003194 pe_err("Failed to send a TPC Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303195 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003196 /* Pkt will be freed up by the callback */
3197 }
3198
3199} /* End lim_send_tpc_request_frame. */
3200
3201/**
3202 * \brief Send a TPC Report Action frame
3203 *
3204 *
3205 * \param pMac Pointer to the global MAC datastructure
3206 *
3207 * \param pTpcReqFrame Pointer to the received TPC Request
3208 *
3209 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3210 *
3211 *
3212 */
3213
3214tSirRetStatus
3215lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3216 tpSirMacTpcReqActionFrame pTpcReqFrame,
3217 tSirMacAddr peer, tpPESession psessionEntry)
3218{
3219 tDot11fTPCReport frm;
3220 uint8_t *pFrame;
3221 tpSirMacMgmtHdr pMacHdr;
3222 uint32_t nBytes, nPayload, nStatus;
3223 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303224 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303226 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003227
3228 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3229 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3230 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3231
3232 frm.TPCReport.tx_power = 0;
3233 frm.TPCReport.link_margin = 0;
3234 frm.TPCReport.present = 1;
3235
3236 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3237 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003238 pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003239 /* We'll fall back on the worst case scenario: */
3240 nPayload = sizeof(tDot11fTPCReport);
3241 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003242 pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)",
3243 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003244 }
3245
3246 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3247
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303248 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3250 (uint16_t) nBytes, (void **)&pFrame,
3251 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303252 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003253 pe_err("Failed to allocate %d bytes for a TPC"
3254 " Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003255 return eSIR_FAILURE;
3256 }
3257 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303258 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003259
3260 /* Next, we fill out the buffer descriptor: */
3261 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3262 SIR_MAC_MGMT_ACTION, peer);
3263
3264 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3265
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303266 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267
3268#ifdef WLAN_FEATURE_11W
3269 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3270#endif
3271
3272 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3273 sizeof(tSirMacMgmtHdr),
3274 nPayload, &nPayload);
3275 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003276 pe_err("Failed to pack a TPC Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277 nStatus);
3278 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3279 (void *)pFrame, (void *)pPacket);
3280 return eSIR_FAILURE; /* allocated! */
3281 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003282 pe_warn("There were warnings while packing a TPC Report (0x%08x)",
3283 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003284
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303285 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003286 ((psessionEntry) ? psessionEntry->
3287 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303288 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003289 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3290 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3291 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303292 MTRACE(qdf_trace
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003293 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3294 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3295 qdf_status));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303296 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003297 pe_err("Failed to send a TPC Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303298 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003299 /* Pkt will be freed up by the callback */
3300 return eSIR_FAILURE; /* just allocated... */
3301 }
3302
3303 return eSIR_SUCCESS;
3304
3305} /* End lim_send_tpc_report_frame. */
3306#endif /* ANI_SUPPORT_11H */
3307
3308/**
3309 * \brief Send a Channel Switch Announcement
3310 *
3311 *
3312 * \param pMac Pointer to the global MAC datastructure
3313 *
3314 * \param peer MAC address to which this frame will be sent
3315 *
3316 * \param nMode
3317 *
3318 * \param nNewChannel
3319 *
3320 * \param nCount
3321 *
3322 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3323 *
3324 *
3325 */
3326
3327tSirRetStatus
3328lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3329 tSirMacAddr peer,
3330 uint8_t nMode,
3331 uint8_t nNewChannel,
3332 uint8_t nCount, tpPESession psessionEntry)
3333{
3334 tDot11fChannelSwitch frm;
3335 uint8_t *pFrame;
3336 tpSirMacMgmtHdr pMacHdr;
3337 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3338 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303339 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003340 uint8_t txFlag = 0;
3341
3342 uint8_t smeSessionId = 0;
3343
3344 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003345 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003346 return eSIR_FAILURE;
3347 }
3348 smeSessionId = psessionEntry->smeSessionId;
3349
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303350 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003351
3352 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3353 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
3354 frm.ChanSwitchAnn.switchMode = nMode;
3355 frm.ChanSwitchAnn.newChannel = nNewChannel;
3356 frm.ChanSwitchAnn.switchCount = nCount;
3357 frm.ChanSwitchAnn.present = 1;
3358
3359 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
3360 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003361 pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003362 nStatus);
3363 /* We'll fall back on the worst case scenario: */
3364 nPayload = sizeof(tDot11fChannelSwitch);
3365 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003366 pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)",
3367 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368 }
3369
3370 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3371
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303372 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003373 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3374 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303375 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003376 pe_err("Failed to allocate %d bytes for a TPC Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003377 return eSIR_FAILURE;
3378 }
3379 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303380 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003381
3382 /* Next, we fill out the buffer descriptor: */
3383 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3384 SIR_MAC_MGMT_ACTION, peer,
3385 psessionEntry->selfMacAddr);
3386 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303387 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003388 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3389
3390#ifdef WLAN_FEATURE_11W
3391 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3392#endif
3393
3394 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
3395 sizeof(tSirMacMgmtHdr),
3396 nPayload, &nPayload);
3397 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003398 pe_err("Failed to pack a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003399 nStatus);
3400 cds_packet_free((void *)pPacket);
3401 return eSIR_FAILURE; /* allocated! */
3402 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003403 pe_warn("There were warnings while packing a Channel Switch (0x%08x)",
3404 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003405 }
3406
3407 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303408 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3409 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410 ) {
3411 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3412 }
3413
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303414 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003415 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303416 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003417 TXRX_FRM_802_11_MGMT,
3418 ANI_TXDIR_TODS,
3419 7, lim_tx_complete, pFrame, txFlag,
3420 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303421 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303422 psessionEntry->peSessionId, qdf_status));
3423 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003424 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303425 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003426 /* Pkt will be freed up by the callback */
3427 return eSIR_FAILURE;
3428 }
3429
3430 return eSIR_SUCCESS;
3431
3432} /* End lim_send_channel_switch_mgmt_frame. */
3433
Abhishek Singh518323d2015-10-19 17:42:01 +05303434/**
3435 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
3436 * action frame over the air .
3437 * @mac_ctx: pointer to global mac structure
3438 * @peer: Destination mac.
3439 * @mode: channel switch mode
3440 * @new_op_class: new op class
3441 * @new_channel: new channel to switch
3442 * @count: channel switch count
3443 *
3444 * This function is called to send ECSA frame.
3445 *
3446 * Return: success if frame is sent else return failure
3447 */
3448
3449tSirRetStatus
3450lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
3451 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
3452 uint8_t new_channel, uint8_t count, tpPESession session_entry)
3453{
3454 tDot11fext_channel_switch_action_frame frm;
3455 uint8_t *frame;
3456 tpSirMacMgmtHdr mac_hdr;
3457 uint32_t num_bytes, n_payload, status;
3458 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303459 QDF_STATUS qdf_status;
Abhishek Singh518323d2015-10-19 17:42:01 +05303460 uint8_t txFlag = 0;
3461 uint8_t sme_session_id = 0;
3462
3463 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003464 pe_err("Session entry is NULL!!!");
Abhishek Singh518323d2015-10-19 17:42:01 +05303465 return eSIR_FAILURE;
3466 }
3467
3468 sme_session_id = session_entry->smeSessionId;
3469
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303470 qdf_mem_set(&frm, sizeof(frm), 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303471
3472 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
3473 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
3474
3475 frm.ext_chan_switch_ann_action.switch_mode = mode;
3476 frm.ext_chan_switch_ann_action.op_class = new_op_class;
3477 frm.ext_chan_switch_ann_action.new_channel = new_channel;
3478 frm.ext_chan_switch_ann_action.switch_count = count;
3479
3480
3481 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
3482 &frm, &n_payload);
3483 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003484 pe_err("Failed to get packed size for Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303485 status);
3486 /* We'll fall back on the worst case scenario*/
3487 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
3488 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003489 pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)",
Abhishek Singh518323d2015-10-19 17:42:01 +05303490 status);
3491 }
3492
3493 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3494
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303495 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303496 (void **) &frame, (void **) &packet);
3497
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303498 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003499 pe_err("Failed to allocate %d bytes for a Ext Channel Switch",
Abhishek Singh518323d2015-10-19 17:42:01 +05303500 num_bytes);
3501 return eSIR_FAILURE;
3502 }
3503
3504 /* Paranoia*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303505 qdf_mem_set(frame, num_bytes, 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303506
3507 /* Next, we fill out the buffer descriptor */
3508 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3509 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3510 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303511 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Abhishek Singh518323d2015-10-19 17:42:01 +05303512 (uint8_t *) session_entry->bssId,
3513 sizeof(tSirMacAddr));
3514
3515 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
3516 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3517 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003518 pe_err("Failed to pack a Channel Switch 0x%08x", status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303519 cds_packet_free((void *)packet);
3520 return eSIR_FAILURE;
3521 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003522 pe_warn("There were warnings while packing a Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303523 status);
3524 }
3525
3526 if ((SIR_BAND_5_GHZ ==
3527 lim_get_rf_band(session_entry->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05303528 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3529 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303530 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3531 }
3532
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003533 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 +05303534 MAC_ADDR_ARRAY(mac_hdr->da),
3535 frm.ext_chan_switch_ann_action.switch_count,
3536 frm.ext_chan_switch_ann_action.switch_mode,
3537 frm.ext_chan_switch_ann_action.new_channel,
3538 frm.ext_chan_switch_ann_action.op_class);
3539
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303540 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Abhishek Singh518323d2015-10-19 17:42:01 +05303541 session_entry->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303542 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303543 TXRX_FRM_802_11_MGMT,
3544 ANI_TXDIR_TODS,
3545 7,
3546 lim_tx_complete, frame,
3547 txFlag, sme_session_id, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303548 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303549 session_entry->peSessionId, qdf_status));
3550 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003551 pe_err("Failed to send a Ext Channel Switch %X!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303552 qdf_status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303553 /* Pkt will be freed up by the callback */
3554 return eSIR_FAILURE;
3555 }
3556 return eSIR_SUCCESS;
3557} /* End lim_send_extended_chan_switch_action_frame */
3558
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303559
3560/**
3561 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
3562 * sent over the air
3563 *
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303564 * @context: pointer to global mac
3565 * @buf: buffer
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303566 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303567 * @params: tx completion params
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303568 *
3569 * Return: This returns QDF_STATUS
3570 */
3571
3572static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303573 void *context,
3574 qdf_nbuf_t buf,
3575 uint32_t tx_complete,
3576 void *params)
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303577{
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003578 pe_debug("tx_complete: %d", tx_complete);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303579 return QDF_STATUS_SUCCESS;
3580}
3581
3582/**
3583 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
3584 * p2p oper chan change confirm action frame
3585 * @mac_ctx: pointer to global mac structure
3586 * @peer: Destination mac.
3587 * @session_entry: session entry
3588 *
3589 * This function is called to send p2p oper chan change confirm action frame.
3590 *
3591 * Return: success if frame is sent else return failure
3592 */
3593
3594tSirRetStatus
3595lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
3596 tSirMacAddr peer, tpPESession session_entry)
3597{
3598 tDot11fp2p_oper_chan_change_confirm frm;
3599 uint8_t *frame;
3600 tpSirMacMgmtHdr mac_hdr;
3601 uint32_t num_bytes, n_payload, status;
3602 void *packet;
3603 QDF_STATUS qdf_status;
3604 uint8_t tx_flag = 0;
3605 uint8_t sme_session_id = 0;
3606
3607 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003608 pe_err("Session entry is NULL!!!");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303609 return eSIR_FAILURE;
3610 }
3611
3612 sme_session_id = session_entry->smeSessionId;
3613
3614 qdf_mem_set(&frm, sizeof(frm), 0);
3615
3616 frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
3617
3618 qdf_mem_copy(frm.p2p_action_oui.oui_data,
3619 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
3620 frm.p2p_action_subtype.subtype = 0x04;
3621 frm.DialogToken.token = 0x0;
3622
3623 if (session_entry->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003624 pe_debug("Populate HT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303625 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
3626 }
3627
3628 if (session_entry->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003629 pe_debug("Populate VHT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303630 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
3631 populate_dot11f_operating_mode(mac_ctx,
3632 &frm.OperatingMode, session_entry);
3633 }
3634
3635 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
3636 &frm, &n_payload);
3637 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003638 pe_err("Failed to get packed size 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303639 /* We'll fall back on the worst case scenario*/
3640 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
3641 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003642 pe_warn("There were warnings while calculating the packed size (0x%08x)",
3643 status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303644 }
3645
3646 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3647
3648 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
3649 (void **) &frame, (void **) &packet);
3650
3651 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003652 pe_err("Failed to allocate %d bytes", num_bytes);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303653 return eSIR_FAILURE;
3654 }
3655
3656 qdf_mem_set(frame, num_bytes, 0);
3657
3658 /* Next, fill out the buffer descriptor */
3659 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3660 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3661 mac_hdr = (tpSirMacMgmtHdr) frame;
3662 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
3663 (uint8_t *) session_entry->bssId,
3664 sizeof(tSirMacAddr));
3665
3666 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
3667 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3668 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003669 pe_err("Failed to pack 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303670 cds_packet_free((void *)packet);
3671 return eSIR_FAILURE;
3672 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003673 pe_warn("There were warnings while packing 0x%08x",
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303674 status);
3675 }
3676
3677 if ((SIR_BAND_5_GHZ ==
3678 lim_get_rf_band(session_entry->currentOperChannel)) ||
3679 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3680 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
3681 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3682 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003683 pe_debug("Send frame on channel %d to mac "
3684 MAC_ADDRESS_STR, session_entry->currentOperChannel,
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303685 MAC_ADDR_ARRAY(peer));
3686
3687 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3688 session_entry->peSessionId, mac_hdr->fc.subType));
3689
3690 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
3691 (uint16_t)num_bytes,
3692 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3693 7, lim_tx_complete, frame,
3694 lim_oper_chan_change_confirm_tx_complete_cnf,
3695 tx_flag, sme_session_id, false, 0);
3696
3697 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3698 session_entry->peSessionId, qdf_status));
3699 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003700 pe_err("Failed to send status %X!", qdf_status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303701 /* Pkt will be freed up by the callback */
3702 return eSIR_FAILURE;
3703 }
3704 return eSIR_SUCCESS;
3705}
3706
3707
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003708tSirRetStatus
3709lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
3710 tSirMacAddr peer,
3711 uint8_t nMode, tpPESession psessionEntry)
3712{
3713 tDot11fOperatingMode frm;
3714 uint8_t *pFrame;
3715 tpSirMacMgmtHdr pMacHdr;
3716 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
3717 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303718 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003719 uint8_t txFlag = 0;
3720
3721 uint8_t smeSessionId = 0;
3722
3723 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003724 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003725 return eSIR_FAILURE;
3726 }
3727 smeSessionId = psessionEntry->smeSessionId;
3728
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303729 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003730
3731 frm.Category.category = SIR_MAC_ACTION_VHT;
3732 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
3733 frm.OperatingMode.chanWidth = nMode;
3734 frm.OperatingMode.rxNSS = 0;
3735 frm.OperatingMode.rxNSSType = 0;
3736
3737 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
3738 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003739 pe_err("Failed to calculate the packed size for a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003740 nStatus);
3741 /* We'll fall back on the worst case scenario: */
3742 nPayload = sizeof(tDot11fOperatingMode);
3743 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003744 pe_warn("There were warnings while calculating the packed size for a Operating Mode (0x%08x)",
3745 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003746 }
3747
3748 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3749
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303750 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003751 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3752 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303753 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003754 pe_err("Failed to allocate %d bytes for a Operating Mode Report",
3755 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003756 return eSIR_FAILURE;
3757 }
3758 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303759 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003760
3761 /* Next, we fill out the buffer descriptor: */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303762 if (psessionEntry->pePersona == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003763 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3764 SIR_MAC_MGMT_ACTION, peer,
3765 psessionEntry->selfMacAddr);
3766 else
3767 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3768 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
3769 psessionEntry->selfMacAddr);
3770 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303771 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003772 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3773 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
3774 sizeof(tSirMacMgmtHdr),
3775 nPayload, &nPayload);
3776 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003777 pe_err("Failed to pack a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003778 nStatus);
3779 cds_packet_free((void *)pPacket);
3780 return eSIR_FAILURE; /* allocated! */
3781 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003782 pe_warn("There were warnings while packing a Operating Mode (0x%08x)",
3783 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003784 }
3785 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303786 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3787 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003788 ) {
3789 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3790 }
3791
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303792 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003793 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303794 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003795 TXRX_FRM_802_11_MGMT,
3796 ANI_TXDIR_TODS,
3797 7, lim_tx_complete, pFrame, txFlag,
3798 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303799 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303800 psessionEntry->peSessionId, qdf_status));
3801 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003802 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303803 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003804 /* Pkt will be freed up by the callback */
3805 return eSIR_FAILURE;
3806 }
3807
3808 return eSIR_SUCCESS;
3809}
3810
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003811/**
3812 * \brief Send a Neighbor Report Request Action frame
3813 *
3814 *
3815 * \param pMac Pointer to the global MAC structure
3816 *
3817 * \param pNeighborReq Address of a tSirMacNeighborReportReq
3818 *
3819 * \param peer mac address of peer station.
3820 *
3821 * \param psessionEntry address of session entry.
3822 *
3823 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3824 *
3825 *
3826 */
3827
3828tSirRetStatus
3829lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
3830 tpSirMacNeighborReportReq pNeighborReq,
3831 tSirMacAddr peer, tpPESession psessionEntry)
3832{
3833 tSirRetStatus statusCode = eSIR_SUCCESS;
3834 tDot11fNeighborReportRequest frm;
3835 uint8_t *pFrame;
3836 tpSirMacMgmtHdr pMacHdr;
3837 uint32_t nBytes, nPayload, nStatus;
3838 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303839 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003840 uint8_t txFlag = 0;
3841 uint8_t smeSessionId = 0;
3842
3843 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003844 pe_err("(psession == NULL) in Request to send Neighbor Report request action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003845 return eSIR_FAILURE;
3846 }
3847 smeSessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303848 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003849
3850 frm.Category.category = SIR_MAC_ACTION_RRM;
3851 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
3852 frm.DialogToken.token = pNeighborReq->dialogToken;
3853
3854 if (pNeighborReq->ssid_present) {
3855 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
3856 }
3857
3858 nStatus =
3859 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
3860 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003861 pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003862 nStatus);
3863 /* We'll fall back on the worst case scenario: */
3864 nPayload = sizeof(tDot11fNeighborReportRequest);
3865 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003866 pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)",
3867 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003868 }
3869
3870 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3871
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303872 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003873 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3874 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303875 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003876 pe_err("Failed to allocate %d bytes for a Neighbor "
3877 "Report Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003878 return eSIR_FAILURE;
3879 }
3880 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303881 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003882
3883 /* Copy necessary info to BD */
3884 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3885 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
3886
3887 /* Update A3 with the BSSID */
3888 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3889
3890 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3891
3892#ifdef WLAN_FEATURE_11W
3893 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3894#endif
3895
3896 /* Now, we're ready to "pack" the frames */
3897 nStatus = dot11f_pack_neighbor_report_request(pMac,
3898 &frm,
3899 pFrame +
3900 sizeof(tSirMacMgmtHdr),
3901 nPayload, &nPayload);
3902
3903 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003904 pe_err("Failed to pack an Neighbor Report Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905 nStatus);
3906
3907 /* FIXME - Need to convert to tSirRetStatus */
3908 statusCode = eSIR_FAILURE;
3909 goto returnAfterError;
3910 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003911 pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)",
3912 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003913 }
3914
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003915 pe_debug("Sending a Neighbor Report Request to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +05303916 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003917
3918 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303919 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3920 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003921 ) {
3922 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3923 }
3924
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303925 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003926 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303927 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003928 pPacket,
3929 (uint16_t) nBytes,
3930 TXRX_FRM_802_11_MGMT,
3931 ANI_TXDIR_TODS,
3932 7, lim_tx_complete, pFrame, txFlag,
3933 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303934 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303935 psessionEntry->peSessionId, qdf_status));
3936 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003937 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003938 statusCode = eSIR_FAILURE;
3939 /* Pkt will be freed up by the callback */
3940 return statusCode;
3941 } else
3942 return eSIR_SUCCESS;
3943
3944returnAfterError:
3945 cds_packet_free((void *)pPacket);
3946
3947 return statusCode;
3948} /* End lim_send_neighbor_report_request_frame. */
3949
3950/**
3951 * \brief Send a Link Report Action frame
3952 *
3953 *
3954 * \param pMac Pointer to the global MAC structure
3955 *
3956 * \param pLinkReport Address of a tSirMacLinkReport
3957 *
3958 * \param peer mac address of peer station.
3959 *
3960 * \param psessionEntry address of session entry.
3961 *
3962 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3963 *
3964 *
3965 */
3966
3967tSirRetStatus
3968lim_send_link_report_action_frame(tpAniSirGlobal pMac,
3969 tpSirMacLinkReport pLinkReport,
3970 tSirMacAddr peer, tpPESession psessionEntry)
3971{
3972 tSirRetStatus statusCode = eSIR_SUCCESS;
3973 tDot11fLinkMeasurementReport frm;
3974 uint8_t *pFrame;
3975 tpSirMacMgmtHdr pMacHdr;
3976 uint32_t nBytes, nPayload, nStatus;
3977 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303978 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003979 uint8_t txFlag = 0;
3980 uint8_t smeSessionId = 0;
3981
3982 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003983 pe_err("(psession == NULL) in Request to send Link Report action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003984 return eSIR_FAILURE;
3985 }
3986
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303987 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003988
3989 frm.Category.category = SIR_MAC_ACTION_RRM;
3990 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
3991 frm.DialogToken.token = pLinkReport->dialogToken;
3992
3993 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
3994 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
3995 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
3996 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
3997 /* such case this way than changing the frame parser. */
3998 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
3999 frm.TPCEleLen.TPCLen = 2;
4000 frm.TxPower.txPower = pLinkReport->txPower;
4001 frm.LinkMargin.linkMargin = 0;
4002
4003 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4004 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4005 frm.RCPI.rcpi = pLinkReport->rcpi;
4006 frm.RSNI.rsni = pLinkReport->rsni;
4007
4008 nStatus =
4009 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4010 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004011 pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004012 /* We'll fall back on the worst case scenario: */
4013 nPayload = sizeof(tDot11fLinkMeasurementReport);
4014 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004015 pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)",
4016 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004017 }
4018
4019 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4020
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304021 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004022 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4023 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304024 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004025 pe_err("Failed to allocate %d bytes for a Link "
4026 "Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004027 return eSIR_FAILURE;
4028 }
4029 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304030 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004031
4032 /* Copy necessary info to BD */
4033 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4034 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4035
4036 /* Update A3 with the BSSID */
4037 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4038
4039 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4040
4041#ifdef WLAN_FEATURE_11W
4042 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4043#endif
4044
4045 /* Now, we're ready to "pack" the frames */
4046 nStatus = dot11f_pack_link_measurement_report(pMac,
4047 &frm,
4048 pFrame +
4049 sizeof(tSirMacMgmtHdr),
4050 nPayload, &nPayload);
4051
4052 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004053 pe_err("Failed to pack an Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004054
4055 /* FIXME - Need to convert to tSirRetStatus */
4056 statusCode = eSIR_FAILURE;
4057 goto returnAfterError;
4058 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004059 pe_warn("There were warnings while packing Link Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004060 nStatus);
4061 }
4062
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004063 pe_warn("Sending a Link Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004064 lim_print_mac_addr(pMac, peer, LOGW);
4065
4066 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304067 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4068 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004069 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4070 }
4071
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304072 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004073 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304074 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004075 pPacket,
4076 (uint16_t) nBytes,
4077 TXRX_FRM_802_11_MGMT,
4078 ANI_TXDIR_TODS,
4079 7, lim_tx_complete, pFrame, txFlag,
4080 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304081 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304082 psessionEntry->peSessionId, qdf_status));
4083 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004084 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004085 statusCode = eSIR_FAILURE;
4086 /* Pkt will be freed up by the callback */
4087 return statusCode;
4088 } else
4089 return eSIR_SUCCESS;
4090
4091returnAfterError:
4092 cds_packet_free((void *)pPacket);
4093
4094 return statusCode;
4095} /* End lim_send_link_report_action_frame. */
4096
4097/**
4098 * \brief Send a Beacon Report Action frame
4099 *
4100 *
4101 * \param pMac Pointer to the global MAC structure
4102 *
4103 * \param dialog_token dialog token to be used in the action frame.
4104 *
4105 * \param num_report number of reports in pRRMReport.
4106 *
4107 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4108 *
4109 * \param peer mac address of peer station.
4110 *
4111 * \param psessionEntry address of session entry.
4112 *
4113 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4114 *
4115 *
4116 */
4117
4118tSirRetStatus
4119lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4120 uint8_t dialog_token,
4121 uint8_t num_report,
4122 tpSirMacRadioMeasureReport pRRMReport,
4123 tSirMacAddr peer,
4124 tpPESession psessionEntry)
4125{
4126 tSirRetStatus statusCode = eSIR_SUCCESS;
4127 uint8_t *pFrame;
4128 tpSirMacMgmtHdr pMacHdr;
4129 uint32_t nBytes, nPayload, nStatus;
4130 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304131 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004132 uint8_t i;
4133 uint8_t txFlag = 0;
4134 uint8_t smeSessionId = 0;
4135
4136 tDot11fRadioMeasurementReport *frm =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304137 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004138 if (!frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004139 pe_err("Not enough memory to allocate tDot11fRadioMeasurementReport");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004140 return eSIR_MEM_ALLOC_FAILED;
4141 }
4142
4143 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004144 pe_err("(psession == NULL) in Request to send Beacon Report action frame");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304145 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004146 return eSIR_FAILURE;
4147 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004148
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004149 pe_debug("dialog_token %d num_report %d",
Padma, Santhosh Kumar93ec7d22016-12-26 15:58:37 +05304150 dialog_token, num_report);
4151
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004152 frm->Category.category = SIR_MAC_ACTION_RRM;
4153 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4154 frm->DialogToken.token = dialog_token;
4155
4156 frm->num_MeasurementReport =
4157 (num_report >
4158 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4159 num_report;
4160
4161 for (i = 0; i < frm->num_MeasurementReport; i++) {
4162 frm->MeasurementReport[i].type = pRRMReport[i].type;
4163 frm->MeasurementReport[i].token = pRRMReport[i].token;
4164 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4165 switch (pRRMReport[i].type) {
4166 case SIR_MAC_RRM_BEACON_TYPE:
4167 populate_dot11f_beacon_report(pMac,
4168 &frm->MeasurementReport[i],
4169 &pRRMReport[i].report.
4170 beaconReport);
4171 frm->MeasurementReport[i].incapable =
4172 pRRMReport[i].incapable;
4173 frm->MeasurementReport[i].refused =
4174 pRRMReport[i].refused;
4175 frm->MeasurementReport[i].present = 1;
4176 break;
4177 default:
4178 frm->MeasurementReport[i].incapable =
4179 pRRMReport[i].incapable;
4180 frm->MeasurementReport[i].refused =
4181 pRRMReport[i].refused;
4182 frm->MeasurementReport[i].present = 1;
4183 break;
4184 }
4185 }
4186
4187 nStatus =
4188 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4189 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004190 pe_err("Failed to calculate the packed size for a Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004191 nStatus);
4192 /* We'll fall back on the worst case scenario: */
4193 nPayload = sizeof(tDot11fLinkMeasurementReport);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304194 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004195 return eSIR_FAILURE;
4196 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004197 pe_warn("There were warnings while calculating the packed size for a Radio Measure Report (0x%08x)",
4198 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004199 }
4200
4201 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4202
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304203 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004204 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4205 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304206 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004207 pe_err("Failed to allocate %d bytes for a Radio Measure "
4208 "Report", nBytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304209 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004210 return eSIR_FAILURE;
4211 }
4212 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304213 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004214
4215 /* Copy necessary info to BD */
4216 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4217 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4218
4219 /* Update A3 with the BSSID */
4220 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4221
4222 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4223
4224#ifdef WLAN_FEATURE_11W
4225 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4226#endif
4227
4228 /* Now, we're ready to "pack" the frames */
4229 nStatus = dot11f_pack_radio_measurement_report(pMac,
4230 frm,
4231 pFrame +
4232 sizeof(tSirMacMgmtHdr),
4233 nPayload, &nPayload);
4234
4235 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004236 pe_err("Failed to pack an Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004237 nStatus);
4238
4239 /* FIXME - Need to convert to tSirRetStatus */
4240 statusCode = eSIR_FAILURE;
4241 goto returnAfterError;
4242 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004243 pe_warn("There were warnings while packing Radio Measure Report (0x%08x)",
4244 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004245 }
4246
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004247 pe_warn("Sending a Radio Measure Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004248 lim_print_mac_addr(pMac, peer, LOGW);
4249
4250 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304251 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4252 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004253 ) {
4254 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4255 }
4256
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304257 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004258 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304259 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004260 pPacket,
4261 (uint16_t) nBytes,
4262 TXRX_FRM_802_11_MGMT,
4263 ANI_TXDIR_TODS,
4264 7, lim_tx_complete, pFrame, txFlag,
4265 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304266 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304267 psessionEntry->peSessionId, qdf_status));
4268 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004269 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004270 statusCode = eSIR_FAILURE;
4271 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304272 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004273 return statusCode;
4274 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304275 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004276 return eSIR_SUCCESS;
4277 }
4278
4279returnAfterError:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304280 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004281 cds_packet_free((void *)pPacket);
4282 return statusCode;
4283}
4284
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004285#ifdef WLAN_FEATURE_11W
4286/**
4287 * \brief Send SA query request action frame to peer
4288 *
4289 * \sa lim_send_sa_query_request_frame
4290 *
4291 *
4292 * \param pMac The global tpAniSirGlobal object
4293 *
4294 * \param transId Transaction identifier
4295 *
4296 * \param peer The Mac address of the station to which this action frame is addressed
4297 *
4298 * \param psessionEntry The PE session entry
4299 *
4300 * \return eSIR_SUCCESS if setup completes successfully
4301 * eSIR_FAILURE is some problem is encountered
4302 */
4303
4304tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4305 tSirMacAddr peer,
4306 tpPESession psessionEntry)
4307{
4308
4309 tDot11fSaQueryReq frm; /* SA query request action frame */
4310 uint8_t *pFrame;
4311 tSirRetStatus nSirStatus;
4312 tpSirMacMgmtHdr pMacHdr;
4313 uint32_t nBytes, nPayload, nStatus;
4314 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304315 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004316 uint8_t txFlag = 0;
4317 uint8_t smeSessionId = 0;
4318
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304319 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004320 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4321 /* 11w action field is :
4322 action: 0 --> SA Query Request action frame
4323 action: 1 --> SA Query Response action frame */
4324 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4325 /* 11w SA Query Request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304326 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004327
4328 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4329 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004330 pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004331 nStatus);
4332 /* We'll fall back on the worst case scenario: */
4333 nPayload = sizeof(tDot11fSaQueryReq);
4334 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004335 pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)",
4336 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004337 }
4338
4339 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304340 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004341 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304342 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004343 pe_err("Failed to allocate %d bytes for a SA Query Request "
4344 "action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004345 return eSIR_FAILURE;
4346 }
4347 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304348 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004349
4350 /* Copy necessary info to BD */
4351 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4352 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4353
4354 /* Update A3 with the BSSID */
4355 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4356
4357 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4358
4359 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4360 /* in the FC */
4361 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4362
4363 /* Pack 11w SA Query Request frame */
4364 nStatus = dot11f_pack_sa_query_req(pMac,
4365 &frm,
4366 pFrame + sizeof(tSirMacMgmtHdr),
4367 nPayload, &nPayload);
4368
4369 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004370 pe_err("Failed to pack an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004371 nStatus);
4372 /* FIXME - Need to convert to tSirRetStatus */
4373 nSirStatus = eSIR_FAILURE;
4374 goto returnAfterError;
4375 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004376 pe_warn("There were warnings while packing SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004377 nStatus);
4378 }
4379
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004380 pe_debug("Sending an SA Query Request to");
4381 lim_print_mac_addr(pMac, peer, LOGD);
4382 pe_debug("Sending an SA Query Request from ");
4383 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004384
4385 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4386#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304387 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4388 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004389#endif
4390 ) {
4391 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4392 }
4393 smeSessionId = psessionEntry->smeSessionId;
4394
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304395 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004396 pPacket,
4397 (uint16_t) nBytes,
4398 TXRX_FRM_802_11_MGMT,
4399 ANI_TXDIR_TODS,
4400 7, lim_tx_complete, pFrame, txFlag,
4401 smeSessionId, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304402 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004403 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004404 nSirStatus = eSIR_FAILURE;
4405 /* Pkt will be freed up by the callback */
4406 return nSirStatus;
4407 } else {
4408 return eSIR_SUCCESS;
4409 }
4410
4411returnAfterError:
4412 cds_packet_free((void *)pPacket);
4413 return nSirStatus;
4414} /* End lim_send_sa_query_request_frame */
4415
4416/**
4417 * \brief Send SA query response action frame to peer
4418 *
4419 * \sa lim_send_sa_query_response_frame
4420 *
4421 *
4422 * \param pMac The global tpAniSirGlobal object
4423 *
4424 * \param transId Transaction identifier received in SA query request action frame
4425 *
4426 * \param peer The Mac address of the AP to which this action frame is addressed
4427 *
4428 * \param psessionEntry The PE session entry
4429 *
4430 * \return eSIR_SUCCESS if setup completes successfully
4431 * eSIR_FAILURE is some problem is encountered
4432 */
4433
4434tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
4435 uint8_t *transId, tSirMacAddr peer,
4436 tpPESession psessionEntry)
4437{
4438
4439 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
4440 uint8_t *pFrame;
4441 tSirRetStatus nSirStatus;
4442 tpSirMacMgmtHdr pMacHdr;
4443 uint32_t nBytes, nPayload, nStatus;
4444 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304445 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004446 uint8_t txFlag = 0;
4447 uint8_t smeSessionId = 0;
4448
4449 smeSessionId = psessionEntry->smeSessionId;
4450
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304451 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004452 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4453 /*11w action field is :
4454 action: 0 --> SA query request action frame
4455 action: 1 --> SA query response action frame */
4456 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
4457 /*11w SA query response transId is same as
4458 SA query request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304459 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004460
4461 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
4462 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004463 pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004464 nStatus);
4465 /* We'll fall back on the worst case scenario: */
4466 nPayload = sizeof(tDot11fSaQueryRsp);
4467 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004468 pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)",
4469 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004470 }
4471
4472 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304473 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004474 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304475 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004476 pe_err("Failed to allocate %d bytes for a SA query response"
4477 " action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004478 return eSIR_FAILURE;
4479 }
4480 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304481 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004482
4483 /* Copy necessary info to BD */
4484 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4485 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4486
4487 /* Update A3 with the BSSID */
4488 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4489
4490 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4491
4492 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
4493 /* in the FC */
4494 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4495
4496 /* Pack 11w SA query response frame */
4497 nStatus = dot11f_pack_sa_query_rsp(pMac,
4498 &frm,
4499 pFrame + sizeof(tSirMacMgmtHdr),
4500 nPayload, &nPayload);
4501
4502 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004503 pe_err("Failed to pack an SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004504 nStatus);
4505 /* FIXME - Need to convert to tSirRetStatus */
4506 nSirStatus = eSIR_FAILURE;
4507 goto returnAfterError;
4508 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004509 pe_warn("There were warnings while packing SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004510 nStatus);
4511 }
4512
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004513 pe_debug("Sending a SA Query Response to");
Srinivas Girigowdaf936d822017-03-19 23:23:59 -07004514 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004515
4516 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4517#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304518 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4519 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004520#endif
4521 ) {
4522 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4523 }
4524
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304525 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004526 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304527 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004528 pPacket,
4529 (uint16_t) nBytes,
4530 TXRX_FRM_802_11_MGMT,
4531 ANI_TXDIR_TODS,
4532 7, lim_tx_complete, pFrame, txFlag,
4533 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304534 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304535 psessionEntry->peSessionId, qdf_status));
4536 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004537 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004538 nSirStatus = eSIR_FAILURE;
4539 /* Pkt will be freed up by the callback */
4540 return nSirStatus;
4541 } else {
4542 return eSIR_SUCCESS;
4543 }
4544
4545returnAfterError:
4546 cds_packet_free((void *)pPacket);
4547 return nSirStatus;
4548} /* End lim_send_sa_query_response_frame */
4549#endif
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004550
4551/**
4552 * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
4553 * @mac_ctx: mac context
4554 * @peer_mac: Peer MAC address
4555 * @tid: TID for which addba response is being sent
4556 * @session: PE session entry
4557 *
4558 * This function is called when ADDBA request is successful. ADDBA response is
4559 * setup by calling addba_response_setup API and frame is then sent out OTA.
4560 *
4561 * Return: QDF_STATUS
4562 */
4563QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
4564 tSirMacAddr peer_mac, uint16_t tid, tpPESession session)
4565{
4566
4567 tDot11faddba_rsp frm;
4568 uint8_t *frame_ptr;
4569 tpSirMacMgmtHdr mgmt_hdr;
4570 uint32_t num_bytes, payload_size, status;
4571 void *pkt_ptr;
4572 QDF_STATUS qdf_status;
4573 uint8_t tx_flag = 0;
4574 uint8_t sme_sessionid = 0;
4575 uint16_t buff_size, status_code, batimeout;
4576 uint8_t peer_id, dialog_token;
4577 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4578 void *peer, *pdev;
4579
4580 sme_sessionid = session->smeSessionId;
4581
4582 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4583 if (!pdev) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004584 pe_err("pdev is NULL");
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004585 return QDF_STATUS_E_FAILURE;
4586 }
4587
4588 peer = cdp_peer_find_by_addr(soc, pdev, peer_mac, &peer_id);
4589 if (!peer) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004590 pe_err("PEER [%pM] not found", peer_mac);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004591 return QDF_STATUS_E_FAILURE;
4592 }
4593
4594 cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
4595 &status_code, &buff_size, &batimeout);
4596
4597 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4598 frm.Category.category = SIR_MAC_ACTION_BLKACK;
4599 frm.Action.action = SIR_MAC_ADDBA_RSP;
4600
4601 frm.DialogToken.token = dialog_token;
4602 frm.Status.status = status_code;
4603 frm.addba_param_set.tid = tid;
4604 frm.addba_param_set.buff_size = buff_size;
4605 frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE;
4606 frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED;
4607 frm.ba_timeout.timeout = batimeout;
4608
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004609 pe_debug("Sending a ADDBA Response from %pM to %pM",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004610 session->selfMacAddr, peer_mac);
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004611 pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004612 tid, frm.DialogToken.token, frm.Status.status,
4613 frm.addba_param_set.buff_size);
4614
4615 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
4616 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004617 pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004618 status);
4619 /* We'll fall back on the worst case scenario: */
4620 payload_size = sizeof(tDot11faddba_rsp);
4621 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004622 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 -08004623 }
4624
4625 num_bytes = payload_size + sizeof(*mgmt_hdr);
4626 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
4627 (void **)&pkt_ptr);
4628 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004629 pe_err("Failed to allocate %d bytes for a ADDBA response action frame",
4630 num_bytes);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004631 return QDF_STATUS_E_FAILURE;
4632 }
4633 qdf_mem_set(frame_ptr, num_bytes, 0);
4634
4635 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
4636 SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
4637
4638 /* Update A3 with the BSSID */
4639 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
4640 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
4641
4642 /* ADDBA Response is a robust mgmt action frame,
4643 * set the "protect" (aka WEP) bit in the FC
4644 */
4645 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
4646
4647 status = dot11f_pack_addba_rsp(mac_ctx, &frm,
4648 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
4649 &payload_size);
4650
4651 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004652 pe_err("Failed to pack a ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004653 status);
4654 qdf_status = QDF_STATUS_E_FAILURE;
4655 goto error_addba_rsp;
4656 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004657 pe_warn("There were warnings while packing ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004658 status);
4659 }
4660
4661
4662 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
4663#ifdef WLAN_FEATURE_P2P
4664 || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
4665 (session->pePersona == QDF_P2P_GO_MODE)
4666#endif
4667 ) {
4668 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4669 }
4670
4671 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4672 session->peSessionId, mgmt_hdr->fc.subType));
4673 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
4674 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
4675 lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0);
4676 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4677 session->peSessionId, qdf_status));
4678 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004679 pe_err("wma_tx_frame FAILED! Status [%d]",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004680 qdf_status);
4681 qdf_status = QDF_STATUS_E_FAILURE;
4682 /*
4683 * wma_tx_frame free memory in certain cases, free pkt_ptr
4684 * only if not freed already.
4685 */
4686 if (pkt_ptr)
4687 cds_packet_free((void *)pkt_ptr);
4688 return qdf_status;
4689 } else {
4690 return eSIR_SUCCESS;
4691 }
4692
4693error_addba_rsp:
4694 cds_packet_free((void *)pkt_ptr);
4695 return qdf_status;
4696}