blob: ea68f568f12eafcca17d21344e86d583f42f0ca2 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * \file lim_send_management_frames.c
30 *
31 * \brief Code for preparing and sending 802.11 Management frames
32 *
33 *
34 */
35
36#include "sir_api.h"
37#include "ani_global.h"
38#include "sir_mac_prot_def.h"
39#include "cfg_api.h"
40#include "utils_api.h"
41#include "lim_types.h"
42#include "lim_utils.h"
43#include "lim_security_utils.h"
44#include "lim_prop_exts_utils.h"
45#include "dot11f.h"
46#include "lim_sta_hash_api.h"
47#include "sch_api.h"
48#include "lim_send_messages.h"
49#include "lim_assoc_utils.h"
50#include "lim_ft.h"
51#ifdef WLAN_FEATURE_11W
52#include "wni_cfg.h"
53#endif
54
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080055#include "lim_ft_defs.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080056#include "lim_session.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053057#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053058#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059#include "cds_utils.h"
60#include "sme_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#include "rrm_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
63#include "wma_types.h"
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -080064#include <cdp_txrx_cmn.h>
Tushnim Bhattacharyya45ed04f2017-03-15 10:15:05 -070065#include <cdp_txrx_peer_ops.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080066
67/**
68 *
69 * \brief This function is called to add the sequence number to the
70 * management frames
71 *
72 * \param pMac Pointer to Global MAC structure
73 *
74 * \param pMacHdr Pointer to MAC management header
75 *
76 * The pMacHdr argument points to the MAC management header. The
77 * sequence number stored in the pMac structure will be incremented
78 * and updated to the MAC management header. The start sequence
79 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
80 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
81 * number will roll over.
82 *
83 */
Jeff Johnson38112a32016-10-07 07:30:50 -070084static void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085{
86 if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
87 pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
88 }
89
90 pMac->mgmtSeqNum++;
91
92 pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
93 pMacHdr->seqControl.seqNumHi =
94 ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
95}
96
97/**
98 *
99 * \brief This function is called before sending a p2p action frame
100 * inorder to add sequence numbers to action packets
101 *
102 * \param pMac Pointer to Global MAC structure
103 *
104 * \param pBD Pointer to the frame buffer that needs to be populate
105 *
106 * The pMacHdr argument points to the MAC management header. The
107 * sequence number stored in the pMac structure will be incremented
108 * and updated to the MAC management header. The start sequence
109 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
110 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
111 * number will roll over.
112 *
113 */
114void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
115{
116 tpSirMacMgmtHdr pMacHdr;
117
118 /* / Prepare MAC management header */
119 pMacHdr = (tpSirMacMgmtHdr) (pBD);
120
121 /* Prepare sequence number */
122 lim_add_mgmt_seq_num(pMac, pMacHdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700123 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800124 pMacHdr->seqControl.seqNumLo,
125 pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
126}
127
128/**
129 * lim_populate_mac_header() - Fill in 802.11 header of frame
130 *
131 * @mac_ctx: Pointer to Global MAC structure
132 * @buf: Pointer to the frame buffer that needs to be populate
133 * @type: 802.11 Type of the frame
134 * @sub_type: 802.11 Subtype of the frame
135 * @peer_addr: dst address
136 * @self_mac_addr: local mac address
137 *
138 * This function is called by various LIM modules to prepare the
139 * 802.11 frame MAC header
140 *
141 * The buf argument points to the beginning of the frame buffer to
142 * which - a) The 802.11 MAC header is set b) Following this MAC header
143 * will be the MGMT frame payload The payload itself is populated by the
144 * caller API
145 *
146 * Return: None
147 */
148
149void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
150 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
151 tSirMacAddr self_mac_addr)
152{
153 tpSirMacMgmtHdr mac_hdr;
154
155 /* Prepare MAC management header */
156 mac_hdr = (tpSirMacMgmtHdr) (buf);
157
158 /* Prepare FC */
159 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
160 mac_hdr->fc.type = type;
161 mac_hdr->fc.subType = sub_type;
162
163 /* Prepare Address 1 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530164 qdf_mem_copy((uint8_t *) mac_hdr->da,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800165 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
166
167 /* Prepare Address 2 */
168 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
169
170 /* Prepare Address 3 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530171 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
173
174 /* Prepare sequence number */
175 lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700176 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177 mac_hdr->seqControl.seqNumLo,
178 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
179}
180
181/**
182 * lim_send_probe_req_mgmt_frame() - send probe request management frame
183 * @mac_ctx: Pointer to Global MAC structure
184 * @ssid: SSID to be sent in Probe Request frame
185 * @bssid: BSSID to be sent in Probe Request frame
186 * @channel: Channel # on which the Probe Request is going out
187 * @self_macaddr: self MAC address
188 * @dot11mode: self dotllmode
189 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
190 * frame
191 * @additional_ie: if additional_ielen is non zero, include this field in the
192 * Probe Request frame
193 *
194 * This function is called by various LIM modules to send Probe Request frame
195 * during active scan/learn phase.
196 * Probe request is sent out in the following scenarios:
197 * --heartbeat failure: session needed
198 * --join req: session needed
199 * --foreground scan: no session
200 * --background scan: no session
201 * --sch_beacon_processing: to get EDCA parameters: session needed
202 *
203 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
204 */
205tSirRetStatus
206lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
207 tSirMacSSid *ssid,
208 tSirMacAddr bssid,
209 uint8_t channel,
210 tSirMacAddr self_macaddr,
211 uint32_t dot11mode,
212 uint32_t additional_ielen, uint8_t *additional_ie)
213{
214 tDot11fProbeRequest pr;
215 uint32_t status, bytes, payload;
216 uint8_t *frame;
217 void *packet;
Kapil Guptac03eb072016-08-09 14:01:36 +0530218 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219 tpPESession pesession;
220 uint8_t sessionid;
221 uint8_t *p2pie = NULL;
222 uint8_t txflag = 0;
223 uint8_t sme_sessionid = 0;
224 bool is_vht_enabled = false;
225 uint8_t txPower;
226 uint16_t addn_ielen = additional_ielen;
Kapil Guptac03eb072016-08-09 14:01:36 +0530227 bool extracted_ext_cap_flag = false;
228 tDot11fIEExtCap extracted_ext_cap;
229 tSirRetStatus sir_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230
231 /* The probe req should not send 11ac capabilieties if band is 2.4GHz,
232 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
233 * is false and dot11mode is 11ac set it to 11n.
234 */
235 if (channel <= SIR_11B_CHANNEL_END &&
236 (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
237 (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
238 WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
239 dot11mode = WNI_CFG_DOT11_MODE_11N;
240 /*
241 * session context may or may not be present, when probe request needs
242 * to be sent out. Following cases exist:
243 * --heartbeat failure: session needed
244 * --join req: session needed
245 * --foreground scan: no session
246 * --background scan: no session
247 * --sch_beacon_processing: to get EDCA parameters: session needed
248 * If session context does not exist, some IEs will be populated from
249 * CFGs, e.g. Supported and Extended rate set IEs
250 */
251 pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
252
253 if (pesession != NULL)
254 sme_sessionid = pesession->smeSessionId;
255
256 /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
257 /* and then hand it off to 'dot11f_pack_probe_request' (for */
258 /* serialization). We start by zero-initializing the structure: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530259 qdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800260
261 /* & delegating to assorted helpers: */
262 populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
263
264 if (addn_ielen && additional_ie)
265 p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
266
267 /*
268 * Don't include 11b rate if it is a P2P serach or probe request is
269 * sent by P2P Client
270 */
271 if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
272 (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
273 mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
274 ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530275 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 )
277 ) {
278 /*
279 * In the below API pass channel number > 14, do that it fills
280 * only 11a rates in supported rates
281 */
282 populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
283 pesession);
284 } else {
285 populate_dot11f_supp_rates(mac_ctx, channel,
286 &pr.SuppRates, pesession);
287
288 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
289 populate_dot11f_ext_supp_rates1(mac_ctx, channel,
290 &pr.ExtSuppRates);
291 }
292 }
293
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800294 /*
295 * Table 7-14 in IEEE Std. 802.11k-2008 says
296 * DS params "can" be present in RRM is disabled and "is" present if
297 * RRM is enabled. It should be ok even if we add it into probe req when
298 * RRM is not enabled.
299 */
300 populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
301 /* Call RRM module to get the tx power for management used. */
302 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
303 populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
304
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305
306 if (pesession != NULL) {
307 pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
308 /* Include HT Capability IE */
309 if (pesession->htCapability)
310 populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
311 } else { /* pesession == NULL */
312 if (IS_DOT11_MODE_HT(dot11mode))
313 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
314 }
315
316 /*
317 * Set channelbonding information as "disabled" when tunned to a
318 * 2.4 GHz channel
319 */
320 if (channel <= SIR_11B_CHANNEL_END) {
321 if (mac_ctx->roam.configParam.channelBondingMode24GHz
322 == PHY_SINGLE_CHANNEL_CENTERED) {
323 pr.HTCaps.supportedChannelWidthSet =
324 eHT_CHANNEL_WIDTH_20MHZ;
325 pr.HTCaps.shortGI40MHz = 0;
326 } else {
327 pr.HTCaps.supportedChannelWidthSet =
328 eHT_CHANNEL_WIDTH_40MHZ;
329 }
330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331 if (pesession != NULL) {
332 pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
333 /* Include VHT Capability IE */
334 if (pesession->vhtCapability) {
335 populate_dot11f_vht_caps(mac_ctx, pesession,
336 &pr.VHTCaps);
337 is_vht_enabled = true;
338 }
339 } else {
340 if (IS_DOT11_MODE_VHT(dot11mode)) {
341 populate_dot11f_vht_caps(mac_ctx, pesession,
342 &pr.VHTCaps);
343 is_vht_enabled = true;
344 }
345 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346 if (pesession != NULL)
347 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
348 pesession);
349
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +0530350 if (mac_ctx->roam.configParam.qcn_ie_support)
351 populate_dot11f_qcn_ie(&pr.QCN_IE);
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +0530352
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800353 if (IS_DOT11_MODE_HE(dot11mode) && NULL != pesession)
354 lim_update_session_he_capable(mac_ctx, pesession);
355
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700356 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800357 populate_dot11f_he_caps(mac_ctx, pesession, &pr.vendor_he_cap);
358
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359 if (addn_ielen) {
Kapil Guptac03eb072016-08-09 14:01:36 +0530360 qdf_mem_zero((uint8_t *)&extracted_ext_cap,
361 sizeof(tDot11fIEExtCap));
362 sir_status = lim_strip_extcap_update_struct(mac_ctx,
363 additional_ie,
364 &addn_ielen,
365 &extracted_ext_cap);
366 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700367 pe_debug("Unable to Stripoff ExtCap IE from Probe Req");
Kapil Guptac03eb072016-08-09 14:01:36 +0530368 } else {
369 struct s_ext_cap *p_ext_cap =
370 (struct s_ext_cap *)
371 extracted_ext_cap.bytes;
372 if (p_ext_cap->interworking_service)
373 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +0800374 extracted_ext_cap.num_bytes =
375 lim_compute_ext_cap_ie_length
376 (&extracted_ext_cap);
Kapil Guptac03eb072016-08-09 14:01:36 +0530377 extracted_ext_cap_flag =
Hu Wang411e0cc2016-10-28 14:56:01 +0800378 (extracted_ext_cap.num_bytes > 0);
Kapil Guptac03eb072016-08-09 14:01:36 +0530379 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380 }
381
Hu Wang411e0cc2016-10-28 14:56:01 +0800382 /*
383 * Extcap IE now support variable length, merge Extcap IE from addn_ie
384 * may change the frame size. Therefore, MUST merge ExtCap IE before
385 * dot11f get packed payload size.
386 */
387 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800388 lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800389
390 /* That's it-- now we pack it. First, how much space are we going to */
391 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
392 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700393 pe_err("Failed to calculate the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800394 status);
395 /* We'll fall back on the worst case scenario: */
396 payload = sizeof(tDot11fProbeRequest);
397 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700398 pe_warn("There were warnings while calculating the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800399 status);
400 }
401
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
403
404 /* Ok-- try to allocate some memory: */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530405 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530407 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700408 pe_err("Failed to allocate %d bytes for a Probe Request", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 return eSIR_MEM_ALLOC_FAILED;
410 }
411 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530412 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413
414 /* Next, we fill out the buffer descriptor: */
415 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
416 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
417
418 /* That done, pack the Probe Request: */
419 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
420 sizeof(tSirMacMgmtHdr),
421 payload, &payload);
422 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700423 pe_err("Failed to pack a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424 cds_packet_free((void *)packet);
425 return eSIR_FAILURE; /* allocated! */
426 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700427 pe_warn("There were warnings while packing a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 }
429 /* Append any AddIE if present. */
430 if (addn_ielen) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530431 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800432 additional_ie, addn_ielen);
433 payload += addn_ielen;
434 }
435
436 /* If this probe request is sent during P2P Search State, then we need
437 * to send it at OFDM rate.
438 */
439 if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
440 || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
441 mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
442 /*
443 * For unicast probe req mgmt from Join function we don't set
444 * above variables. So we need to add one more check whether it
445 * is pePersona is P2P_CLIENT or not
446 */
447 || ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530448 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 ) {
450 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
451 }
452
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530453 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 wma_tx_frame(mac_ctx, packet,
455 (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
456 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
457 lim_tx_complete, frame, txflag, sme_sessionid,
458 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530459 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700460 pe_err("could not send Probe Request frame!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 /* Pkt will be freed up by the callback */
462 return eSIR_FAILURE;
463 }
464
465 return eSIR_SUCCESS;
466} /* End lim_send_probe_req_mgmt_frame. */
467
Jeff Johnson38112a32016-10-07 07:30:50 -0700468static tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800469 uint8_t *addIE, uint16_t *addnIELen,
470 uint8_t probeReqP2pIe)
471{
472 /* If Probe request doesn't have P2P IE, then take out P2P IE
473 from additional IE */
474 if (!probeReqP2pIe) {
475 uint8_t *tempbuf = NULL;
476 uint16_t tempLen = 0;
477 int left = *addnIELen;
478 uint8_t *ptr = addIE;
479 uint8_t elem_id, elem_len;
480
481 if (NULL == addIE) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700482 pe_err("NULL addIE pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800483 return eSIR_FAILURE;
484 }
485
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530486 tempbuf = qdf_mem_malloc(left);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487 if (NULL == tempbuf) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700488 pe_err("Unable to allocate memory to store addn IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489 return eSIR_MEM_ALLOC_FAILED;
490 }
491
492 while (left >= 2) {
493 elem_id = ptr[0];
494 elem_len = ptr[1];
495 left -= 2;
496 if (elem_len > left) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700497 pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800498 elem_id, elem_len, left);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530499 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500 return eSIR_FAILURE;
501 }
502 if (!((SIR_MAC_EID_VENDOR == elem_id) &&
503 (memcmp
504 (&ptr[2], SIR_MAC_P2P_OUI,
505 SIR_MAC_P2P_OUI_SIZE) == 0))) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530506 qdf_mem_copy(tempbuf + tempLen, &ptr[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800507 elem_len + 2);
508 tempLen += (elem_len + 2);
509 }
510 left -= elem_len;
511 ptr += (elem_len + 2);
512 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530513 qdf_mem_copy(addIE, tempbuf, tempLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514 *addnIELen = tempLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530515 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 }
517 return eSIR_SUCCESS;
518}
519
520/**
521 * lim_send_probe_rsp_mgmt_frame() - Send probe response
522 *
523 * @mac_ctx: Handle for mac context
524 * @peer_macaddr: Mac address of requesting peer
525 * @ssid: SSID for response
526 * @n_staid: Station ID, currently unused.
527 * @pe_session: PE session id
528 * @keepalive: Keep alive flag. Currently unused.
529 * @preq_p2pie: P2P IE in incoming probe request
530 *
531 * Builds and sends probe response frame to the requesting peer
532 *
533 * Return: void
534 */
535
536void
537lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
538 tSirMacAddr peer_macaddr,
539 tpAniSSID ssid,
540 short n_staid,
541 uint8_t keepalive,
542 tpPESession pe_session, uint8_t preq_p2pie)
543{
544 tDot11fProbeResponse *frm;
545 tSirRetStatus sir_status;
Hu Wang411e0cc2016-10-28 14:56:01 +0800546 uint32_t cfg, payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800547 tpSirMacMgmtHdr mac_hdr;
548 uint8_t *frame;
Arif Hussainfbf50682016-06-15 12:57:43 -0700549 void *packet = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530550 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551 uint32_t addn_ie_present = false;
552
553 uint16_t addn_ie_len = 0;
554 uint32_t wps_ap = 0, tmp;
555 uint8_t tx_flag = 0;
556 uint8_t *add_ie = NULL;
557 uint8_t *p2p_ie = NULL;
558 uint8_t noalen = 0;
559 uint8_t total_noalen = 0;
560 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
561 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
562 uint8_t sme_sessionid = 0;
563 bool is_vht_enabled = false;
Padma, Santhosh Kumar92234472017-04-19 18:20:02 +0530564 tDot11fIEExtCap extracted_ext_cap = {0};
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530565 bool extracted_ext_cap_flag = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800566
567 /* We don't answer requests in this case*/
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700568 if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800569 return;
570
571 if (NULL == pe_session)
572 return;
573
574 /*
575 * In case when cac timer is running for this SAP session then
576 * avoid sending probe rsp out. It is violation of dfs specification.
577 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530578 if (((pe_session->pePersona == QDF_SAP_MODE) ||
579 (pe_session->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800580 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530581 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582 FL("CAC timer is running, probe response dropped"));
583 return;
584 }
585 sme_sessionid = pe_session->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530586 frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700588 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 return;
590 }
591
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 /*
593 * Fill out 'frm', after which we'll just hand the struct off to
594 * 'dot11f_pack_probe_response'.
595 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530596 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597
598 /*
599 * Timestamp to be updated by TFP, below.
600 *
601 * Beacon Interval:
602 */
603 if (LIM_IS_AP_ROLE(pe_session)) {
604 frm->BeaconInterval.interval =
605 mac_ctx->sch.schObject.gSchBeaconInterval;
606 } else {
607 sir_status = wlan_cfg_get_int(mac_ctx,
608 WNI_CFG_BEACON_INTERVAL, &cfg);
609 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700610 pe_err("Failed to get WNI_CFG_BEACON_INTERVAL (%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 sir_status);
612 goto err_ret;
613 }
614 frm->BeaconInterval.interval = (uint16_t) cfg;
615 }
616
617 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
618 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
619 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
620 &frm->SuppRates, pe_session);
621
622 populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
623 pe_session->currentOperChannel);
624 populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
625
626 if (LIM_IS_AP_ROLE(pe_session)) {
627 if (pe_session->wps_state != SAP_WPS_DISABLED)
628 populate_dot11f_probe_res_wpsi_es(mac_ctx,
629 &frm->WscProbeRes,
630 pe_session);
631 } else {
632 if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
633 &tmp) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700634 pe_err("Failed to cfg get id %d", WNI_CFG_WPS_ENABLE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635
636 wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
637
638 if (wps_ap)
639 populate_dot11f_wsc_in_probe_res(mac_ctx,
640 &frm->WscProbeRes);
641
642 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
643 eLIM_WSC_ENROLL_BEGIN) {
644 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
645 &frm->WscProbeRes);
646 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
647 eLIM_WSC_ENROLL_IN_PROGRESS;
648 }
649
650 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
651 eLIM_WSC_ENROLL_END) {
652 de_populate_dot11f_wsc_registrar_info_in_probe_res(
653 mac_ctx, &frm->WscProbeRes);
654 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
655 eLIM_WSC_ENROLL_NOOP;
656 }
657 }
658
659 populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
660 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
661
662 if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
663 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
664
665 populate_dot11f_ext_supp_rates(mac_ctx,
666 POPULATE_DOT11F_RATES_OPERATIONAL,
667 &frm->ExtSuppRates, pe_session);
668
669 /* Populate HT IEs, when operating in 11n */
670 if (pe_session->htCapability) {
671 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
672 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
673 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 if (pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700675 pe_debug("Populate VHT IE in Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
677 populate_dot11f_vht_operation(mac_ctx, pe_session,
678 &frm->VHTOperation);
679 /*
680 * we do not support multi users yet.
681 * populate_dot11f_vht_ext_bss_load( mac_ctx,
682 * &frm.VHTExtBssLoad );
683 */
684 is_vht_enabled = true;
685 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800686
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800687 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700688 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800689 populate_dot11f_he_caps(mac_ctx, pe_session,
690 &frm->vendor_he_cap);
691 populate_dot11f_he_operation(mac_ctx, pe_session,
692 &frm->vendor_he_op);
693 }
694
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
696 pe_session);
697
698 if (pe_session->pLimStartBssReq) {
699 populate_dot11f_wpa(mac_ctx,
700 &(pe_session->pLimStartBssReq->rsnIE),
701 &frm->WPA);
702 populate_dot11f_rsn_opaque(mac_ctx,
703 &(pe_session->pLimStartBssReq->rsnIE),
704 &frm->RSNOpaque);
705 }
706
707 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
708 &frm->WMMCaps, pe_session);
709
710#if defined(FEATURE_WLAN_WAPI)
711 if (pe_session->pLimStartBssReq)
712 populate_dot11f_wapi(mac_ctx,
713 &(pe_session->pLimStartBssReq->rsnIE),
714 &frm->WAPI);
715#endif /* defined(FEATURE_WLAN_WAPI) */
716
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 if (mac_ctx->lim.gpLimRemainOnChanReq)
718 bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
719 sizeof(tSirRemainOnChnReq));
720 else
721 /*
722 * Only use CFG for non-listen mode. This CFG is not working for
723 * concurrency. In listening mode, probe rsp IEs is passed in
724 * the message from SME to PE.
725 */
726 addn_ie_present =
727 (pe_session->addIeParams.probeRespDataLen != 0);
728
729 if (addn_ie_present) {
730
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530731 add_ie = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800732 pe_session->addIeParams.probeRespDataLen);
733 if (NULL == add_ie) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700734 pe_err("add_ie allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735 goto err_ret;
736 }
737
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530738 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739 pe_session->addIeParams.probeRespData_buff,
740 pe_session->addIeParams.probeRespDataLen);
741 addn_ie_len = pe_session->addIeParams.probeRespDataLen;
742
743 if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
744 add_ie, &addn_ie_len, preq_p2pie)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700745 pe_err("Unable to get addn_ie");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800746 goto err_ret;
747 }
748
749 sir_status = lim_strip_extcap_update_struct(mac_ctx,
750 add_ie, &addn_ie_len,
751 &extracted_ext_cap);
752 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700753 pe_debug("Unable to strip off ExtCap IE");
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530754 } else {
755 extracted_ext_cap_flag = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 }
757
758 bytes = bytes + addn_ie_len;
759
760 if (preq_p2pie)
761 p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
762 addn_ie_len);
763
764 if (p2p_ie != NULL) {
765 /* get NoA attribute stream P2P IE */
766 noalen = lim_get_noa_attr_stream(mac_ctx,
767 noa_stream, pe_session);
768 if (noalen != 0) {
769 total_noalen =
770 lim_build_p2p_ie(mac_ctx, &noa_ie[0],
771 &noa_stream[0], noalen);
772 bytes = bytes + total_noalen;
773 }
774 }
775 }
776
Hu Wang411e0cc2016-10-28 14:56:01 +0800777 /*
778 * Extcap IE now support variable length, merge Extcap IE from addn_ie
779 * may change the frame size. Therefore, MUST merge ExtCap IE before
780 * dot11f get packed payload size.
781 */
782 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800783 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
784 true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800785
786 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
787 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700788 pe_err("Probe Response size error (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800789 status);
790 /* We'll fall back on the worst case scenario: */
791 payload = sizeof(tDot11fProbeResponse);
792 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700793 pe_warn("Probe Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800794 status);
795 }
796
797 bytes += payload + sizeof(tSirMacMgmtHdr);
798
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530799 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530801 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700802 pe_err("Probe Response allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 goto err_ret;
804 }
805 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530806 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807
808 /* Next, we fill out the buffer descriptor: */
809 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
810 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
811 pe_session->selfMacAddr);
812
813 mac_hdr = (tpSirMacMgmtHdr) frame;
814
815 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
816
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 /* That done, pack the Probe Response: */
818 status =
819 dot11f_pack_probe_response(mac_ctx, frm,
820 frame + sizeof(tSirMacMgmtHdr),
821 payload, &payload);
822 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700823 pe_err("Probe Response pack failure (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 status);
825 goto err_ret;
826 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700827 pe_warn("Probe Response pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800828 }
829
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700830 pe_debug("Sending Probe Response frame to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +0530831 lim_print_mac_addr(mac_ctx, peer_macaddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800832
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800833 if (mac_ctx->lim.gpLimRemainOnChanReq)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530834 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835 mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
836 (mac_ctx->lim.gpLimRemainOnChanReq->length -
837 sizeof(tSirRemainOnChnReq)));
838
839 if (addn_ie_present)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530840 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841 &add_ie[0], addn_ie_len);
842
843 if (noalen != 0) {
844 if (total_noalen >
845 (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700846 pe_err("Not able to insert NoA, total len=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847 total_noalen);
848 goto err_ret;
849 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530850 qdf_mem_copy(&frame[bytes - (total_noalen)],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851 &noa_ie[0], total_noalen);
852 }
853 }
854
855 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +0530856 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
857 (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800858 )
859 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
860
861 /* Queue Probe Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530862 qdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800863 (uint16_t) bytes,
864 TXRX_FRM_802_11_MGMT,
865 ANI_TXDIR_TODS,
866 7, lim_tx_complete, frame, tx_flag,
867 sme_sessionid, 0);
868
869 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530870 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700871 pe_err("Could not send Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872
873 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530874 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530876 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 return;
878
879err_ret:
880 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530881 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882 if (frm != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530883 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 if (packet != NULL)
885 cds_packet_free((void *)packet);
886 return;
887
888} /* End lim_send_probe_rsp_mgmt_frame. */
889
890void
891lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
892 tSirMacAddr peerMacAddr,
893 tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
894{
895 uint16_t i;
896 uint8_t *pFrame;
897 tDot11fAddTSRequest AddTSReq;
898 tDot11fWMMAddTSRequest WMMAddTSReq;
899 uint32_t nPayload, nBytes, nStatus;
900 tpSirMacMgmtHdr pMacHdr;
901 void *pPacket;
902#ifdef FEATURE_WLAN_ESE
903 uint32_t phyMode;
904#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530905 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800906 uint8_t txFlag = 0;
907 uint8_t smeSessionId = 0;
908
909 if (NULL == psessionEntry) {
910 return;
911 }
912
913 smeSessionId = psessionEntry->smeSessionId;
914
915 if (!pAddTS->wmeTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530916 qdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800917
918 AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
919 AddTSReq.DialogToken.token = pAddTS->dialogToken;
920 AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
921 if (pAddTS->lleTspecPresent) {
922 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
923 } else {
924 populate_dot11f_wmmtspec(&pAddTS->tspec,
925 &AddTSReq.WMMTSPEC);
926 }
927
928 if (pAddTS->lleTspecPresent) {
929 AddTSReq.num_WMMTCLAS = 0;
930 AddTSReq.num_TCLAS = pAddTS->numTclas;
931 for (i = 0; i < pAddTS->numTclas; ++i) {
932 populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
933 &AddTSReq.TCLAS[i]);
934 }
935 } else {
936 AddTSReq.num_TCLAS = 0;
937 AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
938 for (i = 0; i < pAddTS->numTclas; ++i) {
939 populate_dot11f_wmmtclas(pMac,
940 &pAddTS->tclasInfo[i],
941 &AddTSReq.WMMTCLAS[i]);
942 }
943 }
944
945 if (pAddTS->tclasProcPresent) {
946 if (pAddTS->lleTspecPresent) {
947 AddTSReq.TCLASSPROC.processing =
948 pAddTS->tclasProc;
949 AddTSReq.TCLASSPROC.present = 1;
950 } else {
951 AddTSReq.WMMTCLASPROC.version = 1;
952 AddTSReq.WMMTCLASPROC.processing =
953 pAddTS->tclasProc;
954 AddTSReq.WMMTCLASPROC.present = 1;
955 }
956 }
957
958 nStatus =
959 dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
960 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700961 pe_err("Failed to calculate the packed size for an Add TS Request (0x%08x)",
962 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 /* We'll fall back on the worst case scenario: */
964 nPayload = sizeof(tDot11fAddTSRequest);
965 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700966 pe_warn("There were warnings while calculating the packed size for an Add TS Request (0x%08x)",
967 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800968 }
969 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530970 qdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971
972 WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
973 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
974 WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
975
976 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
977 WMMAddTSReq.StatusCode.statusCode = 0;
978
979 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
980#ifdef FEATURE_WLAN_ESE
981 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
982
983 if (phyMode == WNI_CFG_PHY_MODE_11G
984 || phyMode == WNI_CFG_PHY_MODE_11A) {
985 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
986 } else {
987 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
988 }
989 populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
990 &WMMAddTSReq.ESETrafStrmRateSet,
991 sizeof(uint8_t));
992#endif
993 /* fillWmeTspecIE */
994
995 nStatus =
996 dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
997 &nPayload);
998 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700999 pe_err("Failed to calculate the packed size for a WMM Add TS Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001000 nStatus);
1001 /* We'll fall back on the worst case scenario: */
1002 nPayload = sizeof(tDot11fAddTSRequest);
1003 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001004 pe_warn("There were warnings while calculating the packed size for a WMM Add TS Request (0x%08x)",
1005 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001006 }
1007 }
1008
1009 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1010
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301011 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301013 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001014 pe_err("Failed to allocate %d bytes for an Add TS Request",
1015 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001016 return;
1017 }
1018 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301019 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001020
1021 /* Next, we fill out the buffer descriptor: */
1022 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1023 SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
1024 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1025
1026 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1027
1028#ifdef WLAN_FEATURE_11W
1029 lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
1030#endif
1031
1032 /* That done, pack the struct: */
1033 if (!pAddTS->wmeTspecPresent) {
1034 nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
1035 pFrame +
1036 sizeof(tSirMacMgmtHdr),
1037 nPayload, &nPayload);
1038 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001039 pe_err("Failed to pack an Add TS Request "
1040 "(0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001041 cds_packet_free((void *)pPacket);
1042 return; /* allocated! */
1043 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001044 pe_warn("There were warnings while packing an Add TS Request (0x%08x)",
1045 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001046 }
1047 } else {
1048 nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
1049 pFrame +
1050 sizeof(tSirMacMgmtHdr),
1051 nPayload, &nPayload);
1052 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001053 pe_err("Failed to pack a WMM Add TS Request (0x%08x)",
1054 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055 cds_packet_free((void *)pPacket);
1056 return; /* allocated! */
1057 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001058 pe_warn("There were warnings while packing a WMM Add TS Request (0x%08x)",
1059 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001060 }
1061 }
1062
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001063 pe_debug("Sending an Add TS Request frame to");
1064 lim_print_mac_addr(pMac, peerMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001065
1066 if ((SIR_BAND_5_GHZ ==
1067 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301068 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1069 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001070 ) {
1071 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1072 }
1073
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301074 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001075 psessionEntry->peSessionId, pMacHdr->fc.subType));
1076
1077 /* Queue Addts Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301078 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001079 TXRX_FRM_802_11_MGMT,
1080 ANI_TXDIR_TODS,
1081 7, lim_tx_complete, pFrame, txFlag,
1082 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301083 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301084 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001085
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001086 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1087 pe_err("Could not send an Add TS Request (%X",
1088 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089} /* End lim_send_addts_req_action_frame. */
1090
1091/**
1092 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
1093 * @mac_ctx: Handle for mac context
1094 * @status_code: Status code for assoc response frame
1095 * @aid: Association ID
1096 * @peer_addr: Mac address of requesting peer
1097 * @subtype: Assoc/Reassoc
1098 * @sta: Pointer to station node
1099 * @pe_session: PE session id.
1100 *
1101 * Builds and sends association response frame to the requesting peer.
1102 *
1103 * Return: void
1104 */
1105
1106void
1107lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
1108 uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
1109 uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
1110{
1111 static tDot11fAssocResponse frm;
1112 uint8_t *frame;
1113 tpSirMacMgmtHdr mac_hdr;
1114 tSirRetStatus sir_status;
1115 uint8_t lle_mode = 0, addts;
1116 tHalBitVal qos_mode, wme_mode;
Hu Wang411e0cc2016-10-28 14:56:01 +08001117 uint32_t payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001118 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301119 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001120 tUpdateBeaconParams beacon_params;
1121 uint8_t tx_flag = 0;
1122 uint32_t addn_ie_len = 0;
1123 uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
1124 tpSirAssocReq assoc_req = NULL;
1125 uint8_t sme_session = 0;
1126 bool is_vht = false;
1127 uint16_t stripoff_len = 0;
1128 tDot11fIEExtCap extracted_ext_cap;
1129 bool extracted_flag = false;
1130#ifdef WLAN_FEATURE_11W
1131 uint32_t retry_int;
1132 uint32_t max_retries;
1133#endif
1134
1135 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001136 pe_err("pe_session is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001137 return;
1138 }
1139
1140 sme_session = pe_session->smeSessionId;
1141
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301142 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001143
1144 limGetQosMode(pe_session, &qos_mode);
1145 limGetWmeMode(pe_session, &wme_mode);
1146
1147 /*
1148 * An Add TS IE is added only if the AP supports it and
1149 * the requesting STA sent a traffic spec.
1150 */
1151 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
1152
1153 frm.Status.status = status_code;
1154
1155 frm.AID.associd = aid | LIM_AID_MASK;
1156
1157 if (NULL == sta) {
1158 populate_dot11f_supp_rates(mac_ctx,
1159 POPULATE_DOT11F_RATES_OPERATIONAL,
1160 &frm.SuppRates, pe_session);
1161 populate_dot11f_ext_supp_rates(mac_ctx,
1162 POPULATE_DOT11F_RATES_OPERATIONAL,
1163 &frm.ExtSuppRates, pe_session);
1164 } else {
1165 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
1166 &frm.ExtSuppRates,
1167 sta->supportedRates.llbRates,
1168 sta->supportedRates.llaRates);
1169 }
1170
1171 if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
1172 eSIR_SUCCESS == status_code) {
1173 assoc_req = (tpSirAssocReq)
1174 pe_session->parsedAssocReq[sta->assocId];
1175 /*
1176 * populate P2P IE in AssocRsp when assocReq from the peer
1177 * includes P2P IE
1178 */
1179 if (assoc_req != NULL && assoc_req->addIEPresent)
1180 populate_dot11_assoc_res_p2p_ie(mac_ctx,
1181 &frm.P2PAssocRes,
1182 assoc_req);
1183 }
1184
1185 if (NULL != sta) {
1186 if (eHAL_SET == qos_mode) {
1187 if (sta->lleEnabled) {
1188 lle_mode = 1;
1189 populate_dot11f_edca_param_set(mac_ctx,
1190 &frm.EDCAParamSet, pe_session);
1191 }
1192 }
1193
1194 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
1195 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
1196 pe_session);
1197
1198 if (sta->wsmEnabled)
1199 populate_dot11f_wmm_caps(&frm.WMMCaps);
1200 }
1201
1202 if (sta->mlmStaContext.htCapability &&
1203 pe_session->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001204 pe_debug("Populate HT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 populate_dot11f_ht_caps(mac_ctx, pe_session,
1206 &frm.HTCaps);
Krunal Sonief3294b2015-06-12 15:12:19 -07001207 /*
1208 * Check the STA capability and
1209 * update the HTCaps accordingly
1210 */
1211 frm.HTCaps.supportedChannelWidthSet = (
1212 sta->htSupportedChannelWidthSet <
1213 pe_session->htSupportedChannelWidthSet) ?
1214 sta->htSupportedChannelWidthSet :
1215 pe_session->htSupportedChannelWidthSet;
1216 if (!frm.HTCaps.supportedChannelWidthSet)
1217 frm.HTCaps.shortGI40MHz = 0;
1218
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001219 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1220 pe_session);
1221 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001222 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 +05301223 frm.HTCaps.supportedChannelWidthSet,
1224 frm.HTCaps.mimoPowerSave,
1225 frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
1226 frm.HTCaps.shortGI40MHz,
1227 frm.HTCaps.dsssCckMode40MHz,
1228 frm.HTCaps.maxRxAMPDUFactor);
1229
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 if (sta->mlmStaContext.vhtCapability &&
1231 pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001232 pe_debug("Populate VHT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233 populate_dot11f_vht_caps(mac_ctx, pe_session,
1234 &frm.VHTCaps);
1235 populate_dot11f_vht_operation(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301236 &frm.VHTOperation);
1237 is_vht = true;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301238 } else {
Tushnim Bhattacharyya3d17def2017-06-19 11:13:43 -07001239 /*
1240 * 2G-AS platform: SAP associates with HT (11n)clients
1241 * as 2x1 in 2G and 2X2 in 5G
1242 * Non-2G-AS platform: SAP associates with HT (11n)
1243 * clients as 2X2 in 2G and 5G
1244 * 5G-AS: DonÂ’t care
1245 */
1246 if (!policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc) &&
1247 frm.HTCaps.present && mac_ctx->hw_dbs_capable &&
1248 mac_ctx->lteCoexAntShare &&
1249 IS_24G_CH(pe_session->currentOperChannel))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301250 frm.HTCaps.supportedMCSSet[1] = 0;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301251 }
1252 if (pe_session->vhtCapability &&
1253 pe_session->vendor_vht_sap &&
1254 (assoc_req != NULL) &&
1255 assoc_req->vendor_vht_ie.VHTCaps.present) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001256 pe_debug("Populate Vendor VHT IEs in Assoc Rsponse");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301257 frm.vendor_vht_ie.present = 1;
1258 frm.vendor_vht_ie.type =
1259 pe_session->vendor_specific_vht_ie_type;
1260 frm.vendor_vht_ie.sub_type =
1261 pe_session->vendor_specific_vht_ie_sub_type;
1262
1263 frm.vendor_vht_ie.VHTCaps.present = 1;
1264 populate_dot11f_vht_caps(mac_ctx, pe_session,
1265 &frm.vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 is_vht = true;
1267 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1269 pe_session);
1270
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001271 if (lim_is_sta_he_capable(sta) &&
1272 lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001273 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001274 populate_dot11f_he_caps(mac_ctx, pe_session,
1275 &frm.vendor_he_cap);
1276 populate_dot11f_he_operation(mac_ctx, pe_session,
1277 &frm.vendor_he_op);
1278 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279#ifdef WLAN_FEATURE_11W
1280 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1281 if (wlan_cfg_get_int
1282 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1283 &max_retries) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001284 pe_err("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285 else if (wlan_cfg_get_int
1286 (mac_ctx,
1287 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1288 &retry_int) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001289 pe_err("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 else
1291 populate_dot11f_timeout_interval(mac_ctx,
1292 &frm.TimeoutInterval,
1293 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1294 (max_retries -
1295 sta->pmfSaQueryRetryCount)
1296 * retry_int);
1297 }
1298#endif
Arif Hussain0c816922017-04-06 15:04:44 -07001299
1300 if (LIM_IS_AP_ROLE(pe_session) && sta->non_ecsa_capable)
1301 pe_session->lim_non_ecsa_cap_num++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302 }
1303
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301304 qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305
1306 if (LIM_IS_AP_ROLE(pe_session) &&
1307 (pe_session->gLimProtectionControl !=
1308 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1309 lim_decide_ap_protection(mac_ctx, peer_addr,
1310 &beacon_params, pe_session);
1311
1312 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1313 pe_session);
1314 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1315 pe_session);
1316
1317 /*
1318 * Populate Do11capabilities after updating session with
1319 * Assos req details
1320 */
1321 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1322
1323 beacon_params.bssIdx = pe_session->bssIdx;
1324
1325 /* Send message to HAL about beacon parameter change. */
1326 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1327 && beacon_params.paramChangeBitmap) {
1328 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1329 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331
1332 if (assoc_req != NULL) {
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001333 addn_ie_len = pe_session->addIeParams.assocRespDataLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334
1335 /* Nonzero length indicates Assoc rsp IE available */
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001336 if (addn_ie_len > 0 &&
1337 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
1338 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301339 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 pe_session->addIeParams.assocRespData_buff,
1341 pe_session->addIeParams.assocRespDataLen);
1342
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301343 qdf_mem_set((uint8_t *) &extracted_ext_cap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 sizeof(extracted_ext_cap), 0);
1345
1346 stripoff_len = addn_ie_len;
1347 sir_status =
1348 lim_strip_extcap_update_struct
1349 (mac_ctx, &add_ie[0], &stripoff_len,
1350 &extracted_ext_cap);
1351 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001352 pe_debug("strip off extcap IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 } else {
1354 addn_ie_len = stripoff_len;
1355 extracted_flag = true;
1356 }
1357 bytes = bytes + addn_ie_len;
1358 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001359 pe_debug("addn_ie_len: %d for Assoc Resp: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 addn_ie_len, assoc_req->addIEPresent);
1361 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001362
1363 /*
1364 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1365 * may change the frame size. Therefore, MUST merge ExtCap IE before
1366 * dot11f get packed payload size.
1367 */
1368 if (extracted_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001369 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
1370 true);
Hu Wang411e0cc2016-10-28 14:56:01 +08001371
1372 /* Allocate a buffer for this frame: */
1373 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1374 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001375 pe_err("get Association Response size failure (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001376 status);
1377 return;
1378 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001379 pe_warn("get Association Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001380 status);
1381 }
1382
1383 bytes += sizeof(tSirMacMgmtHdr) + payload;
1384
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301385 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301387 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001388 pe_err("cds_packet_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001389 return;
1390 }
1391 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301392 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393
1394 /* Next, we fill out the buffer descriptor: */
1395 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1396 (LIM_ASSOC == subtype) ?
1397 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1398 peer_addr,
1399 pe_session->selfMacAddr);
1400 mac_hdr = (tpSirMacMgmtHdr) frame;
1401
1402 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001404 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1405 frame + sizeof(tSirMacMgmtHdr),
1406 payload, &payload);
1407 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001408 pe_err("Association Response pack failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001409 status);
1410 cds_packet_free((void *)packet);
1411 return;
1412 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001413 pe_warn("Association Response pack warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001414 status);
1415 }
1416
1417 if (subtype == LIM_ASSOC)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001418 pe_debug("*** Sending Assoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419 status_code, aid);
1420 else
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001421 pe_debug("*** Sending ReAssoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422 status_code, aid);
1423
1424 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1425
1426 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301427 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 &add_ie[0], addn_ie_len);
1429
1430 if ((SIR_BAND_5_GHZ ==
1431 lim_get_rf_band(pe_session->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05301432 (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
1433 (pe_session->pePersona == QDF_P2P_GO_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001434 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1435
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301436 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437 pe_session->peSessionId, mac_hdr->fc.subType));
1438 /* Queue Association Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301439 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 TXRX_FRM_802_11_MGMT,
1441 ANI_TXDIR_TODS,
1442 7, lim_tx_complete, frame, tx_flag,
1443 sme_session, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301444 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301445 pe_session->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446
1447 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301448 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001449 pe_err("Could not Send Re/AssocRsp, retCode=%X",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301450 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451
1452 /*
1453 * update the ANI peer station count.
1454 * FIXME_PROTECTION : take care of different type of station
1455 * counter inside this function.
1456 */
1457 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1458
1459}
1460
1461void
1462lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1463 tSirMacAddr peer,
1464 uint8_t wmmTspecPresent,
1465 tSirMacTSInfo *pTsinfo,
1466 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1467{
1468 uint8_t *pFrame;
1469 tpSirMacMgmtHdr pMacHdr;
1470 tDot11fDelTS DelTS;
1471 tDot11fWMMDelTS WMMDelTS;
1472 uint32_t nBytes, nPayload, nStatus;
1473 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301474 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475 uint8_t txFlag = 0;
1476 uint8_t smeSessionId = 0;
1477
1478 if (NULL == psessionEntry) {
1479 return;
1480 }
1481
1482 smeSessionId = psessionEntry->smeSessionId;
1483
1484 if (!wmmTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301485 qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001486
1487 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1488 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1489 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1490
1491 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1492 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001493 pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494 /* We'll fall back on the worst case scenario: */
1495 nPayload = sizeof(tDot11fDelTS);
1496 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001497 pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)",
1498 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 }
1500 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301501 qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001502
1503 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1504 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1505 WMMDelTS.DialogToken.token = 0;
1506 WMMDelTS.StatusCode.statusCode = 0;
1507 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1508 nStatus =
1509 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1510 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001511 pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 /* We'll fall back on the worst case scenario: */
1513 nPayload = sizeof(tDot11fDelTS);
1514 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001515 pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)",
1516 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001517 }
1518 }
1519
1520 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1521
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301522 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1524 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301525 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001526 pe_err("Failed to allocate %d bytes for an Add TS Response",
1527 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 return;
1529 }
1530 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301531 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532
1533 /* Next, we fill out the buffer descriptor: */
1534 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1535 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1536 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1537
1538 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1539
1540#ifdef WLAN_FEATURE_11W
1541 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1542#endif
1543
1544 /* That done, pack the struct: */
1545 if (!wmmTspecPresent) {
1546 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1547 pFrame + sizeof(tSirMacMgmtHdr),
1548 nPayload, &nPayload);
1549 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001550 pe_err("Failed to pack a Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 nStatus);
1552 cds_packet_free((void *)pPacket);
1553 return; /* allocated! */
1554 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001555 pe_warn("There were warnings while packing a Del TS frame (0x%08x)",
1556 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 }
1558 } else {
1559 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1560 pFrame + sizeof(tSirMacMgmtHdr),
1561 nPayload, &nPayload);
1562 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001563 pe_err("Failed to pack a WMM Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001564 nStatus);
1565 cds_packet_free((void *)pPacket);
1566 return; /* allocated! */
1567 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001568 pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)",
1569 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 }
1571 }
1572
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001573 pe_debug("Sending DELTS REQ (size %d) to ", nBytes);
1574 lim_print_mac_addr(pMac, pMacHdr->da, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001575
1576 if ((SIR_BAND_5_GHZ ==
1577 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301578 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1579 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580 ) {
1581 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1582 }
1583
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301584 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301586 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 TXRX_FRM_802_11_MGMT,
1588 ANI_TXDIR_TODS,
1589 7, lim_tx_complete, pFrame, txFlag,
1590 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301591 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301592 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001593 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301594 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001595 pe_err("Failed to send Del TS (%X)!", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001596
1597} /* End lim_send_delts_req_action_frame. */
1598
1599/**
1600 * lim_send_assoc_req_mgmt_frame() - Send association request
1601 * @mac_ctx: Handle to MAC context
1602 * @mlm_assoc_req: Association request information
1603 * @pe_session: PE session information
1604 *
1605 * Builds and transmits association request frame to AP.
1606 *
1607 * Return: Void
1608 */
1609
1610void
1611lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1612 tLimMlmAssocReq *mlm_assoc_req,
1613 tpPESession pe_session)
1614{
1615 tDot11fAssocRequest *frm;
1616 uint16_t caps;
1617 uint8_t *frame;
1618 tSirRetStatus sir_status;
1619 tLimMlmAssocCnf assoc_cnf;
Hu Wang411e0cc2016-10-28 14:56:01 +08001620 uint32_t bytes = 0, payload, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001621 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1622 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301623 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624 uint16_t add_ie_len;
1625 uint8_t *add_ie;
1626 uint8_t *wps_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 uint8_t power_caps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628 uint8_t tx_flag = 0;
1629 uint8_t sme_sessionid = 0;
1630 bool vht_enabled = false;
1631 tDot11fIEExtCap extr_ext_cap;
1632 bool extr_ext_flag = true;
1633 tpSirMacMgmtHdr mac_hdr;
Hu Wangfbd279d2016-10-31 18:24:34 +08001634 uint32_t ie_offset = 0;
1635 uint8_t *p_ext_cap = NULL;
1636 tDot11fIEExtCap bcn_ext_cap;
1637 uint8_t *bcn_ie = NULL;
1638 uint32_t bcn_ie_len = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001639
1640 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001641 pe_err("pe_session is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301642 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 return;
1644 }
1645
1646 sme_sessionid = pe_session->smeSessionId;
1647
1648 /* check this early to avoid unncessary operation */
1649 if (NULL == pe_session->pLimJoinReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001650 pe_err("pe_session->pLimJoinReq is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301651 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 return;
1653 }
1654 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1655 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1656
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301657 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001659 pe_err("Unable to allocate memory");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301660 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 return;
1662 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001663 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301665 if (add_ie_len && pe_session->is_ext_caps_present) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301666 qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667 0);
1668 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1669 add_ie, &add_ie_len, &extr_ext_cap);
1670 if (eSIR_SUCCESS != sir_status) {
1671 extr_ext_flag = false;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001672 pe_debug("Unable to Stripoff ExtCap IE from Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673 } else {
1674 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1675 extr_ext_cap.bytes;
1676
1677 if (p_ext_cap->interworking_service)
1678 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +08001679 extr_ext_cap.num_bytes =
1680 lim_compute_ext_cap_ie_length(&extr_ext_cap);
1681 extr_ext_flag = (extr_ext_cap.num_bytes > 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001682 }
1683 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001684 pe_debug("No addn IE or peer dosen't support addnIE for Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685 extr_ext_flag = false;
1686 }
1687
1688 caps = mlm_assoc_req->capabilityInfo;
1689#if defined(FEATURE_WLAN_WAPI)
1690 /*
1691 * According to WAPI standard:
1692 * 7.3.1.4 Capability Information field
1693 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1694 * in transmitted Association or Reassociation management frames.
1695 * APs ignore the Privacy subfield within received Association and
1696 * Reassociation management frames.
1697 */
1698 if (pe_session->encryptType == eSIR_ED_WPI)
1699 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1700#endif
1701 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1702
1703 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1704 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1705 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1706 &frm->SuppRates, pe_session);
1707
1708 qos_enabled = (pe_session->limQosEnabled) &&
1709 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1710
1711 wme_enabled = (pe_session->limWmeEnabled) &&
1712 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1713
1714 /* We prefer .11e asociations: */
1715 if (qos_enabled)
1716 wme_enabled = false;
1717
1718 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1719 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1720
1721 if (pe_session->lim11hEnable &&
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07001722 pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001723 power_caps = true;
1724
1725 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1726 LIM_ASSOC, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1728 LIM_ASSOC, pe_session);
1729
1730 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001731 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1732 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1733 if (power_caps == false) {
1734 power_caps = true;
1735 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1736 LIM_ASSOC, pe_session);
1737 }
1738 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739 if (qos_enabled)
Naveen Rawatcd118312016-11-22 10:46:21 -08001740 populate_dot11f_qos_caps_station(mac_ctx, pe_session,
1741 &frm->QOSCapsStation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742
1743 populate_dot11f_ext_supp_rates(mac_ctx,
1744 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1745 pe_session);
1746
Gupta, Kapil54a16992016-01-13 19:34:02 +05301747 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1748 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1750 pe_session);
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08001751
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752 /*
1753 * The join request *should* contain zero or one of the WPA and RSN
1754 * IEs. The payload send along with the request is a
1755 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1756 * typedef struct sSirRSNie
1757 * {
1758 * uint16_t length;
1759 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1760 * } tSirRSNie, *tpSirRSNie;
1761 * So, we should be able to make the following two calls harmlessly,
1762 * since they do nothing if they don't find the given IE in the
1763 * bytestream with which they're provided.
1764 * The net effect of this will be to faithfully transmit whatever
1765 * security IE is in the join request.
1766 * However, if we're associating for the purpose of WPS
1767 * enrollment, and we've been configured to indicate that by
1768 * eliding the WPA or RSN IE, we just skip this:
1769 */
1770 if (add_ie_len && add_ie)
1771 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1772
1773 if (NULL == wps_ie) {
1774 populate_dot11f_rsn_opaque(mac_ctx,
1775 &(pe_session->pLimJoinReq->rsnIE),
1776 &frm->RSNOpaque);
1777 populate_dot11f_wpa_opaque(mac_ctx,
1778 &(pe_session->pLimJoinReq->rsnIE),
1779 &frm->WPAOpaque);
1780#if defined(FEATURE_WLAN_WAPI)
1781 populate_dot11f_wapi_opaque(mac_ctx,
1782 &(pe_session->pLimJoinReq->rsnIE),
1783 &frm->WAPIOpaque);
1784#endif /* defined(FEATURE_WLAN_WAPI) */
1785 }
1786 /* include WME EDCA IE as well */
1787 if (wme_enabled) {
1788 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1789 pe_session, &frm->WMMInfoStation);
1790
1791 if (wsm_enabled)
1792 populate_dot11f_wmm_caps(&frm->WMMCaps);
1793 }
1794
1795 /*
1796 * Populate HT IEs, when operating in 11n and
1797 * when AP is also operating in 11n mode
1798 */
1799 if (pe_session->htCapability &&
1800 mac_ctx->lim.htCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001801 pe_debug("Populate HT Caps in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001803 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1804 &frm->HTCaps, sizeof(frm->HTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001806 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 +05301807 frm->HTCaps.supportedChannelWidthSet,
1808 frm->HTCaps.mimoPowerSave,
1809 frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
1810 frm->HTCaps.shortGI40MHz,
1811 frm->HTCaps.dsssCckMode40MHz,
1812 frm->HTCaps.maxRxAMPDUFactor);
1813
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001814 if (pe_session->vhtCapability &&
1815 pe_session->vhtCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001816 pe_debug("Populate VHT IEs in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001818 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1819 &frm->VHTCaps, sizeof(frm->VHTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820 vht_enabled = true;
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001821 if (pe_session->enableHtSmps &&
1822 !pe_session->supported_nss_1x1) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001823 pe_err("VHT OP mode IE in Assoc Req");
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001824 populate_dot11f_operating_mode(mac_ctx,
1825 &frm->OperatingMode, pe_session);
1826 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001827 }
1828 if (!vht_enabled &&
1829 pe_session->is_vendor_specific_vhtcaps) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001830 pe_debug("Populate Vendor VHT IEs in Assoc Request");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301831 frm->vendor_vht_ie.present = 1;
1832 frm->vendor_vht_ie.type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001833 pe_session->vendor_specific_vht_ie_type;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301834 frm->vendor_vht_ie.sub_type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835 pe_session->vendor_specific_vht_ie_sub_type;
1836
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301837 frm->vendor_vht_ie.VHTCaps.present = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001838 populate_dot11f_vht_caps(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301839 &frm->vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001840 vht_enabled = true;
1841 }
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301842 if (pe_session->is_ext_caps_present)
1843 populate_dot11f_ext_cap(mac_ctx, vht_enabled,
1844 &frm->ExtCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +05301846 if (mac_ctx->roam.configParam.qcn_ie_support)
1847 populate_dot11f_qcn_ie(&frm->QCN_IE);
1848
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001849 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001850 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001851 populate_dot11f_he_caps(mac_ctx, pe_session,
1852 &frm->vendor_he_cap);
1853 }
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301854
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001855 if (pe_session->pLimJoinReq->is11Rconnection) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001856 tSirBssDescription *bssdescr;
1857
1858 bssdescr = &pe_session->pLimJoinReq->bssDescription;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001859 pe_debug("mdie = %02x %02x %02x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 (unsigned int) bssdescr->mdie[0],
1861 (unsigned int) bssdescr->mdie[1],
1862 (unsigned int) bssdescr->mdie[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001863 populate_mdie(mac_ctx, &frm->MobilityDomain,
1864 pe_session->pLimJoinReq->bssDescription.mdie);
1865 } else {
1866 /* No 11r IEs dont send any MDIE */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001867 pe_debug("MDIE not present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001869
1870#ifdef FEATURE_WLAN_ESE
1871 /*
1872 * ESE Version IE will be included in association request
1873 * when ESE is enabled on DUT through ini and it is also
1874 * advertised by the peer AP to which we are trying to
1875 * associate to.
1876 */
1877 if (pe_session->is_ese_version_ie_present &&
1878 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1879 populate_dot11f_ese_version(&frm->ESEVersion);
1880 /* For ESE Associations fill the ESE IEs */
1881 if (pe_session->isESEconnection &&
1882 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1883#ifndef FEATURE_DISABLE_RM
1884 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1885#endif
1886 }
1887#endif
1888
Hu Wang411e0cc2016-10-28 14:56:01 +08001889 /*
1890 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1891 * may change the frame size. Therefore, MUST merge ExtCap IE before
1892 * dot11f get packed payload size.
1893 */
1894 if (extr_ext_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001895 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
1896
1897 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
1898 if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
1899 ie_offset = DOT11F_FF_TIMESTAMP_LEN +
1900 DOT11F_FF_BEACONINTERVAL_LEN +
1901 DOT11F_FF_CAPABILITIES_LEN;
1902
1903 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
1904 if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
1905 bcn_ie = pe_session->beacon + ie_offset;
1906 bcn_ie_len = pe_session->bcnLen - ie_offset;
1907 p_ext_cap = lim_get_ie_ptr_new(mac_ctx,
1908 bcn_ie,
1909 bcn_ie_len,
1910 DOT11F_EID_EXTCAP,
1911 ONE_BYTE);
1912 lim_update_extcap_struct(mac_ctx, p_ext_cap,
1913 &bcn_ext_cap);
1914 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
1915 false);
1916 }
1917 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001918
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001919 if (eSIR_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
1920 add_ie, &add_ie_len, &frm->SuppOperatingClasses))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001921 pe_debug("Unable to Stripoff supp op classes IE from Assoc Req");
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001922
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001923 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1924 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001925 pe_err("Association Request packet size failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001926 status);
1927 /* We'll fall back on the worst case scenario: */
1928 payload = sizeof(tDot11fAssocRequest);
1929 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001930 pe_warn("Association request packet size warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001931 status);
1932 }
1933
1934 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1935
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301936 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001937 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301938 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001939 pe_err("Failed to allocate %d bytes", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001940
1941 pe_session->limMlmState = pe_session->limPrevMlmState;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301942 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 pe_session->peSessionId,
1944 pe_session->limMlmState));
1945
1946 /* Update PE session id */
1947 assoc_cnf.sessionId = pe_session->peSessionId;
1948
1949 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1950
1951 cds_packet_free((void *)packet);
1952
1953 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1954 (uint32_t *) &assoc_cnf);
1955
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301956 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001957 }
1958 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301959 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001960
1961 /* Next, we fill out the buffer descriptor: */
1962 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1963 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1964 pe_session->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 /* That done, pack the Assoc Request: */
1966 status = dot11f_pack_assoc_request(mac_ctx, frm,
1967 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1968 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001969 pe_err("Assoc request pack failure (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 cds_packet_free((void *)packet);
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301971 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001972 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001973 pe_warn("Assoc request pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974 }
1975
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001976 pe_debug("Sending Association Request length %d to ", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001977 if (pe_session->assocReq != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301978 qdf_mem_free(pe_session->assocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001980 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 }
1982
1983 if (add_ie_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301984 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985 add_ie, add_ie_len);
1986 payload += add_ie_len;
1987 }
1988
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301989 pe_session->assocReq = qdf_mem_malloc(payload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990 if (NULL == pe_session->assocReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001991 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992 } else {
1993 /*
1994 * Store the Assoc request. This is sent to csr/hdd in
1995 * join cnf response.
1996 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301997 qdf_mem_copy(pe_session->assocReq,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998 frame + sizeof(tSirMacMgmtHdr), payload);
1999 pe_session->assocReqLen = payload;
2000 }
2001
2002 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302003 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
2004 || (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002005 )
2006 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2007
Anurag Chouhan6d760662016-02-20 16:05:43 +05302008 if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
2009 pe_session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2011
2012#ifdef FEATURE_WLAN_DIAG_SUPPORT
2013 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
2014 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2015#endif
2016 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302017 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 pe_session->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302019 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002020 wma_tx_frame(mac_ctx, packet,
2021 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
2022 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2023 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302024 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302025 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302026 pe_session->peSessionId, qdf_status));
2027 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002028 pe_err("Failed to send Association Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302029 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002030 /* Pkt will be freed up by the callback */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031 }
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05302032end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002033 /* Free up buffer allocated for mlm_assoc_req */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302034 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002035 mlm_assoc_req = NULL;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302036 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002037 return;
2038}
2039
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040/**
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302041 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302042 * @context: pointer to global mac
2043 * @buf: buffer
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302044 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302045 * @params; tx completion params
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302046 *
2047 * Return: This returns QDF_STATUS
2048 */
2049
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302050static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
2051 qdf_nbuf_t buf,
2052 uint32_t tx_complete,
2053 void *params)
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302054{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302055 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
2056
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002057 pe_debug("tx_complete= %d", tx_complete);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302058 if (tx_complete) {
2059 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
2060 /* 'Change' timer for future activations */
2061 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2062 } else {
2063 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2064 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302065
2066 if (buf)
2067 qdf_nbuf_free(buf);
2068
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302069 return QDF_STATUS_SUCCESS;
2070}
2071
2072/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002073 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2074 *
2075 * @mac_ctx: Pointer to Global MAC structure
2076 * @auth_frame: Pointer to Authentication frame structure
2077 * @peer_addr: MAC address of destination peer
2078 * @wep_bit: wep bit in frame control for Authentication frame3
2079 * @session: PE session information
2080 *
2081 * This function is called by lim_process_mlm_messages(). Authentication frame
2082 * is formatted and sent when this function is called.
2083 *
2084 * Return: void
2085 */
2086
2087void
2088lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2089 tpSirMacAuthFrameBody auth_frame,
2090 tSirMacAddr peer_addr,
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302091 uint8_t wep_bit,
2092 tpPESession session, bool wait_for_ack)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002093{
2094 uint8_t *frame, *body;
2095 uint32_t frame_len = 0, body_len = 0;
2096 tpSirMacMgmtHdr mac_hdr;
2097 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302098 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 uint8_t tx_flag = 0;
2100 uint8_t sme_sessionid = 0;
2101 uint16_t ft_ies_length = 0;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002102 bool challenge_req = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103
2104 if (NULL == session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002105 pe_err("Error: psession Entry is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106 return;
2107 }
2108
2109 sme_sessionid = session->smeSessionId;
2110
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002111 if (wep_bit == LIM_WEP_IN_FC) {
2112 /*
2113 * Auth frame3 to be sent with encrypted framebody
2114 *
2115 * Allocate buffer for Authenticaton frame of size
2116 * equal to management frame header length plus 2 bytes
2117 * each for auth algorithm number, transaction number,
2118 * status code, 128 bytes for challenge text and
2119 * 4 bytes each for IV & ICV.
2120 */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002121 pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
2122 MAC_ADDR_ARRAY(peer_addr));
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002123
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002124 body_len = LIM_ENCR_AUTH_BODY_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002125 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002126
2127 goto alloc_packet;
2128 }
2129
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002130 pe_info("Sending Auth seq# %d status %d (%d) wait_for_ack %d to "
2131 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002132 auth_frame->authTransactionSeqNumber,
2133 auth_frame->authStatusCode,
2134 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302135 wait_for_ack,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002136 MAC_ADDR_ARRAY(peer_addr));
2137
2138 switch (auth_frame->authTransactionSeqNumber) {
2139 case SIR_MAC_AUTH_FRAME_1:
2140 /*
2141 * Allocate buffer for Authenticaton frame of size
2142 * equal to management frame header length plus 2 bytes
2143 * each for auth algorithm number, transaction number
2144 * and status code.
2145 */
2146
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002147 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2148 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2151 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2152 0 != session->ftPEContext.pFTPreAuthReq->
2153 ft_ies_length) {
2154 ft_ies_length = session->ftPEContext.
2155 pFTPreAuthReq->ft_ies_length;
2156 frame_len += ft_ies_length;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002157 pe_debug("Auth frame, FTIES length added=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002158 ft_ies_length);
2159 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002160 pe_debug("Auth frame, Does not contain FTIES!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002161 frame_len += (2 + SIR_MDIE_SIZE);
2162 }
2163 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164 break;
2165
2166 case SIR_MAC_AUTH_FRAME_2:
2167 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2168 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2169 (auth_frame->authStatusCode !=
2170 eSIR_MAC_SUCCESS_STATUS))) {
2171 /*
2172 * Allocate buffer for Authenticaton frame of size
2173 * equal to management frame header length plus
2174 * 2 bytes each for auth algorithm number,
2175 * transaction number and status code.
2176 */
2177
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002178 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2179 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180 } else {
2181 /*
2182 * Shared Key algorithm with challenge text
2183 * to be sent.
2184 *
2185 * Allocate buffer for Authenticaton frame of size
2186 * equal to management frame header length plus
2187 * 2 bytes each for auth algorithm number,
2188 * transaction number, status code and 128 bytes
2189 * for challenge text.
2190 */
2191
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002192 challenge_req = true;
2193 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
2194 SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2195 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 }
2197 break;
2198
2199 case SIR_MAC_AUTH_FRAME_3:
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002200 /*
2201 * Auth frame3 to be sent without encrypted framebody
2202 *
2203 * Allocate buffer for Authenticaton frame of size equal
2204 * to management frame header length plus 2 bytes each
2205 * for auth algorithm number, transaction number and
2206 * status code.
2207 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002209 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2210 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002211 break;
2212
2213 case SIR_MAC_AUTH_FRAME_4:
2214 /*
2215 * Allocate buffer for Authenticaton frame of size equal
2216 * to management frame header length plus 2 bytes each
2217 * for auth algorithm number, transaction number and
2218 * status code.
2219 */
2220
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002221 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2222 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223
2224 break;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002225 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002226 pe_err("Invalid auth transaction seq num");
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002227 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228 } /* switch (auth_frame->authTransactionSeqNumber) */
2229
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002230alloc_packet:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302231 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002232 (void **)&packet);
2233
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302234 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002235 pe_err("call to bufAlloc failed for AUTH frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002236 return;
2237 }
2238
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302239 qdf_mem_zero(frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002240
2241 /* Prepare BD */
2242 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2243 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2244 mac_hdr = (tpSirMacMgmtHdr) frame;
2245 mac_hdr->fc.wep = wep_bit;
2246
2247 /* Prepare BSSId */
Rajeev Kumarcf835a02016-04-15 15:01:31 -07002248 if (LIM_IS_AP_ROLE(session))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302249 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002250 (uint8_t *) session->bssId,
2251 sizeof(tSirMacAddr));
2252
2253 /* Prepare Authentication frame body */
2254 body = frame + sizeof(tSirMacMgmtHdr);
2255
2256 if (wep_bit == LIM_WEP_IN_FC) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302257 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002258
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002259 pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002260 MAC_ADDR_ARRAY(mac_hdr->da));
2261
2262 } else {
2263 *((uint16_t *) (body)) =
2264 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2265 body += sizeof(uint16_t);
2266 body_len -= sizeof(uint16_t);
2267
2268 *((uint16_t *) (body)) =
2269 sir_swap_u16if_needed(
2270 auth_frame->authTransactionSeqNumber);
2271 body += sizeof(uint16_t);
2272 body_len -= sizeof(uint16_t);
2273
2274 *((uint16_t *) (body)) =
2275 sir_swap_u16if_needed(auth_frame->authStatusCode);
2276 body += sizeof(uint16_t);
2277 body_len -= sizeof(uint16_t);
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002278
2279 if (challenge_req) {
2280 if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
2281 qdf_mem_copy(body, (uint8_t *)&auth_frame->type,
2282 body_len);
2283 pe_err("Incomplete challenge info: length: %d, expected: %d",
2284 body_len,
2285 SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
2286 body += body_len;
2287 body_len = 0;
2288 } else {
2289 /* copy challenge IE id, len, challenge text */
2290 *body = auth_frame->type;
2291 body++;
2292 *body = auth_frame->length;
2293 body++;
2294 qdf_mem_copy(body, auth_frame->challengeText,
2295 SIR_MAC_AUTH_CHALLENGE_LENGTH);
2296 body += SIR_MAC_AUTH_CHALLENGE_LENGTH;
2297
2298 body_len -= SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2299 }
2300 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002301
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002302 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2303 (auth_frame->authTransactionSeqNumber ==
2304 SIR_MAC_AUTH_FRAME_1) &&
2305 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2306
2307 if (ft_ies_length > 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302308 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002309 session->ftPEContext.
2310 pFTPreAuthReq->ft_ies,
2311 ft_ies_length);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002312 pe_debug("Auth1 Frame FTIE is: ");
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002313 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2314 QDF_TRACE_LEVEL_DEBUG,
2315 (uint8_t *) body,
2316 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002317 } else if (NULL != session->ftPEContext.
2318 pFTPreAuthReq->pbssDescription) {
2319 /* MDID attr is 54 */
2320 *body = SIR_MDIE_ELEMENT_ID;
2321 body++;
2322 *body = SIR_MDIE_SIZE;
2323 body++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302324 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002325 &session->ftPEContext.pFTPreAuthReq->
2326 pbssDescription->mdie[0],
2327 SIR_MDIE_SIZE);
2328 }
2329 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002330
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002331 pe_debug("*** Sending Auth seq# %d status %d (%d) to "
2332 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333 auth_frame->authTransactionSeqNumber,
2334 auth_frame->authStatusCode,
2335 (auth_frame->authStatusCode ==
2336 eSIR_MAC_SUCCESS_STATUS),
2337 MAC_ADDR_ARRAY(mac_hdr->da));
2338 }
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002339 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2340 QDF_TRACE_LEVEL_DEBUG,
2341 frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002342
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302343 if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
2344 (SIR_BAND_5_GHZ == lim_get_rf_band(
2345 session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002346 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302347 else if ((SIR_BAND_5_GHZ ==
2348 lim_get_rf_band(session->currentOperChannel))
2349 || (session->pePersona == QDF_P2P_CLIENT_MODE)
2350 || (session->pePersona == QDF_P2P_GO_MODE))
2351 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352
Anurag Chouhan6d760662016-02-20 16:05:43 +05302353 if (session->pePersona == QDF_P2P_CLIENT_MODE ||
2354 session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002355 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2356
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302357 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002358 session->peSessionId, mac_hdr->fc.subType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002359
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302360 if (wait_for_ack) {
2361 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
2362 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
2363 (uint16_t)frame_len,
2364 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2365 7, lim_tx_complete, frame,
2366 lim_auth_tx_complete_cnf,
2367 tx_flag, sme_sessionid, false, 0);
2368 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2369 session->peSessionId, qdf_status));
2370 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002371 pe_err("*** Could not send Auth frame, retCode=%X ***",
2372 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302373 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2374 /* Pkt will be freed up by the callback */
2375 }
2376 } else {
2377 /* Queue Authentication frame in high priority WQ */
2378 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
2379 TXRX_FRM_802_11_MGMT,
2380 ANI_TXDIR_TODS, 7, lim_tx_complete,
2381 frame, tx_flag, sme_sessionid, 0);
2382 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2383 session->peSessionId, qdf_status));
2384 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002385 pe_err("*** Could not send Auth frame, retCode=%X ***",
2386 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302387 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002388 return;
2389}
2390
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302391QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392{
2393 uint16_t aid;
2394 tpDphHashNode pStaDs;
2395 tLimMlmDeauthReq *pMlmDeauthReq;
2396 tLimMlmDeauthCnf mlmDeauthCnf;
2397 tpPESession psessionEntry;
2398
2399 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
2400 if (pMlmDeauthReq) {
2401 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
2402 lim_deactivate_and_change_timer(pMac,
2403 eLIM_DEAUTH_ACK_TIMER);
2404 }
2405
2406 psessionEntry = pe_find_session_by_session_id(pMac,
2407 pMlmDeauthReq->sessionId);
2408 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002409 pe_err("session does not exist for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002410 mlmDeauthCnf.resultCode =
2411 eSIR_SME_INVALID_PARAMETERS;
2412 goto end;
2413 }
2414
2415 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002416 dph_lookup_hash_entry(pMac,
2417 pMlmDeauthReq->peer_macaddr.bytes,
2418 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002419 &psessionEntry->dph.dphHashTable);
2420 if (pStaDs == NULL) {
2421 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2422 goto end;
2423 }
2424
2425 /* / Receive path cleanup with dummy packet */
2426 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2427 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002428 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
2429 (
Abhishek Singhe0680852015-12-16 14:28:48 +05302430#ifdef FEATURE_WLAN_ESE
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002431 (psessionEntry->isESEconnection) ||
Abhishek Singhe0680852015-12-16 14:28:48 +05302432#endif
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002433 (psessionEntry->isFastRoamIniFeatureEnabled) ||
2434 (psessionEntry->is11Rconnection))) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002435 pe_debug("FT Preauth (%p,%d) Deauth rc %d src = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002436 psessionEntry,
2437 psessionEntry->peSessionId,
2438 pMlmDeauthReq->reasonCode,
2439 pMlmDeauthReq->deauthTrigger);
2440 lim_ft_cleanup(pMac, psessionEntry);
2441 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002442 pe_debug("No FT Preauth Session Cleanup in role %d"
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002443#ifdef FEATURE_WLAN_ESE
2444 " isESE %d"
2445#endif
2446 " isLFR %d"
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002447 " is11r %d, Deauth reason %d Trigger = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002448 psessionEntry->limSystemRole,
2449#ifdef FEATURE_WLAN_ESE
2450 psessionEntry->isESEconnection,
2451#endif
2452 psessionEntry->isFastRoamIniFeatureEnabled,
2453 psessionEntry->is11Rconnection,
Abhishek Singhe0680852015-12-16 14:28:48 +05302454 pMlmDeauthReq->reasonCode,
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002455 pMlmDeauthReq->deauthTrigger);
2456 }
2457 /* Free up buffer allocated for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302458 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002459 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
2460 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302461 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462end:
Anurag Chouhanc5548422016-02-24 18:33:27 +05302463 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002464 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002465 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
2466 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
2467 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
2468
2469 /* Free up buffer allocated */
2470 /* for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302471 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472
2473 lim_post_sme_message(pMac,
2474 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302475 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002476}
2477
2478/**
2479 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
2480 *
2481 * @mac_ctx: Handle to MAC context
2482 *
2483 * Sends disassoc confirmation to SME. Removes disassoc request stored
2484 * in lim.
2485 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302486 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002487 */
2488
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302489QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490{
2491 uint16_t aid;
2492 tpDphHashNode sta_ds;
2493 tLimMlmDisassocCnf disassoc_cnf;
2494 tpPESession pe_session;
2495 tLimMlmDisassocReq *disassoc_req;
2496
2497 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
2498 if (disassoc_req) {
2499 if (tx_timer_running(
2500 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
2501 lim_deactivate_and_change_timer(mac_ctx,
2502 eLIM_DISASSOC_ACK_TIMER);
2503
2504 pe_session = pe_find_session_by_session_id(
2505 mac_ctx, disassoc_req->sessionId);
2506 if (pe_session == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002507 pe_err("No session for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002508 disassoc_cnf.resultCode =
2509 eSIR_SME_INVALID_PARAMETERS;
2510 goto end;
2511 }
2512
2513 sta_ds = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002514 disassoc_req->peer_macaddr.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002515 &pe_session->dph.dphHashTable);
2516 if (sta_ds == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002517 pe_err("StaDs Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002518 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2519 goto end;
2520 }
2521 /* Receive path cleanup with dummy packet */
2522 if (eSIR_SUCCESS !=
2523 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
2524 disassoc_cnf.resultCode =
2525 eSIR_SME_RESOURCES_UNAVAILABLE;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002526 pe_err("cleanup_rx_path error");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002527 goto end;
2528 }
Deepak Dhamdhere57c95ff2016-09-30 16:44:44 -07002529 if (LIM_IS_STA_ROLE(pe_session) &&
2530 (disassoc_req->reasonCode !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002531 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002532 pe_debug("FT Preauth Session (%p %d) Clean up",
2533 pe_session, pe_session->peSessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002535 /* Delete FT session if there exists one */
2536 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002537 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002538 /* Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302539 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002540 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302541 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002542 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302543 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002544 }
2545end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302546 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002547 (uint8_t *) disassoc_req->peer_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302548 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002549 disassoc_cnf.aid = disassoc_req->aid;
2550 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
2551
2552 /* Update PE session ID */
2553 disassoc_cnf.sessionId = disassoc_req->sessionId;
2554
2555 if (disassoc_req != NULL) {
2556 /* / Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302557 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
2559 }
2560
2561 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
2562 (uint32_t *) &disassoc_cnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302563 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002564}
2565
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302566QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
2567 qdf_nbuf_t buf,
2568 uint32_t txCompleteSuccess,
2569 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002570{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302571 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2572
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002573 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302574
2575 if (buf)
2576 qdf_nbuf_free(buf);
2577
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002578 return lim_send_disassoc_cnf(pMac);
2579}
2580
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302581QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
2582 qdf_nbuf_t buf,
2583 uint32_t txCompleteSuccess,
2584 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002585{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302586 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2587
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002588 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302589
2590 if (buf)
2591 qdf_nbuf_free(buf);
2592
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002593 return lim_send_deauth_cnf(pMac);
2594}
2595
2596/**
2597 * \brief This function is called to send Disassociate frame.
2598 *
2599 *
2600 * \param pMac Pointer to Global MAC structure
2601 *
2602 * \param nReason Indicates the reason that need to be sent in
2603 * Disassociation frame
2604 *
2605 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
2606 * sent
2607 *
2608 *
2609 */
2610
2611void
2612lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
2613 uint16_t nReason,
2614 tSirMacAddr peer,
2615 tpPESession psessionEntry, bool waitForAck)
2616{
2617 tDot11fDisassociation frm;
2618 uint8_t *pFrame;
2619 tpSirMacMgmtHdr pMacHdr;
2620 uint32_t nBytes, nPayload, nStatus;
2621 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302622 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002623 uint8_t txFlag = 0;
2624 uint32_t val = 0;
2625 uint8_t smeSessionId = 0;
2626 if (NULL == psessionEntry) {
2627 return;
2628 }
2629
2630 /*
2631 * In case when cac timer is running for this SAP session then
2632 * avoid sending disassoc out. It is violation of dfs specification.
2633 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302634 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2635 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002636 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302637 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002638 FL
2639 ("CAC timer is running, drop disassoc from going out"));
2640 return;
2641 }
2642 smeSessionId = psessionEntry->smeSessionId;
2643
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302644 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002645
2646 frm.Reason.code = nReason;
2647
2648 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
2649 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002650 pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002651 nStatus);
2652 /* We'll fall back on the worst case scenario: */
2653 nPayload = sizeof(tDot11fDisassociation);
2654 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002655 pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)",
2656 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002657 }
2658
2659 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2660
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302661 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002662 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302663 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002664 pe_err("Failed to allocate %d bytes for a Disassociation",
2665 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666 return;
2667 }
2668 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302669 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670
2671 /* Next, we fill out the buffer descriptor: */
2672 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2673 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
2674 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2675
2676 /* Prepare the BSSID */
2677 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2678
2679#ifdef WLAN_FEATURE_11W
2680 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2681#endif
2682
2683 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
2684 sizeof(tSirMacMgmtHdr),
2685 nPayload, &nPayload);
2686 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002687 pe_err("Failed to pack a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002688 nStatus);
2689 cds_packet_free((void *)pPacket);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002690 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002691 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002692 pe_warn("There were warnings while packing a Disassociation (0x%08x)",
2693 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694 }
2695
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002696 pe_debug("***Sessionid %d Sending Disassociation frame with "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002697 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002698 MAC_ADDRESS_STR, psessionEntry->peSessionId, nReason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002699 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
2700 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2701
2702 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302703 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2704 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002705 ) {
2706 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2707 }
2708
Sushant Kaushik46556062015-12-02 16:57:47 +05302709 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002710
2711 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302712 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713 psessionEntry->peSessionId,
2714 pMacHdr->fc.subType));
2715 /* Queue Disassociation frame in high priority WQ */
2716 /* get the duration from the request */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302717 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002718 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2719 TXRX_FRM_802_11_MGMT,
2720 ANI_TXDIR_TODS, 7, lim_tx_complete,
2721 pFrame, lim_disassoc_tx_complete_cnf,
2722 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302723 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302724 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302725 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002726
2727 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2728
2729 if (tx_timer_change
2730 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
2731 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002732 pe_err("Unable to change Disassoc ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002733 return;
2734 } else if (TX_SUCCESS !=
2735 tx_timer_activate(&pMac->lim.limTimers.
2736 gLimDisassocAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002737 pe_err("Unable to activate Disassoc ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002738 lim_deactivate_and_change_timer(pMac,
2739 eLIM_DISASSOC_ACK_TIMER);
2740 return;
2741 }
2742 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302743 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002744 psessionEntry->peSessionId,
2745 pMacHdr->fc.subType));
2746 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302747 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002748 TXRX_FRM_802_11_MGMT,
2749 ANI_TXDIR_TODS,
2750 7,
2751 lim_tx_complete, pFrame, txFlag,
2752 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302753 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302754 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302755 psessionEntry->peSessionId, qdf_status));
2756 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002757 pe_err("Failed to send Disassociation (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302758 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002759 /* Pkt will be freed up by the callback */
2760 }
2761 }
2762} /* End lim_send_disassoc_mgmt_frame. */
2763
2764/**
2765 * \brief This function is called to send a Deauthenticate frame
2766 *
2767 *
2768 * \param pMac Pointer to global MAC structure
2769 *
2770 * \param nReason Indicates the reason that need to be sent in the
2771 * Deauthenticate frame
2772 *
2773 * \param peeer address of the STA to which the frame is to be sent
2774 *
2775 *
2776 */
2777
2778void
2779lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
2780 uint16_t nReason,
2781 tSirMacAddr peer,
2782 tpPESession psessionEntry, bool waitForAck)
2783{
2784 tDot11fDeAuth frm;
2785 uint8_t *pFrame;
2786 tpSirMacMgmtHdr pMacHdr;
2787 uint32_t nBytes, nPayload, nStatus;
2788 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302789 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002790 uint8_t txFlag = 0;
2791 uint32_t val = 0;
2792#ifdef FEATURE_WLAN_TDLS
2793 uint16_t aid;
2794 tpDphHashNode pStaDs;
2795#endif
2796 uint8_t smeSessionId = 0;
2797
2798 if (NULL == psessionEntry) {
2799 return;
2800 }
2801
2802 /*
2803 * In case when cac timer is running for this SAP session then
2804 * avoid deauth frame out. It is violation of dfs specification.
2805 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302806 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2807 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002808 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302809 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002810 FL
2811 ("CAC timer is running, drop the deauth from going out"));
2812 return;
2813 }
2814 smeSessionId = psessionEntry->smeSessionId;
2815
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302816 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002817
2818 frm.Reason.code = nReason;
2819
2820 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
2821 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002822 pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002823 nStatus);
2824 /* We'll fall back on the worst case scenario: */
2825 nPayload = sizeof(tDot11fDeAuth);
2826 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002827 pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)",
2828 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002829 }
2830
2831 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2832
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302833 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002834 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302835 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002836 pe_err("Failed to allocate %d bytes for a De-Authentication",
2837 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002838 return;
2839 }
2840 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302841 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002842
2843 /* Next, we fill out the buffer descriptor: */
2844 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2845 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
2846 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2847
2848 /* Prepare the BSSID */
2849 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2850
2851#ifdef WLAN_FEATURE_11W
2852 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2853#endif
2854
2855 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
2856 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
2857 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002858 pe_err("Failed to pack a DeAuthentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002859 nStatus);
2860 cds_packet_free((void *)pPacket);
2861 return;
2862 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002863 pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
2864 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002865 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002866 pe_debug("***Sessionid %d Sending Deauth frame with "
2867 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
2868 " ,From " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002869 psessionEntry->peSessionId, nReason, waitForAck,
2870 MAC_ADDR_ARRAY(pMacHdr->da),
2871 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2872
2873 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302874 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2875 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002876 ) {
2877 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2878 }
2879
Sushant Kaushik46556062015-12-02 16:57:47 +05302880 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002881#ifdef FEATURE_WLAN_TDLS
2882 pStaDs =
2883 dph_lookup_hash_entry(pMac, peer, &aid,
2884 &psessionEntry->dph.dphHashTable);
2885#endif
2886
2887 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302888 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002889 psessionEntry->peSessionId,
2890 pMacHdr->fc.subType));
2891 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302892 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002893 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2894 TXRX_FRM_802_11_MGMT,
2895 ANI_TXDIR_TODS, 7, lim_tx_complete,
2896 pFrame, lim_deauth_tx_complete_cnf,
2897 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302898 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302899 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302900 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002901 /* Pkt will be freed up by the callback lim_tx_complete */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302902 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002903 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302904 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002905
2906 /* Call lim_process_deauth_ack_timeout which will send
2907 * DeauthCnf for this frame
2908 */
2909 lim_process_deauth_ack_timeout(pMac);
2910 return;
2911 }
2912
2913 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2914
2915 if (tx_timer_change
2916 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
2917 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002918 pe_err("Unable to change Deauth ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002919 return;
2920 } else if (TX_SUCCESS !=
2921 tx_timer_activate(&pMac->lim.limTimers.
2922 gLimDeauthAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002923 pe_err("Unable to activate Deauth ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002924 lim_deactivate_and_change_timer(pMac,
2925 eLIM_DEAUTH_ACK_TIMER);
2926 return;
2927 }
2928 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302929 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002930 psessionEntry->peSessionId,
2931 pMacHdr->fc.subType));
2932#ifdef FEATURE_WLAN_TDLS
2933 if ((NULL != pStaDs)
2934 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
2935 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302936 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002937 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2938 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
2939 7, lim_tx_complete, pFrame, txFlag,
2940 smeSessionId, 0);
2941 } else {
2942#endif
2943 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302944 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002945 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2946 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2947 7, lim_tx_complete, pFrame, txFlag,
2948 smeSessionId, 0);
2949#ifdef FEATURE_WLAN_TDLS
2950 }
2951#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302952 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302953 psessionEntry->peSessionId, qdf_status));
2954 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002955 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302956 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002957 /* Pkt will be freed up by the callback */
2958 }
2959 }
2960
2961} /* End lim_send_deauth_mgmt_frame. */
2962
2963#ifdef ANI_SUPPORT_11H
2964/**
2965 * \brief Send a Measurement Report Action frame
2966 *
2967 *
2968 * \param pMac Pointer to the global MAC structure
2969 *
2970 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
2971 *
2972 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
2973 *
2974 *
2975 */
2976
2977tSirRetStatus
2978lim_send_meas_report_frame(tpAniSirGlobal pMac,
2979 tpSirMacMeasReqActionFrame pMeasReqFrame,
2980 tSirMacAddr peer, tpPESession psessionEntry)
2981{
2982 tDot11fMeasurementReport frm;
2983 uint8_t *pFrame;
2984 tSirRetStatus nSirStatus;
2985 tpSirMacMgmtHdr pMacHdr;
2986 uint32_t nBytes, nPayload, nStatus;
2987 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302988 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002989
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302990 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002991
2992 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
2993 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
2994 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
2995
2996 switch (pMeasReqFrame->measReqIE.measType) {
2997 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
2998 nSirStatus =
2999 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3000 &frm.MeasurementReport);
3001 break;
3002 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3003 nSirStatus =
3004 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3005 &frm.MeasurementReport);
3006 break;
3007 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3008 nSirStatus =
3009 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3010 &frm.MeasurementReport);
3011 break;
3012 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003013 pe_err("Unknown measurement type %d in limSen"
3014 "dMeasReportFrame",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003015 pMeasReqFrame->measReqIE.measType);
3016 return eSIR_FAILURE;
3017 }
3018
3019 if (eSIR_SUCCESS != nSirStatus)
3020 return eSIR_FAILURE;
3021
3022 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3023 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003024 pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003025 nStatus);
3026 /* We'll fall back on the worst case scenario: */
3027 nPayload = sizeof(tDot11fMeasurementReport);
3028 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003029 pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)",
3030 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003031 }
3032
3033 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3034
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303035 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003036 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3037 (uint16_t) nBytes, (void **)&pFrame,
3038 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303039 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003040 pe_err("Failed to allocate %d bytes for a "
3041 "De-Authentication", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003042 return eSIR_FAILURE;
3043 }
3044 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303045 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003046
3047 /* Next, we fill out the buffer descriptor: */
3048 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3049 SIR_MAC_MGMT_ACTION, peer);
3050 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3051
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303052 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003053
3054#ifdef WLAN_FEATURE_11W
3055 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3056#endif
3057
3058 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3059 sizeof(tSirMacMgmtHdr),
3060 nPayload, &nPayload);
3061 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003062 pe_err("Failed to pack a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003063 nStatus);
3064 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3065 (void *)pFrame, (void *)pPacket);
3066 return eSIR_FAILURE; /* allocated! */
3067 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003068 pe_warn("There were warnings while packing a Measurement Report (0x%08x)",
3069 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003070 }
3071
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303072 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003073 ((psessionEntry) ? psessionEntry->
3074 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303075 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003076 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3077 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3078 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303079 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303080 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003081 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303082 qdf_status));
3083 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003084 pe_err("Failed to send a Measurement Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303085 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003086 /* Pkt will be freed up by the callback */
3087 return eSIR_FAILURE; /* just allocated... */
3088 }
3089
3090 return eSIR_SUCCESS;
3091
3092} /* End lim_send_meas_report_frame. */
3093
3094/**
3095 * \brief Send a TPC Request Action frame
3096 *
3097 *
3098 * \param pMac Pointer to the global MAC datastructure
3099 *
3100 * \param peer MAC address to which the frame should be sent
3101 *
3102 *
3103 */
3104
3105void
3106lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3107 tSirMacAddr peer, tpPESession psessionEntry)
3108{
3109 tDot11fTPCRequest frm;
3110 uint8_t *pFrame;
3111 tpSirMacMgmtHdr pMacHdr;
3112 uint32_t nBytes, nPayload, nStatus;
3113 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303114 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003115
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303116 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003117
3118 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3119 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3120 frm.DialogToken.token = 1;
3121 frm.TPCRequest.present = 1;
3122
3123 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3124 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003125 pe_err("Failed to calculate the packed size for a TPC Request (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003126 /* We'll fall back on the worst case scenario: */
3127 nPayload = sizeof(tDot11fTPCRequest);
3128 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003129 pe_warn("There were warnings while calculating the packed size for a TPC Request (0x%08x)",
3130 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003131 }
3132
3133 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3134
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303135 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003136 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3137 (uint16_t) nBytes, (void **)&pFrame,
3138 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303139 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003140 pe_err("Failed to allocate %d bytes for a TPC"
3141 " Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003142 return;
3143 }
3144 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303145 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003146
3147 /* Next, we fill out the buffer descriptor: */
3148 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3149 SIR_MAC_MGMT_ACTION, peer);
3150 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3151
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303152 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003153
3154#ifdef WLAN_FEATURE_11W
3155 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3156#endif
3157
3158 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3159 sizeof(tSirMacMgmtHdr),
3160 nPayload, &nPayload);
3161 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003162 pe_err("Failed to pack a TPC Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003163 nStatus);
3164 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3165 (void *)pFrame, (void *)pPacket);
3166 return; /* allocated! */
3167 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003168 pe_warn("There were warnings while packing a TPC Request (0x%08x)",
3169 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003170 }
3171
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303172 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003173 ((psessionEntry) ? psessionEntry->
3174 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303175 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003176 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3177 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3178 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303179 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303180 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003181 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303182 qdf_status));
3183 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003184 pe_err("Failed to send a TPC Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303185 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003186 /* Pkt will be freed up by the callback */
3187 }
3188
3189} /* End lim_send_tpc_request_frame. */
3190
3191/**
3192 * \brief Send a TPC Report Action frame
3193 *
3194 *
3195 * \param pMac Pointer to the global MAC datastructure
3196 *
3197 * \param pTpcReqFrame Pointer to the received TPC Request
3198 *
3199 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3200 *
3201 *
3202 */
3203
3204tSirRetStatus
3205lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3206 tpSirMacTpcReqActionFrame pTpcReqFrame,
3207 tSirMacAddr peer, tpPESession psessionEntry)
3208{
3209 tDot11fTPCReport frm;
3210 uint8_t *pFrame;
3211 tpSirMacMgmtHdr pMacHdr;
3212 uint32_t nBytes, nPayload, nStatus;
3213 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303214 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003215
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303216 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003217
3218 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3219 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3220 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3221
3222 frm.TPCReport.tx_power = 0;
3223 frm.TPCReport.link_margin = 0;
3224 frm.TPCReport.present = 1;
3225
3226 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3227 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003228 pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003229 /* We'll fall back on the worst case scenario: */
3230 nPayload = sizeof(tDot11fTPCReport);
3231 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003232 pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)",
3233 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003234 }
3235
3236 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3237
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303238 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003239 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3240 (uint16_t) nBytes, (void **)&pFrame,
3241 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303242 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003243 pe_err("Failed to allocate %d bytes for a TPC"
3244 " Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003245 return eSIR_FAILURE;
3246 }
3247 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303248 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249
3250 /* Next, we fill out the buffer descriptor: */
3251 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3252 SIR_MAC_MGMT_ACTION, peer);
3253
3254 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3255
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303256 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003257
3258#ifdef WLAN_FEATURE_11W
3259 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3260#endif
3261
3262 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3263 sizeof(tSirMacMgmtHdr),
3264 nPayload, &nPayload);
3265 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003266 pe_err("Failed to pack a TPC Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267 nStatus);
3268 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3269 (void *)pFrame, (void *)pPacket);
3270 return eSIR_FAILURE; /* allocated! */
3271 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003272 pe_warn("There were warnings while packing a TPC Report (0x%08x)",
3273 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303275 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003276 ((psessionEntry) ? psessionEntry->
3277 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303278 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3280 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3281 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303282 MTRACE(qdf_trace
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003283 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3284 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3285 qdf_status));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303286 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003287 pe_err("Failed to send a TPC Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303288 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003289 /* Pkt will be freed up by the callback */
3290 return eSIR_FAILURE; /* just allocated... */
3291 }
3292
3293 return eSIR_SUCCESS;
3294
3295} /* End lim_send_tpc_report_frame. */
3296#endif /* ANI_SUPPORT_11H */
3297
3298/**
3299 * \brief Send a Channel Switch Announcement
3300 *
3301 *
3302 * \param pMac Pointer to the global MAC datastructure
3303 *
3304 * \param peer MAC address to which this frame will be sent
3305 *
3306 * \param nMode
3307 *
3308 * \param nNewChannel
3309 *
3310 * \param nCount
3311 *
3312 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3313 *
3314 *
3315 */
3316
3317tSirRetStatus
3318lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3319 tSirMacAddr peer,
3320 uint8_t nMode,
3321 uint8_t nNewChannel,
3322 uint8_t nCount, tpPESession psessionEntry)
3323{
3324 tDot11fChannelSwitch frm;
3325 uint8_t *pFrame;
3326 tpSirMacMgmtHdr pMacHdr;
3327 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3328 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303329 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003330 uint8_t txFlag = 0;
3331
3332 uint8_t smeSessionId = 0;
3333
3334 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003335 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003336 return eSIR_FAILURE;
3337 }
3338 smeSessionId = psessionEntry->smeSessionId;
3339
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303340 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003341
3342 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3343 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
3344 frm.ChanSwitchAnn.switchMode = nMode;
3345 frm.ChanSwitchAnn.newChannel = nNewChannel;
3346 frm.ChanSwitchAnn.switchCount = nCount;
3347 frm.ChanSwitchAnn.present = 1;
3348
3349 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
3350 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003351 pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003352 nStatus);
3353 /* We'll fall back on the worst case scenario: */
3354 nPayload = sizeof(tDot11fChannelSwitch);
3355 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003356 pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)",
3357 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003358 }
3359
3360 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3361
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303362 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003363 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3364 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303365 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003366 pe_err("Failed to allocate %d bytes for a TPC Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003367 return eSIR_FAILURE;
3368 }
3369 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303370 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003371
3372 /* Next, we fill out the buffer descriptor: */
3373 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3374 SIR_MAC_MGMT_ACTION, peer,
3375 psessionEntry->selfMacAddr);
3376 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303377 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003378 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3379
3380#ifdef WLAN_FEATURE_11W
3381 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3382#endif
3383
3384 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
3385 sizeof(tSirMacMgmtHdr),
3386 nPayload, &nPayload);
3387 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003388 pe_err("Failed to pack a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003389 nStatus);
3390 cds_packet_free((void *)pPacket);
3391 return eSIR_FAILURE; /* allocated! */
3392 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003393 pe_warn("There were warnings while packing a Channel Switch (0x%08x)",
3394 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003395 }
3396
3397 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303398 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3399 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003400 ) {
3401 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3402 }
3403
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303404 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003405 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303406 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003407 TXRX_FRM_802_11_MGMT,
3408 ANI_TXDIR_TODS,
3409 7, lim_tx_complete, pFrame, txFlag,
3410 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303411 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303412 psessionEntry->peSessionId, qdf_status));
3413 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003414 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303415 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003416 /* Pkt will be freed up by the callback */
3417 return eSIR_FAILURE;
3418 }
3419
3420 return eSIR_SUCCESS;
3421
3422} /* End lim_send_channel_switch_mgmt_frame. */
3423
Abhishek Singh518323d2015-10-19 17:42:01 +05303424/**
3425 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
3426 * action frame over the air .
3427 * @mac_ctx: pointer to global mac structure
3428 * @peer: Destination mac.
3429 * @mode: channel switch mode
3430 * @new_op_class: new op class
3431 * @new_channel: new channel to switch
3432 * @count: channel switch count
3433 *
3434 * This function is called to send ECSA frame.
3435 *
3436 * Return: success if frame is sent else return failure
3437 */
3438
3439tSirRetStatus
3440lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
3441 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
3442 uint8_t new_channel, uint8_t count, tpPESession session_entry)
3443{
3444 tDot11fext_channel_switch_action_frame frm;
3445 uint8_t *frame;
3446 tpSirMacMgmtHdr mac_hdr;
3447 uint32_t num_bytes, n_payload, status;
3448 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303449 QDF_STATUS qdf_status;
Abhishek Singh518323d2015-10-19 17:42:01 +05303450 uint8_t txFlag = 0;
3451 uint8_t sme_session_id = 0;
3452
3453 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003454 pe_err("Session entry is NULL!!!");
Abhishek Singh518323d2015-10-19 17:42:01 +05303455 return eSIR_FAILURE;
3456 }
3457
3458 sme_session_id = session_entry->smeSessionId;
3459
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303460 qdf_mem_set(&frm, sizeof(frm), 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303461
3462 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
3463 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
3464
3465 frm.ext_chan_switch_ann_action.switch_mode = mode;
3466 frm.ext_chan_switch_ann_action.op_class = new_op_class;
3467 frm.ext_chan_switch_ann_action.new_channel = new_channel;
3468 frm.ext_chan_switch_ann_action.switch_count = count;
3469
3470
3471 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
3472 &frm, &n_payload);
3473 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003474 pe_err("Failed to get packed size for Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303475 status);
3476 /* We'll fall back on the worst case scenario*/
3477 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
3478 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003479 pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)",
Abhishek Singh518323d2015-10-19 17:42:01 +05303480 status);
3481 }
3482
3483 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3484
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303485 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303486 (void **) &frame, (void **) &packet);
3487
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303488 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003489 pe_err("Failed to allocate %d bytes for a Ext Channel Switch",
Abhishek Singh518323d2015-10-19 17:42:01 +05303490 num_bytes);
3491 return eSIR_FAILURE;
3492 }
3493
3494 /* Paranoia*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303495 qdf_mem_set(frame, num_bytes, 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303496
3497 /* Next, we fill out the buffer descriptor */
3498 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3499 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3500 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303501 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Abhishek Singh518323d2015-10-19 17:42:01 +05303502 (uint8_t *) session_entry->bssId,
3503 sizeof(tSirMacAddr));
3504
3505 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
3506 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3507 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003508 pe_err("Failed to pack a Channel Switch 0x%08x", status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303509 cds_packet_free((void *)packet);
3510 return eSIR_FAILURE;
3511 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003512 pe_warn("There were warnings while packing a Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303513 status);
3514 }
3515
3516 if ((SIR_BAND_5_GHZ ==
3517 lim_get_rf_band(session_entry->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05303518 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3519 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303520 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3521 }
3522
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003523 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 +05303524 MAC_ADDR_ARRAY(mac_hdr->da),
3525 frm.ext_chan_switch_ann_action.switch_count,
3526 frm.ext_chan_switch_ann_action.switch_mode,
3527 frm.ext_chan_switch_ann_action.new_channel,
3528 frm.ext_chan_switch_ann_action.op_class);
3529
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303530 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Abhishek Singh518323d2015-10-19 17:42:01 +05303531 session_entry->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303532 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303533 TXRX_FRM_802_11_MGMT,
3534 ANI_TXDIR_TODS,
3535 7,
3536 lim_tx_complete, frame,
3537 txFlag, sme_session_id, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303538 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303539 session_entry->peSessionId, qdf_status));
3540 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003541 pe_err("Failed to send a Ext Channel Switch %X!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303542 qdf_status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303543 /* Pkt will be freed up by the callback */
3544 return eSIR_FAILURE;
3545 }
3546 return eSIR_SUCCESS;
3547} /* End lim_send_extended_chan_switch_action_frame */
3548
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303549
3550/**
3551 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
3552 * sent over the air
3553 *
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303554 * @context: pointer to global mac
3555 * @buf: buffer
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303556 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303557 * @params: tx completion params
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303558 *
3559 * Return: This returns QDF_STATUS
3560 */
3561
3562static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303563 void *context,
3564 qdf_nbuf_t buf,
3565 uint32_t tx_complete,
3566 void *params)
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303567{
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003568 pe_debug("tx_complete: %d", tx_complete);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303569 return QDF_STATUS_SUCCESS;
3570}
3571
3572/**
3573 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
3574 * p2p oper chan change confirm action frame
3575 * @mac_ctx: pointer to global mac structure
3576 * @peer: Destination mac.
3577 * @session_entry: session entry
3578 *
3579 * This function is called to send p2p oper chan change confirm action frame.
3580 *
3581 * Return: success if frame is sent else return failure
3582 */
3583
3584tSirRetStatus
3585lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
3586 tSirMacAddr peer, tpPESession session_entry)
3587{
3588 tDot11fp2p_oper_chan_change_confirm frm;
3589 uint8_t *frame;
3590 tpSirMacMgmtHdr mac_hdr;
3591 uint32_t num_bytes, n_payload, status;
3592 void *packet;
3593 QDF_STATUS qdf_status;
3594 uint8_t tx_flag = 0;
3595 uint8_t sme_session_id = 0;
3596
3597 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003598 pe_err("Session entry is NULL!!!");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303599 return eSIR_FAILURE;
3600 }
3601
3602 sme_session_id = session_entry->smeSessionId;
3603
3604 qdf_mem_set(&frm, sizeof(frm), 0);
3605
3606 frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
3607
3608 qdf_mem_copy(frm.p2p_action_oui.oui_data,
3609 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
3610 frm.p2p_action_subtype.subtype = 0x04;
3611 frm.DialogToken.token = 0x0;
3612
3613 if (session_entry->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003614 pe_debug("Populate HT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303615 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
3616 }
3617
3618 if (session_entry->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003619 pe_debug("Populate VHT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303620 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
3621 populate_dot11f_operating_mode(mac_ctx,
3622 &frm.OperatingMode, session_entry);
3623 }
3624
3625 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
3626 &frm, &n_payload);
3627 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003628 pe_err("Failed to get packed size 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303629 /* We'll fall back on the worst case scenario*/
3630 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
3631 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003632 pe_warn("There were warnings while calculating the packed size (0x%08x)",
3633 status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303634 }
3635
3636 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3637
3638 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
3639 (void **) &frame, (void **) &packet);
3640
3641 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003642 pe_err("Failed to allocate %d bytes", num_bytes);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303643 return eSIR_FAILURE;
3644 }
3645
3646 qdf_mem_set(frame, num_bytes, 0);
3647
3648 /* Next, fill out the buffer descriptor */
3649 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3650 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3651 mac_hdr = (tpSirMacMgmtHdr) frame;
3652 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
3653 (uint8_t *) session_entry->bssId,
3654 sizeof(tSirMacAddr));
3655
3656 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
3657 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3658 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003659 pe_err("Failed to pack 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303660 cds_packet_free((void *)packet);
3661 return eSIR_FAILURE;
3662 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003663 pe_warn("There were warnings while packing 0x%08x",
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303664 status);
3665 }
3666
3667 if ((SIR_BAND_5_GHZ ==
3668 lim_get_rf_band(session_entry->currentOperChannel)) ||
3669 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3670 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
3671 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3672 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003673 pe_debug("Send frame on channel %d to mac "
3674 MAC_ADDRESS_STR, session_entry->currentOperChannel,
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303675 MAC_ADDR_ARRAY(peer));
3676
3677 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3678 session_entry->peSessionId, mac_hdr->fc.subType));
3679
3680 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
3681 (uint16_t)num_bytes,
3682 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3683 7, lim_tx_complete, frame,
3684 lim_oper_chan_change_confirm_tx_complete_cnf,
3685 tx_flag, sme_session_id, false, 0);
3686
3687 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3688 session_entry->peSessionId, qdf_status));
3689 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003690 pe_err("Failed to send status %X!", qdf_status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303691 /* Pkt will be freed up by the callback */
3692 return eSIR_FAILURE;
3693 }
3694 return eSIR_SUCCESS;
3695}
3696
3697
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003698tSirRetStatus
3699lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
3700 tSirMacAddr peer,
3701 uint8_t nMode, tpPESession psessionEntry)
3702{
3703 tDot11fOperatingMode frm;
3704 uint8_t *pFrame;
3705 tpSirMacMgmtHdr pMacHdr;
3706 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
3707 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303708 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003709 uint8_t txFlag = 0;
3710
3711 uint8_t smeSessionId = 0;
3712
3713 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003714 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003715 return eSIR_FAILURE;
3716 }
3717 smeSessionId = psessionEntry->smeSessionId;
3718
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303719 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003720
3721 frm.Category.category = SIR_MAC_ACTION_VHT;
3722 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
3723 frm.OperatingMode.chanWidth = nMode;
3724 frm.OperatingMode.rxNSS = 0;
3725 frm.OperatingMode.rxNSSType = 0;
3726
3727 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
3728 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003729 pe_err("Failed to calculate the packed size for a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003730 nStatus);
3731 /* We'll fall back on the worst case scenario: */
3732 nPayload = sizeof(tDot11fOperatingMode);
3733 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003734 pe_warn("There were warnings while calculating the packed size for a Operating Mode (0x%08x)",
3735 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736 }
3737
3738 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3739
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303740 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3742 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303743 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003744 pe_err("Failed to allocate %d bytes for a Operating Mode Report",
3745 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003746 return eSIR_FAILURE;
3747 }
3748 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303749 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003750
3751 /* Next, we fill out the buffer descriptor: */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303752 if (psessionEntry->pePersona == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003753 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3754 SIR_MAC_MGMT_ACTION, peer,
3755 psessionEntry->selfMacAddr);
3756 else
3757 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3758 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
3759 psessionEntry->selfMacAddr);
3760 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303761 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003762 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3763 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
3764 sizeof(tSirMacMgmtHdr),
3765 nPayload, &nPayload);
3766 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003767 pe_err("Failed to pack a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003768 nStatus);
3769 cds_packet_free((void *)pPacket);
3770 return eSIR_FAILURE; /* allocated! */
3771 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003772 pe_warn("There were warnings while packing a Operating Mode (0x%08x)",
3773 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003774 }
3775 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303776 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3777 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003778 ) {
3779 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3780 }
3781
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303782 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003783 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303784 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003785 TXRX_FRM_802_11_MGMT,
3786 ANI_TXDIR_TODS,
3787 7, lim_tx_complete, pFrame, txFlag,
3788 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303789 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303790 psessionEntry->peSessionId, qdf_status));
3791 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003792 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303793 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003794 /* Pkt will be freed up by the callback */
3795 return eSIR_FAILURE;
3796 }
3797
3798 return eSIR_SUCCESS;
3799}
3800
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003801/**
3802 * \brief Send a Neighbor Report Request Action frame
3803 *
3804 *
3805 * \param pMac Pointer to the global MAC structure
3806 *
3807 * \param pNeighborReq Address of a tSirMacNeighborReportReq
3808 *
3809 * \param peer mac address of peer station.
3810 *
3811 * \param psessionEntry address of session entry.
3812 *
3813 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3814 *
3815 *
3816 */
3817
3818tSirRetStatus
3819lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
3820 tpSirMacNeighborReportReq pNeighborReq,
3821 tSirMacAddr peer, tpPESession psessionEntry)
3822{
3823 tSirRetStatus statusCode = eSIR_SUCCESS;
3824 tDot11fNeighborReportRequest frm;
3825 uint8_t *pFrame;
3826 tpSirMacMgmtHdr pMacHdr;
3827 uint32_t nBytes, nPayload, nStatus;
3828 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303829 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003830 uint8_t txFlag = 0;
3831 uint8_t smeSessionId = 0;
3832
3833 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003834 pe_err("(psession == NULL) in Request to send Neighbor Report request action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003835 return eSIR_FAILURE;
3836 }
3837 smeSessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303838 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003839
3840 frm.Category.category = SIR_MAC_ACTION_RRM;
3841 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
3842 frm.DialogToken.token = pNeighborReq->dialogToken;
3843
3844 if (pNeighborReq->ssid_present) {
3845 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
3846 }
3847
3848 nStatus =
3849 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
3850 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003851 pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003852 nStatus);
3853 /* We'll fall back on the worst case scenario: */
3854 nPayload = sizeof(tDot11fNeighborReportRequest);
3855 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003856 pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)",
3857 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003858 }
3859
3860 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3861
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303862 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003863 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3864 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303865 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003866 pe_err("Failed to allocate %d bytes for a Neighbor "
3867 "Report Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003868 return eSIR_FAILURE;
3869 }
3870 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303871 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003872
3873 /* Copy necessary info to BD */
3874 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3875 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
3876
3877 /* Update A3 with the BSSID */
3878 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3879
3880 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3881
3882#ifdef WLAN_FEATURE_11W
3883 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3884#endif
3885
3886 /* Now, we're ready to "pack" the frames */
3887 nStatus = dot11f_pack_neighbor_report_request(pMac,
3888 &frm,
3889 pFrame +
3890 sizeof(tSirMacMgmtHdr),
3891 nPayload, &nPayload);
3892
3893 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003894 pe_err("Failed to pack an Neighbor Report Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003895 nStatus);
3896
3897 /* FIXME - Need to convert to tSirRetStatus */
3898 statusCode = eSIR_FAILURE;
3899 goto returnAfterError;
3900 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003901 pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)",
3902 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003903 }
3904
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003905 pe_debug("Sending a Neighbor Report Request to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +05303906 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003907
3908 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303909 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3910 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003911 ) {
3912 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3913 }
3914
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303915 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003916 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303917 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003918 pPacket,
3919 (uint16_t) nBytes,
3920 TXRX_FRM_802_11_MGMT,
3921 ANI_TXDIR_TODS,
3922 7, lim_tx_complete, pFrame, txFlag,
3923 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303924 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303925 psessionEntry->peSessionId, qdf_status));
3926 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003927 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003928 statusCode = eSIR_FAILURE;
3929 /* Pkt will be freed up by the callback */
3930 return statusCode;
3931 } else
3932 return eSIR_SUCCESS;
3933
3934returnAfterError:
3935 cds_packet_free((void *)pPacket);
3936
3937 return statusCode;
3938} /* End lim_send_neighbor_report_request_frame. */
3939
3940/**
3941 * \brief Send a Link Report Action frame
3942 *
3943 *
3944 * \param pMac Pointer to the global MAC structure
3945 *
3946 * \param pLinkReport Address of a tSirMacLinkReport
3947 *
3948 * \param peer mac address of peer station.
3949 *
3950 * \param psessionEntry address of session entry.
3951 *
3952 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3953 *
3954 *
3955 */
3956
3957tSirRetStatus
3958lim_send_link_report_action_frame(tpAniSirGlobal pMac,
3959 tpSirMacLinkReport pLinkReport,
3960 tSirMacAddr peer, tpPESession psessionEntry)
3961{
3962 tSirRetStatus statusCode = eSIR_SUCCESS;
3963 tDot11fLinkMeasurementReport frm;
3964 uint8_t *pFrame;
3965 tpSirMacMgmtHdr pMacHdr;
3966 uint32_t nBytes, nPayload, nStatus;
3967 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303968 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003969 uint8_t txFlag = 0;
3970 uint8_t smeSessionId = 0;
3971
3972 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003973 pe_err("(psession == NULL) in Request to send Link Report action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003974 return eSIR_FAILURE;
3975 }
3976
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303977 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003978
3979 frm.Category.category = SIR_MAC_ACTION_RRM;
3980 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
3981 frm.DialogToken.token = pLinkReport->dialogToken;
3982
3983 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
3984 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
3985 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
3986 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
3987 /* such case this way than changing the frame parser. */
3988 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
3989 frm.TPCEleLen.TPCLen = 2;
3990 frm.TxPower.txPower = pLinkReport->txPower;
3991 frm.LinkMargin.linkMargin = 0;
3992
3993 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
3994 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
3995 frm.RCPI.rcpi = pLinkReport->rcpi;
3996 frm.RSNI.rsni = pLinkReport->rsni;
3997
3998 nStatus =
3999 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4000 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004001 pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004002 /* We'll fall back on the worst case scenario: */
4003 nPayload = sizeof(tDot11fLinkMeasurementReport);
4004 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004005 pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)",
4006 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004007 }
4008
4009 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4010
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304011 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004012 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4013 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304014 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004015 pe_err("Failed to allocate %d bytes for a Link "
4016 "Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004017 return eSIR_FAILURE;
4018 }
4019 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304020 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004021
4022 /* Copy necessary info to BD */
4023 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4024 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4025
4026 /* Update A3 with the BSSID */
4027 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4028
4029 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4030
4031#ifdef WLAN_FEATURE_11W
4032 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4033#endif
4034
4035 /* Now, we're ready to "pack" the frames */
4036 nStatus = dot11f_pack_link_measurement_report(pMac,
4037 &frm,
4038 pFrame +
4039 sizeof(tSirMacMgmtHdr),
4040 nPayload, &nPayload);
4041
4042 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004043 pe_err("Failed to pack an Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004044
4045 /* FIXME - Need to convert to tSirRetStatus */
4046 statusCode = eSIR_FAILURE;
4047 goto returnAfterError;
4048 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004049 pe_warn("There were warnings while packing Link Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004050 nStatus);
4051 }
4052
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004053 pe_warn("Sending a Link Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004054 lim_print_mac_addr(pMac, peer, LOGW);
4055
4056 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304057 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4058 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004059 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4060 }
4061
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304062 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004063 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304064 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004065 pPacket,
4066 (uint16_t) nBytes,
4067 TXRX_FRM_802_11_MGMT,
4068 ANI_TXDIR_TODS,
4069 7, lim_tx_complete, pFrame, txFlag,
4070 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304071 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304072 psessionEntry->peSessionId, qdf_status));
4073 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004074 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004075 statusCode = eSIR_FAILURE;
4076 /* Pkt will be freed up by the callback */
4077 return statusCode;
4078 } else
4079 return eSIR_SUCCESS;
4080
4081returnAfterError:
4082 cds_packet_free((void *)pPacket);
4083
4084 return statusCode;
4085} /* End lim_send_link_report_action_frame. */
4086
4087/**
4088 * \brief Send a Beacon Report Action frame
4089 *
4090 *
4091 * \param pMac Pointer to the global MAC structure
4092 *
4093 * \param dialog_token dialog token to be used in the action frame.
4094 *
4095 * \param num_report number of reports in pRRMReport.
4096 *
4097 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4098 *
4099 * \param peer mac address of peer station.
4100 *
4101 * \param psessionEntry address of session entry.
4102 *
4103 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4104 *
4105 *
4106 */
4107
4108tSirRetStatus
4109lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4110 uint8_t dialog_token,
4111 uint8_t num_report,
4112 tpSirMacRadioMeasureReport pRRMReport,
4113 tSirMacAddr peer,
4114 tpPESession psessionEntry)
4115{
4116 tSirRetStatus statusCode = eSIR_SUCCESS;
4117 uint8_t *pFrame;
4118 tpSirMacMgmtHdr pMacHdr;
4119 uint32_t nBytes, nPayload, nStatus;
4120 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304121 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004122 uint8_t i;
4123 uint8_t txFlag = 0;
4124 uint8_t smeSessionId = 0;
4125
4126 tDot11fRadioMeasurementReport *frm =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304127 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004128 if (!frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004129 pe_err("Not enough memory to allocate tDot11fRadioMeasurementReport");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004130 return eSIR_MEM_ALLOC_FAILED;
4131 }
4132
4133 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004134 pe_err("(psession == NULL) in Request to send Beacon Report action frame");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304135 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004136 return eSIR_FAILURE;
4137 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004138
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004139 pe_debug("dialog_token %d num_report %d",
Padma, Santhosh Kumar93ec7d22016-12-26 15:58:37 +05304140 dialog_token, num_report);
4141
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004142 frm->Category.category = SIR_MAC_ACTION_RRM;
4143 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4144 frm->DialogToken.token = dialog_token;
4145
4146 frm->num_MeasurementReport =
4147 (num_report >
4148 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4149 num_report;
4150
4151 for (i = 0; i < frm->num_MeasurementReport; i++) {
4152 frm->MeasurementReport[i].type = pRRMReport[i].type;
4153 frm->MeasurementReport[i].token = pRRMReport[i].token;
4154 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4155 switch (pRRMReport[i].type) {
4156 case SIR_MAC_RRM_BEACON_TYPE:
4157 populate_dot11f_beacon_report(pMac,
4158 &frm->MeasurementReport[i],
4159 &pRRMReport[i].report.
4160 beaconReport);
4161 frm->MeasurementReport[i].incapable =
4162 pRRMReport[i].incapable;
4163 frm->MeasurementReport[i].refused =
4164 pRRMReport[i].refused;
4165 frm->MeasurementReport[i].present = 1;
4166 break;
4167 default:
4168 frm->MeasurementReport[i].incapable =
4169 pRRMReport[i].incapable;
4170 frm->MeasurementReport[i].refused =
4171 pRRMReport[i].refused;
4172 frm->MeasurementReport[i].present = 1;
4173 break;
4174 }
4175 }
4176
4177 nStatus =
4178 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4179 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004180 pe_err("Failed to calculate the packed size for a Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004181 nStatus);
4182 /* We'll fall back on the worst case scenario: */
4183 nPayload = sizeof(tDot11fLinkMeasurementReport);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304184 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004185 return eSIR_FAILURE;
4186 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004187 pe_warn("There were warnings while calculating the packed size for a Radio Measure Report (0x%08x)",
4188 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004189 }
4190
4191 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4192
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304193 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004194 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4195 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304196 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004197 pe_err("Failed to allocate %d bytes for a Radio Measure "
4198 "Report", nBytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304199 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004200 return eSIR_FAILURE;
4201 }
4202 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304203 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004204
4205 /* Copy necessary info to BD */
4206 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4207 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4208
4209 /* Update A3 with the BSSID */
4210 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4211
4212 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4213
4214#ifdef WLAN_FEATURE_11W
4215 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4216#endif
4217
4218 /* Now, we're ready to "pack" the frames */
4219 nStatus = dot11f_pack_radio_measurement_report(pMac,
4220 frm,
4221 pFrame +
4222 sizeof(tSirMacMgmtHdr),
4223 nPayload, &nPayload);
4224
4225 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004226 pe_err("Failed to pack an Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004227 nStatus);
4228
4229 /* FIXME - Need to convert to tSirRetStatus */
4230 statusCode = eSIR_FAILURE;
4231 goto returnAfterError;
4232 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004233 pe_warn("There were warnings while packing Radio Measure Report (0x%08x)",
4234 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004235 }
4236
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004237 pe_warn("Sending a Radio Measure Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004238 lim_print_mac_addr(pMac, peer, LOGW);
4239
4240 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304241 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4242 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004243 ) {
4244 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4245 }
4246
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304247 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004248 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304249 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004250 pPacket,
4251 (uint16_t) nBytes,
4252 TXRX_FRM_802_11_MGMT,
4253 ANI_TXDIR_TODS,
4254 7, lim_tx_complete, pFrame, txFlag,
4255 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304256 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304257 psessionEntry->peSessionId, qdf_status));
4258 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004259 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004260 statusCode = eSIR_FAILURE;
4261 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304262 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004263 return statusCode;
4264 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304265 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004266 return eSIR_SUCCESS;
4267 }
4268
4269returnAfterError:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304270 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004271 cds_packet_free((void *)pPacket);
4272 return statusCode;
4273}
4274
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275#ifdef WLAN_FEATURE_11W
4276/**
4277 * \brief Send SA query request action frame to peer
4278 *
4279 * \sa lim_send_sa_query_request_frame
4280 *
4281 *
4282 * \param pMac The global tpAniSirGlobal object
4283 *
4284 * \param transId Transaction identifier
4285 *
4286 * \param peer The Mac address of the station to which this action frame is addressed
4287 *
4288 * \param psessionEntry The PE session entry
4289 *
4290 * \return eSIR_SUCCESS if setup completes successfully
4291 * eSIR_FAILURE is some problem is encountered
4292 */
4293
4294tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4295 tSirMacAddr peer,
4296 tpPESession psessionEntry)
4297{
4298
4299 tDot11fSaQueryReq frm; /* SA query request action frame */
4300 uint8_t *pFrame;
4301 tSirRetStatus nSirStatus;
4302 tpSirMacMgmtHdr pMacHdr;
4303 uint32_t nBytes, nPayload, nStatus;
4304 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304305 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004306 uint8_t txFlag = 0;
4307 uint8_t smeSessionId = 0;
4308
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304309 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004310 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4311 /* 11w action field is :
4312 action: 0 --> SA Query Request action frame
4313 action: 1 --> SA Query Response action frame */
4314 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4315 /* 11w SA Query Request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304316 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004317
4318 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4319 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004320 pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004321 nStatus);
4322 /* We'll fall back on the worst case scenario: */
4323 nPayload = sizeof(tDot11fSaQueryReq);
4324 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004325 pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)",
4326 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004327 }
4328
4329 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304330 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004331 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304332 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004333 pe_err("Failed to allocate %d bytes for a SA Query Request "
4334 "action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004335 return eSIR_FAILURE;
4336 }
4337 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304338 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004339
4340 /* Copy necessary info to BD */
4341 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4342 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4343
4344 /* Update A3 with the BSSID */
4345 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4346
4347 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4348
4349 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4350 /* in the FC */
4351 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4352
4353 /* Pack 11w SA Query Request frame */
4354 nStatus = dot11f_pack_sa_query_req(pMac,
4355 &frm,
4356 pFrame + sizeof(tSirMacMgmtHdr),
4357 nPayload, &nPayload);
4358
4359 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004360 pe_err("Failed to pack an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004361 nStatus);
4362 /* FIXME - Need to convert to tSirRetStatus */
4363 nSirStatus = eSIR_FAILURE;
4364 goto returnAfterError;
4365 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004366 pe_warn("There were warnings while packing SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004367 nStatus);
4368 }
4369
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004370 pe_debug("Sending an SA Query Request to");
4371 lim_print_mac_addr(pMac, peer, LOGD);
4372 pe_debug("Sending an SA Query Request from ");
4373 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004374
4375 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4376#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304377 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4378 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004379#endif
4380 ) {
4381 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4382 }
4383 smeSessionId = psessionEntry->smeSessionId;
4384
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304385 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004386 pPacket,
4387 (uint16_t) nBytes,
4388 TXRX_FRM_802_11_MGMT,
4389 ANI_TXDIR_TODS,
4390 7, lim_tx_complete, pFrame, txFlag,
4391 smeSessionId, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304392 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004393 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004394 nSirStatus = eSIR_FAILURE;
4395 /* Pkt will be freed up by the callback */
4396 return nSirStatus;
4397 } else {
4398 return eSIR_SUCCESS;
4399 }
4400
4401returnAfterError:
4402 cds_packet_free((void *)pPacket);
4403 return nSirStatus;
4404} /* End lim_send_sa_query_request_frame */
4405
4406/**
4407 * \brief Send SA query response action frame to peer
4408 *
4409 * \sa lim_send_sa_query_response_frame
4410 *
4411 *
4412 * \param pMac The global tpAniSirGlobal object
4413 *
4414 * \param transId Transaction identifier received in SA query request action frame
4415 *
4416 * \param peer The Mac address of the AP to which this action frame is addressed
4417 *
4418 * \param psessionEntry The PE session entry
4419 *
4420 * \return eSIR_SUCCESS if setup completes successfully
4421 * eSIR_FAILURE is some problem is encountered
4422 */
4423
4424tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
4425 uint8_t *transId, tSirMacAddr peer,
4426 tpPESession psessionEntry)
4427{
4428
4429 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
4430 uint8_t *pFrame;
4431 tSirRetStatus nSirStatus;
4432 tpSirMacMgmtHdr pMacHdr;
4433 uint32_t nBytes, nPayload, nStatus;
4434 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304435 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004436 uint8_t txFlag = 0;
4437 uint8_t smeSessionId = 0;
4438
4439 smeSessionId = psessionEntry->smeSessionId;
4440
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304441 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004442 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4443 /*11w action field is :
4444 action: 0 --> SA query request action frame
4445 action: 1 --> SA query response action frame */
4446 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
4447 /*11w SA query response transId is same as
4448 SA query request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304449 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004450
4451 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
4452 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004453 pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004454 nStatus);
4455 /* We'll fall back on the worst case scenario: */
4456 nPayload = sizeof(tDot11fSaQueryRsp);
4457 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004458 pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)",
4459 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004460 }
4461
4462 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304463 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004464 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304465 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004466 pe_err("Failed to allocate %d bytes for a SA query response"
4467 " action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004468 return eSIR_FAILURE;
4469 }
4470 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304471 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004472
4473 /* Copy necessary info to BD */
4474 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4475 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4476
4477 /* Update A3 with the BSSID */
4478 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4479
4480 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4481
4482 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
4483 /* in the FC */
4484 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4485
4486 /* Pack 11w SA query response frame */
4487 nStatus = dot11f_pack_sa_query_rsp(pMac,
4488 &frm,
4489 pFrame + sizeof(tSirMacMgmtHdr),
4490 nPayload, &nPayload);
4491
4492 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004493 pe_err("Failed to pack an SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004494 nStatus);
4495 /* FIXME - Need to convert to tSirRetStatus */
4496 nSirStatus = eSIR_FAILURE;
4497 goto returnAfterError;
4498 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004499 pe_warn("There were warnings while packing SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004500 nStatus);
4501 }
4502
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004503 pe_debug("Sending a SA Query Response to");
Srinivas Girigowdaf936d822017-03-19 23:23:59 -07004504 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004505
4506 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4507#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304508 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4509 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004510#endif
4511 ) {
4512 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4513 }
4514
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304515 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004516 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304517 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004518 pPacket,
4519 (uint16_t) nBytes,
4520 TXRX_FRM_802_11_MGMT,
4521 ANI_TXDIR_TODS,
4522 7, lim_tx_complete, pFrame, txFlag,
4523 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304524 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304525 psessionEntry->peSessionId, qdf_status));
4526 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004527 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004528 nSirStatus = eSIR_FAILURE;
4529 /* Pkt will be freed up by the callback */
4530 return nSirStatus;
4531 } else {
4532 return eSIR_SUCCESS;
4533 }
4534
4535returnAfterError:
4536 cds_packet_free((void *)pPacket);
4537 return nSirStatus;
4538} /* End lim_send_sa_query_response_frame */
4539#endif
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004540
4541/**
4542 * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
4543 * @mac_ctx: mac context
4544 * @peer_mac: Peer MAC address
4545 * @tid: TID for which addba response is being sent
4546 * @session: PE session entry
4547 *
4548 * This function is called when ADDBA request is successful. ADDBA response is
4549 * setup by calling addba_response_setup API and frame is then sent out OTA.
4550 *
4551 * Return: QDF_STATUS
4552 */
4553QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
4554 tSirMacAddr peer_mac, uint16_t tid, tpPESession session)
4555{
4556
4557 tDot11faddba_rsp frm;
4558 uint8_t *frame_ptr;
4559 tpSirMacMgmtHdr mgmt_hdr;
4560 uint32_t num_bytes, payload_size, status;
4561 void *pkt_ptr;
4562 QDF_STATUS qdf_status;
4563 uint8_t tx_flag = 0;
4564 uint8_t sme_sessionid = 0;
4565 uint16_t buff_size, status_code, batimeout;
4566 uint8_t peer_id, dialog_token;
4567 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4568 void *peer, *pdev;
4569
4570 sme_sessionid = session->smeSessionId;
4571
4572 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4573 if (!pdev) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004574 pe_err("pdev is NULL");
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004575 return QDF_STATUS_E_FAILURE;
4576 }
4577
4578 peer = cdp_peer_find_by_addr(soc, pdev, peer_mac, &peer_id);
4579 if (!peer) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004580 pe_err("PEER [%pM] not found", peer_mac);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004581 return QDF_STATUS_E_FAILURE;
4582 }
4583
4584 cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
4585 &status_code, &buff_size, &batimeout);
4586
4587 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4588 frm.Category.category = SIR_MAC_ACTION_BLKACK;
4589 frm.Action.action = SIR_MAC_ADDBA_RSP;
4590
4591 frm.DialogToken.token = dialog_token;
4592 frm.Status.status = status_code;
4593 frm.addba_param_set.tid = tid;
4594 frm.addba_param_set.buff_size = buff_size;
4595 frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE;
4596 frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED;
4597 frm.ba_timeout.timeout = batimeout;
4598
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004599 pe_debug("Sending a ADDBA Response from %pM to %pM",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004600 session->selfMacAddr, peer_mac);
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004601 pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004602 tid, frm.DialogToken.token, frm.Status.status,
4603 frm.addba_param_set.buff_size);
4604
4605 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
4606 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004607 pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004608 status);
4609 /* We'll fall back on the worst case scenario: */
4610 payload_size = sizeof(tDot11faddba_rsp);
4611 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004612 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 -08004613 }
4614
4615 num_bytes = payload_size + sizeof(*mgmt_hdr);
4616 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
4617 (void **)&pkt_ptr);
4618 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004619 pe_err("Failed to allocate %d bytes for a ADDBA response action frame",
4620 num_bytes);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004621 return QDF_STATUS_E_FAILURE;
4622 }
4623 qdf_mem_set(frame_ptr, num_bytes, 0);
4624
4625 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
4626 SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
4627
4628 /* Update A3 with the BSSID */
4629 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
4630 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
4631
4632 /* ADDBA Response is a robust mgmt action frame,
4633 * set the "protect" (aka WEP) bit in the FC
4634 */
4635 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
4636
4637 status = dot11f_pack_addba_rsp(mac_ctx, &frm,
4638 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
4639 &payload_size);
4640
4641 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004642 pe_err("Failed to pack a ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004643 status);
4644 qdf_status = QDF_STATUS_E_FAILURE;
4645 goto error_addba_rsp;
4646 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004647 pe_warn("There were warnings while packing ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004648 status);
4649 }
4650
4651
4652 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
4653#ifdef WLAN_FEATURE_P2P
4654 || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
4655 (session->pePersona == QDF_P2P_GO_MODE)
4656#endif
4657 ) {
4658 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4659 }
4660
4661 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4662 session->peSessionId, mgmt_hdr->fc.subType));
4663 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
4664 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
4665 lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0);
4666 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4667 session->peSessionId, qdf_status));
4668 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004669 pe_err("wma_tx_frame FAILED! Status [%d]",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004670 qdf_status);
4671 qdf_status = QDF_STATUS_E_FAILURE;
4672 /*
4673 * wma_tx_frame free memory in certain cases, free pkt_ptr
4674 * only if not freed already.
4675 */
4676 if (pkt_ptr)
4677 cds_packet_free((void *)pkt_ptr);
4678 return qdf_status;
4679 } else {
4680 return eSIR_SUCCESS;
4681 }
4682
4683error_addba_rsp:
4684 cds_packet_free((void *)pkt_ptr);
4685 return qdf_status;
4686}