blob: 889a561c994abeda083eb9648e959c8d78fd0fa6 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * \file lim_send_management_frames.c
30 *
31 * \brief Code for preparing and sending 802.11 Management frames
32 *
33 *
34 */
35
36#include "sir_api.h"
37#include "ani_global.h"
38#include "sir_mac_prot_def.h"
39#include "cfg_api.h"
40#include "utils_api.h"
41#include "lim_types.h"
42#include "lim_utils.h"
43#include "lim_security_utils.h"
44#include "lim_prop_exts_utils.h"
45#include "dot11f.h"
46#include "lim_sta_hash_api.h"
47#include "sch_api.h"
48#include "lim_send_messages.h"
49#include "lim_assoc_utils.h"
50#include "lim_ft.h"
51#ifdef WLAN_FEATURE_11W
52#include "wni_cfg.h"
53#endif
54
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080055#include "lim_ft_defs.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080056#include "lim_session.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053057#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053058#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059#include "cds_utils.h"
60#include "sme_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#include "rrm_api.h"
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +053062#include "qdf_crypto.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063
64#include "wma_types.h"
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -080065#include <cdp_txrx_cmn.h>
Tushnim Bhattacharyya45ed04f2017-03-15 10:15:05 -070066#include <cdp_txrx_peer_ops.h>
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053067#include "lim_process_fils.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068
69/**
70 *
71 * \brief This function is called to add the sequence number to the
72 * management frames
73 *
74 * \param pMac Pointer to Global MAC structure
75 *
76 * \param pMacHdr Pointer to MAC management header
77 *
78 * The pMacHdr argument points to the MAC management header. The
79 * sequence number stored in the pMac structure will be incremented
80 * and updated to the MAC management header. The start sequence
81 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
82 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
83 * number will roll over.
84 *
85 */
Jeff Johnson38112a32016-10-07 07:30:50 -070086static void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087{
88 if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
89 pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
90 }
91
92 pMac->mgmtSeqNum++;
93
94 pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
95 pMacHdr->seqControl.seqNumHi =
96 ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
97}
98
99/**
100 *
101 * \brief This function is called before sending a p2p action frame
102 * inorder to add sequence numbers to action packets
103 *
104 * \param pMac Pointer to Global MAC structure
105 *
106 * \param pBD Pointer to the frame buffer that needs to be populate
107 *
108 * The pMacHdr argument points to the MAC management header. The
109 * sequence number stored in the pMac structure will be incremented
110 * and updated to the MAC management header. The start sequence
111 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
112 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
113 * number will roll over.
114 *
115 */
116void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
117{
118 tpSirMacMgmtHdr pMacHdr;
119
120 /* / Prepare MAC management header */
121 pMacHdr = (tpSirMacMgmtHdr) (pBD);
122
123 /* Prepare sequence number */
124 lim_add_mgmt_seq_num(pMac, pMacHdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700125 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800126 pMacHdr->seqControl.seqNumLo,
127 pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
128}
129
130/**
131 * lim_populate_mac_header() - Fill in 802.11 header of frame
132 *
133 * @mac_ctx: Pointer to Global MAC structure
134 * @buf: Pointer to the frame buffer that needs to be populate
135 * @type: 802.11 Type of the frame
136 * @sub_type: 802.11 Subtype of the frame
137 * @peer_addr: dst address
138 * @self_mac_addr: local mac address
139 *
140 * This function is called by various LIM modules to prepare the
141 * 802.11 frame MAC header
142 *
143 * The buf argument points to the beginning of the frame buffer to
144 * which - a) The 802.11 MAC header is set b) Following this MAC header
145 * will be the MGMT frame payload The payload itself is populated by the
146 * caller API
147 *
148 * Return: None
149 */
150
151void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
152 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
153 tSirMacAddr self_mac_addr)
154{
155 tpSirMacMgmtHdr mac_hdr;
156
157 /* Prepare MAC management header */
158 mac_hdr = (tpSirMacMgmtHdr) (buf);
159
160 /* Prepare FC */
161 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
162 mac_hdr->fc.type = type;
163 mac_hdr->fc.subType = sub_type;
164
165 /* Prepare Address 1 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530166 qdf_mem_copy((uint8_t *) mac_hdr->da,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800167 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
168
169 /* Prepare Address 2 */
170 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
171
172 /* Prepare Address 3 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530173 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
175
176 /* Prepare sequence number */
177 lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700178 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179 mac_hdr->seqControl.seqNumLo,
180 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
181}
182
183/**
184 * lim_send_probe_req_mgmt_frame() - send probe request management frame
185 * @mac_ctx: Pointer to Global MAC structure
186 * @ssid: SSID to be sent in Probe Request frame
187 * @bssid: BSSID to be sent in Probe Request frame
188 * @channel: Channel # on which the Probe Request is going out
189 * @self_macaddr: self MAC address
190 * @dot11mode: self dotllmode
191 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
192 * frame
193 * @additional_ie: if additional_ielen is non zero, include this field in the
194 * Probe Request frame
195 *
196 * This function is called by various LIM modules to send Probe Request frame
197 * during active scan/learn phase.
198 * Probe request is sent out in the following scenarios:
199 * --heartbeat failure: session needed
200 * --join req: session needed
201 * --foreground scan: no session
202 * --background scan: no session
203 * --sch_beacon_processing: to get EDCA parameters: session needed
204 *
205 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
206 */
207tSirRetStatus
208lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
209 tSirMacSSid *ssid,
210 tSirMacAddr bssid,
211 uint8_t channel,
212 tSirMacAddr self_macaddr,
213 uint32_t dot11mode,
214 uint32_t additional_ielen, uint8_t *additional_ie)
215{
216 tDot11fProbeRequest pr;
217 uint32_t status, bytes, payload;
218 uint8_t *frame;
219 void *packet;
Kapil Guptac03eb072016-08-09 14:01:36 +0530220 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800221 tpPESession pesession;
222 uint8_t sessionid;
223 uint8_t *p2pie = NULL;
224 uint8_t txflag = 0;
225 uint8_t sme_sessionid = 0;
226 bool is_vht_enabled = false;
227 uint8_t txPower;
228 uint16_t addn_ielen = additional_ielen;
Kapil Guptac03eb072016-08-09 14:01:36 +0530229 bool extracted_ext_cap_flag = false;
230 tDot11fIEExtCap extracted_ext_cap;
231 tSirRetStatus sir_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800232
233 /* The probe req should not send 11ac capabilieties if band is 2.4GHz,
234 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
235 * is false and dot11mode is 11ac set it to 11n.
236 */
237 if (channel <= SIR_11B_CHANNEL_END &&
238 (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
239 (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
240 WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
241 dot11mode = WNI_CFG_DOT11_MODE_11N;
242 /*
243 * session context may or may not be present, when probe request needs
244 * to be sent out. Following cases exist:
245 * --heartbeat failure: session needed
246 * --join req: session needed
247 * --foreground scan: no session
248 * --background scan: no session
249 * --sch_beacon_processing: to get EDCA parameters: session needed
250 * If session context does not exist, some IEs will be populated from
251 * CFGs, e.g. Supported and Extended rate set IEs
252 */
253 pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
254
255 if (pesession != NULL)
256 sme_sessionid = pesession->smeSessionId;
257
258 /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
259 /* and then hand it off to 'dot11f_pack_probe_request' (for */
260 /* serialization). We start by zero-initializing the structure: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530261 qdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262
263 /* & delegating to assorted helpers: */
264 populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
265
266 if (addn_ielen && additional_ie)
267 p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
268
269 /*
270 * Don't include 11b rate if it is a P2P serach or probe request is
271 * sent by P2P Client
272 */
273 if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
274 (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
275 mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
276 ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530277 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800278 )
279 ) {
280 /*
281 * In the below API pass channel number > 14, do that it fills
282 * only 11a rates in supported rates
283 */
284 populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
285 pesession);
286 } else {
287 populate_dot11f_supp_rates(mac_ctx, channel,
288 &pr.SuppRates, pesession);
289
290 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
291 populate_dot11f_ext_supp_rates1(mac_ctx, channel,
292 &pr.ExtSuppRates);
293 }
294 }
295
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800296 /*
297 * Table 7-14 in IEEE Std. 802.11k-2008 says
298 * DS params "can" be present in RRM is disabled and "is" present if
299 * RRM is enabled. It should be ok even if we add it into probe req when
300 * RRM is not enabled.
301 */
302 populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
303 /* Call RRM module to get the tx power for management used. */
304 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
305 populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
306
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800307
308 if (pesession != NULL) {
309 pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
310 /* Include HT Capability IE */
311 if (pesession->htCapability)
312 populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
313 } else { /* pesession == NULL */
314 if (IS_DOT11_MODE_HT(dot11mode))
315 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
316 }
317
318 /*
319 * Set channelbonding information as "disabled" when tunned to a
320 * 2.4 GHz channel
321 */
322 if (channel <= SIR_11B_CHANNEL_END) {
323 if (mac_ctx->roam.configParam.channelBondingMode24GHz
324 == PHY_SINGLE_CHANNEL_CENTERED) {
325 pr.HTCaps.supportedChannelWidthSet =
326 eHT_CHANNEL_WIDTH_20MHZ;
327 pr.HTCaps.shortGI40MHz = 0;
328 } else {
329 pr.HTCaps.supportedChannelWidthSet =
330 eHT_CHANNEL_WIDTH_40MHZ;
331 }
332 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333 if (pesession != NULL) {
334 pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
335 /* Include VHT Capability IE */
336 if (pesession->vhtCapability) {
337 populate_dot11f_vht_caps(mac_ctx, pesession,
338 &pr.VHTCaps);
339 is_vht_enabled = true;
340 }
341 } else {
342 if (IS_DOT11_MODE_VHT(dot11mode)) {
343 populate_dot11f_vht_caps(mac_ctx, pesession,
344 &pr.VHTCaps);
345 is_vht_enabled = true;
346 }
347 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800348 if (pesession != NULL)
349 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
350 pesession);
351
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +0530352 if (mac_ctx->roam.configParam.qcn_ie_support)
353 populate_dot11f_qcn_ie(&pr.QCN_IE);
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +0530354
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800355 if (IS_DOT11_MODE_HE(dot11mode) && NULL != pesession)
356 lim_update_session_he_capable(mac_ctx, pesession);
357
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700358 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800359 populate_dot11f_he_caps(mac_ctx, pesession, &pr.vendor_he_cap);
360
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800361 if (addn_ielen) {
Kapil Guptac03eb072016-08-09 14:01:36 +0530362 qdf_mem_zero((uint8_t *)&extracted_ext_cap,
363 sizeof(tDot11fIEExtCap));
364 sir_status = lim_strip_extcap_update_struct(mac_ctx,
365 additional_ie,
366 &addn_ielen,
367 &extracted_ext_cap);
368 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700369 pe_debug("Unable to Stripoff ExtCap IE from Probe Req");
Kapil Guptac03eb072016-08-09 14:01:36 +0530370 } else {
371 struct s_ext_cap *p_ext_cap =
372 (struct s_ext_cap *)
373 extracted_ext_cap.bytes;
374 if (p_ext_cap->interworking_service)
375 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +0800376 extracted_ext_cap.num_bytes =
377 lim_compute_ext_cap_ie_length
378 (&extracted_ext_cap);
Kapil Guptac03eb072016-08-09 14:01:36 +0530379 extracted_ext_cap_flag =
Hu Wang411e0cc2016-10-28 14:56:01 +0800380 (extracted_ext_cap.num_bytes > 0);
Kapil Guptac03eb072016-08-09 14:01:36 +0530381 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800382 }
383
Hu Wang411e0cc2016-10-28 14:56:01 +0800384 /*
385 * Extcap IE now support variable length, merge Extcap IE from addn_ie
386 * may change the frame size. Therefore, MUST merge ExtCap IE before
387 * dot11f get packed payload size.
388 */
389 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800390 lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800391
392 /* That's it-- now we pack it. First, how much space are we going to */
393 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
394 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700395 pe_err("Failed to calculate the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800396 status);
397 /* We'll fall back on the worst case scenario: */
398 payload = sizeof(tDot11fProbeRequest);
399 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700400 pe_warn("There were warnings while calculating the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800401 status);
402 }
403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
405
406 /* Ok-- try to allocate some memory: */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530407 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800408 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530409 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700410 pe_err("Failed to allocate %d bytes for a Probe Request", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800411 return eSIR_MEM_ALLOC_FAILED;
412 }
413 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530414 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415
416 /* Next, we fill out the buffer descriptor: */
417 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
418 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
419
420 /* That done, pack the Probe Request: */
421 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
422 sizeof(tSirMacMgmtHdr),
423 payload, &payload);
424 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700425 pe_err("Failed to pack a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426 cds_packet_free((void *)packet);
427 return eSIR_FAILURE; /* allocated! */
428 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700429 pe_warn("There were warnings while packing a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800430 }
431 /* Append any AddIE if present. */
432 if (addn_ielen) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530433 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800434 additional_ie, addn_ielen);
435 payload += addn_ielen;
436 }
437
438 /* If this probe request is sent during P2P Search State, then we need
439 * to send it at OFDM rate.
440 */
441 if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
442 || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
443 mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
444 /*
445 * For unicast probe req mgmt from Join function we don't set
446 * above variables. So we need to add one more check whether it
447 * is pePersona is P2P_CLIENT or not
448 */
449 || ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530450 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 ) {
452 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
453 }
454
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530455 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800456 wma_tx_frame(mac_ctx, packet,
457 (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
458 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
459 lim_tx_complete, frame, txflag, sme_sessionid,
460 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530461 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700462 pe_err("could not send Probe Request frame!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800463 /* Pkt will be freed up by the callback */
464 return eSIR_FAILURE;
465 }
466
467 return eSIR_SUCCESS;
468} /* End lim_send_probe_req_mgmt_frame. */
469
Jeff Johnson38112a32016-10-07 07:30:50 -0700470static tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800471 uint8_t *addIE, uint16_t *addnIELen,
472 uint8_t probeReqP2pIe)
473{
474 /* If Probe request doesn't have P2P IE, then take out P2P IE
475 from additional IE */
476 if (!probeReqP2pIe) {
477 uint8_t *tempbuf = NULL;
478 uint16_t tempLen = 0;
479 int left = *addnIELen;
480 uint8_t *ptr = addIE;
481 uint8_t elem_id, elem_len;
482
483 if (NULL == addIE) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700484 pe_err("NULL addIE pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800485 return eSIR_FAILURE;
486 }
487
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530488 tempbuf = qdf_mem_malloc(left);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489 if (NULL == tempbuf) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700490 pe_err("Unable to allocate memory to store addn IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800491 return eSIR_MEM_ALLOC_FAILED;
492 }
493
494 while (left >= 2) {
495 elem_id = ptr[0];
496 elem_len = ptr[1];
497 left -= 2;
498 if (elem_len > left) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700499 pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500 elem_id, elem_len, left);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530501 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800502 return eSIR_FAILURE;
503 }
504 if (!((SIR_MAC_EID_VENDOR == elem_id) &&
505 (memcmp
506 (&ptr[2], SIR_MAC_P2P_OUI,
507 SIR_MAC_P2P_OUI_SIZE) == 0))) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530508 qdf_mem_copy(tempbuf + tempLen, &ptr[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800509 elem_len + 2);
510 tempLen += (elem_len + 2);
511 }
512 left -= elem_len;
513 ptr += (elem_len + 2);
514 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530515 qdf_mem_copy(addIE, tempbuf, tempLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 *addnIELen = tempLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530517 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518 }
519 return eSIR_SUCCESS;
520}
521
522/**
523 * lim_send_probe_rsp_mgmt_frame() - Send probe response
524 *
525 * @mac_ctx: Handle for mac context
526 * @peer_macaddr: Mac address of requesting peer
527 * @ssid: SSID for response
528 * @n_staid: Station ID, currently unused.
529 * @pe_session: PE session id
530 * @keepalive: Keep alive flag. Currently unused.
531 * @preq_p2pie: P2P IE in incoming probe request
532 *
533 * Builds and sends probe response frame to the requesting peer
534 *
535 * Return: void
536 */
537
538void
539lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
540 tSirMacAddr peer_macaddr,
541 tpAniSSID ssid,
542 short n_staid,
543 uint8_t keepalive,
544 tpPESession pe_session, uint8_t preq_p2pie)
545{
546 tDot11fProbeResponse *frm;
547 tSirRetStatus sir_status;
Hu Wang411e0cc2016-10-28 14:56:01 +0800548 uint32_t cfg, payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800549 tpSirMacMgmtHdr mac_hdr;
550 uint8_t *frame;
Arif Hussainfbf50682016-06-15 12:57:43 -0700551 void *packet = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530552 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 uint32_t addn_ie_present = false;
554
555 uint16_t addn_ie_len = 0;
556 uint32_t wps_ap = 0, tmp;
557 uint8_t tx_flag = 0;
558 uint8_t *add_ie = NULL;
559 uint8_t *p2p_ie = NULL;
560 uint8_t noalen = 0;
561 uint8_t total_noalen = 0;
562 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
563 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
564 uint8_t sme_sessionid = 0;
565 bool is_vht_enabled = false;
Padma, Santhosh Kumar92234472017-04-19 18:20:02 +0530566 tDot11fIEExtCap extracted_ext_cap = {0};
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530567 bool extracted_ext_cap_flag = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800568
569 /* We don't answer requests in this case*/
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700570 if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 return;
572
573 if (NULL == pe_session)
574 return;
575
576 /*
577 * In case when cac timer is running for this SAP session then
578 * avoid sending probe rsp out. It is violation of dfs specification.
579 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530580 if (((pe_session->pePersona == QDF_SAP_MODE) ||
581 (pe_session->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530583 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 FL("CAC timer is running, probe response dropped"));
585 return;
586 }
587 sme_sessionid = pe_session->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530588 frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700590 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800591 return;
592 }
593
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594 /*
595 * Fill out 'frm', after which we'll just hand the struct off to
596 * 'dot11f_pack_probe_response'.
597 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530598 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599
600 /*
601 * Timestamp to be updated by TFP, below.
602 *
603 * Beacon Interval:
604 */
605 if (LIM_IS_AP_ROLE(pe_session)) {
606 frm->BeaconInterval.interval =
607 mac_ctx->sch.schObject.gSchBeaconInterval;
608 } else {
609 sir_status = wlan_cfg_get_int(mac_ctx,
610 WNI_CFG_BEACON_INTERVAL, &cfg);
611 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700612 pe_err("Failed to get WNI_CFG_BEACON_INTERVAL (%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613 sir_status);
614 goto err_ret;
615 }
616 frm->BeaconInterval.interval = (uint16_t) cfg;
617 }
618
619 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
620 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
621 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
622 &frm->SuppRates, pe_session);
623
624 populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
625 pe_session->currentOperChannel);
626 populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
627
628 if (LIM_IS_AP_ROLE(pe_session)) {
629 if (pe_session->wps_state != SAP_WPS_DISABLED)
630 populate_dot11f_probe_res_wpsi_es(mac_ctx,
631 &frm->WscProbeRes,
632 pe_session);
633 } else {
634 if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
635 &tmp) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700636 pe_err("Failed to cfg get id %d", WNI_CFG_WPS_ENABLE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800637
638 wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
639
640 if (wps_ap)
641 populate_dot11f_wsc_in_probe_res(mac_ctx,
642 &frm->WscProbeRes);
643
644 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
645 eLIM_WSC_ENROLL_BEGIN) {
646 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
647 &frm->WscProbeRes);
648 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
649 eLIM_WSC_ENROLL_IN_PROGRESS;
650 }
651
652 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
653 eLIM_WSC_ENROLL_END) {
654 de_populate_dot11f_wsc_registrar_info_in_probe_res(
655 mac_ctx, &frm->WscProbeRes);
656 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
657 eLIM_WSC_ENROLL_NOOP;
658 }
659 }
660
661 populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
662 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
663
664 if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
665 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
666
667 populate_dot11f_ext_supp_rates(mac_ctx,
668 POPULATE_DOT11F_RATES_OPERATIONAL,
669 &frm->ExtSuppRates, pe_session);
670
671 /* Populate HT IEs, when operating in 11n */
672 if (pe_session->htCapability) {
673 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
674 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
675 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676 if (pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700677 pe_debug("Populate VHT IE in Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
679 populate_dot11f_vht_operation(mac_ctx, pe_session,
680 &frm->VHTOperation);
681 /*
682 * we do not support multi users yet.
683 * populate_dot11f_vht_ext_bss_load( mac_ctx,
684 * &frm.VHTExtBssLoad );
685 */
686 is_vht_enabled = true;
687 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800688
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800689 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700690 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800691 populate_dot11f_he_caps(mac_ctx, pe_session,
692 &frm->vendor_he_cap);
693 populate_dot11f_he_operation(mac_ctx, pe_session,
694 &frm->vendor_he_op);
695 }
696
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
698 pe_session);
699
700 if (pe_session->pLimStartBssReq) {
701 populate_dot11f_wpa(mac_ctx,
702 &(pe_session->pLimStartBssReq->rsnIE),
703 &frm->WPA);
704 populate_dot11f_rsn_opaque(mac_ctx,
705 &(pe_session->pLimStartBssReq->rsnIE),
706 &frm->RSNOpaque);
707 }
708
709 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
710 &frm->WMMCaps, pe_session);
711
712#if defined(FEATURE_WLAN_WAPI)
713 if (pe_session->pLimStartBssReq)
714 populate_dot11f_wapi(mac_ctx,
715 &(pe_session->pLimStartBssReq->rsnIE),
716 &frm->WAPI);
717#endif /* defined(FEATURE_WLAN_WAPI) */
718
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719 if (mac_ctx->lim.gpLimRemainOnChanReq)
720 bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
721 sizeof(tSirRemainOnChnReq));
722 else
723 /*
724 * Only use CFG for non-listen mode. This CFG is not working for
725 * concurrency. In listening mode, probe rsp IEs is passed in
726 * the message from SME to PE.
727 */
728 addn_ie_present =
729 (pe_session->addIeParams.probeRespDataLen != 0);
730
731 if (addn_ie_present) {
732
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530733 add_ie = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800734 pe_session->addIeParams.probeRespDataLen);
735 if (NULL == add_ie) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700736 pe_err("add_ie allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800737 goto err_ret;
738 }
739
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530740 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800741 pe_session->addIeParams.probeRespData_buff,
742 pe_session->addIeParams.probeRespDataLen);
743 addn_ie_len = pe_session->addIeParams.probeRespDataLen;
744
745 if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
746 add_ie, &addn_ie_len, preq_p2pie)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700747 pe_err("Unable to get addn_ie");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800748 goto err_ret;
749 }
750
751 sir_status = lim_strip_extcap_update_struct(mac_ctx,
752 add_ie, &addn_ie_len,
753 &extracted_ext_cap);
754 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700755 pe_debug("Unable to strip off ExtCap IE");
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530756 } else {
757 extracted_ext_cap_flag = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758 }
759
760 bytes = bytes + addn_ie_len;
761
762 if (preq_p2pie)
763 p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
764 addn_ie_len);
765
766 if (p2p_ie != NULL) {
767 /* get NoA attribute stream P2P IE */
768 noalen = lim_get_noa_attr_stream(mac_ctx,
769 noa_stream, pe_session);
770 if (noalen != 0) {
771 total_noalen =
772 lim_build_p2p_ie(mac_ctx, &noa_ie[0],
773 &noa_stream[0], noalen);
774 bytes = bytes + total_noalen;
775 }
776 }
777 }
778
Hu Wang411e0cc2016-10-28 14:56:01 +0800779 /*
780 * Extcap IE now support variable length, merge Extcap IE from addn_ie
781 * may change the frame size. Therefore, MUST merge ExtCap IE before
782 * dot11f get packed payload size.
783 */
784 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800785 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
786 true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800787
788 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
789 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700790 pe_err("Probe Response size error (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800791 status);
792 /* We'll fall back on the worst case scenario: */
793 payload = sizeof(tDot11fProbeResponse);
794 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700795 pe_warn("Probe Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800796 status);
797 }
798
799 bytes += payload + sizeof(tSirMacMgmtHdr);
800
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530801 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800802 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530803 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700804 pe_err("Probe Response allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805 goto err_ret;
806 }
807 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530808 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800809
810 /* Next, we fill out the buffer descriptor: */
811 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
812 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
813 pe_session->selfMacAddr);
814
815 mac_hdr = (tpSirMacMgmtHdr) frame;
816
817 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
818
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800819 /* That done, pack the Probe Response: */
820 status =
821 dot11f_pack_probe_response(mac_ctx, frm,
822 frame + sizeof(tSirMacMgmtHdr),
823 payload, &payload);
824 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700825 pe_err("Probe Response pack failure (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 status);
827 goto err_ret;
828 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700829 pe_warn("Probe Response pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830 }
831
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700832 pe_debug("Sending Probe Response frame to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +0530833 lim_print_mac_addr(mac_ctx, peer_macaddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835 if (mac_ctx->lim.gpLimRemainOnChanReq)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530836 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800837 mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
838 (mac_ctx->lim.gpLimRemainOnChanReq->length -
839 sizeof(tSirRemainOnChnReq)));
840
841 if (addn_ie_present)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530842 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800843 &add_ie[0], addn_ie_len);
844
845 if (noalen != 0) {
846 if (total_noalen >
847 (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700848 pe_err("Not able to insert NoA, total len=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800849 total_noalen);
850 goto err_ret;
851 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530852 qdf_mem_copy(&frame[bytes - (total_noalen)],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800853 &noa_ie[0], total_noalen);
854 }
855 }
856
857 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +0530858 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
859 (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800860 )
861 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
862
863 /* Queue Probe Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530864 qdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865 (uint16_t) bytes,
866 TXRX_FRM_802_11_MGMT,
867 ANI_TXDIR_TODS,
868 7, lim_tx_complete, frame, tx_flag,
869 sme_sessionid, 0);
870
871 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530872 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700873 pe_err("Could not send Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800874
875 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530876 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530878 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800879 return;
880
881err_ret:
882 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530883 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 if (frm != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530885 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 if (packet != NULL)
887 cds_packet_free((void *)packet);
888 return;
889
890} /* End lim_send_probe_rsp_mgmt_frame. */
891
892void
893lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
894 tSirMacAddr peerMacAddr,
895 tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
896{
897 uint16_t i;
898 uint8_t *pFrame;
899 tDot11fAddTSRequest AddTSReq;
900 tDot11fWMMAddTSRequest WMMAddTSReq;
901 uint32_t nPayload, nBytes, nStatus;
902 tpSirMacMgmtHdr pMacHdr;
903 void *pPacket;
904#ifdef FEATURE_WLAN_ESE
905 uint32_t phyMode;
906#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530907 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800908 uint8_t txFlag = 0;
909 uint8_t smeSessionId = 0;
910
911 if (NULL == psessionEntry) {
912 return;
913 }
914
915 smeSessionId = psessionEntry->smeSessionId;
916
917 if (!pAddTS->wmeTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530918 qdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800919
920 AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
921 AddTSReq.DialogToken.token = pAddTS->dialogToken;
922 AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
923 if (pAddTS->lleTspecPresent) {
924 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
925 } else {
926 populate_dot11f_wmmtspec(&pAddTS->tspec,
927 &AddTSReq.WMMTSPEC);
928 }
929
930 if (pAddTS->lleTspecPresent) {
931 AddTSReq.num_WMMTCLAS = 0;
932 AddTSReq.num_TCLAS = pAddTS->numTclas;
933 for (i = 0; i < pAddTS->numTclas; ++i) {
934 populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
935 &AddTSReq.TCLAS[i]);
936 }
937 } else {
938 AddTSReq.num_TCLAS = 0;
939 AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
940 for (i = 0; i < pAddTS->numTclas; ++i) {
941 populate_dot11f_wmmtclas(pMac,
942 &pAddTS->tclasInfo[i],
943 &AddTSReq.WMMTCLAS[i]);
944 }
945 }
946
947 if (pAddTS->tclasProcPresent) {
948 if (pAddTS->lleTspecPresent) {
949 AddTSReq.TCLASSPROC.processing =
950 pAddTS->tclasProc;
951 AddTSReq.TCLASSPROC.present = 1;
952 } else {
953 AddTSReq.WMMTCLASPROC.version = 1;
954 AddTSReq.WMMTCLASPROC.processing =
955 pAddTS->tclasProc;
956 AddTSReq.WMMTCLASPROC.present = 1;
957 }
958 }
959
960 nStatus =
961 dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
962 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700963 pe_err("Failed to calculate the packed size for an Add TS Request (0x%08x)",
964 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800965 /* We'll fall back on the worst case scenario: */
966 nPayload = sizeof(tDot11fAddTSRequest);
967 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700968 pe_warn("There were warnings while calculating the packed size for an Add TS Request (0x%08x)",
969 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800970 }
971 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530972 qdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800973
974 WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
975 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
976 WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
977
978 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
979 WMMAddTSReq.StatusCode.statusCode = 0;
980
981 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
982#ifdef FEATURE_WLAN_ESE
983 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
984
985 if (phyMode == WNI_CFG_PHY_MODE_11G
986 || phyMode == WNI_CFG_PHY_MODE_11A) {
987 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
988 } else {
989 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
990 }
991 populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
992 &WMMAddTSReq.ESETrafStrmRateSet,
993 sizeof(uint8_t));
994#endif
995 /* fillWmeTspecIE */
996
997 nStatus =
998 dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
999 &nPayload);
1000 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001001 pe_err("Failed to calculate the packed size for a WMM Add TS Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001002 nStatus);
1003 /* We'll fall back on the worst case scenario: */
1004 nPayload = sizeof(tDot11fAddTSRequest);
1005 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001006 pe_warn("There were warnings while calculating the packed size for a WMM Add TS Request (0x%08x)",
1007 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001008 }
1009 }
1010
1011 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1012
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301013 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001014 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301015 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001016 pe_err("Failed to allocate %d bytes for an Add TS Request",
1017 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001018 return;
1019 }
1020 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301021 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001022
1023 /* Next, we fill out the buffer descriptor: */
1024 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1025 SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
1026 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1027
1028 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1029
1030#ifdef WLAN_FEATURE_11W
1031 lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
1032#endif
1033
1034 /* That done, pack the struct: */
1035 if (!pAddTS->wmeTspecPresent) {
1036 nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
1037 pFrame +
1038 sizeof(tSirMacMgmtHdr),
1039 nPayload, &nPayload);
1040 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001041 pe_err("Failed to pack an Add TS Request "
1042 "(0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043 cds_packet_free((void *)pPacket);
1044 return; /* allocated! */
1045 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001046 pe_warn("There were warnings while packing an Add TS Request (0x%08x)",
1047 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048 }
1049 } else {
1050 nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
1051 pFrame +
1052 sizeof(tSirMacMgmtHdr),
1053 nPayload, &nPayload);
1054 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001055 pe_err("Failed to pack a WMM Add TS Request (0x%08x)",
1056 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057 cds_packet_free((void *)pPacket);
1058 return; /* allocated! */
1059 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001060 pe_warn("There were warnings while packing a WMM Add TS Request (0x%08x)",
1061 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001062 }
1063 }
1064
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001065 pe_debug("Sending an Add TS Request frame to");
1066 lim_print_mac_addr(pMac, peerMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001067
1068 if ((SIR_BAND_5_GHZ ==
1069 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301070 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1071 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001072 ) {
1073 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1074 }
1075
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301076 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001077 psessionEntry->peSessionId, pMacHdr->fc.subType));
1078
1079 /* Queue Addts Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301080 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001081 TXRX_FRM_802_11_MGMT,
1082 ANI_TXDIR_TODS,
1083 7, lim_tx_complete, pFrame, txFlag,
1084 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301085 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301086 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001087
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001088 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1089 pe_err("Could not send an Add TS Request (%X",
1090 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001091} /* End lim_send_addts_req_action_frame. */
1092
1093/**
1094 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
1095 * @mac_ctx: Handle for mac context
1096 * @status_code: Status code for assoc response frame
1097 * @aid: Association ID
1098 * @peer_addr: Mac address of requesting peer
1099 * @subtype: Assoc/Reassoc
1100 * @sta: Pointer to station node
1101 * @pe_session: PE session id.
1102 *
1103 * Builds and sends association response frame to the requesting peer.
1104 *
1105 * Return: void
1106 */
1107
1108void
1109lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
1110 uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
1111 uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
1112{
1113 static tDot11fAssocResponse frm;
1114 uint8_t *frame;
1115 tpSirMacMgmtHdr mac_hdr;
1116 tSirRetStatus sir_status;
1117 uint8_t lle_mode = 0, addts;
1118 tHalBitVal qos_mode, wme_mode;
Hu Wang411e0cc2016-10-28 14:56:01 +08001119 uint32_t payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001120 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301121 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001122 tUpdateBeaconParams beacon_params;
1123 uint8_t tx_flag = 0;
1124 uint32_t addn_ie_len = 0;
1125 uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
1126 tpSirAssocReq assoc_req = NULL;
1127 uint8_t sme_session = 0;
1128 bool is_vht = false;
1129 uint16_t stripoff_len = 0;
1130 tDot11fIEExtCap extracted_ext_cap;
1131 bool extracted_flag = false;
1132#ifdef WLAN_FEATURE_11W
1133 uint32_t retry_int;
1134 uint32_t max_retries;
1135#endif
1136
1137 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001138 pe_err("pe_session is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001139 return;
1140 }
1141
1142 sme_session = pe_session->smeSessionId;
1143
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301144 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001145
1146 limGetQosMode(pe_session, &qos_mode);
1147 limGetWmeMode(pe_session, &wme_mode);
1148
1149 /*
1150 * An Add TS IE is added only if the AP supports it and
1151 * the requesting STA sent a traffic spec.
1152 */
1153 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
1154
1155 frm.Status.status = status_code;
1156
1157 frm.AID.associd = aid | LIM_AID_MASK;
1158
1159 if (NULL == sta) {
1160 populate_dot11f_supp_rates(mac_ctx,
1161 POPULATE_DOT11F_RATES_OPERATIONAL,
1162 &frm.SuppRates, pe_session);
1163 populate_dot11f_ext_supp_rates(mac_ctx,
1164 POPULATE_DOT11F_RATES_OPERATIONAL,
1165 &frm.ExtSuppRates, pe_session);
1166 } else {
1167 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
1168 &frm.ExtSuppRates,
1169 sta->supportedRates.llbRates,
1170 sta->supportedRates.llaRates);
1171 }
1172
1173 if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
1174 eSIR_SUCCESS == status_code) {
1175 assoc_req = (tpSirAssocReq)
1176 pe_session->parsedAssocReq[sta->assocId];
1177 /*
1178 * populate P2P IE in AssocRsp when assocReq from the peer
1179 * includes P2P IE
1180 */
1181 if (assoc_req != NULL && assoc_req->addIEPresent)
1182 populate_dot11_assoc_res_p2p_ie(mac_ctx,
1183 &frm.P2PAssocRes,
1184 assoc_req);
1185 }
1186
1187 if (NULL != sta) {
1188 if (eHAL_SET == qos_mode) {
1189 if (sta->lleEnabled) {
1190 lle_mode = 1;
1191 populate_dot11f_edca_param_set(mac_ctx,
1192 &frm.EDCAParamSet, pe_session);
1193 }
1194 }
1195
1196 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
1197 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
1198 pe_session);
1199
1200 if (sta->wsmEnabled)
1201 populate_dot11f_wmm_caps(&frm.WMMCaps);
1202 }
1203
1204 if (sta->mlmStaContext.htCapability &&
1205 pe_session->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001206 pe_debug("Populate HT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 populate_dot11f_ht_caps(mac_ctx, pe_session,
1208 &frm.HTCaps);
Krunal Sonief3294b2015-06-12 15:12:19 -07001209 /*
1210 * Check the STA capability and
1211 * update the HTCaps accordingly
1212 */
1213 frm.HTCaps.supportedChannelWidthSet = (
1214 sta->htSupportedChannelWidthSet <
1215 pe_session->htSupportedChannelWidthSet) ?
1216 sta->htSupportedChannelWidthSet :
1217 pe_session->htSupportedChannelWidthSet;
1218 if (!frm.HTCaps.supportedChannelWidthSet)
1219 frm.HTCaps.shortGI40MHz = 0;
1220
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1222 pe_session);
1223 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001224 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 +05301225 frm.HTCaps.supportedChannelWidthSet,
1226 frm.HTCaps.mimoPowerSave,
1227 frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
1228 frm.HTCaps.shortGI40MHz,
1229 frm.HTCaps.dsssCckMode40MHz,
1230 frm.HTCaps.maxRxAMPDUFactor);
1231
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001232 if (sta->mlmStaContext.vhtCapability &&
1233 pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001234 pe_debug("Populate VHT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001235 populate_dot11f_vht_caps(mac_ctx, pe_session,
1236 &frm.VHTCaps);
1237 populate_dot11f_vht_operation(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301238 &frm.VHTOperation);
1239 is_vht = true;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301240 } else {
Tushnim Bhattacharyya3d17def2017-06-19 11:13:43 -07001241 /*
1242 * 2G-AS platform: SAP associates with HT (11n)clients
1243 * as 2x1 in 2G and 2X2 in 5G
1244 * Non-2G-AS platform: SAP associates with HT (11n)
1245 * clients as 2X2 in 2G and 5G
1246 * 5G-AS: DonÂ’t care
1247 */
1248 if (!policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc) &&
1249 frm.HTCaps.present && mac_ctx->hw_dbs_capable &&
1250 mac_ctx->lteCoexAntShare &&
1251 IS_24G_CH(pe_session->currentOperChannel))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301252 frm.HTCaps.supportedMCSSet[1] = 0;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301253 }
1254 if (pe_session->vhtCapability &&
1255 pe_session->vendor_vht_sap &&
1256 (assoc_req != NULL) &&
1257 assoc_req->vendor_vht_ie.VHTCaps.present) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001258 pe_debug("Populate Vendor VHT IEs in Assoc Rsponse");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301259 frm.vendor_vht_ie.present = 1;
1260 frm.vendor_vht_ie.type =
1261 pe_session->vendor_specific_vht_ie_type;
1262 frm.vendor_vht_ie.sub_type =
1263 pe_session->vendor_specific_vht_ie_sub_type;
1264
1265 frm.vendor_vht_ie.VHTCaps.present = 1;
1266 populate_dot11f_vht_caps(mac_ctx, pe_session,
1267 &frm.vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 is_vht = true;
1269 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001270 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1271 pe_session);
1272
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001273 if (lim_is_sta_he_capable(sta) &&
1274 lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001275 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001276 populate_dot11f_he_caps(mac_ctx, pe_session,
1277 &frm.vendor_he_cap);
1278 populate_dot11f_he_operation(mac_ctx, pe_session,
1279 &frm.vendor_he_op);
1280 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001281#ifdef WLAN_FEATURE_11W
1282 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1283 if (wlan_cfg_get_int
1284 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1285 &max_retries) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001286 pe_err("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001287 else if (wlan_cfg_get_int
1288 (mac_ctx,
1289 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1290 &retry_int) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001291 pe_err("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292 else
1293 populate_dot11f_timeout_interval(mac_ctx,
1294 &frm.TimeoutInterval,
1295 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1296 (max_retries -
1297 sta->pmfSaQueryRetryCount)
1298 * retry_int);
1299 }
1300#endif
Arif Hussain0c816922017-04-06 15:04:44 -07001301
1302 if (LIM_IS_AP_ROLE(pe_session) && sta->non_ecsa_capable)
1303 pe_session->lim_non_ecsa_cap_num++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001304 }
1305
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301306 qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001307
1308 if (LIM_IS_AP_ROLE(pe_session) &&
1309 (pe_session->gLimProtectionControl !=
1310 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1311 lim_decide_ap_protection(mac_ctx, peer_addr,
1312 &beacon_params, pe_session);
1313
1314 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1315 pe_session);
1316 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1317 pe_session);
1318
1319 /*
1320 * Populate Do11capabilities after updating session with
1321 * Assos req details
1322 */
1323 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1324
1325 beacon_params.bssIdx = pe_session->bssIdx;
1326
1327 /* Send message to HAL about beacon parameter change. */
1328 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1329 && beacon_params.paramChangeBitmap) {
1330 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1331 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1332 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333
1334 if (assoc_req != NULL) {
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001335 addn_ie_len = pe_session->addIeParams.assocRespDataLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336
1337 /* Nonzero length indicates Assoc rsp IE available */
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001338 if (addn_ie_len > 0 &&
1339 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
1340 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301341 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 pe_session->addIeParams.assocRespData_buff,
1343 pe_session->addIeParams.assocRespDataLen);
1344
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301345 qdf_mem_set((uint8_t *) &extracted_ext_cap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346 sizeof(extracted_ext_cap), 0);
1347
1348 stripoff_len = addn_ie_len;
1349 sir_status =
1350 lim_strip_extcap_update_struct
1351 (mac_ctx, &add_ie[0], &stripoff_len,
1352 &extracted_ext_cap);
1353 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001354 pe_debug("strip off extcap IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355 } else {
1356 addn_ie_len = stripoff_len;
1357 extracted_flag = true;
1358 }
1359 bytes = bytes + addn_ie_len;
1360 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001361 pe_debug("addn_ie_len: %d for Assoc Resp: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362 addn_ie_len, assoc_req->addIEPresent);
1363 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001364
1365 /*
1366 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1367 * may change the frame size. Therefore, MUST merge ExtCap IE before
1368 * dot11f get packed payload size.
1369 */
1370 if (extracted_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001371 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
1372 true);
Hu Wang411e0cc2016-10-28 14:56:01 +08001373
1374 /* Allocate a buffer for this frame: */
1375 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1376 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001377 pe_err("get Association Response size failure (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001378 status);
1379 return;
1380 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001381 pe_warn("get Association Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001382 status);
1383 }
1384
1385 bytes += sizeof(tSirMacMgmtHdr) + payload;
1386
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301387 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301389 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001390 pe_err("cds_packet_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391 return;
1392 }
1393 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301394 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001395
1396 /* Next, we fill out the buffer descriptor: */
1397 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1398 (LIM_ASSOC == subtype) ?
1399 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1400 peer_addr,
1401 pe_session->selfMacAddr);
1402 mac_hdr = (tpSirMacMgmtHdr) frame;
1403
1404 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1405
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001406 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1407 frame + sizeof(tSirMacMgmtHdr),
1408 payload, &payload);
1409 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001410 pe_err("Association Response pack failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 status);
1412 cds_packet_free((void *)packet);
1413 return;
1414 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001415 pe_warn("Association Response pack warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001416 status);
1417 }
1418
1419 if (subtype == LIM_ASSOC)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001420 pe_debug("*** Sending Assoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001421 status_code, aid);
1422 else
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001423 pe_debug("*** Sending ReAssoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001424 status_code, aid);
1425
1426 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1427
1428 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301429 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001430 &add_ie[0], addn_ie_len);
1431
1432 if ((SIR_BAND_5_GHZ ==
1433 lim_get_rf_band(pe_session->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05301434 (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
1435 (pe_session->pePersona == QDF_P2P_GO_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1437
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301438 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439 pe_session->peSessionId, mac_hdr->fc.subType));
1440 /* Queue Association Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301441 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001442 TXRX_FRM_802_11_MGMT,
1443 ANI_TXDIR_TODS,
1444 7, lim_tx_complete, frame, tx_flag,
1445 sme_session, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301446 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301447 pe_session->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001448
1449 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301450 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001451 pe_err("Could not Send Re/AssocRsp, retCode=%X",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301452 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001453
1454 /*
1455 * update the ANI peer station count.
1456 * FIXME_PROTECTION : take care of different type of station
1457 * counter inside this function.
1458 */
1459 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1460
1461}
1462
1463void
1464lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1465 tSirMacAddr peer,
1466 uint8_t wmmTspecPresent,
1467 tSirMacTSInfo *pTsinfo,
1468 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1469{
1470 uint8_t *pFrame;
1471 tpSirMacMgmtHdr pMacHdr;
1472 tDot11fDelTS DelTS;
1473 tDot11fWMMDelTS WMMDelTS;
1474 uint32_t nBytes, nPayload, nStatus;
1475 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301476 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001477 uint8_t txFlag = 0;
1478 uint8_t smeSessionId = 0;
1479
1480 if (NULL == psessionEntry) {
1481 return;
1482 }
1483
1484 smeSessionId = psessionEntry->smeSessionId;
1485
1486 if (!wmmTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301487 qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488
1489 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1490 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1491 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1492
1493 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1494 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001495 pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496 /* We'll fall back on the worst case scenario: */
1497 nPayload = sizeof(tDot11fDelTS);
1498 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001499 pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)",
1500 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001501 }
1502 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301503 qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504
1505 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1506 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1507 WMMDelTS.DialogToken.token = 0;
1508 WMMDelTS.StatusCode.statusCode = 0;
1509 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1510 nStatus =
1511 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1512 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001513 pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514 /* We'll fall back on the worst case scenario: */
1515 nPayload = sizeof(tDot11fDelTS);
1516 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001517 pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)",
1518 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001519 }
1520 }
1521
1522 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1523
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301524 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001525 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1526 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301527 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001528 pe_err("Failed to allocate %d bytes for an Add TS Response",
1529 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001530 return;
1531 }
1532 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301533 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001534
1535 /* Next, we fill out the buffer descriptor: */
1536 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1537 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1538 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1539
1540 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1541
1542#ifdef WLAN_FEATURE_11W
1543 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1544#endif
1545
1546 /* That done, pack the struct: */
1547 if (!wmmTspecPresent) {
1548 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1549 pFrame + sizeof(tSirMacMgmtHdr),
1550 nPayload, &nPayload);
1551 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001552 pe_err("Failed to pack a Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001553 nStatus);
1554 cds_packet_free((void *)pPacket);
1555 return; /* allocated! */
1556 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001557 pe_warn("There were warnings while packing a Del TS frame (0x%08x)",
1558 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 }
1560 } else {
1561 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1562 pFrame + sizeof(tSirMacMgmtHdr),
1563 nPayload, &nPayload);
1564 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001565 pe_err("Failed to pack a WMM Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001566 nStatus);
1567 cds_packet_free((void *)pPacket);
1568 return; /* allocated! */
1569 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001570 pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)",
1571 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572 }
1573 }
1574
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001575 pe_debug("Sending DELTS REQ (size %d) to ", nBytes);
1576 lim_print_mac_addr(pMac, pMacHdr->da, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001577
1578 if ((SIR_BAND_5_GHZ ==
1579 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301580 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1581 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001582 ) {
1583 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1584 }
1585
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301586 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301588 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589 TXRX_FRM_802_11_MGMT,
1590 ANI_TXDIR_TODS,
1591 7, lim_tx_complete, pFrame, txFlag,
1592 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301593 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301594 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301596 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001597 pe_err("Failed to send Del TS (%X)!", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001598
1599} /* End lim_send_delts_req_action_frame. */
1600
1601/**
1602 * lim_send_assoc_req_mgmt_frame() - Send association request
1603 * @mac_ctx: Handle to MAC context
1604 * @mlm_assoc_req: Association request information
1605 * @pe_session: PE session information
1606 *
1607 * Builds and transmits association request frame to AP.
1608 *
1609 * Return: Void
1610 */
1611
1612void
1613lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1614 tLimMlmAssocReq *mlm_assoc_req,
1615 tpPESession pe_session)
1616{
1617 tDot11fAssocRequest *frm;
1618 uint16_t caps;
1619 uint8_t *frame;
1620 tSirRetStatus sir_status;
1621 tLimMlmAssocCnf assoc_cnf;
Hu Wang411e0cc2016-10-28 14:56:01 +08001622 uint32_t bytes = 0, payload, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1624 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301625 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626 uint16_t add_ie_len;
1627 uint8_t *add_ie;
1628 uint8_t *wps_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629 uint8_t power_caps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630 uint8_t tx_flag = 0;
1631 uint8_t sme_sessionid = 0;
1632 bool vht_enabled = false;
1633 tDot11fIEExtCap extr_ext_cap;
1634 bool extr_ext_flag = true;
1635 tpSirMacMgmtHdr mac_hdr;
Hu Wangfbd279d2016-10-31 18:24:34 +08001636 uint32_t ie_offset = 0;
1637 uint8_t *p_ext_cap = NULL;
1638 tDot11fIEExtCap bcn_ext_cap;
1639 uint8_t *bcn_ie = NULL;
1640 uint32_t bcn_ie_len = 0;
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05301641 uint32_t aes_block_size_len = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642
1643 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001644 pe_err("pe_session is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301645 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001646 return;
1647 }
1648
1649 sme_sessionid = pe_session->smeSessionId;
1650
1651 /* check this early to avoid unncessary operation */
1652 if (NULL == pe_session->pLimJoinReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001653 pe_err("pe_session->pLimJoinReq is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301654 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 return;
1656 }
1657 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1658 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1659
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301660 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001662 pe_err("Unable to allocate memory");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301663 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664 return;
1665 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001666 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301668 if (add_ie_len && pe_session->is_ext_caps_present) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301669 qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670 0);
1671 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1672 add_ie, &add_ie_len, &extr_ext_cap);
1673 if (eSIR_SUCCESS != sir_status) {
1674 extr_ext_flag = false;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001675 pe_debug("Unable to Stripoff ExtCap IE from Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 } else {
1677 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1678 extr_ext_cap.bytes;
1679
1680 if (p_ext_cap->interworking_service)
1681 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +08001682 extr_ext_cap.num_bytes =
1683 lim_compute_ext_cap_ie_length(&extr_ext_cap);
1684 extr_ext_flag = (extr_ext_cap.num_bytes > 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685 }
1686 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001687 pe_debug("No addn IE or peer dosen't support addnIE for Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 extr_ext_flag = false;
1689 }
1690
1691 caps = mlm_assoc_req->capabilityInfo;
1692#if defined(FEATURE_WLAN_WAPI)
1693 /*
1694 * According to WAPI standard:
1695 * 7.3.1.4 Capability Information field
1696 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1697 * in transmitted Association or Reassociation management frames.
1698 * APs ignore the Privacy subfield within received Association and
1699 * Reassociation management frames.
1700 */
1701 if (pe_session->encryptType == eSIR_ED_WPI)
1702 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1703#endif
1704 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1705
1706 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1707 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1708 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1709 &frm->SuppRates, pe_session);
1710
1711 qos_enabled = (pe_session->limQosEnabled) &&
1712 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1713
1714 wme_enabled = (pe_session->limWmeEnabled) &&
1715 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1716
1717 /* We prefer .11e asociations: */
1718 if (qos_enabled)
1719 wme_enabled = false;
1720
1721 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1722 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1723
1724 if (pe_session->lim11hEnable &&
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07001725 pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001726 power_caps = true;
1727
1728 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1729 LIM_ASSOC, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1731 LIM_ASSOC, pe_session);
1732
1733 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1735 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1736 if (power_caps == false) {
1737 power_caps = true;
1738 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1739 LIM_ASSOC, pe_session);
1740 }
1741 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742 if (qos_enabled)
Naveen Rawatcd118312016-11-22 10:46:21 -08001743 populate_dot11f_qos_caps_station(mac_ctx, pe_session,
1744 &frm->QOSCapsStation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001745
1746 populate_dot11f_ext_supp_rates(mac_ctx,
1747 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1748 pe_session);
1749
Gupta, Kapil54a16992016-01-13 19:34:02 +05301750 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1751 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1753 pe_session);
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08001754
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001755 /*
1756 * The join request *should* contain zero or one of the WPA and RSN
1757 * IEs. The payload send along with the request is a
1758 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1759 * typedef struct sSirRSNie
1760 * {
1761 * uint16_t length;
1762 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1763 * } tSirRSNie, *tpSirRSNie;
1764 * So, we should be able to make the following two calls harmlessly,
1765 * since they do nothing if they don't find the given IE in the
1766 * bytestream with which they're provided.
1767 * The net effect of this will be to faithfully transmit whatever
1768 * security IE is in the join request.
1769 * However, if we're associating for the purpose of WPS
1770 * enrollment, and we've been configured to indicate that by
1771 * eliding the WPA or RSN IE, we just skip this:
1772 */
1773 if (add_ie_len && add_ie)
1774 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1775
1776 if (NULL == wps_ie) {
1777 populate_dot11f_rsn_opaque(mac_ctx,
1778 &(pe_session->pLimJoinReq->rsnIE),
1779 &frm->RSNOpaque);
1780 populate_dot11f_wpa_opaque(mac_ctx,
1781 &(pe_session->pLimJoinReq->rsnIE),
1782 &frm->WPAOpaque);
1783#if defined(FEATURE_WLAN_WAPI)
1784 populate_dot11f_wapi_opaque(mac_ctx,
1785 &(pe_session->pLimJoinReq->rsnIE),
1786 &frm->WAPIOpaque);
1787#endif /* defined(FEATURE_WLAN_WAPI) */
1788 }
1789 /* include WME EDCA IE as well */
1790 if (wme_enabled) {
1791 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1792 pe_session, &frm->WMMInfoStation);
1793
1794 if (wsm_enabled)
1795 populate_dot11f_wmm_caps(&frm->WMMCaps);
1796 }
1797
1798 /*
1799 * Populate HT IEs, when operating in 11n and
1800 * when AP is also operating in 11n mode
1801 */
1802 if (pe_session->htCapability &&
1803 mac_ctx->lim.htCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001804 pe_debug("Populate HT Caps in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001806 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1807 &frm->HTCaps, sizeof(frm->HTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001809 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 +05301810 frm->HTCaps.supportedChannelWidthSet,
1811 frm->HTCaps.mimoPowerSave,
1812 frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
1813 frm->HTCaps.shortGI40MHz,
1814 frm->HTCaps.dsssCckMode40MHz,
1815 frm->HTCaps.maxRxAMPDUFactor);
1816
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817 if (pe_session->vhtCapability &&
1818 pe_session->vhtCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001819 pe_debug("Populate VHT IEs in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001821 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1822 &frm->VHTCaps, sizeof(frm->VHTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823 vht_enabled = true;
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001824 if (pe_session->enableHtSmps &&
1825 !pe_session->supported_nss_1x1) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001826 pe_err("VHT OP mode IE in Assoc Req");
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001827 populate_dot11f_operating_mode(mac_ctx,
1828 &frm->OperatingMode, pe_session);
1829 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001830 }
1831 if (!vht_enabled &&
1832 pe_session->is_vendor_specific_vhtcaps) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001833 pe_debug("Populate Vendor VHT IEs in Assoc Request");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301834 frm->vendor_vht_ie.present = 1;
1835 frm->vendor_vht_ie.type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001836 pe_session->vendor_specific_vht_ie_type;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301837 frm->vendor_vht_ie.sub_type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001838 pe_session->vendor_specific_vht_ie_sub_type;
1839
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301840 frm->vendor_vht_ie.VHTCaps.present = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 populate_dot11f_vht_caps(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301842 &frm->vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001843 vht_enabled = true;
1844 }
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301845 if (pe_session->is_ext_caps_present)
1846 populate_dot11f_ext_cap(mac_ctx, vht_enabled,
1847 &frm->ExtCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001848
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +05301849 if (mac_ctx->roam.configParam.qcn_ie_support)
1850 populate_dot11f_qcn_ie(&frm->QCN_IE);
1851
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001852 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001853 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001854 populate_dot11f_he_caps(mac_ctx, pe_session,
1855 &frm->vendor_he_cap);
1856 }
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301857
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001858 if (pe_session->pLimJoinReq->is11Rconnection) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001859 tSirBssDescription *bssdescr;
1860
1861 bssdescr = &pe_session->pLimJoinReq->bssDescription;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001862 pe_debug("mdie = %02x %02x %02x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001863 (unsigned int) bssdescr->mdie[0],
1864 (unsigned int) bssdescr->mdie[1],
1865 (unsigned int) bssdescr->mdie[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001866 populate_mdie(mac_ctx, &frm->MobilityDomain,
1867 pe_session->pLimJoinReq->bssDescription.mdie);
1868 } else {
1869 /* No 11r IEs dont send any MDIE */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001870 pe_debug("MDIE not present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001872
1873#ifdef FEATURE_WLAN_ESE
1874 /*
1875 * ESE Version IE will be included in association request
1876 * when ESE is enabled on DUT through ini and it is also
1877 * advertised by the peer AP to which we are trying to
1878 * associate to.
1879 */
1880 if (pe_session->is_ese_version_ie_present &&
1881 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1882 populate_dot11f_ese_version(&frm->ESEVersion);
1883 /* For ESE Associations fill the ESE IEs */
1884 if (pe_session->isESEconnection &&
1885 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1886#ifndef FEATURE_DISABLE_RM
1887 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1888#endif
1889 }
1890#endif
1891
Hu Wang411e0cc2016-10-28 14:56:01 +08001892 /*
1893 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1894 * may change the frame size. Therefore, MUST merge ExtCap IE before
1895 * dot11f get packed payload size.
1896 */
1897 if (extr_ext_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001898 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
1899
1900 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
1901 if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
1902 ie_offset = DOT11F_FF_TIMESTAMP_LEN +
1903 DOT11F_FF_BEACONINTERVAL_LEN +
1904 DOT11F_FF_CAPABILITIES_LEN;
1905
1906 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
1907 if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
1908 bcn_ie = pe_session->beacon + ie_offset;
1909 bcn_ie_len = pe_session->bcnLen - ie_offset;
1910 p_ext_cap = lim_get_ie_ptr_new(mac_ctx,
1911 bcn_ie,
1912 bcn_ie_len,
1913 DOT11F_EID_EXTCAP,
1914 ONE_BYTE);
1915 lim_update_extcap_struct(mac_ctx, p_ext_cap,
1916 &bcn_ext_cap);
1917 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
1918 false);
1919 }
1920 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001921
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001922 if (eSIR_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
1923 add_ie, &add_ie_len, &frm->SuppOperatingClasses))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001924 pe_debug("Unable to Stripoff supp op classes IE from Assoc Req");
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001925
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05301926 if (lim_is_fils_connection(pe_session)) {
1927 populate_dot11f_fils_params(mac_ctx, frm, pe_session);
1928 aes_block_size_len = AES_BLOCK_SIZE;
1929 }
1930
1931 /*
1932 * Do unpack to populate the add_ie buffer to frm structure
1933 * before packing the frm structure. In this way, the IE ordering
1934 * which the latest 802.11 spec mandates is maintained.
1935 */
1936 if (add_ie_len)
1937 dot11f_unpack_assoc_request(mac_ctx, add_ie,
1938 add_ie_len, frm, true);
1939
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001940 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1941 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001942 pe_err("Association Request packet size failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 status);
1944 /* We'll fall back on the worst case scenario: */
1945 payload = sizeof(tDot11fAssocRequest);
1946 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001947 pe_warn("Association request packet size warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001948 status);
1949 }
1950
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05301951 bytes = payload + sizeof(tSirMacMgmtHdr) +
1952 aes_block_size_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001953
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301954 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001955 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301956 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001957 pe_err("Failed to allocate %d bytes", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001958
1959 pe_session->limMlmState = pe_session->limPrevMlmState;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301960 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 pe_session->peSessionId,
1962 pe_session->limMlmState));
1963
1964 /* Update PE session id */
1965 assoc_cnf.sessionId = pe_session->peSessionId;
1966
1967 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1968
1969 cds_packet_free((void *)packet);
1970
1971 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1972 (uint32_t *) &assoc_cnf);
1973
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301974 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001975 }
1976 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301977 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001978
1979 /* Next, we fill out the buffer descriptor: */
1980 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1981 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1982 pe_session->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001983 /* That done, pack the Assoc Request: */
1984 status = dot11f_pack_assoc_request(mac_ctx, frm,
1985 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1986 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001987 pe_err("Assoc request pack failure (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001988 cds_packet_free((void *)packet);
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301989 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001991 pe_warn("Assoc request pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992 }
1993
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001994 if (pe_session->assocReq != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301995 qdf_mem_free(pe_session->assocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001996 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001997 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998 }
1999
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05302000 if (lim_is_fils_connection(pe_session)) {
2001 qdf_status = aead_encrypt_assoc_req(mac_ctx, pe_session,
2002 frame, &payload);
2003 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
2004 cds_packet_free((void *)packet);
2005 qdf_mem_free(frm);
2006 return;
2007 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008 }
2009
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302010 pe_session->assocReq = qdf_mem_malloc(payload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 if (NULL == pe_session->assocReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002012 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002013 } else {
2014 /*
2015 * Store the Assoc request. This is sent to csr/hdd in
2016 * join cnf response.
2017 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302018 qdf_mem_copy(pe_session->assocReq,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019 frame + sizeof(tSirMacMgmtHdr), payload);
2020 pe_session->assocReqLen = payload;
2021 }
2022
2023 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302024 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
2025 || (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002026 )
2027 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2028
Anurag Chouhan6d760662016-02-20 16:05:43 +05302029 if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
2030 pe_session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2032
2033#ifdef FEATURE_WLAN_DIAG_SUPPORT
2034 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
2035 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2036#endif
2037 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302038 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002039 pe_session->peSessionId, mac_hdr->fc.subType));
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05302040
2041 pe_debug("Sending Association Request length %d to ", bytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302042 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043 wma_tx_frame(mac_ctx, packet,
2044 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
2045 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2046 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302047 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302048 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302049 pe_session->peSessionId, qdf_status));
2050 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002051 pe_err("Failed to send Association Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302052 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002053 /* Pkt will be freed up by the callback */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002054 }
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05302055end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002056 /* Free up buffer allocated for mlm_assoc_req */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302057 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002058 mlm_assoc_req = NULL;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302059 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002060 return;
2061}
2062
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002063/**
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302064 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302065 * @context: pointer to global mac
2066 * @buf: buffer
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302067 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302068 * @params; tx completion params
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302069 *
2070 * Return: This returns QDF_STATUS
2071 */
2072
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302073static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
2074 qdf_nbuf_t buf,
2075 uint32_t tx_complete,
2076 void *params)
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302077{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302078 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
2079
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002080 pe_debug("tx_complete= %d", tx_complete);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302081 if (tx_complete) {
2082 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
2083 /* 'Change' timer for future activations */
2084 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2085 } else {
2086 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2087 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302088
2089 if (buf)
2090 qdf_nbuf_free(buf);
2091
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302092 return QDF_STATUS_SUCCESS;
2093}
2094
2095/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002096 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2097 *
2098 * @mac_ctx: Pointer to Global MAC structure
2099 * @auth_frame: Pointer to Authentication frame structure
2100 * @peer_addr: MAC address of destination peer
2101 * @wep_bit: wep bit in frame control for Authentication frame3
2102 * @session: PE session information
2103 *
2104 * This function is called by lim_process_mlm_messages(). Authentication frame
2105 * is formatted and sent when this function is called.
2106 *
2107 * Return: void
2108 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002109void
2110lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2111 tpSirMacAuthFrameBody auth_frame,
2112 tSirMacAddr peer_addr,
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302113 uint8_t wep_challenge_len,
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302114 tpPESession session, bool wait_for_ack)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002115{
2116 uint8_t *frame, *body;
2117 uint32_t frame_len = 0, body_len = 0;
2118 tpSirMacMgmtHdr mac_hdr;
2119 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302120 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002121 uint8_t tx_flag = 0;
2122 uint8_t sme_sessionid = 0;
2123 uint16_t ft_ies_length = 0;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002124 bool challenge_req = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002125
2126 if (NULL == session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002127 pe_err("Error: psession Entry is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002128 return;
2129 }
2130
2131 sme_sessionid = session->smeSessionId;
2132
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302133 if (wep_challenge_len) {
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002134 /*
2135 * Auth frame3 to be sent with encrypted framebody
2136 *
2137 * Allocate buffer for Authenticaton frame of size
2138 * equal to management frame header length plus 2 bytes
2139 * each for auth algorithm number, transaction number,
2140 * status code, 128 bytes for challenge text and
2141 * 4 bytes each for IV & ICV.
2142 */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002143 pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
2144 MAC_ADDR_ARRAY(peer_addr));
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002145
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302146 body_len = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002147 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002148
2149 goto alloc_packet;
2150 }
2151
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002152 pe_info("Sending Auth seq# %d status %d (%d) wait_for_ack %d to "
2153 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002154 auth_frame->authTransactionSeqNumber,
2155 auth_frame->authStatusCode,
2156 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302157 wait_for_ack,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002158 MAC_ADDR_ARRAY(peer_addr));
2159
2160 switch (auth_frame->authTransactionSeqNumber) {
2161 case SIR_MAC_AUTH_FRAME_1:
2162 /*
2163 * Allocate buffer for Authenticaton frame of size
2164 * equal to management frame header length plus 2 bytes
2165 * each for auth algorithm number, transaction number
2166 * and status code.
2167 */
2168
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002169 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2170 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002171
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05302172 frame_len += lim_create_fils_auth_data(mac_ctx,
2173 auth_frame, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002174 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2175 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2176 0 != session->ftPEContext.pFTPreAuthReq->
2177 ft_ies_length) {
2178 ft_ies_length = session->ftPEContext.
2179 pFTPreAuthReq->ft_ies_length;
2180 frame_len += ft_ies_length;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002181 pe_debug("Auth frame, FTIES length added=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182 ft_ies_length);
2183 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002184 pe_debug("Auth frame, Does not contain FTIES!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185 frame_len += (2 + SIR_MDIE_SIZE);
2186 }
2187 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002188 break;
2189
2190 case SIR_MAC_AUTH_FRAME_2:
2191 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2192 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2193 (auth_frame->authStatusCode !=
2194 eSIR_MAC_SUCCESS_STATUS))) {
2195 /*
2196 * Allocate buffer for Authenticaton frame of size
2197 * equal to management frame header length plus
2198 * 2 bytes each for auth algorithm number,
2199 * transaction number and status code.
2200 */
2201
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002202 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2203 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002204 } else {
2205 /*
2206 * Shared Key algorithm with challenge text
2207 * to be sent.
2208 *
2209 * Allocate buffer for Authenticaton frame of size
2210 * equal to management frame header length plus
2211 * 2 bytes each for auth algorithm number,
2212 * transaction number, status code and 128 bytes
2213 * for challenge text.
2214 */
2215
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002216 challenge_req = true;
2217 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
2218 SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2219 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002220 }
2221 break;
2222
2223 case SIR_MAC_AUTH_FRAME_3:
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002224 /*
2225 * Auth frame3 to be sent without encrypted framebody
2226 *
2227 * Allocate buffer for Authenticaton frame of size equal
2228 * to management frame header length plus 2 bytes each
2229 * for auth algorithm number, transaction number and
2230 * status code.
2231 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002232
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002233 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2234 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002235 break;
2236
2237 case SIR_MAC_AUTH_FRAME_4:
2238 /*
2239 * Allocate buffer for Authenticaton frame of size equal
2240 * to management frame header length plus 2 bytes each
2241 * for auth algorithm number, transaction number and
2242 * status code.
2243 */
2244
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002245 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2246 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002247
2248 break;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002249 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002250 pe_err("Invalid auth transaction seq num");
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002251 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002252 } /* switch (auth_frame->authTransactionSeqNumber) */
2253
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002254alloc_packet:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302255 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002256 (void **)&packet);
2257
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302258 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002259 pe_err("call to bufAlloc failed for AUTH frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002260 return;
2261 }
2262
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302263 qdf_mem_zero(frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002264
2265 /* Prepare BD */
2266 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2267 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2268 mac_hdr = (tpSirMacMgmtHdr) frame;
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302269 if (wep_challenge_len)
2270 mac_hdr->fc.wep = LIM_WEP_IN_FC;
2271 else
2272 mac_hdr->fc.wep = LIM_NO_WEP_IN_FC;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002273
2274 /* Prepare BSSId */
Rajeev Kumarcf835a02016-04-15 15:01:31 -07002275 if (LIM_IS_AP_ROLE(session))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302276 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002277 (uint8_t *) session->bssId,
2278 sizeof(tSirMacAddr));
2279
2280 /* Prepare Authentication frame body */
2281 body = frame + sizeof(tSirMacMgmtHdr);
2282
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302283 if (wep_challenge_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302284 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002285
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002286 pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002287 MAC_ADDR_ARRAY(mac_hdr->da));
2288
2289 } else {
2290 *((uint16_t *) (body)) =
2291 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2292 body += sizeof(uint16_t);
2293 body_len -= sizeof(uint16_t);
2294
2295 *((uint16_t *) (body)) =
2296 sir_swap_u16if_needed(
2297 auth_frame->authTransactionSeqNumber);
2298 body += sizeof(uint16_t);
2299 body_len -= sizeof(uint16_t);
2300
2301 *((uint16_t *) (body)) =
2302 sir_swap_u16if_needed(auth_frame->authStatusCode);
2303 body += sizeof(uint16_t);
2304 body_len -= sizeof(uint16_t);
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002305
2306 if (challenge_req) {
2307 if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
2308 qdf_mem_copy(body, (uint8_t *)&auth_frame->type,
2309 body_len);
2310 pe_err("Incomplete challenge info: length: %d, expected: %d",
2311 body_len,
2312 SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
2313 body += body_len;
2314 body_len = 0;
2315 } else {
2316 /* copy challenge IE id, len, challenge text */
2317 *body = auth_frame->type;
2318 body++;
2319 *body = auth_frame->length;
2320 body++;
2321 qdf_mem_copy(body, auth_frame->challengeText,
2322 SIR_MAC_AUTH_CHALLENGE_LENGTH);
2323 body += SIR_MAC_AUTH_CHALLENGE_LENGTH;
2324
2325 body_len -= SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2326 }
2327 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002328
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2330 (auth_frame->authTransactionSeqNumber ==
2331 SIR_MAC_AUTH_FRAME_1) &&
2332 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2333
2334 if (ft_ies_length > 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302335 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002336 session->ftPEContext.
2337 pFTPreAuthReq->ft_ies,
2338 ft_ies_length);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002339 pe_debug("Auth1 Frame FTIE is: ");
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002340 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2341 QDF_TRACE_LEVEL_DEBUG,
2342 (uint8_t *) body,
2343 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002344 } else if (NULL != session->ftPEContext.
2345 pFTPreAuthReq->pbssDescription) {
2346 /* MDID attr is 54 */
2347 *body = SIR_MDIE_ELEMENT_ID;
2348 body++;
2349 *body = SIR_MDIE_SIZE;
2350 body++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302351 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352 &session->ftPEContext.pFTPreAuthReq->
2353 pbssDescription->mdie[0],
2354 SIR_MDIE_SIZE);
2355 }
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05302356 } else if (auth_frame->authAlgoNumber ==
2357 eSIR_FILS_SK_WITHOUT_PFS) {
2358 /* TODO MDIE */
2359 pe_debug("appending fils Auth data");
2360 lim_add_fils_data_to_auth_frame(session, body);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002361 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002362
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002363 pe_debug("*** Sending Auth seq# %d status %d (%d) to "
2364 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002365 auth_frame->authTransactionSeqNumber,
2366 auth_frame->authStatusCode,
2367 (auth_frame->authStatusCode ==
2368 eSIR_MAC_SUCCESS_STATUS),
2369 MAC_ADDR_ARRAY(mac_hdr->da));
2370 }
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002371 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2372 QDF_TRACE_LEVEL_DEBUG,
2373 frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002374
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302375 if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
2376 (SIR_BAND_5_GHZ == lim_get_rf_band(
2377 session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302379 else if ((SIR_BAND_5_GHZ ==
2380 lim_get_rf_band(session->currentOperChannel))
2381 || (session->pePersona == QDF_P2P_CLIENT_MODE)
2382 || (session->pePersona == QDF_P2P_GO_MODE))
2383 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002384
Anurag Chouhan6d760662016-02-20 16:05:43 +05302385 if (session->pePersona == QDF_P2P_CLIENT_MODE ||
2386 session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002387 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2388
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302389 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390 session->peSessionId, mac_hdr->fc.subType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002391
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302392 if (wait_for_ack) {
2393 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
2394 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
2395 (uint16_t)frame_len,
2396 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2397 7, lim_tx_complete, frame,
2398 lim_auth_tx_complete_cnf,
2399 tx_flag, sme_sessionid, false, 0);
2400 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2401 session->peSessionId, qdf_status));
2402 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002403 pe_err("*** Could not send Auth frame, retCode=%X ***",
2404 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302405 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2406 /* Pkt will be freed up by the callback */
2407 }
2408 } else {
2409 /* Queue Authentication frame in high priority WQ */
2410 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
2411 TXRX_FRM_802_11_MGMT,
2412 ANI_TXDIR_TODS, 7, lim_tx_complete,
2413 frame, tx_flag, sme_sessionid, 0);
2414 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2415 session->peSessionId, qdf_status));
2416 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002417 pe_err("*** Could not send Auth frame, retCode=%X ***",
2418 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302419 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002420 return;
2421}
2422
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302423QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002424{
2425 uint16_t aid;
2426 tpDphHashNode pStaDs;
2427 tLimMlmDeauthReq *pMlmDeauthReq;
2428 tLimMlmDeauthCnf mlmDeauthCnf;
2429 tpPESession psessionEntry;
2430
2431 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
2432 if (pMlmDeauthReq) {
2433 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
2434 lim_deactivate_and_change_timer(pMac,
2435 eLIM_DEAUTH_ACK_TIMER);
2436 }
2437
2438 psessionEntry = pe_find_session_by_session_id(pMac,
2439 pMlmDeauthReq->sessionId);
2440 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002441 pe_err("session does not exist for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002442 mlmDeauthCnf.resultCode =
2443 eSIR_SME_INVALID_PARAMETERS;
2444 goto end;
2445 }
2446
2447 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002448 dph_lookup_hash_entry(pMac,
2449 pMlmDeauthReq->peer_macaddr.bytes,
2450 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002451 &psessionEntry->dph.dphHashTable);
2452 if (pStaDs == NULL) {
2453 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2454 goto end;
2455 }
2456
2457 /* / Receive path cleanup with dummy packet */
2458 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2459 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002460 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
2461 (
Abhishek Singhe0680852015-12-16 14:28:48 +05302462#ifdef FEATURE_WLAN_ESE
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002463 (psessionEntry->isESEconnection) ||
Abhishek Singhe0680852015-12-16 14:28:48 +05302464#endif
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002465 (psessionEntry->isFastRoamIniFeatureEnabled) ||
2466 (psessionEntry->is11Rconnection))) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002467 pe_debug("FT Preauth (%p,%d) Deauth rc %d src = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002468 psessionEntry,
2469 psessionEntry->peSessionId,
2470 pMlmDeauthReq->reasonCode,
2471 pMlmDeauthReq->deauthTrigger);
2472 lim_ft_cleanup(pMac, psessionEntry);
2473 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002474 pe_debug("No FT Preauth Session Cleanup in role %d"
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002475#ifdef FEATURE_WLAN_ESE
2476 " isESE %d"
2477#endif
2478 " isLFR %d"
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002479 " is11r %d, Deauth reason %d Trigger = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002480 psessionEntry->limSystemRole,
2481#ifdef FEATURE_WLAN_ESE
2482 psessionEntry->isESEconnection,
2483#endif
2484 psessionEntry->isFastRoamIniFeatureEnabled,
2485 psessionEntry->is11Rconnection,
Abhishek Singhe0680852015-12-16 14:28:48 +05302486 pMlmDeauthReq->reasonCode,
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002487 pMlmDeauthReq->deauthTrigger);
2488 }
2489 /* Free up buffer allocated for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302490 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002491 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
2492 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302493 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002494end:
Anurag Chouhanc5548422016-02-24 18:33:27 +05302495 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002496 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002497 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
2498 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
2499 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
2500
2501 /* Free up buffer allocated */
2502 /* for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302503 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002504
2505 lim_post_sme_message(pMac,
2506 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302507 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002508}
2509
2510/**
2511 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
2512 *
2513 * @mac_ctx: Handle to MAC context
2514 *
2515 * Sends disassoc confirmation to SME. Removes disassoc request stored
2516 * in lim.
2517 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302518 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002519 */
2520
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302521QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002522{
2523 uint16_t aid;
2524 tpDphHashNode sta_ds;
2525 tLimMlmDisassocCnf disassoc_cnf;
2526 tpPESession pe_session;
2527 tLimMlmDisassocReq *disassoc_req;
2528
2529 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
2530 if (disassoc_req) {
2531 if (tx_timer_running(
2532 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
2533 lim_deactivate_and_change_timer(mac_ctx,
2534 eLIM_DISASSOC_ACK_TIMER);
2535
2536 pe_session = pe_find_session_by_session_id(
2537 mac_ctx, disassoc_req->sessionId);
2538 if (pe_session == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002539 pe_err("No session for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002540 disassoc_cnf.resultCode =
2541 eSIR_SME_INVALID_PARAMETERS;
2542 goto end;
2543 }
2544
2545 sta_ds = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002546 disassoc_req->peer_macaddr.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547 &pe_session->dph.dphHashTable);
2548 if (sta_ds == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002549 pe_err("StaDs Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002550 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2551 goto end;
2552 }
2553 /* Receive path cleanup with dummy packet */
2554 if (eSIR_SUCCESS !=
2555 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
2556 disassoc_cnf.resultCode =
2557 eSIR_SME_RESOURCES_UNAVAILABLE;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002558 pe_err("cleanup_rx_path error");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002559 goto end;
2560 }
Deepak Dhamdhere57c95ff2016-09-30 16:44:44 -07002561 if (LIM_IS_STA_ROLE(pe_session) &&
2562 (disassoc_req->reasonCode !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002563 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002564 pe_debug("FT Preauth Session (%p %d) Clean up",
2565 pe_session, pe_session->peSessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002566
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002567 /* Delete FT session if there exists one */
2568 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002569 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002570 /* Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302571 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002572 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302573 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002574 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302575 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002576 }
2577end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302578 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002579 (uint8_t *) disassoc_req->peer_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302580 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002581 disassoc_cnf.aid = disassoc_req->aid;
2582 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
2583
2584 /* Update PE session ID */
2585 disassoc_cnf.sessionId = disassoc_req->sessionId;
2586
2587 if (disassoc_req != NULL) {
2588 /* / Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302589 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002590 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
2591 }
2592
2593 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
2594 (uint32_t *) &disassoc_cnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302595 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002596}
2597
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302598QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
2599 qdf_nbuf_t buf,
2600 uint32_t txCompleteSuccess,
2601 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002602{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302603 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2604
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002605 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302606
2607 if (buf)
2608 qdf_nbuf_free(buf);
2609
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002610 return lim_send_disassoc_cnf(pMac);
2611}
2612
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302613QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
2614 qdf_nbuf_t buf,
2615 uint32_t txCompleteSuccess,
2616 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002617{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302618 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2619
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002620 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302621
2622 if (buf)
2623 qdf_nbuf_free(buf);
2624
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002625 return lim_send_deauth_cnf(pMac);
2626}
2627
2628/**
2629 * \brief This function is called to send Disassociate frame.
2630 *
2631 *
2632 * \param pMac Pointer to Global MAC structure
2633 *
2634 * \param nReason Indicates the reason that need to be sent in
2635 * Disassociation frame
2636 *
2637 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
2638 * sent
2639 *
2640 *
2641 */
2642
2643void
2644lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
2645 uint16_t nReason,
2646 tSirMacAddr peer,
2647 tpPESession psessionEntry, bool waitForAck)
2648{
2649 tDot11fDisassociation frm;
2650 uint8_t *pFrame;
2651 tpSirMacMgmtHdr pMacHdr;
2652 uint32_t nBytes, nPayload, nStatus;
2653 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302654 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002655 uint8_t txFlag = 0;
2656 uint32_t val = 0;
2657 uint8_t smeSessionId = 0;
2658 if (NULL == psessionEntry) {
2659 return;
2660 }
2661
2662 /*
2663 * In case when cac timer is running for this SAP session then
2664 * avoid sending disassoc out. It is violation of dfs specification.
2665 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302666 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2667 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002668 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302669 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670 FL
2671 ("CAC timer is running, drop disassoc from going out"));
2672 return;
2673 }
2674 smeSessionId = psessionEntry->smeSessionId;
2675
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302676 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002677
2678 frm.Reason.code = nReason;
2679
2680 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
2681 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002682 pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002683 nStatus);
2684 /* We'll fall back on the worst case scenario: */
2685 nPayload = sizeof(tDot11fDisassociation);
2686 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002687 pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)",
2688 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002689 }
2690
2691 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2692
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302693 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302695 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002696 pe_err("Failed to allocate %d bytes for a Disassociation",
2697 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698 return;
2699 }
2700 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302701 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002702
2703 /* Next, we fill out the buffer descriptor: */
2704 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2705 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
2706 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2707
2708 /* Prepare the BSSID */
2709 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2710
2711#ifdef WLAN_FEATURE_11W
2712 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2713#endif
2714
2715 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
2716 sizeof(tSirMacMgmtHdr),
2717 nPayload, &nPayload);
2718 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002719 pe_err("Failed to pack a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720 nStatus);
2721 cds_packet_free((void *)pPacket);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002722 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002723 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002724 pe_warn("There were warnings while packing a Disassociation (0x%08x)",
2725 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002726 }
2727
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002728 pe_debug("***Sessionid %d Sending Disassociation frame with "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002730 MAC_ADDRESS_STR, psessionEntry->peSessionId, nReason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002731 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
2732 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2733
2734 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302735 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2736 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002737 ) {
2738 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2739 }
2740
Sushant Kaushik46556062015-12-02 16:57:47 +05302741 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002742
2743 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302744 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002745 psessionEntry->peSessionId,
2746 pMacHdr->fc.subType));
2747 /* Queue Disassociation frame in high priority WQ */
2748 /* get the duration from the request */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302749 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002750 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2751 TXRX_FRM_802_11_MGMT,
2752 ANI_TXDIR_TODS, 7, lim_tx_complete,
2753 pFrame, lim_disassoc_tx_complete_cnf,
2754 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302755 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302756 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302757 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002758
2759 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2760
2761 if (tx_timer_change
2762 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
2763 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002764 pe_err("Unable to change Disassoc ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002765 return;
2766 } else if (TX_SUCCESS !=
2767 tx_timer_activate(&pMac->lim.limTimers.
2768 gLimDisassocAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002769 pe_err("Unable to activate Disassoc ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002770 lim_deactivate_and_change_timer(pMac,
2771 eLIM_DISASSOC_ACK_TIMER);
2772 return;
2773 }
2774 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302775 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002776 psessionEntry->peSessionId,
2777 pMacHdr->fc.subType));
2778 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302779 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002780 TXRX_FRM_802_11_MGMT,
2781 ANI_TXDIR_TODS,
2782 7,
2783 lim_tx_complete, pFrame, txFlag,
2784 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302785 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302786 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302787 psessionEntry->peSessionId, qdf_status));
2788 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002789 pe_err("Failed to send Disassociation (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302790 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002791 /* Pkt will be freed up by the callback */
2792 }
2793 }
2794} /* End lim_send_disassoc_mgmt_frame. */
2795
2796/**
2797 * \brief This function is called to send a Deauthenticate frame
2798 *
2799 *
2800 * \param pMac Pointer to global MAC structure
2801 *
2802 * \param nReason Indicates the reason that need to be sent in the
2803 * Deauthenticate frame
2804 *
2805 * \param peeer address of the STA to which the frame is to be sent
2806 *
2807 *
2808 */
2809
2810void
2811lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
2812 uint16_t nReason,
2813 tSirMacAddr peer,
2814 tpPESession psessionEntry, bool waitForAck)
2815{
2816 tDot11fDeAuth frm;
2817 uint8_t *pFrame;
2818 tpSirMacMgmtHdr pMacHdr;
2819 uint32_t nBytes, nPayload, nStatus;
2820 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302821 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002822 uint8_t txFlag = 0;
2823 uint32_t val = 0;
2824#ifdef FEATURE_WLAN_TDLS
2825 uint16_t aid;
2826 tpDphHashNode pStaDs;
2827#endif
2828 uint8_t smeSessionId = 0;
2829
2830 if (NULL == psessionEntry) {
2831 return;
2832 }
2833
2834 /*
2835 * In case when cac timer is running for this SAP session then
2836 * avoid deauth frame out. It is violation of dfs specification.
2837 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302838 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2839 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002840 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302841 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002842 FL
2843 ("CAC timer is running, drop the deauth from going out"));
2844 return;
2845 }
2846 smeSessionId = psessionEntry->smeSessionId;
2847
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302848 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002849
2850 frm.Reason.code = nReason;
2851
2852 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
2853 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002854 pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002855 nStatus);
2856 /* We'll fall back on the worst case scenario: */
2857 nPayload = sizeof(tDot11fDeAuth);
2858 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002859 pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)",
2860 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002861 }
2862
2863 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2864
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302865 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002866 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302867 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002868 pe_err("Failed to allocate %d bytes for a De-Authentication",
2869 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002870 return;
2871 }
2872 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302873 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002874
2875 /* Next, we fill out the buffer descriptor: */
2876 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2877 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
2878 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2879
2880 /* Prepare the BSSID */
2881 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2882
2883#ifdef WLAN_FEATURE_11W
2884 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2885#endif
2886
2887 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
2888 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
2889 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002890 pe_err("Failed to pack a DeAuthentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002891 nStatus);
2892 cds_packet_free((void *)pPacket);
2893 return;
2894 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002895 pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
2896 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002897 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002898 pe_debug("***Sessionid %d Sending Deauth frame with "
2899 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
2900 " ,From " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002901 psessionEntry->peSessionId, nReason, waitForAck,
2902 MAC_ADDR_ARRAY(pMacHdr->da),
2903 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2904
2905 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302906 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2907 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908 ) {
2909 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2910 }
2911
Sushant Kaushik46556062015-12-02 16:57:47 +05302912 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002913#ifdef FEATURE_WLAN_TDLS
2914 pStaDs =
2915 dph_lookup_hash_entry(pMac, peer, &aid,
2916 &psessionEntry->dph.dphHashTable);
2917#endif
2918
2919 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302920 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002921 psessionEntry->peSessionId,
2922 pMacHdr->fc.subType));
2923 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302924 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002925 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2926 TXRX_FRM_802_11_MGMT,
2927 ANI_TXDIR_TODS, 7, lim_tx_complete,
2928 pFrame, lim_deauth_tx_complete_cnf,
2929 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302930 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302931 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302932 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002933 /* Pkt will be freed up by the callback lim_tx_complete */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302934 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002935 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302936 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002937
2938 /* Call lim_process_deauth_ack_timeout which will send
2939 * DeauthCnf for this frame
2940 */
2941 lim_process_deauth_ack_timeout(pMac);
2942 return;
2943 }
2944
2945 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2946
2947 if (tx_timer_change
2948 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
2949 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002950 pe_err("Unable to change Deauth ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002951 return;
2952 } else if (TX_SUCCESS !=
2953 tx_timer_activate(&pMac->lim.limTimers.
2954 gLimDeauthAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002955 pe_err("Unable to activate Deauth ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002956 lim_deactivate_and_change_timer(pMac,
2957 eLIM_DEAUTH_ACK_TIMER);
2958 return;
2959 }
2960 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302961 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002962 psessionEntry->peSessionId,
2963 pMacHdr->fc.subType));
2964#ifdef FEATURE_WLAN_TDLS
2965 if ((NULL != pStaDs)
2966 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
2967 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302968 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002969 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2970 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
2971 7, lim_tx_complete, pFrame, txFlag,
2972 smeSessionId, 0);
2973 } else {
2974#endif
2975 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302976 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002977 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2978 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2979 7, lim_tx_complete, pFrame, txFlag,
2980 smeSessionId, 0);
2981#ifdef FEATURE_WLAN_TDLS
2982 }
2983#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302984 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302985 psessionEntry->peSessionId, qdf_status));
2986 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002987 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302988 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002989 /* Pkt will be freed up by the callback */
2990 }
2991 }
2992
2993} /* End lim_send_deauth_mgmt_frame. */
2994
2995#ifdef ANI_SUPPORT_11H
2996/**
2997 * \brief Send a Measurement Report Action frame
2998 *
2999 *
3000 * \param pMac Pointer to the global MAC structure
3001 *
3002 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
3003 *
3004 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3005 *
3006 *
3007 */
3008
3009tSirRetStatus
3010lim_send_meas_report_frame(tpAniSirGlobal pMac,
3011 tpSirMacMeasReqActionFrame pMeasReqFrame,
3012 tSirMacAddr peer, tpPESession psessionEntry)
3013{
3014 tDot11fMeasurementReport frm;
3015 uint8_t *pFrame;
3016 tSirRetStatus nSirStatus;
3017 tpSirMacMgmtHdr pMacHdr;
3018 uint32_t nBytes, nPayload, nStatus;
3019 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303020 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003021
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303022 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003023
3024 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3025 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3026 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3027
3028 switch (pMeasReqFrame->measReqIE.measType) {
3029 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3030 nSirStatus =
3031 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3032 &frm.MeasurementReport);
3033 break;
3034 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3035 nSirStatus =
3036 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3037 &frm.MeasurementReport);
3038 break;
3039 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3040 nSirStatus =
3041 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3042 &frm.MeasurementReport);
3043 break;
3044 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003045 pe_err("Unknown measurement type %d in limSen"
3046 "dMeasReportFrame",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003047 pMeasReqFrame->measReqIE.measType);
3048 return eSIR_FAILURE;
3049 }
3050
3051 if (eSIR_SUCCESS != nSirStatus)
3052 return eSIR_FAILURE;
3053
3054 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3055 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003056 pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003057 nStatus);
3058 /* We'll fall back on the worst case scenario: */
3059 nPayload = sizeof(tDot11fMeasurementReport);
3060 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003061 pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)",
3062 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063 }
3064
3065 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3066
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303067 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003068 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3069 (uint16_t) nBytes, (void **)&pFrame,
3070 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303071 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003072 pe_err("Failed to allocate %d bytes for a "
3073 "De-Authentication", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003074 return eSIR_FAILURE;
3075 }
3076 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303077 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003078
3079 /* Next, we fill out the buffer descriptor: */
3080 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3081 SIR_MAC_MGMT_ACTION, peer);
3082 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3083
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303084 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003085
3086#ifdef WLAN_FEATURE_11W
3087 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3088#endif
3089
3090 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3091 sizeof(tSirMacMgmtHdr),
3092 nPayload, &nPayload);
3093 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003094 pe_err("Failed to pack a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095 nStatus);
3096 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3097 (void *)pFrame, (void *)pPacket);
3098 return eSIR_FAILURE; /* allocated! */
3099 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003100 pe_warn("There were warnings while packing a Measurement Report (0x%08x)",
3101 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102 }
3103
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303104 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003105 ((psessionEntry) ? psessionEntry->
3106 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303107 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003108 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3109 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3110 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303111 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303112 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003113 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303114 qdf_status));
3115 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003116 pe_err("Failed to send a Measurement Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303117 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003118 /* Pkt will be freed up by the callback */
3119 return eSIR_FAILURE; /* just allocated... */
3120 }
3121
3122 return eSIR_SUCCESS;
3123
3124} /* End lim_send_meas_report_frame. */
3125
3126/**
3127 * \brief Send a TPC Request Action frame
3128 *
3129 *
3130 * \param pMac Pointer to the global MAC datastructure
3131 *
3132 * \param peer MAC address to which the frame should be sent
3133 *
3134 *
3135 */
3136
3137void
3138lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3139 tSirMacAddr peer, tpPESession psessionEntry)
3140{
3141 tDot11fTPCRequest frm;
3142 uint8_t *pFrame;
3143 tpSirMacMgmtHdr pMacHdr;
3144 uint32_t nBytes, nPayload, nStatus;
3145 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303146 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003147
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303148 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003149
3150 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3151 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3152 frm.DialogToken.token = 1;
3153 frm.TPCRequest.present = 1;
3154
3155 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3156 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003157 pe_err("Failed to calculate the packed size for a TPC Request (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003158 /* We'll fall back on the worst case scenario: */
3159 nPayload = sizeof(tDot11fTPCRequest);
3160 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003161 pe_warn("There were warnings while calculating the packed size for a TPC Request (0x%08x)",
3162 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003163 }
3164
3165 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3166
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303167 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003168 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3169 (uint16_t) nBytes, (void **)&pFrame,
3170 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303171 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003172 pe_err("Failed to allocate %d bytes for a TPC"
3173 " Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003174 return;
3175 }
3176 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303177 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003178
3179 /* Next, we fill out the buffer descriptor: */
3180 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3181 SIR_MAC_MGMT_ACTION, peer);
3182 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3183
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303184 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003185
3186#ifdef WLAN_FEATURE_11W
3187 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3188#endif
3189
3190 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3191 sizeof(tSirMacMgmtHdr),
3192 nPayload, &nPayload);
3193 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003194 pe_err("Failed to pack a TPC Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003195 nStatus);
3196 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3197 (void *)pFrame, (void *)pPacket);
3198 return; /* allocated! */
3199 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003200 pe_warn("There were warnings while packing a TPC Request (0x%08x)",
3201 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003202 }
3203
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303204 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003205 ((psessionEntry) ? psessionEntry->
3206 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303207 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003208 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3209 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3210 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303211 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303212 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003213 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303214 qdf_status));
3215 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003216 pe_err("Failed to send a TPC Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303217 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003218 /* Pkt will be freed up by the callback */
3219 }
3220
3221} /* End lim_send_tpc_request_frame. */
3222
3223/**
3224 * \brief Send a TPC Report Action frame
3225 *
3226 *
3227 * \param pMac Pointer to the global MAC datastructure
3228 *
3229 * \param pTpcReqFrame Pointer to the received TPC Request
3230 *
3231 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3232 *
3233 *
3234 */
3235
3236tSirRetStatus
3237lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3238 tpSirMacTpcReqActionFrame pTpcReqFrame,
3239 tSirMacAddr peer, tpPESession psessionEntry)
3240{
3241 tDot11fTPCReport frm;
3242 uint8_t *pFrame;
3243 tpSirMacMgmtHdr pMacHdr;
3244 uint32_t nBytes, nPayload, nStatus;
3245 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303246 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003247
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303248 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249
3250 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3251 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3252 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3253
3254 frm.TPCReport.tx_power = 0;
3255 frm.TPCReport.link_margin = 0;
3256 frm.TPCReport.present = 1;
3257
3258 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3259 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003260 pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003261 /* We'll fall back on the worst case scenario: */
3262 nPayload = sizeof(tDot11fTPCReport);
3263 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003264 pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)",
3265 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003266 }
3267
3268 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3269
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303270 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003271 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3272 (uint16_t) nBytes, (void **)&pFrame,
3273 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303274 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003275 pe_err("Failed to allocate %d bytes for a TPC"
3276 " Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277 return eSIR_FAILURE;
3278 }
3279 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303280 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003281
3282 /* Next, we fill out the buffer descriptor: */
3283 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3284 SIR_MAC_MGMT_ACTION, peer);
3285
3286 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3287
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303288 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003289
3290#ifdef WLAN_FEATURE_11W
3291 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3292#endif
3293
3294 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3295 sizeof(tSirMacMgmtHdr),
3296 nPayload, &nPayload);
3297 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003298 pe_err("Failed to pack a TPC Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003299 nStatus);
3300 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3301 (void *)pFrame, (void *)pPacket);
3302 return eSIR_FAILURE; /* allocated! */
3303 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003304 pe_warn("There were warnings while packing a TPC Report (0x%08x)",
3305 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003306
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303307 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003308 ((psessionEntry) ? psessionEntry->
3309 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303310 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003311 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3312 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3313 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303314 MTRACE(qdf_trace
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003315 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3316 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3317 qdf_status));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303318 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003319 pe_err("Failed to send a TPC Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303320 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003321 /* Pkt will be freed up by the callback */
3322 return eSIR_FAILURE; /* just allocated... */
3323 }
3324
3325 return eSIR_SUCCESS;
3326
3327} /* End lim_send_tpc_report_frame. */
3328#endif /* ANI_SUPPORT_11H */
3329
3330/**
3331 * \brief Send a Channel Switch Announcement
3332 *
3333 *
3334 * \param pMac Pointer to the global MAC datastructure
3335 *
3336 * \param peer MAC address to which this frame will be sent
3337 *
3338 * \param nMode
3339 *
3340 * \param nNewChannel
3341 *
3342 * \param nCount
3343 *
3344 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3345 *
3346 *
3347 */
3348
3349tSirRetStatus
3350lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3351 tSirMacAddr peer,
3352 uint8_t nMode,
3353 uint8_t nNewChannel,
3354 uint8_t nCount, tpPESession psessionEntry)
3355{
3356 tDot11fChannelSwitch frm;
3357 uint8_t *pFrame;
3358 tpSirMacMgmtHdr pMacHdr;
3359 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3360 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303361 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003362 uint8_t txFlag = 0;
3363
3364 uint8_t smeSessionId = 0;
3365
3366 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003367 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368 return eSIR_FAILURE;
3369 }
3370 smeSessionId = psessionEntry->smeSessionId;
3371
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303372 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003373
3374 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3375 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
3376 frm.ChanSwitchAnn.switchMode = nMode;
3377 frm.ChanSwitchAnn.newChannel = nNewChannel;
3378 frm.ChanSwitchAnn.switchCount = nCount;
3379 frm.ChanSwitchAnn.present = 1;
3380
3381 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
3382 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003383 pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003384 nStatus);
3385 /* We'll fall back on the worst case scenario: */
3386 nPayload = sizeof(tDot11fChannelSwitch);
3387 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003388 pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)",
3389 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003390 }
3391
3392 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3393
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303394 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003395 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3396 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303397 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003398 pe_err("Failed to allocate %d bytes for a TPC Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003399 return eSIR_FAILURE;
3400 }
3401 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303402 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003403
3404 /* Next, we fill out the buffer descriptor: */
3405 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3406 SIR_MAC_MGMT_ACTION, peer,
3407 psessionEntry->selfMacAddr);
3408 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303409 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3411
3412#ifdef WLAN_FEATURE_11W
3413 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3414#endif
3415
3416 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
3417 sizeof(tSirMacMgmtHdr),
3418 nPayload, &nPayload);
3419 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003420 pe_err("Failed to pack a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003421 nStatus);
3422 cds_packet_free((void *)pPacket);
3423 return eSIR_FAILURE; /* allocated! */
3424 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003425 pe_warn("There were warnings while packing a Channel Switch (0x%08x)",
3426 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003427 }
3428
3429 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303430 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3431 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003432 ) {
3433 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3434 }
3435
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303436 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003437 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303438 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003439 TXRX_FRM_802_11_MGMT,
3440 ANI_TXDIR_TODS,
3441 7, lim_tx_complete, pFrame, txFlag,
3442 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303443 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303444 psessionEntry->peSessionId, qdf_status));
3445 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003446 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303447 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003448 /* Pkt will be freed up by the callback */
3449 return eSIR_FAILURE;
3450 }
3451
3452 return eSIR_SUCCESS;
3453
3454} /* End lim_send_channel_switch_mgmt_frame. */
3455
Abhishek Singh518323d2015-10-19 17:42:01 +05303456/**
3457 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
3458 * action frame over the air .
3459 * @mac_ctx: pointer to global mac structure
3460 * @peer: Destination mac.
3461 * @mode: channel switch mode
3462 * @new_op_class: new op class
3463 * @new_channel: new channel to switch
3464 * @count: channel switch count
3465 *
3466 * This function is called to send ECSA frame.
3467 *
3468 * Return: success if frame is sent else return failure
3469 */
3470
3471tSirRetStatus
3472lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
3473 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
3474 uint8_t new_channel, uint8_t count, tpPESession session_entry)
3475{
3476 tDot11fext_channel_switch_action_frame frm;
3477 uint8_t *frame;
3478 tpSirMacMgmtHdr mac_hdr;
3479 uint32_t num_bytes, n_payload, status;
3480 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303481 QDF_STATUS qdf_status;
Abhishek Singh518323d2015-10-19 17:42:01 +05303482 uint8_t txFlag = 0;
3483 uint8_t sme_session_id = 0;
3484
3485 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003486 pe_err("Session entry is NULL!!!");
Abhishek Singh518323d2015-10-19 17:42:01 +05303487 return eSIR_FAILURE;
3488 }
3489
3490 sme_session_id = session_entry->smeSessionId;
3491
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303492 qdf_mem_set(&frm, sizeof(frm), 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303493
3494 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
3495 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
3496
3497 frm.ext_chan_switch_ann_action.switch_mode = mode;
3498 frm.ext_chan_switch_ann_action.op_class = new_op_class;
3499 frm.ext_chan_switch_ann_action.new_channel = new_channel;
3500 frm.ext_chan_switch_ann_action.switch_count = count;
3501
3502
3503 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
3504 &frm, &n_payload);
3505 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003506 pe_err("Failed to get packed size for Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303507 status);
3508 /* We'll fall back on the worst case scenario*/
3509 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
3510 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003511 pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)",
Abhishek Singh518323d2015-10-19 17:42:01 +05303512 status);
3513 }
3514
3515 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3516
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303517 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303518 (void **) &frame, (void **) &packet);
3519
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303520 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003521 pe_err("Failed to allocate %d bytes for a Ext Channel Switch",
Abhishek Singh518323d2015-10-19 17:42:01 +05303522 num_bytes);
3523 return eSIR_FAILURE;
3524 }
3525
3526 /* Paranoia*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303527 qdf_mem_set(frame, num_bytes, 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303528
3529 /* Next, we fill out the buffer descriptor */
3530 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3531 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3532 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303533 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Abhishek Singh518323d2015-10-19 17:42:01 +05303534 (uint8_t *) session_entry->bssId,
3535 sizeof(tSirMacAddr));
3536
3537 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
3538 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3539 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003540 pe_err("Failed to pack a Channel Switch 0x%08x", status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303541 cds_packet_free((void *)packet);
3542 return eSIR_FAILURE;
3543 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003544 pe_warn("There were warnings while packing a Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303545 status);
3546 }
3547
3548 if ((SIR_BAND_5_GHZ ==
3549 lim_get_rf_band(session_entry->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05303550 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3551 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303552 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3553 }
3554
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003555 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 +05303556 MAC_ADDR_ARRAY(mac_hdr->da),
3557 frm.ext_chan_switch_ann_action.switch_count,
3558 frm.ext_chan_switch_ann_action.switch_mode,
3559 frm.ext_chan_switch_ann_action.new_channel,
3560 frm.ext_chan_switch_ann_action.op_class);
3561
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303562 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Abhishek Singh518323d2015-10-19 17:42:01 +05303563 session_entry->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303564 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303565 TXRX_FRM_802_11_MGMT,
3566 ANI_TXDIR_TODS,
3567 7,
3568 lim_tx_complete, frame,
3569 txFlag, sme_session_id, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303570 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303571 session_entry->peSessionId, qdf_status));
3572 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003573 pe_err("Failed to send a Ext Channel Switch %X!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303574 qdf_status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303575 /* Pkt will be freed up by the callback */
3576 return eSIR_FAILURE;
3577 }
3578 return eSIR_SUCCESS;
3579} /* End lim_send_extended_chan_switch_action_frame */
3580
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303581
3582/**
3583 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
3584 * sent over the air
3585 *
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303586 * @context: pointer to global mac
3587 * @buf: buffer
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303588 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303589 * @params: tx completion params
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303590 *
3591 * Return: This returns QDF_STATUS
3592 */
3593
3594static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303595 void *context,
3596 qdf_nbuf_t buf,
3597 uint32_t tx_complete,
3598 void *params)
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303599{
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003600 pe_debug("tx_complete: %d", tx_complete);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303601 return QDF_STATUS_SUCCESS;
3602}
3603
3604/**
3605 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
3606 * p2p oper chan change confirm action frame
3607 * @mac_ctx: pointer to global mac structure
3608 * @peer: Destination mac.
3609 * @session_entry: session entry
3610 *
3611 * This function is called to send p2p oper chan change confirm action frame.
3612 *
3613 * Return: success if frame is sent else return failure
3614 */
3615
3616tSirRetStatus
3617lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
3618 tSirMacAddr peer, tpPESession session_entry)
3619{
3620 tDot11fp2p_oper_chan_change_confirm frm;
3621 uint8_t *frame;
3622 tpSirMacMgmtHdr mac_hdr;
3623 uint32_t num_bytes, n_payload, status;
3624 void *packet;
3625 QDF_STATUS qdf_status;
3626 uint8_t tx_flag = 0;
3627 uint8_t sme_session_id = 0;
3628
3629 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003630 pe_err("Session entry is NULL!!!");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303631 return eSIR_FAILURE;
3632 }
3633
3634 sme_session_id = session_entry->smeSessionId;
3635
3636 qdf_mem_set(&frm, sizeof(frm), 0);
3637
3638 frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
3639
3640 qdf_mem_copy(frm.p2p_action_oui.oui_data,
3641 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
3642 frm.p2p_action_subtype.subtype = 0x04;
3643 frm.DialogToken.token = 0x0;
3644
3645 if (session_entry->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003646 pe_debug("Populate HT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303647 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
3648 }
3649
3650 if (session_entry->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003651 pe_debug("Populate VHT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303652 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
3653 populate_dot11f_operating_mode(mac_ctx,
3654 &frm.OperatingMode, session_entry);
3655 }
3656
3657 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
3658 &frm, &n_payload);
3659 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003660 pe_err("Failed to get packed size 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303661 /* We'll fall back on the worst case scenario*/
3662 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
3663 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003664 pe_warn("There were warnings while calculating the packed size (0x%08x)",
3665 status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303666 }
3667
3668 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3669
3670 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
3671 (void **) &frame, (void **) &packet);
3672
3673 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003674 pe_err("Failed to allocate %d bytes", num_bytes);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303675 return eSIR_FAILURE;
3676 }
3677
3678 qdf_mem_set(frame, num_bytes, 0);
3679
3680 /* Next, fill out the buffer descriptor */
3681 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3682 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3683 mac_hdr = (tpSirMacMgmtHdr) frame;
3684 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
3685 (uint8_t *) session_entry->bssId,
3686 sizeof(tSirMacAddr));
3687
3688 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
3689 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3690 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003691 pe_err("Failed to pack 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303692 cds_packet_free((void *)packet);
3693 return eSIR_FAILURE;
3694 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003695 pe_warn("There were warnings while packing 0x%08x",
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303696 status);
3697 }
3698
3699 if ((SIR_BAND_5_GHZ ==
3700 lim_get_rf_band(session_entry->currentOperChannel)) ||
3701 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3702 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
3703 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3704 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003705 pe_debug("Send frame on channel %d to mac "
3706 MAC_ADDRESS_STR, session_entry->currentOperChannel,
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303707 MAC_ADDR_ARRAY(peer));
3708
3709 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3710 session_entry->peSessionId, mac_hdr->fc.subType));
3711
3712 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
3713 (uint16_t)num_bytes,
3714 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3715 7, lim_tx_complete, frame,
3716 lim_oper_chan_change_confirm_tx_complete_cnf,
3717 tx_flag, sme_session_id, false, 0);
3718
3719 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3720 session_entry->peSessionId, qdf_status));
3721 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003722 pe_err("Failed to send status %X!", qdf_status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303723 /* Pkt will be freed up by the callback */
3724 return eSIR_FAILURE;
3725 }
3726 return eSIR_SUCCESS;
3727}
3728
3729
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003730tSirRetStatus
3731lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
3732 tSirMacAddr peer,
3733 uint8_t nMode, tpPESession psessionEntry)
3734{
3735 tDot11fOperatingMode frm;
3736 uint8_t *pFrame;
3737 tpSirMacMgmtHdr pMacHdr;
3738 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
3739 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303740 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741 uint8_t txFlag = 0;
3742
3743 uint8_t smeSessionId = 0;
3744
3745 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003746 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003747 return eSIR_FAILURE;
3748 }
3749 smeSessionId = psessionEntry->smeSessionId;
3750
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303751 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003752
3753 frm.Category.category = SIR_MAC_ACTION_VHT;
3754 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
3755 frm.OperatingMode.chanWidth = nMode;
3756 frm.OperatingMode.rxNSS = 0;
3757 frm.OperatingMode.rxNSSType = 0;
3758
3759 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
3760 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003761 pe_err("Failed to calculate the packed size for a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003762 nStatus);
3763 /* We'll fall back on the worst case scenario: */
3764 nPayload = sizeof(tDot11fOperatingMode);
3765 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003766 pe_warn("There were warnings while calculating the packed size for a Operating Mode (0x%08x)",
3767 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003768 }
3769
3770 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3771
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303772 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003773 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3774 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303775 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003776 pe_err("Failed to allocate %d bytes for a Operating Mode Report",
3777 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003778 return eSIR_FAILURE;
3779 }
3780 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303781 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003782
3783 /* Next, we fill out the buffer descriptor: */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303784 if (psessionEntry->pePersona == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003785 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3786 SIR_MAC_MGMT_ACTION, peer,
3787 psessionEntry->selfMacAddr);
3788 else
3789 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3790 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
3791 psessionEntry->selfMacAddr);
3792 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303793 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003794 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3795 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
3796 sizeof(tSirMacMgmtHdr),
3797 nPayload, &nPayload);
3798 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003799 pe_err("Failed to pack a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003800 nStatus);
3801 cds_packet_free((void *)pPacket);
3802 return eSIR_FAILURE; /* allocated! */
3803 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003804 pe_warn("There were warnings while packing a Operating Mode (0x%08x)",
3805 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003806 }
3807 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303808 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3809 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003810 ) {
3811 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3812 }
3813
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303814 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003815 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303816 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003817 TXRX_FRM_802_11_MGMT,
3818 ANI_TXDIR_TODS,
3819 7, lim_tx_complete, pFrame, txFlag,
3820 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303821 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303822 psessionEntry->peSessionId, qdf_status));
3823 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003824 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303825 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003826 /* Pkt will be freed up by the callback */
3827 return eSIR_FAILURE;
3828 }
3829
3830 return eSIR_SUCCESS;
3831}
3832
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003833/**
3834 * \brief Send a Neighbor Report Request Action frame
3835 *
3836 *
3837 * \param pMac Pointer to the global MAC structure
3838 *
3839 * \param pNeighborReq Address of a tSirMacNeighborReportReq
3840 *
3841 * \param peer mac address of peer station.
3842 *
3843 * \param psessionEntry address of session entry.
3844 *
3845 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3846 *
3847 *
3848 */
3849
3850tSirRetStatus
3851lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
3852 tpSirMacNeighborReportReq pNeighborReq,
3853 tSirMacAddr peer, tpPESession psessionEntry)
3854{
3855 tSirRetStatus statusCode = eSIR_SUCCESS;
3856 tDot11fNeighborReportRequest frm;
3857 uint8_t *pFrame;
3858 tpSirMacMgmtHdr pMacHdr;
3859 uint32_t nBytes, nPayload, nStatus;
3860 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303861 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003862 uint8_t txFlag = 0;
3863 uint8_t smeSessionId = 0;
3864
3865 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003866 pe_err("(psession == NULL) in Request to send Neighbor Report request action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003867 return eSIR_FAILURE;
3868 }
3869 smeSessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303870 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871
3872 frm.Category.category = SIR_MAC_ACTION_RRM;
3873 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
3874 frm.DialogToken.token = pNeighborReq->dialogToken;
3875
3876 if (pNeighborReq->ssid_present) {
3877 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
3878 }
3879
3880 nStatus =
3881 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
3882 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003883 pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003884 nStatus);
3885 /* We'll fall back on the worst case scenario: */
3886 nPayload = sizeof(tDot11fNeighborReportRequest);
3887 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003888 pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)",
3889 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003890 }
3891
3892 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3893
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303894 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003895 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3896 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303897 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003898 pe_err("Failed to allocate %d bytes for a Neighbor "
3899 "Report Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003900 return eSIR_FAILURE;
3901 }
3902 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303903 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003904
3905 /* Copy necessary info to BD */
3906 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3907 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
3908
3909 /* Update A3 with the BSSID */
3910 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3911
3912 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3913
3914#ifdef WLAN_FEATURE_11W
3915 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3916#endif
3917
3918 /* Now, we're ready to "pack" the frames */
3919 nStatus = dot11f_pack_neighbor_report_request(pMac,
3920 &frm,
3921 pFrame +
3922 sizeof(tSirMacMgmtHdr),
3923 nPayload, &nPayload);
3924
3925 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003926 pe_err("Failed to pack an Neighbor Report Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003927 nStatus);
3928
3929 /* FIXME - Need to convert to tSirRetStatus */
3930 statusCode = eSIR_FAILURE;
3931 goto returnAfterError;
3932 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003933 pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)",
3934 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003935 }
3936
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003937 pe_debug("Sending a Neighbor Report Request to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +05303938 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003939
3940 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303941 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3942 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003943 ) {
3944 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3945 }
3946
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303947 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003948 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303949 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003950 pPacket,
3951 (uint16_t) nBytes,
3952 TXRX_FRM_802_11_MGMT,
3953 ANI_TXDIR_TODS,
3954 7, lim_tx_complete, pFrame, txFlag,
3955 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303956 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303957 psessionEntry->peSessionId, qdf_status));
3958 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003959 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003960 statusCode = eSIR_FAILURE;
3961 /* Pkt will be freed up by the callback */
3962 return statusCode;
3963 } else
3964 return eSIR_SUCCESS;
3965
3966returnAfterError:
3967 cds_packet_free((void *)pPacket);
3968
3969 return statusCode;
3970} /* End lim_send_neighbor_report_request_frame. */
3971
3972/**
3973 * \brief Send a Link Report Action frame
3974 *
3975 *
3976 * \param pMac Pointer to the global MAC structure
3977 *
3978 * \param pLinkReport Address of a tSirMacLinkReport
3979 *
3980 * \param peer mac address of peer station.
3981 *
3982 * \param psessionEntry address of session entry.
3983 *
3984 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3985 *
3986 *
3987 */
3988
3989tSirRetStatus
3990lim_send_link_report_action_frame(tpAniSirGlobal pMac,
3991 tpSirMacLinkReport pLinkReport,
3992 tSirMacAddr peer, tpPESession psessionEntry)
3993{
3994 tSirRetStatus statusCode = eSIR_SUCCESS;
3995 tDot11fLinkMeasurementReport frm;
3996 uint8_t *pFrame;
3997 tpSirMacMgmtHdr pMacHdr;
3998 uint32_t nBytes, nPayload, nStatus;
3999 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304000 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004001 uint8_t txFlag = 0;
4002 uint8_t smeSessionId = 0;
4003
4004 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004005 pe_err("(psession == NULL) in Request to send Link Report action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004006 return eSIR_FAILURE;
4007 }
4008
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304009 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004010
4011 frm.Category.category = SIR_MAC_ACTION_RRM;
4012 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
4013 frm.DialogToken.token = pLinkReport->dialogToken;
4014
4015 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
4016 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
4017 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
4018 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
4019 /* such case this way than changing the frame parser. */
4020 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
4021 frm.TPCEleLen.TPCLen = 2;
4022 frm.TxPower.txPower = pLinkReport->txPower;
4023 frm.LinkMargin.linkMargin = 0;
4024
4025 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4026 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4027 frm.RCPI.rcpi = pLinkReport->rcpi;
4028 frm.RSNI.rsni = pLinkReport->rsni;
4029
4030 nStatus =
4031 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4032 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004033 pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004034 /* We'll fall back on the worst case scenario: */
4035 nPayload = sizeof(tDot11fLinkMeasurementReport);
4036 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004037 pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)",
4038 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004039 }
4040
4041 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4042
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304043 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004044 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4045 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304046 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004047 pe_err("Failed to allocate %d bytes for a Link "
4048 "Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004049 return eSIR_FAILURE;
4050 }
4051 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304052 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004053
4054 /* Copy necessary info to BD */
4055 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4056 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4057
4058 /* Update A3 with the BSSID */
4059 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4060
4061 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4062
4063#ifdef WLAN_FEATURE_11W
4064 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4065#endif
4066
4067 /* Now, we're ready to "pack" the frames */
4068 nStatus = dot11f_pack_link_measurement_report(pMac,
4069 &frm,
4070 pFrame +
4071 sizeof(tSirMacMgmtHdr),
4072 nPayload, &nPayload);
4073
4074 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004075 pe_err("Failed to pack an Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004076
4077 /* FIXME - Need to convert to tSirRetStatus */
4078 statusCode = eSIR_FAILURE;
4079 goto returnAfterError;
4080 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004081 pe_warn("There were warnings while packing Link Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082 nStatus);
4083 }
4084
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004085 pe_warn("Sending a Link Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004086 lim_print_mac_addr(pMac, peer, LOGW);
4087
4088 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304089 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4090 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004091 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4092 }
4093
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304094 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004095 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304096 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004097 pPacket,
4098 (uint16_t) nBytes,
4099 TXRX_FRM_802_11_MGMT,
4100 ANI_TXDIR_TODS,
4101 7, lim_tx_complete, pFrame, txFlag,
4102 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304103 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304104 psessionEntry->peSessionId, qdf_status));
4105 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004106 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004107 statusCode = eSIR_FAILURE;
4108 /* Pkt will be freed up by the callback */
4109 return statusCode;
4110 } else
4111 return eSIR_SUCCESS;
4112
4113returnAfterError:
4114 cds_packet_free((void *)pPacket);
4115
4116 return statusCode;
4117} /* End lim_send_link_report_action_frame. */
4118
4119/**
4120 * \brief Send a Beacon Report Action frame
4121 *
4122 *
4123 * \param pMac Pointer to the global MAC structure
4124 *
4125 * \param dialog_token dialog token to be used in the action frame.
4126 *
4127 * \param num_report number of reports in pRRMReport.
4128 *
4129 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4130 *
4131 * \param peer mac address of peer station.
4132 *
4133 * \param psessionEntry address of session entry.
4134 *
4135 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4136 *
4137 *
4138 */
4139
4140tSirRetStatus
4141lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4142 uint8_t dialog_token,
4143 uint8_t num_report,
4144 tpSirMacRadioMeasureReport pRRMReport,
4145 tSirMacAddr peer,
4146 tpPESession psessionEntry)
4147{
4148 tSirRetStatus statusCode = eSIR_SUCCESS;
4149 uint8_t *pFrame;
4150 tpSirMacMgmtHdr pMacHdr;
4151 uint32_t nBytes, nPayload, nStatus;
4152 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304153 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004154 uint8_t i;
4155 uint8_t txFlag = 0;
4156 uint8_t smeSessionId = 0;
4157
4158 tDot11fRadioMeasurementReport *frm =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304159 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004160 if (!frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004161 pe_err("Not enough memory to allocate tDot11fRadioMeasurementReport");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004162 return eSIR_MEM_ALLOC_FAILED;
4163 }
4164
4165 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004166 pe_err("(psession == NULL) in Request to send Beacon Report action frame");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304167 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004168 return eSIR_FAILURE;
4169 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004170
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004171 pe_debug("dialog_token %d num_report %d",
Padma, Santhosh Kumar93ec7d22016-12-26 15:58:37 +05304172 dialog_token, num_report);
4173
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004174 frm->Category.category = SIR_MAC_ACTION_RRM;
4175 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4176 frm->DialogToken.token = dialog_token;
4177
4178 frm->num_MeasurementReport =
4179 (num_report >
4180 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4181 num_report;
4182
4183 for (i = 0; i < frm->num_MeasurementReport; i++) {
4184 frm->MeasurementReport[i].type = pRRMReport[i].type;
4185 frm->MeasurementReport[i].token = pRRMReport[i].token;
4186 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4187 switch (pRRMReport[i].type) {
4188 case SIR_MAC_RRM_BEACON_TYPE:
4189 populate_dot11f_beacon_report(pMac,
4190 &frm->MeasurementReport[i],
4191 &pRRMReport[i].report.
4192 beaconReport);
4193 frm->MeasurementReport[i].incapable =
4194 pRRMReport[i].incapable;
4195 frm->MeasurementReport[i].refused =
4196 pRRMReport[i].refused;
4197 frm->MeasurementReport[i].present = 1;
4198 break;
4199 default:
4200 frm->MeasurementReport[i].incapable =
4201 pRRMReport[i].incapable;
4202 frm->MeasurementReport[i].refused =
4203 pRRMReport[i].refused;
4204 frm->MeasurementReport[i].present = 1;
4205 break;
4206 }
4207 }
4208
4209 nStatus =
4210 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4211 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004212 pe_err("Failed to calculate the packed size for a Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004213 nStatus);
4214 /* We'll fall back on the worst case scenario: */
4215 nPayload = sizeof(tDot11fLinkMeasurementReport);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304216 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004217 return eSIR_FAILURE;
4218 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004219 pe_warn("There were warnings while calculating the packed size for a Radio Measure Report (0x%08x)",
4220 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004221 }
4222
4223 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4224
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304225 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4227 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304228 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004229 pe_err("Failed to allocate %d bytes for a Radio Measure "
4230 "Report", nBytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304231 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004232 return eSIR_FAILURE;
4233 }
4234 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304235 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004236
4237 /* Copy necessary info to BD */
4238 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4239 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4240
4241 /* Update A3 with the BSSID */
4242 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4243
4244 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4245
4246#ifdef WLAN_FEATURE_11W
4247 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4248#endif
4249
4250 /* Now, we're ready to "pack" the frames */
4251 nStatus = dot11f_pack_radio_measurement_report(pMac,
4252 frm,
4253 pFrame +
4254 sizeof(tSirMacMgmtHdr),
4255 nPayload, &nPayload);
4256
4257 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004258 pe_err("Failed to pack an Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004259 nStatus);
4260
4261 /* FIXME - Need to convert to tSirRetStatus */
4262 statusCode = eSIR_FAILURE;
4263 goto returnAfterError;
4264 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004265 pe_warn("There were warnings while packing Radio Measure Report (0x%08x)",
4266 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004267 }
4268
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004269 pe_warn("Sending a Radio Measure Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004270 lim_print_mac_addr(pMac, peer, LOGW);
4271
4272 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304273 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4274 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275 ) {
4276 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4277 }
4278
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304279 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004280 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304281 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004282 pPacket,
4283 (uint16_t) nBytes,
4284 TXRX_FRM_802_11_MGMT,
4285 ANI_TXDIR_TODS,
4286 7, lim_tx_complete, pFrame, txFlag,
4287 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304288 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304289 psessionEntry->peSessionId, qdf_status));
4290 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004291 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004292 statusCode = eSIR_FAILURE;
4293 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304294 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004295 return statusCode;
4296 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304297 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004298 return eSIR_SUCCESS;
4299 }
4300
4301returnAfterError:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304302 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004303 cds_packet_free((void *)pPacket);
4304 return statusCode;
4305}
4306
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004307#ifdef WLAN_FEATURE_11W
4308/**
4309 * \brief Send SA query request action frame to peer
4310 *
4311 * \sa lim_send_sa_query_request_frame
4312 *
4313 *
4314 * \param pMac The global tpAniSirGlobal object
4315 *
4316 * \param transId Transaction identifier
4317 *
4318 * \param peer The Mac address of the station to which this action frame is addressed
4319 *
4320 * \param psessionEntry The PE session entry
4321 *
4322 * \return eSIR_SUCCESS if setup completes successfully
4323 * eSIR_FAILURE is some problem is encountered
4324 */
4325
4326tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4327 tSirMacAddr peer,
4328 tpPESession psessionEntry)
4329{
4330
4331 tDot11fSaQueryReq frm; /* SA query request action frame */
4332 uint8_t *pFrame;
4333 tSirRetStatus nSirStatus;
4334 tpSirMacMgmtHdr pMacHdr;
4335 uint32_t nBytes, nPayload, nStatus;
4336 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304337 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004338 uint8_t txFlag = 0;
4339 uint8_t smeSessionId = 0;
4340
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304341 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004342 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4343 /* 11w action field is :
4344 action: 0 --> SA Query Request action frame
4345 action: 1 --> SA Query Response action frame */
4346 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4347 /* 11w SA Query Request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304348 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004349
4350 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4351 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004352 pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004353 nStatus);
4354 /* We'll fall back on the worst case scenario: */
4355 nPayload = sizeof(tDot11fSaQueryReq);
4356 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004357 pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)",
4358 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004359 }
4360
4361 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304362 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004363 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304364 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004365 pe_err("Failed to allocate %d bytes for a SA Query Request "
4366 "action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004367 return eSIR_FAILURE;
4368 }
4369 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304370 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004371
4372 /* Copy necessary info to BD */
4373 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4374 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4375
4376 /* Update A3 with the BSSID */
4377 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4378
4379 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4380
4381 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4382 /* in the FC */
4383 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4384
4385 /* Pack 11w SA Query Request frame */
4386 nStatus = dot11f_pack_sa_query_req(pMac,
4387 &frm,
4388 pFrame + sizeof(tSirMacMgmtHdr),
4389 nPayload, &nPayload);
4390
4391 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004392 pe_err("Failed to pack an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004393 nStatus);
4394 /* FIXME - Need to convert to tSirRetStatus */
4395 nSirStatus = eSIR_FAILURE;
4396 goto returnAfterError;
4397 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004398 pe_warn("There were warnings while packing SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004399 nStatus);
4400 }
4401
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004402 pe_debug("Sending an SA Query Request to");
4403 lim_print_mac_addr(pMac, peer, LOGD);
4404 pe_debug("Sending an SA Query Request from ");
4405 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004406
4407 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4408#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304409 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4410 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004411#endif
4412 ) {
4413 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4414 }
4415 smeSessionId = psessionEntry->smeSessionId;
4416
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304417 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004418 pPacket,
4419 (uint16_t) nBytes,
4420 TXRX_FRM_802_11_MGMT,
4421 ANI_TXDIR_TODS,
4422 7, lim_tx_complete, pFrame, txFlag,
4423 smeSessionId, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304424 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004425 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004426 nSirStatus = eSIR_FAILURE;
4427 /* Pkt will be freed up by the callback */
4428 return nSirStatus;
4429 } else {
4430 return eSIR_SUCCESS;
4431 }
4432
4433returnAfterError:
4434 cds_packet_free((void *)pPacket);
4435 return nSirStatus;
4436} /* End lim_send_sa_query_request_frame */
4437
4438/**
4439 * \brief Send SA query response action frame to peer
4440 *
4441 * \sa lim_send_sa_query_response_frame
4442 *
4443 *
4444 * \param pMac The global tpAniSirGlobal object
4445 *
4446 * \param transId Transaction identifier received in SA query request action frame
4447 *
4448 * \param peer The Mac address of the AP to which this action frame is addressed
4449 *
4450 * \param psessionEntry The PE session entry
4451 *
4452 * \return eSIR_SUCCESS if setup completes successfully
4453 * eSIR_FAILURE is some problem is encountered
4454 */
4455
4456tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
4457 uint8_t *transId, tSirMacAddr peer,
4458 tpPESession psessionEntry)
4459{
4460
4461 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
4462 uint8_t *pFrame;
4463 tSirRetStatus nSirStatus;
4464 tpSirMacMgmtHdr pMacHdr;
4465 uint32_t nBytes, nPayload, nStatus;
4466 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304467 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004468 uint8_t txFlag = 0;
4469 uint8_t smeSessionId = 0;
4470
4471 smeSessionId = psessionEntry->smeSessionId;
4472
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304473 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004474 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4475 /*11w action field is :
4476 action: 0 --> SA query request action frame
4477 action: 1 --> SA query response action frame */
4478 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
4479 /*11w SA query response transId is same as
4480 SA query request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304481 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004482
4483 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
4484 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004485 pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004486 nStatus);
4487 /* We'll fall back on the worst case scenario: */
4488 nPayload = sizeof(tDot11fSaQueryRsp);
4489 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004490 pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)",
4491 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004492 }
4493
4494 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304495 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004496 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304497 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004498 pe_err("Failed to allocate %d bytes for a SA query response"
4499 " action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004500 return eSIR_FAILURE;
4501 }
4502 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304503 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004504
4505 /* Copy necessary info to BD */
4506 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4507 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4508
4509 /* Update A3 with the BSSID */
4510 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4511
4512 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4513
4514 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
4515 /* in the FC */
4516 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4517
4518 /* Pack 11w SA query response frame */
4519 nStatus = dot11f_pack_sa_query_rsp(pMac,
4520 &frm,
4521 pFrame + sizeof(tSirMacMgmtHdr),
4522 nPayload, &nPayload);
4523
4524 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004525 pe_err("Failed to pack an SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004526 nStatus);
4527 /* FIXME - Need to convert to tSirRetStatus */
4528 nSirStatus = eSIR_FAILURE;
4529 goto returnAfterError;
4530 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004531 pe_warn("There were warnings while packing SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004532 nStatus);
4533 }
4534
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004535 pe_debug("Sending a SA Query Response to");
Srinivas Girigowdaf936d822017-03-19 23:23:59 -07004536 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004537
4538 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4539#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304540 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4541 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004542#endif
4543 ) {
4544 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4545 }
4546
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304547 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004548 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304549 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004550 pPacket,
4551 (uint16_t) nBytes,
4552 TXRX_FRM_802_11_MGMT,
4553 ANI_TXDIR_TODS,
4554 7, lim_tx_complete, pFrame, txFlag,
4555 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304556 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304557 psessionEntry->peSessionId, qdf_status));
4558 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004559 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004560 nSirStatus = eSIR_FAILURE;
4561 /* Pkt will be freed up by the callback */
4562 return nSirStatus;
4563 } else {
4564 return eSIR_SUCCESS;
4565 }
4566
4567returnAfterError:
4568 cds_packet_free((void *)pPacket);
4569 return nSirStatus;
4570} /* End lim_send_sa_query_response_frame */
4571#endif
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004572
4573/**
4574 * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
4575 * @mac_ctx: mac context
4576 * @peer_mac: Peer MAC address
4577 * @tid: TID for which addba response is being sent
4578 * @session: PE session entry
4579 *
4580 * This function is called when ADDBA request is successful. ADDBA response is
4581 * setup by calling addba_response_setup API and frame is then sent out OTA.
4582 *
4583 * Return: QDF_STATUS
4584 */
4585QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
4586 tSirMacAddr peer_mac, uint16_t tid, tpPESession session)
4587{
4588
4589 tDot11faddba_rsp frm;
4590 uint8_t *frame_ptr;
4591 tpSirMacMgmtHdr mgmt_hdr;
4592 uint32_t num_bytes, payload_size, status;
4593 void *pkt_ptr;
4594 QDF_STATUS qdf_status;
4595 uint8_t tx_flag = 0;
4596 uint8_t sme_sessionid = 0;
4597 uint16_t buff_size, status_code, batimeout;
4598 uint8_t peer_id, dialog_token;
4599 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4600 void *peer, *pdev;
4601
4602 sme_sessionid = session->smeSessionId;
4603
4604 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4605 if (!pdev) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004606 pe_err("pdev is NULL");
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004607 return QDF_STATUS_E_FAILURE;
4608 }
4609
4610 peer = cdp_peer_find_by_addr(soc, pdev, peer_mac, &peer_id);
4611 if (!peer) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004612 pe_err("PEER [%pM] not found", peer_mac);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004613 return QDF_STATUS_E_FAILURE;
4614 }
4615
4616 cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
4617 &status_code, &buff_size, &batimeout);
4618
4619 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4620 frm.Category.category = SIR_MAC_ACTION_BLKACK;
4621 frm.Action.action = SIR_MAC_ADDBA_RSP;
4622
4623 frm.DialogToken.token = dialog_token;
4624 frm.Status.status = status_code;
4625 frm.addba_param_set.tid = tid;
4626 frm.addba_param_set.buff_size = buff_size;
4627 frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE;
4628 frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED;
4629 frm.ba_timeout.timeout = batimeout;
4630
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004631 pe_debug("Sending a ADDBA Response from %pM to %pM",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004632 session->selfMacAddr, peer_mac);
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004633 pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004634 tid, frm.DialogToken.token, frm.Status.status,
4635 frm.addba_param_set.buff_size);
4636
4637 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
4638 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004639 pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004640 status);
4641 /* We'll fall back on the worst case scenario: */
4642 payload_size = sizeof(tDot11faddba_rsp);
4643 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004644 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 -08004645 }
4646
4647 num_bytes = payload_size + sizeof(*mgmt_hdr);
4648 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
4649 (void **)&pkt_ptr);
4650 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004651 pe_err("Failed to allocate %d bytes for a ADDBA response action frame",
4652 num_bytes);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004653 return QDF_STATUS_E_FAILURE;
4654 }
4655 qdf_mem_set(frame_ptr, num_bytes, 0);
4656
4657 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
4658 SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
4659
4660 /* Update A3 with the BSSID */
4661 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
4662 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
4663
4664 /* ADDBA Response is a robust mgmt action frame,
4665 * set the "protect" (aka WEP) bit in the FC
4666 */
4667 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
4668
4669 status = dot11f_pack_addba_rsp(mac_ctx, &frm,
4670 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
4671 &payload_size);
4672
4673 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004674 pe_err("Failed to pack a ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004675 status);
4676 qdf_status = QDF_STATUS_E_FAILURE;
4677 goto error_addba_rsp;
4678 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004679 pe_warn("There were warnings while packing ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004680 status);
4681 }
4682
4683
4684 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
4685#ifdef WLAN_FEATURE_P2P
4686 || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
4687 (session->pePersona == QDF_P2P_GO_MODE)
4688#endif
4689 ) {
4690 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4691 }
4692
4693 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4694 session->peSessionId, mgmt_hdr->fc.subType));
4695 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
4696 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
4697 lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0);
4698 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4699 session->peSessionId, qdf_status));
4700 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004701 pe_err("wma_tx_frame FAILED! Status [%d]",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004702 qdf_status);
4703 qdf_status = QDF_STATUS_E_FAILURE;
4704 /*
4705 * wma_tx_frame free memory in certain cases, free pkt_ptr
4706 * only if not freed already.
4707 */
4708 if (pkt_ptr)
4709 cds_packet_free((void *)pkt_ptr);
4710 return qdf_status;
4711 } else {
4712 return eSIR_SUCCESS;
4713 }
4714
4715error_addba_rsp:
4716 cds_packet_free((void *)pkt_ptr);
4717 return qdf_status;
4718}