blob: 391969d05f7149db848f5bc52ef5a73e3b7a9e4c [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*/
568 if (ANI_DRIVER_TYPE(mac_ctx) == eDRIVER_TYPE_MFG)
569 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 {
1239 /* Advertise 1x1 if either is HT-STA */
1240 if (frm.HTCaps.present && mac_ctx->hw_dbs_capable)
1241 frm.HTCaps.supportedMCSSet[1] = 0;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301242 }
1243 if (pe_session->vhtCapability &&
1244 pe_session->vendor_vht_sap &&
1245 (assoc_req != NULL) &&
1246 assoc_req->vendor_vht_ie.VHTCaps.present) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001247 pe_debug("Populate Vendor VHT IEs in Assoc Rsponse");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301248 frm.vendor_vht_ie.present = 1;
1249 frm.vendor_vht_ie.type =
1250 pe_session->vendor_specific_vht_ie_type;
1251 frm.vendor_vht_ie.sub_type =
1252 pe_session->vendor_specific_vht_ie_sub_type;
1253
1254 frm.vendor_vht_ie.VHTCaps.present = 1;
1255 populate_dot11f_vht_caps(mac_ctx, pe_session,
1256 &frm.vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257 is_vht = true;
1258 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001259 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1260 pe_session);
1261
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001262 if (lim_is_sta_he_capable(sta) &&
1263 lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001264 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001265 populate_dot11f_he_caps(mac_ctx, pe_session,
1266 &frm.vendor_he_cap);
1267 populate_dot11f_he_operation(mac_ctx, pe_session,
1268 &frm.vendor_he_op);
1269 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001270#ifdef WLAN_FEATURE_11W
1271 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1272 if (wlan_cfg_get_int
1273 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1274 &max_retries) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001275 pe_err("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 else if (wlan_cfg_get_int
1277 (mac_ctx,
1278 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1279 &retry_int) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001280 pe_err("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001281 else
1282 populate_dot11f_timeout_interval(mac_ctx,
1283 &frm.TimeoutInterval,
1284 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1285 (max_retries -
1286 sta->pmfSaQueryRetryCount)
1287 * retry_int);
1288 }
1289#endif
1290 }
1291
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301292 qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001293
1294 if (LIM_IS_AP_ROLE(pe_session) &&
1295 (pe_session->gLimProtectionControl !=
1296 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1297 lim_decide_ap_protection(mac_ctx, peer_addr,
1298 &beacon_params, pe_session);
1299
1300 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1301 pe_session);
1302 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1303 pe_session);
1304
1305 /*
1306 * Populate Do11capabilities after updating session with
1307 * Assos req details
1308 */
1309 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1310
1311 beacon_params.bssIdx = pe_session->bssIdx;
1312
1313 /* Send message to HAL about beacon parameter change. */
1314 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1315 && beacon_params.paramChangeBitmap) {
1316 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1317 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1318 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001319
1320 if (assoc_req != NULL) {
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001321 addn_ie_len = pe_session->addIeParams.assocRespDataLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001322
1323 /* Nonzero length indicates Assoc rsp IE available */
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001324 if (addn_ie_len > 0 &&
1325 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
1326 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301327 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 pe_session->addIeParams.assocRespData_buff,
1329 pe_session->addIeParams.assocRespDataLen);
1330
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301331 qdf_mem_set((uint8_t *) &extracted_ext_cap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001332 sizeof(extracted_ext_cap), 0);
1333
1334 stripoff_len = addn_ie_len;
1335 sir_status =
1336 lim_strip_extcap_update_struct
1337 (mac_ctx, &add_ie[0], &stripoff_len,
1338 &extracted_ext_cap);
1339 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001340 pe_debug("strip off extcap IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001341 } else {
1342 addn_ie_len = stripoff_len;
1343 extracted_flag = true;
1344 }
1345 bytes = bytes + addn_ie_len;
1346 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001347 pe_debug("addn_ie_len: %d for Assoc Resp: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 addn_ie_len, assoc_req->addIEPresent);
1349 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001350
1351 /*
1352 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1353 * may change the frame size. Therefore, MUST merge ExtCap IE before
1354 * dot11f get packed payload size.
1355 */
1356 if (extracted_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001357 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
1358 true);
Hu Wang411e0cc2016-10-28 14:56:01 +08001359
1360 /* Allocate a buffer for this frame: */
1361 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1362 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001363 pe_err("get Association Response size failure (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001364 status);
1365 return;
1366 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001367 pe_warn("get Association Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001368 status);
1369 }
1370
1371 bytes += sizeof(tSirMacMgmtHdr) + payload;
1372
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301373 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001374 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301375 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001376 pe_err("cds_packet_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001377 return;
1378 }
1379 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301380 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001381
1382 /* Next, we fill out the buffer descriptor: */
1383 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1384 (LIM_ASSOC == subtype) ?
1385 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1386 peer_addr,
1387 pe_session->selfMacAddr);
1388 mac_hdr = (tpSirMacMgmtHdr) frame;
1389
1390 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1391
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001392 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1393 frame + sizeof(tSirMacMgmtHdr),
1394 payload, &payload);
1395 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001396 pe_err("Association Response pack failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001397 status);
1398 cds_packet_free((void *)packet);
1399 return;
1400 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001401 pe_warn("Association Response pack warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001402 status);
1403 }
1404
1405 if (subtype == LIM_ASSOC)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001406 pe_debug("*** Sending Assoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001407 status_code, aid);
1408 else
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001409 pe_debug("*** Sending ReAssoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001410 status_code, aid);
1411
1412 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1413
1414 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301415 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001416 &add_ie[0], addn_ie_len);
1417
1418 if ((SIR_BAND_5_GHZ ==
1419 lim_get_rf_band(pe_session->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05301420 (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
1421 (pe_session->pePersona == QDF_P2P_GO_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1423
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301424 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425 pe_session->peSessionId, mac_hdr->fc.subType));
1426 /* Queue Association Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301427 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 TXRX_FRM_802_11_MGMT,
1429 ANI_TXDIR_TODS,
1430 7, lim_tx_complete, frame, tx_flag,
1431 sme_session, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301432 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301433 pe_session->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001434
1435 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301436 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001437 pe_err("Could not Send Re/AssocRsp, retCode=%X",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301438 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439
1440 /*
1441 * update the ANI peer station count.
1442 * FIXME_PROTECTION : take care of different type of station
1443 * counter inside this function.
1444 */
1445 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1446
1447}
1448
1449void
1450lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1451 tSirMacAddr peer,
1452 uint8_t wmmTspecPresent,
1453 tSirMacTSInfo *pTsinfo,
1454 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1455{
1456 uint8_t *pFrame;
1457 tpSirMacMgmtHdr pMacHdr;
1458 tDot11fDelTS DelTS;
1459 tDot11fWMMDelTS WMMDelTS;
1460 uint32_t nBytes, nPayload, nStatus;
1461 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301462 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 uint8_t txFlag = 0;
1464 uint8_t smeSessionId = 0;
1465
1466 if (NULL == psessionEntry) {
1467 return;
1468 }
1469
1470 smeSessionId = psessionEntry->smeSessionId;
1471
1472 if (!wmmTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301473 qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474
1475 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1476 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1477 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1478
1479 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1480 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001481 pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001482 /* We'll fall back on the worst case scenario: */
1483 nPayload = sizeof(tDot11fDelTS);
1484 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001485 pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)",
1486 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001487 }
1488 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301489 qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001490
1491 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1492 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1493 WMMDelTS.DialogToken.token = 0;
1494 WMMDelTS.StatusCode.statusCode = 0;
1495 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1496 nStatus =
1497 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1498 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001499 pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500 /* We'll fall back on the worst case scenario: */
1501 nPayload = sizeof(tDot11fDelTS);
1502 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001503 pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)",
1504 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001505 }
1506 }
1507
1508 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1509
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301510 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001511 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1512 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301513 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001514 pe_err("Failed to allocate %d bytes for an Add TS Response",
1515 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516 return;
1517 }
1518 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301519 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001520
1521 /* Next, we fill out the buffer descriptor: */
1522 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1523 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1524 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1525
1526 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1527
1528#ifdef WLAN_FEATURE_11W
1529 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1530#endif
1531
1532 /* That done, pack the struct: */
1533 if (!wmmTspecPresent) {
1534 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1535 pFrame + sizeof(tSirMacMgmtHdr),
1536 nPayload, &nPayload);
1537 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001538 pe_err("Failed to pack a Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539 nStatus);
1540 cds_packet_free((void *)pPacket);
1541 return; /* allocated! */
1542 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001543 pe_warn("There were warnings while packing a Del TS frame (0x%08x)",
1544 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001545 }
1546 } else {
1547 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1548 pFrame + sizeof(tSirMacMgmtHdr),
1549 nPayload, &nPayload);
1550 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001551 pe_err("Failed to pack a WMM Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001552 nStatus);
1553 cds_packet_free((void *)pPacket);
1554 return; /* allocated! */
1555 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001556 pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)",
1557 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001558 }
1559 }
1560
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001561 pe_debug("Sending DELTS REQ (size %d) to ", nBytes);
1562 lim_print_mac_addr(pMac, pMacHdr->da, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563
1564 if ((SIR_BAND_5_GHZ ==
1565 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301566 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1567 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001568 ) {
1569 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1570 }
1571
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301572 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301574 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001575 TXRX_FRM_802_11_MGMT,
1576 ANI_TXDIR_TODS,
1577 7, lim_tx_complete, pFrame, txFlag,
1578 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301579 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301580 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001581 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301582 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001583 pe_err("Failed to send Del TS (%X)!", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584
1585} /* End lim_send_delts_req_action_frame. */
1586
1587/**
1588 * lim_send_assoc_req_mgmt_frame() - Send association request
1589 * @mac_ctx: Handle to MAC context
1590 * @mlm_assoc_req: Association request information
1591 * @pe_session: PE session information
1592 *
1593 * Builds and transmits association request frame to AP.
1594 *
1595 * Return: Void
1596 */
1597
1598void
1599lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1600 tLimMlmAssocReq *mlm_assoc_req,
1601 tpPESession pe_session)
1602{
1603 tDot11fAssocRequest *frm;
1604 uint16_t caps;
1605 uint8_t *frame;
1606 tSirRetStatus sir_status;
1607 tLimMlmAssocCnf assoc_cnf;
Hu Wang411e0cc2016-10-28 14:56:01 +08001608 uint32_t bytes = 0, payload, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1610 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301611 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 uint16_t add_ie_len;
1613 uint8_t *add_ie;
1614 uint8_t *wps_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001615 uint8_t power_caps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 uint8_t tx_flag = 0;
1617 uint8_t sme_sessionid = 0;
1618 bool vht_enabled = false;
1619 tDot11fIEExtCap extr_ext_cap;
1620 bool extr_ext_flag = true;
1621 tpSirMacMgmtHdr mac_hdr;
Hu Wangfbd279d2016-10-31 18:24:34 +08001622 uint32_t ie_offset = 0;
1623 uint8_t *p_ext_cap = NULL;
1624 tDot11fIEExtCap bcn_ext_cap;
1625 uint8_t *bcn_ie = NULL;
1626 uint32_t bcn_ie_len = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627
1628 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001629 pe_err("pe_session is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630 return;
1631 }
1632
1633 sme_sessionid = pe_session->smeSessionId;
1634
1635 /* check this early to avoid unncessary operation */
1636 if (NULL == pe_session->pLimJoinReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001637 pe_err("pe_session->pLimJoinReq is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638 return;
1639 }
1640 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1641 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1642
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301643 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001644 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001645 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001646 return;
1647 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001648 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301650 if (add_ie_len && pe_session->is_ext_caps_present) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301651 qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 0);
1653 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1654 add_ie, &add_ie_len, &extr_ext_cap);
1655 if (eSIR_SUCCESS != sir_status) {
1656 extr_ext_flag = false;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001657 pe_debug("Unable to Stripoff ExtCap IE from Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 } else {
1659 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1660 extr_ext_cap.bytes;
1661
1662 if (p_ext_cap->interworking_service)
1663 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +08001664 extr_ext_cap.num_bytes =
1665 lim_compute_ext_cap_ie_length(&extr_ext_cap);
1666 extr_ext_flag = (extr_ext_cap.num_bytes > 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667 }
1668 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001669 pe_debug("No addn IE or peer dosen't support addnIE for Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670 extr_ext_flag = false;
1671 }
1672
1673 caps = mlm_assoc_req->capabilityInfo;
1674#if defined(FEATURE_WLAN_WAPI)
1675 /*
1676 * According to WAPI standard:
1677 * 7.3.1.4 Capability Information field
1678 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1679 * in transmitted Association or Reassociation management frames.
1680 * APs ignore the Privacy subfield within received Association and
1681 * Reassociation management frames.
1682 */
1683 if (pe_session->encryptType == eSIR_ED_WPI)
1684 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1685#endif
1686 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1687
1688 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1689 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1690 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1691 &frm->SuppRates, pe_session);
1692
1693 qos_enabled = (pe_session->limQosEnabled) &&
1694 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1695
1696 wme_enabled = (pe_session->limWmeEnabled) &&
1697 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1698
1699 /* We prefer .11e asociations: */
1700 if (qos_enabled)
1701 wme_enabled = false;
1702
1703 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1704 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1705
1706 if (pe_session->lim11hEnable &&
1707 pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001708 power_caps = true;
1709
1710 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1711 LIM_ASSOC, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001712 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1713 LIM_ASSOC, pe_session);
1714
1715 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001716 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1717 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1718 if (power_caps == false) {
1719 power_caps = true;
1720 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1721 LIM_ASSOC, pe_session);
1722 }
1723 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 if (qos_enabled)
Naveen Rawatcd118312016-11-22 10:46:21 -08001725 populate_dot11f_qos_caps_station(mac_ctx, pe_session,
1726 &frm->QOSCapsStation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727
1728 populate_dot11f_ext_supp_rates(mac_ctx,
1729 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1730 pe_session);
1731
Gupta, Kapil54a16992016-01-13 19:34:02 +05301732 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1733 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1735 pe_session);
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08001736
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001737 /*
1738 * The join request *should* contain zero or one of the WPA and RSN
1739 * IEs. The payload send along with the request is a
1740 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1741 * typedef struct sSirRSNie
1742 * {
1743 * uint16_t length;
1744 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1745 * } tSirRSNie, *tpSirRSNie;
1746 * So, we should be able to make the following two calls harmlessly,
1747 * since they do nothing if they don't find the given IE in the
1748 * bytestream with which they're provided.
1749 * The net effect of this will be to faithfully transmit whatever
1750 * security IE is in the join request.
1751 * However, if we're associating for the purpose of WPS
1752 * enrollment, and we've been configured to indicate that by
1753 * eliding the WPA or RSN IE, we just skip this:
1754 */
1755 if (add_ie_len && add_ie)
1756 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1757
1758 if (NULL == wps_ie) {
1759 populate_dot11f_rsn_opaque(mac_ctx,
1760 &(pe_session->pLimJoinReq->rsnIE),
1761 &frm->RSNOpaque);
1762 populate_dot11f_wpa_opaque(mac_ctx,
1763 &(pe_session->pLimJoinReq->rsnIE),
1764 &frm->WPAOpaque);
1765#if defined(FEATURE_WLAN_WAPI)
1766 populate_dot11f_wapi_opaque(mac_ctx,
1767 &(pe_session->pLimJoinReq->rsnIE),
1768 &frm->WAPIOpaque);
1769#endif /* defined(FEATURE_WLAN_WAPI) */
1770 }
1771 /* include WME EDCA IE as well */
1772 if (wme_enabled) {
1773 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1774 pe_session, &frm->WMMInfoStation);
1775
1776 if (wsm_enabled)
1777 populate_dot11f_wmm_caps(&frm->WMMCaps);
1778 }
1779
1780 /*
1781 * Populate HT IEs, when operating in 11n and
1782 * when AP is also operating in 11n mode
1783 */
1784 if (pe_session->htCapability &&
1785 mac_ctx->lim.htCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001786 pe_debug("Populate HT Caps in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001787 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001788 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1789 &frm->HTCaps, sizeof(frm->HTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001790 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001791 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 +05301792 frm->HTCaps.supportedChannelWidthSet,
1793 frm->HTCaps.mimoPowerSave,
1794 frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
1795 frm->HTCaps.shortGI40MHz,
1796 frm->HTCaps.dsssCckMode40MHz,
1797 frm->HTCaps.maxRxAMPDUFactor);
1798
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001799 if (pe_session->vhtCapability &&
1800 pe_session->vhtCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001801 pe_debug("Populate VHT IEs in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001803 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1804 &frm->VHTCaps, sizeof(frm->VHTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 vht_enabled = true;
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001806 if (pe_session->enableHtSmps &&
1807 !pe_session->supported_nss_1x1) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001808 pe_err("VHT OP mode IE in Assoc Req");
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001809 populate_dot11f_operating_mode(mac_ctx,
1810 &frm->OperatingMode, pe_session);
1811 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001812 }
1813 if (!vht_enabled &&
1814 pe_session->is_vendor_specific_vhtcaps) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001815 pe_debug("Populate Vendor VHT IEs in Assoc Request");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301816 frm->vendor_vht_ie.present = 1;
1817 frm->vendor_vht_ie.type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 pe_session->vendor_specific_vht_ie_type;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301819 frm->vendor_vht_ie.sub_type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820 pe_session->vendor_specific_vht_ie_sub_type;
1821
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301822 frm->vendor_vht_ie.VHTCaps.present = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001823 populate_dot11f_vht_caps(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301824 &frm->vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001825 vht_enabled = true;
1826 }
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301827 if (pe_session->is_ext_caps_present)
1828 populate_dot11f_ext_cap(mac_ctx, vht_enabled,
1829 &frm->ExtCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001830
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +05301831 if (mac_ctx->roam.configParam.qcn_ie_support)
1832 populate_dot11f_qcn_ie(&frm->QCN_IE);
1833
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001834 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001835 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001836 populate_dot11f_he_caps(mac_ctx, pe_session,
1837 &frm->vendor_he_cap);
1838 }
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301839
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001840 if (pe_session->pLimJoinReq->is11Rconnection) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 tSirBssDescription *bssdescr;
1842
1843 bssdescr = &pe_session->pLimJoinReq->bssDescription;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001844 pe_debug("mdie = %02x %02x %02x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845 (unsigned int) bssdescr->mdie[0],
1846 (unsigned int) bssdescr->mdie[1],
1847 (unsigned int) bssdescr->mdie[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001848 populate_mdie(mac_ctx, &frm->MobilityDomain,
1849 pe_session->pLimJoinReq->bssDescription.mdie);
1850 } else {
1851 /* No 11r IEs dont send any MDIE */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001852 pe_debug("MDIE not present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001853 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001854
1855#ifdef FEATURE_WLAN_ESE
1856 /*
1857 * ESE Version IE will be included in association request
1858 * when ESE is enabled on DUT through ini and it is also
1859 * advertised by the peer AP to which we are trying to
1860 * associate to.
1861 */
1862 if (pe_session->is_ese_version_ie_present &&
1863 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1864 populate_dot11f_ese_version(&frm->ESEVersion);
1865 /* For ESE Associations fill the ESE IEs */
1866 if (pe_session->isESEconnection &&
1867 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1868#ifndef FEATURE_DISABLE_RM
1869 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1870#endif
1871 }
1872#endif
1873
Hu Wang411e0cc2016-10-28 14:56:01 +08001874 /*
1875 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1876 * may change the frame size. Therefore, MUST merge ExtCap IE before
1877 * dot11f get packed payload size.
1878 */
1879 if (extr_ext_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001880 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
1881
1882 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
1883 if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
1884 ie_offset = DOT11F_FF_TIMESTAMP_LEN +
1885 DOT11F_FF_BEACONINTERVAL_LEN +
1886 DOT11F_FF_CAPABILITIES_LEN;
1887
1888 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
1889 if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
1890 bcn_ie = pe_session->beacon + ie_offset;
1891 bcn_ie_len = pe_session->bcnLen - ie_offset;
1892 p_ext_cap = lim_get_ie_ptr_new(mac_ctx,
1893 bcn_ie,
1894 bcn_ie_len,
1895 DOT11F_EID_EXTCAP,
1896 ONE_BYTE);
1897 lim_update_extcap_struct(mac_ctx, p_ext_cap,
1898 &bcn_ext_cap);
1899 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
1900 false);
1901 }
1902 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001903
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001904 if (eSIR_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
1905 add_ie, &add_ie_len, &frm->SuppOperatingClasses))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001906 pe_debug("Unable to Stripoff supp op classes IE from Assoc Req");
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001907
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001908 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1909 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001910 pe_err("Association Request packet size failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001911 status);
1912 /* We'll fall back on the worst case scenario: */
1913 payload = sizeof(tDot11fAssocRequest);
1914 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001915 pe_warn("Association request packet size warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001916 status);
1917 }
1918
1919 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1920
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301921 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001922 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301923 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001924 pe_err("Failed to allocate %d bytes", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001925
1926 pe_session->limMlmState = pe_session->limPrevMlmState;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301927 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001928 pe_session->peSessionId,
1929 pe_session->limMlmState));
1930
1931 /* Update PE session id */
1932 assoc_cnf.sessionId = pe_session->peSessionId;
1933
1934 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1935
1936 cds_packet_free((void *)packet);
1937
1938 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1939 (uint32_t *) &assoc_cnf);
1940
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301941 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001942 return;
1943 }
1944 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301945 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001946
1947 /* Next, we fill out the buffer descriptor: */
1948 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1949 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1950 pe_session->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001951 /* That done, pack the Assoc Request: */
1952 status = dot11f_pack_assoc_request(mac_ctx, frm,
1953 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1954 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001955 pe_err("Assoc request pack failure (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001956 cds_packet_free((void *)packet);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301957 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001958 return;
1959 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001960 pe_warn("Assoc request pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 }
1962
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001963 pe_debug("Sending Association Request length %d to ", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 if (pe_session->assocReq != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301965 qdf_mem_free(pe_session->assocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001967 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001968 }
1969
1970 if (add_ie_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301971 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001972 add_ie, add_ie_len);
1973 payload += add_ie_len;
1974 }
1975
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301976 pe_session->assocReq = qdf_mem_malloc(payload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001977 if (NULL == pe_session->assocReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001978 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979 } else {
1980 /*
1981 * Store the Assoc request. This is sent to csr/hdd in
1982 * join cnf response.
1983 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301984 qdf_mem_copy(pe_session->assocReq,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985 frame + sizeof(tSirMacMgmtHdr), payload);
1986 pe_session->assocReqLen = payload;
1987 }
1988
1989 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301990 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
1991 || (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992 )
1993 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1994
Anurag Chouhan6d760662016-02-20 16:05:43 +05301995 if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
1996 pe_session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001997 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
1998
1999#ifdef FEATURE_WLAN_DIAG_SUPPORT
2000 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
2001 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2002#endif
2003 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302004 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002005 pe_session->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302006 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002007 wma_tx_frame(mac_ctx, packet,
2008 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
2009 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2010 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302011 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302012 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302013 pe_session->peSessionId, qdf_status));
2014 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002015 pe_err("Failed to send Association Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302016 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002017 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302018 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002019 return;
2020 }
2021 /* Free up buffer allocated for mlm_assoc_req */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302022 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002023 mlm_assoc_req = NULL;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302024 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002025 return;
2026}
2027
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002028/**
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302029 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302030 * @context: pointer to global mac
2031 * @buf: buffer
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302032 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302033 * @params; tx completion params
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302034 *
2035 * Return: This returns QDF_STATUS
2036 */
2037
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302038static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
2039 qdf_nbuf_t buf,
2040 uint32_t tx_complete,
2041 void *params)
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302042{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302043 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
2044
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002045 pe_debug("tx_complete= %d", tx_complete);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302046 if (tx_complete) {
2047 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
2048 /* 'Change' timer for future activations */
2049 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2050 } else {
2051 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2052 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302053
2054 if (buf)
2055 qdf_nbuf_free(buf);
2056
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302057 return QDF_STATUS_SUCCESS;
2058}
2059
2060/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002061 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2062 *
2063 * @mac_ctx: Pointer to Global MAC structure
2064 * @auth_frame: Pointer to Authentication frame structure
2065 * @peer_addr: MAC address of destination peer
2066 * @wep_bit: wep bit in frame control for Authentication frame3
2067 * @session: PE session information
2068 *
2069 * This function is called by lim_process_mlm_messages(). Authentication frame
2070 * is formatted and sent when this function is called.
2071 *
2072 * Return: void
2073 */
2074
2075void
2076lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2077 tpSirMacAuthFrameBody auth_frame,
2078 tSirMacAddr peer_addr,
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302079 uint8_t wep_bit,
2080 tpPESession session, bool wait_for_ack)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002081{
2082 uint8_t *frame, *body;
2083 uint32_t frame_len = 0, body_len = 0;
2084 tpSirMacMgmtHdr mac_hdr;
2085 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302086 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087 uint8_t tx_flag = 0;
2088 uint8_t sme_sessionid = 0;
2089 uint16_t ft_ies_length = 0;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002090 bool challenge_req = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002091
2092 if (NULL == session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002093 pe_err("Error: psession Entry is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094 return;
2095 }
2096
2097 sme_sessionid = session->smeSessionId;
2098
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002099 if (wep_bit == LIM_WEP_IN_FC) {
2100 /*
2101 * Auth frame3 to be sent with encrypted framebody
2102 *
2103 * Allocate buffer for Authenticaton frame of size
2104 * equal to management frame header length plus 2 bytes
2105 * each for auth algorithm number, transaction number,
2106 * status code, 128 bytes for challenge text and
2107 * 4 bytes each for IV & ICV.
2108 */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002109 pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
2110 MAC_ADDR_ARRAY(peer_addr));
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002111
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002112 body_len = LIM_ENCR_AUTH_BODY_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002113 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002114
2115 goto alloc_packet;
2116 }
2117
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002118 pe_info("Sending Auth seq# %d status %d (%d) wait_for_ack %d to "
2119 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002120 auth_frame->authTransactionSeqNumber,
2121 auth_frame->authStatusCode,
2122 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302123 wait_for_ack,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002124 MAC_ADDR_ARRAY(peer_addr));
2125
2126 switch (auth_frame->authTransactionSeqNumber) {
2127 case SIR_MAC_AUTH_FRAME_1:
2128 /*
2129 * Allocate buffer for Authenticaton frame of size
2130 * equal to management frame header length plus 2 bytes
2131 * each for auth algorithm number, transaction number
2132 * and status code.
2133 */
2134
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002135 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2136 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002137
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2139 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2140 0 != session->ftPEContext.pFTPreAuthReq->
2141 ft_ies_length) {
2142 ft_ies_length = session->ftPEContext.
2143 pFTPreAuthReq->ft_ies_length;
2144 frame_len += ft_ies_length;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002145 pe_debug("Auth frame, FTIES length added=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002146 ft_ies_length);
2147 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002148 pe_debug("Auth frame, Does not contain FTIES!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 frame_len += (2 + SIR_MDIE_SIZE);
2150 }
2151 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152 break;
2153
2154 case SIR_MAC_AUTH_FRAME_2:
2155 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2156 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2157 (auth_frame->authStatusCode !=
2158 eSIR_MAC_SUCCESS_STATUS))) {
2159 /*
2160 * Allocate buffer for Authenticaton frame of size
2161 * equal to management frame header length plus
2162 * 2 bytes each for auth algorithm number,
2163 * transaction number and status code.
2164 */
2165
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002166 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2167 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002168 } else {
2169 /*
2170 * Shared Key algorithm with challenge text
2171 * to be sent.
2172 *
2173 * Allocate buffer for Authenticaton frame of size
2174 * equal to management frame header length plus
2175 * 2 bytes each for auth algorithm number,
2176 * transaction number, status code and 128 bytes
2177 * for challenge text.
2178 */
2179
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002180 challenge_req = true;
2181 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
2182 SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2183 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002184 }
2185 break;
2186
2187 case SIR_MAC_AUTH_FRAME_3:
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002188 /*
2189 * Auth frame3 to be sent without encrypted framebody
2190 *
2191 * Allocate buffer for Authenticaton frame of size equal
2192 * to management frame header length plus 2 bytes each
2193 * for auth algorithm number, transaction number and
2194 * status code.
2195 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002197 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2198 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002199 break;
2200
2201 case SIR_MAC_AUTH_FRAME_4:
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 */
2208
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
2212 break;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002213 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002214 pe_err("Invalid auth transaction seq num");
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002215 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002216 } /* switch (auth_frame->authTransactionSeqNumber) */
2217
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002218alloc_packet:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302219 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002220 (void **)&packet);
2221
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302222 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002223 pe_err("call to bufAlloc failed for AUTH frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002224 return;
2225 }
2226
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302227 qdf_mem_zero(frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228
2229 /* Prepare BD */
2230 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2231 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2232 mac_hdr = (tpSirMacMgmtHdr) frame;
2233 mac_hdr->fc.wep = wep_bit;
2234
2235 /* Prepare BSSId */
Rajeev Kumarcf835a02016-04-15 15:01:31 -07002236 if (LIM_IS_AP_ROLE(session))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302237 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002238 (uint8_t *) session->bssId,
2239 sizeof(tSirMacAddr));
2240
2241 /* Prepare Authentication frame body */
2242 body = frame + sizeof(tSirMacMgmtHdr);
2243
2244 if (wep_bit == LIM_WEP_IN_FC) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302245 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002246
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002247 pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002248 MAC_ADDR_ARRAY(mac_hdr->da));
2249
2250 } else {
2251 *((uint16_t *) (body)) =
2252 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2253 body += sizeof(uint16_t);
2254 body_len -= sizeof(uint16_t);
2255
2256 *((uint16_t *) (body)) =
2257 sir_swap_u16if_needed(
2258 auth_frame->authTransactionSeqNumber);
2259 body += sizeof(uint16_t);
2260 body_len -= sizeof(uint16_t);
2261
2262 *((uint16_t *) (body)) =
2263 sir_swap_u16if_needed(auth_frame->authStatusCode);
2264 body += sizeof(uint16_t);
2265 body_len -= sizeof(uint16_t);
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002266
2267 if (challenge_req) {
2268 if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
2269 qdf_mem_copy(body, (uint8_t *)&auth_frame->type,
2270 body_len);
2271 pe_err("Incomplete challenge info: length: %d, expected: %d",
2272 body_len,
2273 SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
2274 body += body_len;
2275 body_len = 0;
2276 } else {
2277 /* copy challenge IE id, len, challenge text */
2278 *body = auth_frame->type;
2279 body++;
2280 *body = auth_frame->length;
2281 body++;
2282 qdf_mem_copy(body, auth_frame->challengeText,
2283 SIR_MAC_AUTH_CHALLENGE_LENGTH);
2284 body += SIR_MAC_AUTH_CHALLENGE_LENGTH;
2285
2286 body_len -= SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2287 }
2288 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002289
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002290 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2291 (auth_frame->authTransactionSeqNumber ==
2292 SIR_MAC_AUTH_FRAME_1) &&
2293 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2294
2295 if (ft_ies_length > 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302296 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002297 session->ftPEContext.
2298 pFTPreAuthReq->ft_ies,
2299 ft_ies_length);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002300 pe_debug("Auth1 Frame FTIE is: ");
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002301 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2302 QDF_TRACE_LEVEL_DEBUG,
2303 (uint8_t *) body,
2304 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002305 } else if (NULL != session->ftPEContext.
2306 pFTPreAuthReq->pbssDescription) {
2307 /* MDID attr is 54 */
2308 *body = SIR_MDIE_ELEMENT_ID;
2309 body++;
2310 *body = SIR_MDIE_SIZE;
2311 body++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302312 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002313 &session->ftPEContext.pFTPreAuthReq->
2314 pbssDescription->mdie[0],
2315 SIR_MDIE_SIZE);
2316 }
2317 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002318
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002319 pe_debug("*** Sending Auth seq# %d status %d (%d) to "
2320 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002321 auth_frame->authTransactionSeqNumber,
2322 auth_frame->authStatusCode,
2323 (auth_frame->authStatusCode ==
2324 eSIR_MAC_SUCCESS_STATUS),
2325 MAC_ADDR_ARRAY(mac_hdr->da));
2326 }
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002327 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2328 QDF_TRACE_LEVEL_DEBUG,
2329 frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002330
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302331 if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
2332 (SIR_BAND_5_GHZ == lim_get_rf_band(
2333 session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302335 else if ((SIR_BAND_5_GHZ ==
2336 lim_get_rf_band(session->currentOperChannel))
2337 || (session->pePersona == QDF_P2P_CLIENT_MODE)
2338 || (session->pePersona == QDF_P2P_GO_MODE))
2339 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002340
Anurag Chouhan6d760662016-02-20 16:05:43 +05302341 if (session->pePersona == QDF_P2P_CLIENT_MODE ||
2342 session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2344
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302345 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002346 session->peSessionId, mac_hdr->fc.subType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002347
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302348 if (wait_for_ack) {
2349 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
2350 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
2351 (uint16_t)frame_len,
2352 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2353 7, lim_tx_complete, frame,
2354 lim_auth_tx_complete_cnf,
2355 tx_flag, sme_sessionid, false, 0);
2356 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2357 session->peSessionId, qdf_status));
2358 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002359 pe_err("*** Could not send Auth frame, retCode=%X ***",
2360 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302361 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2362 /* Pkt will be freed up by the callback */
2363 }
2364 } else {
2365 /* Queue Authentication frame in high priority WQ */
2366 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
2367 TXRX_FRM_802_11_MGMT,
2368 ANI_TXDIR_TODS, 7, lim_tx_complete,
2369 frame, tx_flag, sme_sessionid, 0);
2370 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2371 session->peSessionId, qdf_status));
2372 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002373 pe_err("*** Could not send Auth frame, retCode=%X ***",
2374 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302375 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002376 return;
2377}
2378
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302379QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002380{
2381 uint16_t aid;
2382 tpDphHashNode pStaDs;
2383 tLimMlmDeauthReq *pMlmDeauthReq;
2384 tLimMlmDeauthCnf mlmDeauthCnf;
2385 tpPESession psessionEntry;
2386
2387 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
2388 if (pMlmDeauthReq) {
2389 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
2390 lim_deactivate_and_change_timer(pMac,
2391 eLIM_DEAUTH_ACK_TIMER);
2392 }
2393
2394 psessionEntry = pe_find_session_by_session_id(pMac,
2395 pMlmDeauthReq->sessionId);
2396 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002397 pe_err("session does not exist for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002398 mlmDeauthCnf.resultCode =
2399 eSIR_SME_INVALID_PARAMETERS;
2400 goto end;
2401 }
2402
2403 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002404 dph_lookup_hash_entry(pMac,
2405 pMlmDeauthReq->peer_macaddr.bytes,
2406 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002407 &psessionEntry->dph.dphHashTable);
2408 if (pStaDs == NULL) {
2409 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2410 goto end;
2411 }
2412
2413 /* / Receive path cleanup with dummy packet */
2414 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2415 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002416 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
2417 (
Abhishek Singhe0680852015-12-16 14:28:48 +05302418#ifdef FEATURE_WLAN_ESE
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002419 (psessionEntry->isESEconnection) ||
Abhishek Singhe0680852015-12-16 14:28:48 +05302420#endif
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002421 (psessionEntry->isFastRoamIniFeatureEnabled) ||
2422 (psessionEntry->is11Rconnection))) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002423 pe_debug("FT Preauth (%p,%d) Deauth rc %d src = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002424 psessionEntry,
2425 psessionEntry->peSessionId,
2426 pMlmDeauthReq->reasonCode,
2427 pMlmDeauthReq->deauthTrigger);
2428 lim_ft_cleanup(pMac, psessionEntry);
2429 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002430 pe_debug("No FT Preauth Session Cleanup in role %d"
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002431#ifdef FEATURE_WLAN_ESE
2432 " isESE %d"
2433#endif
2434 " isLFR %d"
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002435 " is11r %d, Deauth reason %d Trigger = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002436 psessionEntry->limSystemRole,
2437#ifdef FEATURE_WLAN_ESE
2438 psessionEntry->isESEconnection,
2439#endif
2440 psessionEntry->isFastRoamIniFeatureEnabled,
2441 psessionEntry->is11Rconnection,
Abhishek Singhe0680852015-12-16 14:28:48 +05302442 pMlmDeauthReq->reasonCode,
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002443 pMlmDeauthReq->deauthTrigger);
2444 }
2445 /* Free up buffer allocated for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302446 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
2448 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302449 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450end:
Anurag Chouhanc5548422016-02-24 18:33:27 +05302451 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002452 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002453 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
2454 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
2455 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
2456
2457 /* Free up buffer allocated */
2458 /* for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302459 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002460
2461 lim_post_sme_message(pMac,
2462 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302463 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002464}
2465
2466/**
2467 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
2468 *
2469 * @mac_ctx: Handle to MAC context
2470 *
2471 * Sends disassoc confirmation to SME. Removes disassoc request stored
2472 * in lim.
2473 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302474 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002475 */
2476
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302477QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002478{
2479 uint16_t aid;
2480 tpDphHashNode sta_ds;
2481 tLimMlmDisassocCnf disassoc_cnf;
2482 tpPESession pe_session;
2483 tLimMlmDisassocReq *disassoc_req;
2484
2485 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
2486 if (disassoc_req) {
2487 if (tx_timer_running(
2488 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
2489 lim_deactivate_and_change_timer(mac_ctx,
2490 eLIM_DISASSOC_ACK_TIMER);
2491
2492 pe_session = pe_find_session_by_session_id(
2493 mac_ctx, disassoc_req->sessionId);
2494 if (pe_session == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002495 pe_err("No session for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002496 disassoc_cnf.resultCode =
2497 eSIR_SME_INVALID_PARAMETERS;
2498 goto end;
2499 }
2500
2501 sta_ds = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002502 disassoc_req->peer_macaddr.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002503 &pe_session->dph.dphHashTable);
2504 if (sta_ds == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002505 pe_err("StaDs Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002506 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2507 goto end;
2508 }
2509 /* Receive path cleanup with dummy packet */
2510 if (eSIR_SUCCESS !=
2511 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
2512 disassoc_cnf.resultCode =
2513 eSIR_SME_RESOURCES_UNAVAILABLE;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002514 pe_err("cleanup_rx_path error");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002515 goto end;
2516 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002517 if (LIM_IS_STA_ROLE(pe_session) && (
2518#ifdef FEATURE_WLAN_ESE
2519 (pe_session->isESEconnection) ||
2520#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002521 (pe_session->isFastRoamIniFeatureEnabled) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002522 (pe_session->is11Rconnection)) &&
2523 (disassoc_req->reasonCode !=
2524 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002525 pe_debug("FT Preauth Session (%p %d) Clean up",
2526 pe_session, pe_session->peSessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002527
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528 /* Delete FT session if there exists one */
2529 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002530 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002531 pe_debug("FT Preauth Session %d Clean up"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532#ifdef FEATURE_WLAN_ESE
2533 " isESE %d"
2534#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002535 " isLFR %d"
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002536 " is11r %d reason %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002537 GET_LIM_SYSTEM_ROLE(pe_session),
2538#ifdef FEATURE_WLAN_ESE
2539 pe_session->isESEconnection,
2540#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002541 pe_session->isFastRoamIniFeatureEnabled,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002542 pe_session->is11Rconnection,
2543 disassoc_req->reasonCode);
2544 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002545 /* Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302546 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302548 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002549 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302550 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002551 }
2552end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302553 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002554 (uint8_t *) disassoc_req->peer_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302555 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002556 disassoc_cnf.aid = disassoc_req->aid;
2557 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
2558
2559 /* Update PE session ID */
2560 disassoc_cnf.sessionId = disassoc_req->sessionId;
2561
2562 if (disassoc_req != NULL) {
2563 /* / Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302564 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002565 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
2566 }
2567
2568 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
2569 (uint32_t *) &disassoc_cnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302570 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002571}
2572
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302573QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
2574 qdf_nbuf_t buf,
2575 uint32_t txCompleteSuccess,
2576 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002577{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302578 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2579
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002580 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302581
2582 if (buf)
2583 qdf_nbuf_free(buf);
2584
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002585 return lim_send_disassoc_cnf(pMac);
2586}
2587
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302588QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
2589 qdf_nbuf_t buf,
2590 uint32_t txCompleteSuccess,
2591 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002592{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302593 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2594
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002595 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302596
2597 if (buf)
2598 qdf_nbuf_free(buf);
2599
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002600 return lim_send_deauth_cnf(pMac);
2601}
2602
2603/**
2604 * \brief This function is called to send Disassociate frame.
2605 *
2606 *
2607 * \param pMac Pointer to Global MAC structure
2608 *
2609 * \param nReason Indicates the reason that need to be sent in
2610 * Disassociation frame
2611 *
2612 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
2613 * sent
2614 *
2615 *
2616 */
2617
2618void
2619lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
2620 uint16_t nReason,
2621 tSirMacAddr peer,
2622 tpPESession psessionEntry, bool waitForAck)
2623{
2624 tDot11fDisassociation frm;
2625 uint8_t *pFrame;
2626 tpSirMacMgmtHdr pMacHdr;
2627 uint32_t nBytes, nPayload, nStatus;
2628 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302629 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002630 uint8_t txFlag = 0;
2631 uint32_t val = 0;
2632 uint8_t smeSessionId = 0;
2633 if (NULL == psessionEntry) {
2634 return;
2635 }
2636
2637 /*
2638 * In case when cac timer is running for this SAP session then
2639 * avoid sending disassoc out. It is violation of dfs specification.
2640 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302641 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2642 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002643 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302644 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002645 FL
2646 ("CAC timer is running, drop disassoc from going out"));
2647 return;
2648 }
2649 smeSessionId = psessionEntry->smeSessionId;
2650
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302651 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652
2653 frm.Reason.code = nReason;
2654
2655 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
2656 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002657 pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002658 nStatus);
2659 /* We'll fall back on the worst case scenario: */
2660 nPayload = sizeof(tDot11fDisassociation);
2661 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002662 pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)",
2663 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002664 }
2665
2666 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2667
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302668 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302670 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002671 pe_err("Failed to allocate %d bytes for a Disassociation",
2672 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002673 return;
2674 }
2675 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302676 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002677
2678 /* Next, we fill out the buffer descriptor: */
2679 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2680 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
2681 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2682
2683 /* Prepare the BSSID */
2684 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2685
2686#ifdef WLAN_FEATURE_11W
2687 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2688#endif
2689
2690 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
2691 sizeof(tSirMacMgmtHdr),
2692 nPayload, &nPayload);
2693 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002694 pe_err("Failed to pack a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695 nStatus);
2696 cds_packet_free((void *)pPacket);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002697 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002699 pe_warn("There were warnings while packing a Disassociation (0x%08x)",
2700 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701 }
2702
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002703 pe_debug("***Sessionid %d Sending Disassociation frame with "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002704 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002705 MAC_ADDRESS_STR, psessionEntry->peSessionId, nReason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002706 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
2707 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2708
2709 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302710 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2711 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002712 ) {
2713 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2714 }
2715
Sushant Kaushik46556062015-12-02 16:57:47 +05302716 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002717
2718 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302719 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720 psessionEntry->peSessionId,
2721 pMacHdr->fc.subType));
2722 /* Queue Disassociation frame in high priority WQ */
2723 /* get the duration from the request */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302724 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002725 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2726 TXRX_FRM_802_11_MGMT,
2727 ANI_TXDIR_TODS, 7, lim_tx_complete,
2728 pFrame, lim_disassoc_tx_complete_cnf,
2729 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302730 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302731 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302732 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002733
2734 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2735
2736 if (tx_timer_change
2737 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
2738 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002739 pe_err("Unable to change Disassoc ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002740 return;
2741 } else if (TX_SUCCESS !=
2742 tx_timer_activate(&pMac->lim.limTimers.
2743 gLimDisassocAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002744 pe_err("Unable to activate Disassoc ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002745 lim_deactivate_and_change_timer(pMac,
2746 eLIM_DISASSOC_ACK_TIMER);
2747 return;
2748 }
2749 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302750 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002751 psessionEntry->peSessionId,
2752 pMacHdr->fc.subType));
2753 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302754 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002755 TXRX_FRM_802_11_MGMT,
2756 ANI_TXDIR_TODS,
2757 7,
2758 lim_tx_complete, pFrame, txFlag,
2759 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302760 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302761 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302762 psessionEntry->peSessionId, qdf_status));
2763 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002764 pe_err("Failed to send Disassociation (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302765 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002766 /* Pkt will be freed up by the callback */
2767 }
2768 }
2769} /* End lim_send_disassoc_mgmt_frame. */
2770
2771/**
2772 * \brief This function is called to send a Deauthenticate frame
2773 *
2774 *
2775 * \param pMac Pointer to global MAC structure
2776 *
2777 * \param nReason Indicates the reason that need to be sent in the
2778 * Deauthenticate frame
2779 *
2780 * \param peeer address of the STA to which the frame is to be sent
2781 *
2782 *
2783 */
2784
2785void
2786lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
2787 uint16_t nReason,
2788 tSirMacAddr peer,
2789 tpPESession psessionEntry, bool waitForAck)
2790{
2791 tDot11fDeAuth frm;
2792 uint8_t *pFrame;
2793 tpSirMacMgmtHdr pMacHdr;
2794 uint32_t nBytes, nPayload, nStatus;
2795 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302796 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002797 uint8_t txFlag = 0;
2798 uint32_t val = 0;
2799#ifdef FEATURE_WLAN_TDLS
2800 uint16_t aid;
2801 tpDphHashNode pStaDs;
2802#endif
2803 uint8_t smeSessionId = 0;
2804
2805 if (NULL == psessionEntry) {
2806 return;
2807 }
2808
2809 /*
2810 * In case when cac timer is running for this SAP session then
2811 * avoid deauth frame out. It is violation of dfs specification.
2812 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302813 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2814 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002815 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302816 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002817 FL
2818 ("CAC timer is running, drop the deauth from going out"));
2819 return;
2820 }
2821 smeSessionId = psessionEntry->smeSessionId;
2822
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302823 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002824
2825 frm.Reason.code = nReason;
2826
2827 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
2828 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002829 pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002830 nStatus);
2831 /* We'll fall back on the worst case scenario: */
2832 nPayload = sizeof(tDot11fDeAuth);
2833 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002834 pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)",
2835 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002836 }
2837
2838 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2839
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302840 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002841 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302842 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002843 pe_err("Failed to allocate %d bytes for a De-Authentication",
2844 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002845 return;
2846 }
2847 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302848 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002849
2850 /* Next, we fill out the buffer descriptor: */
2851 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2852 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
2853 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2854
2855 /* Prepare the BSSID */
2856 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2857
2858#ifdef WLAN_FEATURE_11W
2859 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2860#endif
2861
2862 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
2863 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
2864 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002865 pe_err("Failed to pack a DeAuthentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002866 nStatus);
2867 cds_packet_free((void *)pPacket);
2868 return;
2869 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002870 pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
2871 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002872 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002873 pe_debug("***Sessionid %d Sending Deauth frame with "
2874 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
2875 " ,From " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002876 psessionEntry->peSessionId, nReason, waitForAck,
2877 MAC_ADDR_ARRAY(pMacHdr->da),
2878 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2879
2880 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302881 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2882 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002883 ) {
2884 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2885 }
2886
Sushant Kaushik46556062015-12-02 16:57:47 +05302887 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002888#ifdef FEATURE_WLAN_TDLS
2889 pStaDs =
2890 dph_lookup_hash_entry(pMac, peer, &aid,
2891 &psessionEntry->dph.dphHashTable);
2892#endif
2893
2894 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302895 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896 psessionEntry->peSessionId,
2897 pMacHdr->fc.subType));
2898 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302899 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002900 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2901 TXRX_FRM_802_11_MGMT,
2902 ANI_TXDIR_TODS, 7, lim_tx_complete,
2903 pFrame, lim_deauth_tx_complete_cnf,
2904 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302905 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302906 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302907 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908 /* Pkt will be freed up by the callback lim_tx_complete */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302909 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002910 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302911 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002912
2913 /* Call lim_process_deauth_ack_timeout which will send
2914 * DeauthCnf for this frame
2915 */
2916 lim_process_deauth_ack_timeout(pMac);
2917 return;
2918 }
2919
2920 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2921
2922 if (tx_timer_change
2923 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
2924 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002925 pe_err("Unable to change Deauth ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002926 return;
2927 } else if (TX_SUCCESS !=
2928 tx_timer_activate(&pMac->lim.limTimers.
2929 gLimDeauthAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002930 pe_err("Unable to activate Deauth ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002931 lim_deactivate_and_change_timer(pMac,
2932 eLIM_DEAUTH_ACK_TIMER);
2933 return;
2934 }
2935 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302936 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002937 psessionEntry->peSessionId,
2938 pMacHdr->fc.subType));
2939#ifdef FEATURE_WLAN_TDLS
2940 if ((NULL != pStaDs)
2941 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
2942 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302943 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002944 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2945 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
2946 7, lim_tx_complete, pFrame, txFlag,
2947 smeSessionId, 0);
2948 } else {
2949#endif
2950 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302951 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002952 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2953 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2954 7, lim_tx_complete, pFrame, txFlag,
2955 smeSessionId, 0);
2956#ifdef FEATURE_WLAN_TDLS
2957 }
2958#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302959 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302960 psessionEntry->peSessionId, qdf_status));
2961 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002962 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302963 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002964 /* Pkt will be freed up by the callback */
2965 }
2966 }
2967
2968} /* End lim_send_deauth_mgmt_frame. */
2969
2970#ifdef ANI_SUPPORT_11H
2971/**
2972 * \brief Send a Measurement Report Action frame
2973 *
2974 *
2975 * \param pMac Pointer to the global MAC structure
2976 *
2977 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
2978 *
2979 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
2980 *
2981 *
2982 */
2983
2984tSirRetStatus
2985lim_send_meas_report_frame(tpAniSirGlobal pMac,
2986 tpSirMacMeasReqActionFrame pMeasReqFrame,
2987 tSirMacAddr peer, tpPESession psessionEntry)
2988{
2989 tDot11fMeasurementReport frm;
2990 uint8_t *pFrame;
2991 tSirRetStatus nSirStatus;
2992 tpSirMacMgmtHdr pMacHdr;
2993 uint32_t nBytes, nPayload, nStatus;
2994 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302995 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002996
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302997 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002998
2999 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3000 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3001 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3002
3003 switch (pMeasReqFrame->measReqIE.measType) {
3004 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3005 nSirStatus =
3006 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3007 &frm.MeasurementReport);
3008 break;
3009 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3010 nSirStatus =
3011 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3012 &frm.MeasurementReport);
3013 break;
3014 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3015 nSirStatus =
3016 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3017 &frm.MeasurementReport);
3018 break;
3019 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003020 pe_err("Unknown measurement type %d in limSen"
3021 "dMeasReportFrame",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003022 pMeasReqFrame->measReqIE.measType);
3023 return eSIR_FAILURE;
3024 }
3025
3026 if (eSIR_SUCCESS != nSirStatus)
3027 return eSIR_FAILURE;
3028
3029 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3030 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003031 pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003032 nStatus);
3033 /* We'll fall back on the worst case scenario: */
3034 nPayload = sizeof(tDot11fMeasurementReport);
3035 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003036 pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)",
3037 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003038 }
3039
3040 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3041
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303042 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003043 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3044 (uint16_t) nBytes, (void **)&pFrame,
3045 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303046 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003047 pe_err("Failed to allocate %d bytes for a "
3048 "De-Authentication", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003049 return eSIR_FAILURE;
3050 }
3051 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303052 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003053
3054 /* Next, we fill out the buffer descriptor: */
3055 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3056 SIR_MAC_MGMT_ACTION, peer);
3057 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3058
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303059 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003060
3061#ifdef WLAN_FEATURE_11W
3062 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3063#endif
3064
3065 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3066 sizeof(tSirMacMgmtHdr),
3067 nPayload, &nPayload);
3068 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003069 pe_err("Failed to pack a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003070 nStatus);
3071 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3072 (void *)pFrame, (void *)pPacket);
3073 return eSIR_FAILURE; /* allocated! */
3074 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003075 pe_warn("There were warnings while packing a Measurement Report (0x%08x)",
3076 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003077 }
3078
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303079 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003080 ((psessionEntry) ? psessionEntry->
3081 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303082 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003083 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3084 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3085 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303086 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303087 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003088 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303089 qdf_status));
3090 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003091 pe_err("Failed to send a Measurement Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303092 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003093 /* Pkt will be freed up by the callback */
3094 return eSIR_FAILURE; /* just allocated... */
3095 }
3096
3097 return eSIR_SUCCESS;
3098
3099} /* End lim_send_meas_report_frame. */
3100
3101/**
3102 * \brief Send a TPC Request Action frame
3103 *
3104 *
3105 * \param pMac Pointer to the global MAC datastructure
3106 *
3107 * \param peer MAC address to which the frame should be sent
3108 *
3109 *
3110 */
3111
3112void
3113lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3114 tSirMacAddr peer, tpPESession psessionEntry)
3115{
3116 tDot11fTPCRequest frm;
3117 uint8_t *pFrame;
3118 tpSirMacMgmtHdr pMacHdr;
3119 uint32_t nBytes, nPayload, nStatus;
3120 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303121 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003122
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303123 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003124
3125 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3126 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3127 frm.DialogToken.token = 1;
3128 frm.TPCRequest.present = 1;
3129
3130 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3131 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003132 pe_err("Failed to calculate the packed size for a TPC Request (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003133 /* We'll fall back on the worst case scenario: */
3134 nPayload = sizeof(tDot11fTPCRequest);
3135 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003136 pe_warn("There were warnings while calculating the packed size for a TPC Request (0x%08x)",
3137 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003138 }
3139
3140 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3141
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303142 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003143 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3144 (uint16_t) nBytes, (void **)&pFrame,
3145 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303146 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003147 pe_err("Failed to allocate %d bytes for a TPC"
3148 " Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003149 return;
3150 }
3151 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303152 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003153
3154 /* Next, we fill out the buffer descriptor: */
3155 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3156 SIR_MAC_MGMT_ACTION, peer);
3157 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3158
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303159 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003160
3161#ifdef WLAN_FEATURE_11W
3162 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3163#endif
3164
3165 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3166 sizeof(tSirMacMgmtHdr),
3167 nPayload, &nPayload);
3168 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003169 pe_err("Failed to pack a TPC Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003170 nStatus);
3171 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3172 (void *)pFrame, (void *)pPacket);
3173 return; /* allocated! */
3174 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003175 pe_warn("There were warnings while packing a TPC Request (0x%08x)",
3176 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003177 }
3178
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303179 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003180 ((psessionEntry) ? psessionEntry->
3181 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303182 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003183 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3184 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3185 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303186 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303187 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003188 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303189 qdf_status));
3190 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003191 pe_err("Failed to send a TPC Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303192 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003193 /* Pkt will be freed up by the callback */
3194 }
3195
3196} /* End lim_send_tpc_request_frame. */
3197
3198/**
3199 * \brief Send a TPC Report Action frame
3200 *
3201 *
3202 * \param pMac Pointer to the global MAC datastructure
3203 *
3204 * \param pTpcReqFrame Pointer to the received TPC Request
3205 *
3206 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3207 *
3208 *
3209 */
3210
3211tSirRetStatus
3212lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3213 tpSirMacTpcReqActionFrame pTpcReqFrame,
3214 tSirMacAddr peer, tpPESession psessionEntry)
3215{
3216 tDot11fTPCReport frm;
3217 uint8_t *pFrame;
3218 tpSirMacMgmtHdr pMacHdr;
3219 uint32_t nBytes, nPayload, nStatus;
3220 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303221 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003222
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303223 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003224
3225 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3226 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3227 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3228
3229 frm.TPCReport.tx_power = 0;
3230 frm.TPCReport.link_margin = 0;
3231 frm.TPCReport.present = 1;
3232
3233 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3234 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003235 pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003236 /* We'll fall back on the worst case scenario: */
3237 nPayload = sizeof(tDot11fTPCReport);
3238 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003239 pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)",
3240 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003241 }
3242
3243 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3244
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303245 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003246 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3247 (uint16_t) nBytes, (void **)&pFrame,
3248 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303249 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003250 pe_err("Failed to allocate %d bytes for a TPC"
3251 " Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003252 return eSIR_FAILURE;
3253 }
3254 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303255 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003256
3257 /* Next, we fill out the buffer descriptor: */
3258 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3259 SIR_MAC_MGMT_ACTION, peer);
3260
3261 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3262
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303263 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003264
3265#ifdef WLAN_FEATURE_11W
3266 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3267#endif
3268
3269 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3270 sizeof(tSirMacMgmtHdr),
3271 nPayload, &nPayload);
3272 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003273 pe_err("Failed to pack a TPC Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274 nStatus);
3275 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3276 (void *)pFrame, (void *)pPacket);
3277 return eSIR_FAILURE; /* allocated! */
3278 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003279 pe_warn("There were warnings while packing a TPC Report (0x%08x)",
3280 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003281
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303282 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003283 ((psessionEntry) ? psessionEntry->
3284 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303285 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003286 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3287 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3288 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303289 MTRACE(qdf_trace
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003290 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3291 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3292 qdf_status));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303293 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003294 pe_err("Failed to send a TPC Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303295 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003296 /* Pkt will be freed up by the callback */
3297 return eSIR_FAILURE; /* just allocated... */
3298 }
3299
3300 return eSIR_SUCCESS;
3301
3302} /* End lim_send_tpc_report_frame. */
3303#endif /* ANI_SUPPORT_11H */
3304
3305/**
3306 * \brief Send a Channel Switch Announcement
3307 *
3308 *
3309 * \param pMac Pointer to the global MAC datastructure
3310 *
3311 * \param peer MAC address to which this frame will be sent
3312 *
3313 * \param nMode
3314 *
3315 * \param nNewChannel
3316 *
3317 * \param nCount
3318 *
3319 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3320 *
3321 *
3322 */
3323
3324tSirRetStatus
3325lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3326 tSirMacAddr peer,
3327 uint8_t nMode,
3328 uint8_t nNewChannel,
3329 uint8_t nCount, tpPESession psessionEntry)
3330{
3331 tDot11fChannelSwitch frm;
3332 uint8_t *pFrame;
3333 tpSirMacMgmtHdr pMacHdr;
3334 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3335 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303336 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003337 uint8_t txFlag = 0;
3338
3339 uint8_t smeSessionId = 0;
3340
3341 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003342 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003343 return eSIR_FAILURE;
3344 }
3345 smeSessionId = psessionEntry->smeSessionId;
3346
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303347 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003348
3349 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3350 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
3351 frm.ChanSwitchAnn.switchMode = nMode;
3352 frm.ChanSwitchAnn.newChannel = nNewChannel;
3353 frm.ChanSwitchAnn.switchCount = nCount;
3354 frm.ChanSwitchAnn.present = 1;
3355
3356 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
3357 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003358 pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003359 nStatus);
3360 /* We'll fall back on the worst case scenario: */
3361 nPayload = sizeof(tDot11fChannelSwitch);
3362 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003363 pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)",
3364 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003365 }
3366
3367 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3368
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303369 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003370 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3371 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303372 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003373 pe_err("Failed to allocate %d bytes for a TPC Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003374 return eSIR_FAILURE;
3375 }
3376 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303377 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003378
3379 /* Next, we fill out the buffer descriptor: */
3380 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3381 SIR_MAC_MGMT_ACTION, peer,
3382 psessionEntry->selfMacAddr);
3383 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303384 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003385 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3386
3387#ifdef WLAN_FEATURE_11W
3388 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3389#endif
3390
3391 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
3392 sizeof(tSirMacMgmtHdr),
3393 nPayload, &nPayload);
3394 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003395 pe_err("Failed to pack a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003396 nStatus);
3397 cds_packet_free((void *)pPacket);
3398 return eSIR_FAILURE; /* allocated! */
3399 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003400 pe_warn("There were warnings while packing a Channel Switch (0x%08x)",
3401 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003402 }
3403
3404 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303405 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3406 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003407 ) {
3408 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3409 }
3410
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303411 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003412 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303413 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003414 TXRX_FRM_802_11_MGMT,
3415 ANI_TXDIR_TODS,
3416 7, lim_tx_complete, pFrame, txFlag,
3417 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303418 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303419 psessionEntry->peSessionId, qdf_status));
3420 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003421 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303422 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003423 /* Pkt will be freed up by the callback */
3424 return eSIR_FAILURE;
3425 }
3426
3427 return eSIR_SUCCESS;
3428
3429} /* End lim_send_channel_switch_mgmt_frame. */
3430
Abhishek Singh518323d2015-10-19 17:42:01 +05303431/**
3432 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
3433 * action frame over the air .
3434 * @mac_ctx: pointer to global mac structure
3435 * @peer: Destination mac.
3436 * @mode: channel switch mode
3437 * @new_op_class: new op class
3438 * @new_channel: new channel to switch
3439 * @count: channel switch count
3440 *
3441 * This function is called to send ECSA frame.
3442 *
3443 * Return: success if frame is sent else return failure
3444 */
3445
3446tSirRetStatus
3447lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
3448 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
3449 uint8_t new_channel, uint8_t count, tpPESession session_entry)
3450{
3451 tDot11fext_channel_switch_action_frame frm;
3452 uint8_t *frame;
3453 tpSirMacMgmtHdr mac_hdr;
3454 uint32_t num_bytes, n_payload, status;
3455 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303456 QDF_STATUS qdf_status;
Abhishek Singh518323d2015-10-19 17:42:01 +05303457 uint8_t txFlag = 0;
3458 uint8_t sme_session_id = 0;
3459
3460 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003461 pe_err("Session entry is NULL!!!");
Abhishek Singh518323d2015-10-19 17:42:01 +05303462 return eSIR_FAILURE;
3463 }
3464
3465 sme_session_id = session_entry->smeSessionId;
3466
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303467 qdf_mem_set(&frm, sizeof(frm), 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303468
3469 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
3470 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
3471
3472 frm.ext_chan_switch_ann_action.switch_mode = mode;
3473 frm.ext_chan_switch_ann_action.op_class = new_op_class;
3474 frm.ext_chan_switch_ann_action.new_channel = new_channel;
3475 frm.ext_chan_switch_ann_action.switch_count = count;
3476
3477
3478 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
3479 &frm, &n_payload);
3480 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003481 pe_err("Failed to get packed size for Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303482 status);
3483 /* We'll fall back on the worst case scenario*/
3484 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
3485 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003486 pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)",
Abhishek Singh518323d2015-10-19 17:42:01 +05303487 status);
3488 }
3489
3490 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3491
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303492 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303493 (void **) &frame, (void **) &packet);
3494
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303495 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003496 pe_err("Failed to allocate %d bytes for a Ext Channel Switch",
Abhishek Singh518323d2015-10-19 17:42:01 +05303497 num_bytes);
3498 return eSIR_FAILURE;
3499 }
3500
3501 /* Paranoia*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303502 qdf_mem_set(frame, num_bytes, 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303503
3504 /* Next, we fill out the buffer descriptor */
3505 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3506 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3507 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303508 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Abhishek Singh518323d2015-10-19 17:42:01 +05303509 (uint8_t *) session_entry->bssId,
3510 sizeof(tSirMacAddr));
3511
3512 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
3513 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3514 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003515 pe_err("Failed to pack a Channel Switch 0x%08x", status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303516 cds_packet_free((void *)packet);
3517 return eSIR_FAILURE;
3518 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003519 pe_warn("There were warnings while packing a Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303520 status);
3521 }
3522
3523 if ((SIR_BAND_5_GHZ ==
3524 lim_get_rf_band(session_entry->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05303525 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3526 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303527 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3528 }
3529
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003530 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 +05303531 MAC_ADDR_ARRAY(mac_hdr->da),
3532 frm.ext_chan_switch_ann_action.switch_count,
3533 frm.ext_chan_switch_ann_action.switch_mode,
3534 frm.ext_chan_switch_ann_action.new_channel,
3535 frm.ext_chan_switch_ann_action.op_class);
3536
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303537 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Abhishek Singh518323d2015-10-19 17:42:01 +05303538 session_entry->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303539 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303540 TXRX_FRM_802_11_MGMT,
3541 ANI_TXDIR_TODS,
3542 7,
3543 lim_tx_complete, frame,
3544 txFlag, sme_session_id, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303545 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303546 session_entry->peSessionId, qdf_status));
3547 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003548 pe_err("Failed to send a Ext Channel Switch %X!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303549 qdf_status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303550 /* Pkt will be freed up by the callback */
3551 return eSIR_FAILURE;
3552 }
3553 return eSIR_SUCCESS;
3554} /* End lim_send_extended_chan_switch_action_frame */
3555
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303556
3557/**
3558 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
3559 * sent over the air
3560 *
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303561 * @context: pointer to global mac
3562 * @buf: buffer
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303563 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303564 * @params: tx completion params
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303565 *
3566 * Return: This returns QDF_STATUS
3567 */
3568
3569static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303570 void *context,
3571 qdf_nbuf_t buf,
3572 uint32_t tx_complete,
3573 void *params)
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303574{
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003575 pe_debug("tx_complete: %d", tx_complete);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303576 return QDF_STATUS_SUCCESS;
3577}
3578
3579/**
3580 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
3581 * p2p oper chan change confirm action frame
3582 * @mac_ctx: pointer to global mac structure
3583 * @peer: Destination mac.
3584 * @session_entry: session entry
3585 *
3586 * This function is called to send p2p oper chan change confirm action frame.
3587 *
3588 * Return: success if frame is sent else return failure
3589 */
3590
3591tSirRetStatus
3592lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
3593 tSirMacAddr peer, tpPESession session_entry)
3594{
3595 tDot11fp2p_oper_chan_change_confirm frm;
3596 uint8_t *frame;
3597 tpSirMacMgmtHdr mac_hdr;
3598 uint32_t num_bytes, n_payload, status;
3599 void *packet;
3600 QDF_STATUS qdf_status;
3601 uint8_t tx_flag = 0;
3602 uint8_t sme_session_id = 0;
3603
3604 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003605 pe_err("Session entry is NULL!!!");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303606 return eSIR_FAILURE;
3607 }
3608
3609 sme_session_id = session_entry->smeSessionId;
3610
3611 qdf_mem_set(&frm, sizeof(frm), 0);
3612
3613 frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
3614
3615 qdf_mem_copy(frm.p2p_action_oui.oui_data,
3616 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
3617 frm.p2p_action_subtype.subtype = 0x04;
3618 frm.DialogToken.token = 0x0;
3619
3620 if (session_entry->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003621 pe_debug("Populate HT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303622 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
3623 }
3624
3625 if (session_entry->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003626 pe_debug("Populate VHT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303627 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
3628 populate_dot11f_operating_mode(mac_ctx,
3629 &frm.OperatingMode, session_entry);
3630 }
3631
3632 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
3633 &frm, &n_payload);
3634 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003635 pe_err("Failed to get packed size 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303636 /* We'll fall back on the worst case scenario*/
3637 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
3638 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003639 pe_warn("There were warnings while calculating the packed size (0x%08x)",
3640 status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303641 }
3642
3643 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3644
3645 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
3646 (void **) &frame, (void **) &packet);
3647
3648 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003649 pe_err("Failed to allocate %d bytes", num_bytes);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303650 return eSIR_FAILURE;
3651 }
3652
3653 qdf_mem_set(frame, num_bytes, 0);
3654
3655 /* Next, fill out the buffer descriptor */
3656 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3657 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3658 mac_hdr = (tpSirMacMgmtHdr) frame;
3659 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
3660 (uint8_t *) session_entry->bssId,
3661 sizeof(tSirMacAddr));
3662
3663 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
3664 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3665 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003666 pe_err("Failed to pack 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303667 cds_packet_free((void *)packet);
3668 return eSIR_FAILURE;
3669 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003670 pe_warn("There were warnings while packing 0x%08x",
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303671 status);
3672 }
3673
3674 if ((SIR_BAND_5_GHZ ==
3675 lim_get_rf_band(session_entry->currentOperChannel)) ||
3676 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3677 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
3678 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3679 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003680 pe_debug("Send frame on channel %d to mac "
3681 MAC_ADDRESS_STR, session_entry->currentOperChannel,
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303682 MAC_ADDR_ARRAY(peer));
3683
3684 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3685 session_entry->peSessionId, mac_hdr->fc.subType));
3686
3687 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
3688 (uint16_t)num_bytes,
3689 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3690 7, lim_tx_complete, frame,
3691 lim_oper_chan_change_confirm_tx_complete_cnf,
3692 tx_flag, sme_session_id, false, 0);
3693
3694 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3695 session_entry->peSessionId, qdf_status));
3696 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003697 pe_err("Failed to send status %X!", qdf_status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303698 /* Pkt will be freed up by the callback */
3699 return eSIR_FAILURE;
3700 }
3701 return eSIR_SUCCESS;
3702}
3703
3704
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003705tSirRetStatus
3706lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
3707 tSirMacAddr peer,
3708 uint8_t nMode, tpPESession psessionEntry)
3709{
3710 tDot11fOperatingMode frm;
3711 uint8_t *pFrame;
3712 tpSirMacMgmtHdr pMacHdr;
3713 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
3714 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303715 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003716 uint8_t txFlag = 0;
3717
3718 uint8_t smeSessionId = 0;
3719
3720 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003721 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003722 return eSIR_FAILURE;
3723 }
3724 smeSessionId = psessionEntry->smeSessionId;
3725
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303726 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003727
3728 frm.Category.category = SIR_MAC_ACTION_VHT;
3729 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
3730 frm.OperatingMode.chanWidth = nMode;
3731 frm.OperatingMode.rxNSS = 0;
3732 frm.OperatingMode.rxNSSType = 0;
3733
3734 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
3735 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003736 pe_err("Failed to calculate the packed size for a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003737 nStatus);
3738 /* We'll fall back on the worst case scenario: */
3739 nPayload = sizeof(tDot11fOperatingMode);
3740 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003741 pe_warn("There were warnings while calculating the packed size for a Operating Mode (0x%08x)",
3742 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003743 }
3744
3745 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3746
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303747 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003748 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3749 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303750 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003751 pe_err("Failed to allocate %d bytes for a Operating Mode Report",
3752 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003753 return eSIR_FAILURE;
3754 }
3755 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303756 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003757
3758 /* Next, we fill out the buffer descriptor: */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303759 if (psessionEntry->pePersona == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003760 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3761 SIR_MAC_MGMT_ACTION, peer,
3762 psessionEntry->selfMacAddr);
3763 else
3764 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3765 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
3766 psessionEntry->selfMacAddr);
3767 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303768 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003769 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3770 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
3771 sizeof(tSirMacMgmtHdr),
3772 nPayload, &nPayload);
3773 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003774 pe_err("Failed to pack a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003775 nStatus);
3776 cds_packet_free((void *)pPacket);
3777 return eSIR_FAILURE; /* allocated! */
3778 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003779 pe_warn("There were warnings while packing a Operating Mode (0x%08x)",
3780 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003781 }
3782 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303783 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3784 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003785 ) {
3786 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3787 }
3788
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303789 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003790 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303791 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003792 TXRX_FRM_802_11_MGMT,
3793 ANI_TXDIR_TODS,
3794 7, lim_tx_complete, pFrame, txFlag,
3795 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303796 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303797 psessionEntry->peSessionId, qdf_status));
3798 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003799 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303800 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003801 /* Pkt will be freed up by the callback */
3802 return eSIR_FAILURE;
3803 }
3804
3805 return eSIR_SUCCESS;
3806}
3807
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003808/**
3809 * \brief Send a Neighbor Report Request Action frame
3810 *
3811 *
3812 * \param pMac Pointer to the global MAC structure
3813 *
3814 * \param pNeighborReq Address of a tSirMacNeighborReportReq
3815 *
3816 * \param peer mac address of peer station.
3817 *
3818 * \param psessionEntry address of session entry.
3819 *
3820 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3821 *
3822 *
3823 */
3824
3825tSirRetStatus
3826lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
3827 tpSirMacNeighborReportReq pNeighborReq,
3828 tSirMacAddr peer, tpPESession psessionEntry)
3829{
3830 tSirRetStatus statusCode = eSIR_SUCCESS;
3831 tDot11fNeighborReportRequest frm;
3832 uint8_t *pFrame;
3833 tpSirMacMgmtHdr pMacHdr;
3834 uint32_t nBytes, nPayload, nStatus;
3835 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303836 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003837 uint8_t txFlag = 0;
3838 uint8_t smeSessionId = 0;
3839
3840 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003841 pe_err("(psession == NULL) in Request to send Neighbor Report request action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003842 return eSIR_FAILURE;
3843 }
3844 smeSessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303845 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003846
3847 frm.Category.category = SIR_MAC_ACTION_RRM;
3848 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
3849 frm.DialogToken.token = pNeighborReq->dialogToken;
3850
3851 if (pNeighborReq->ssid_present) {
3852 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
3853 }
3854
3855 nStatus =
3856 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
3857 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003858 pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003859 nStatus);
3860 /* We'll fall back on the worst case scenario: */
3861 nPayload = sizeof(tDot11fNeighborReportRequest);
3862 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003863 pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)",
3864 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003865 }
3866
3867 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3868
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303869 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003870 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3871 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303872 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003873 pe_err("Failed to allocate %d bytes for a Neighbor "
3874 "Report Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003875 return eSIR_FAILURE;
3876 }
3877 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303878 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003879
3880 /* Copy necessary info to BD */
3881 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3882 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
3883
3884 /* Update A3 with the BSSID */
3885 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3886
3887 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3888
3889#ifdef WLAN_FEATURE_11W
3890 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3891#endif
3892
3893 /* Now, we're ready to "pack" the frames */
3894 nStatus = dot11f_pack_neighbor_report_request(pMac,
3895 &frm,
3896 pFrame +
3897 sizeof(tSirMacMgmtHdr),
3898 nPayload, &nPayload);
3899
3900 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003901 pe_err("Failed to pack an Neighbor Report Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003902 nStatus);
3903
3904 /* FIXME - Need to convert to tSirRetStatus */
3905 statusCode = eSIR_FAILURE;
3906 goto returnAfterError;
3907 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003908 pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)",
3909 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003910 }
3911
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003912 pe_debug("Sending a Neighbor Report Request to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +05303913 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003914
3915 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303916 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3917 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003918 ) {
3919 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3920 }
3921
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303922 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003923 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303924 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003925 pPacket,
3926 (uint16_t) nBytes,
3927 TXRX_FRM_802_11_MGMT,
3928 ANI_TXDIR_TODS,
3929 7, lim_tx_complete, pFrame, txFlag,
3930 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303931 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303932 psessionEntry->peSessionId, qdf_status));
3933 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003934 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003935 statusCode = eSIR_FAILURE;
3936 /* Pkt will be freed up by the callback */
3937 return statusCode;
3938 } else
3939 return eSIR_SUCCESS;
3940
3941returnAfterError:
3942 cds_packet_free((void *)pPacket);
3943
3944 return statusCode;
3945} /* End lim_send_neighbor_report_request_frame. */
3946
3947/**
3948 * \brief Send a Link Report Action frame
3949 *
3950 *
3951 * \param pMac Pointer to the global MAC structure
3952 *
3953 * \param pLinkReport Address of a tSirMacLinkReport
3954 *
3955 * \param peer mac address of peer station.
3956 *
3957 * \param psessionEntry address of session entry.
3958 *
3959 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3960 *
3961 *
3962 */
3963
3964tSirRetStatus
3965lim_send_link_report_action_frame(tpAniSirGlobal pMac,
3966 tpSirMacLinkReport pLinkReport,
3967 tSirMacAddr peer, tpPESession psessionEntry)
3968{
3969 tSirRetStatus statusCode = eSIR_SUCCESS;
3970 tDot11fLinkMeasurementReport frm;
3971 uint8_t *pFrame;
3972 tpSirMacMgmtHdr pMacHdr;
3973 uint32_t nBytes, nPayload, nStatus;
3974 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303975 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003976 uint8_t txFlag = 0;
3977 uint8_t smeSessionId = 0;
3978
3979 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003980 pe_err("(psession == NULL) in Request to send Link Report action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003981 return eSIR_FAILURE;
3982 }
3983
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303984 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003985
3986 frm.Category.category = SIR_MAC_ACTION_RRM;
3987 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
3988 frm.DialogToken.token = pLinkReport->dialogToken;
3989
3990 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
3991 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
3992 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
3993 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
3994 /* such case this way than changing the frame parser. */
3995 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
3996 frm.TPCEleLen.TPCLen = 2;
3997 frm.TxPower.txPower = pLinkReport->txPower;
3998 frm.LinkMargin.linkMargin = 0;
3999
4000 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4001 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4002 frm.RCPI.rcpi = pLinkReport->rcpi;
4003 frm.RSNI.rsni = pLinkReport->rsni;
4004
4005 nStatus =
4006 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4007 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004008 pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004009 /* We'll fall back on the worst case scenario: */
4010 nPayload = sizeof(tDot11fLinkMeasurementReport);
4011 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004012 pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)",
4013 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004014 }
4015
4016 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4017
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304018 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004019 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4020 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304021 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004022 pe_err("Failed to allocate %d bytes for a Link "
4023 "Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004024 return eSIR_FAILURE;
4025 }
4026 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304027 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004028
4029 /* Copy necessary info to BD */
4030 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4031 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4032
4033 /* Update A3 with the BSSID */
4034 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4035
4036 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4037
4038#ifdef WLAN_FEATURE_11W
4039 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4040#endif
4041
4042 /* Now, we're ready to "pack" the frames */
4043 nStatus = dot11f_pack_link_measurement_report(pMac,
4044 &frm,
4045 pFrame +
4046 sizeof(tSirMacMgmtHdr),
4047 nPayload, &nPayload);
4048
4049 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004050 pe_err("Failed to pack an Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004051
4052 /* FIXME - Need to convert to tSirRetStatus */
4053 statusCode = eSIR_FAILURE;
4054 goto returnAfterError;
4055 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004056 pe_warn("There were warnings while packing Link Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004057 nStatus);
4058 }
4059
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004060 pe_warn("Sending a Link Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004061 lim_print_mac_addr(pMac, peer, LOGW);
4062
4063 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304064 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4065 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4067 }
4068
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304069 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004070 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304071 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004072 pPacket,
4073 (uint16_t) nBytes,
4074 TXRX_FRM_802_11_MGMT,
4075 ANI_TXDIR_TODS,
4076 7, lim_tx_complete, pFrame, txFlag,
4077 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304078 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304079 psessionEntry->peSessionId, qdf_status));
4080 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004081 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082 statusCode = eSIR_FAILURE;
4083 /* Pkt will be freed up by the callback */
4084 return statusCode;
4085 } else
4086 return eSIR_SUCCESS;
4087
4088returnAfterError:
4089 cds_packet_free((void *)pPacket);
4090
4091 return statusCode;
4092} /* End lim_send_link_report_action_frame. */
4093
4094/**
4095 * \brief Send a Beacon Report Action frame
4096 *
4097 *
4098 * \param pMac Pointer to the global MAC structure
4099 *
4100 * \param dialog_token dialog token to be used in the action frame.
4101 *
4102 * \param num_report number of reports in pRRMReport.
4103 *
4104 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4105 *
4106 * \param peer mac address of peer station.
4107 *
4108 * \param psessionEntry address of session entry.
4109 *
4110 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4111 *
4112 *
4113 */
4114
4115tSirRetStatus
4116lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4117 uint8_t dialog_token,
4118 uint8_t num_report,
4119 tpSirMacRadioMeasureReport pRRMReport,
4120 tSirMacAddr peer,
4121 tpPESession psessionEntry)
4122{
4123 tSirRetStatus statusCode = eSIR_SUCCESS;
4124 uint8_t *pFrame;
4125 tpSirMacMgmtHdr pMacHdr;
4126 uint32_t nBytes, nPayload, nStatus;
4127 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304128 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004129 uint8_t i;
4130 uint8_t txFlag = 0;
4131 uint8_t smeSessionId = 0;
4132
4133 tDot11fRadioMeasurementReport *frm =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304134 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004135 if (!frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004136 pe_err("Not enough memory to allocate tDot11fRadioMeasurementReport");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004137 return eSIR_MEM_ALLOC_FAILED;
4138 }
4139
4140 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004141 pe_err("(psession == NULL) in Request to send Beacon Report action frame");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304142 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004143 return eSIR_FAILURE;
4144 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004145
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004146 pe_debug("dialog_token %d num_report %d",
Padma, Santhosh Kumar93ec7d22016-12-26 15:58:37 +05304147 dialog_token, num_report);
4148
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004149 frm->Category.category = SIR_MAC_ACTION_RRM;
4150 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4151 frm->DialogToken.token = dialog_token;
4152
4153 frm->num_MeasurementReport =
4154 (num_report >
4155 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4156 num_report;
4157
4158 for (i = 0; i < frm->num_MeasurementReport; i++) {
4159 frm->MeasurementReport[i].type = pRRMReport[i].type;
4160 frm->MeasurementReport[i].token = pRRMReport[i].token;
4161 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4162 switch (pRRMReport[i].type) {
4163 case SIR_MAC_RRM_BEACON_TYPE:
4164 populate_dot11f_beacon_report(pMac,
4165 &frm->MeasurementReport[i],
4166 &pRRMReport[i].report.
4167 beaconReport);
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 default:
4175 frm->MeasurementReport[i].incapable =
4176 pRRMReport[i].incapable;
4177 frm->MeasurementReport[i].refused =
4178 pRRMReport[i].refused;
4179 frm->MeasurementReport[i].present = 1;
4180 break;
4181 }
4182 }
4183
4184 nStatus =
4185 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4186 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004187 pe_err("Failed to calculate the packed size for a Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004188 nStatus);
4189 /* We'll fall back on the worst case scenario: */
4190 nPayload = sizeof(tDot11fLinkMeasurementReport);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304191 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004192 return eSIR_FAILURE;
4193 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004194 pe_warn("There were warnings while calculating the packed size for a Radio Measure Report (0x%08x)",
4195 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004196 }
4197
4198 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4199
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304200 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004201 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4202 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304203 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004204 pe_err("Failed to allocate %d bytes for a Radio Measure "
4205 "Report", nBytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304206 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004207 return eSIR_FAILURE;
4208 }
4209 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304210 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004211
4212 /* Copy necessary info to BD */
4213 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4214 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4215
4216 /* Update A3 with the BSSID */
4217 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4218
4219 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4220
4221#ifdef WLAN_FEATURE_11W
4222 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4223#endif
4224
4225 /* Now, we're ready to "pack" the frames */
4226 nStatus = dot11f_pack_radio_measurement_report(pMac,
4227 frm,
4228 pFrame +
4229 sizeof(tSirMacMgmtHdr),
4230 nPayload, &nPayload);
4231
4232 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004233 pe_err("Failed to pack an Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004234 nStatus);
4235
4236 /* FIXME - Need to convert to tSirRetStatus */
4237 statusCode = eSIR_FAILURE;
4238 goto returnAfterError;
4239 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004240 pe_warn("There were warnings while packing Radio Measure Report (0x%08x)",
4241 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004242 }
4243
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004244 pe_warn("Sending a Radio Measure Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004245 lim_print_mac_addr(pMac, peer, LOGW);
4246
4247 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304248 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4249 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004250 ) {
4251 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4252 }
4253
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304254 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004255 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304256 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004257 pPacket,
4258 (uint16_t) nBytes,
4259 TXRX_FRM_802_11_MGMT,
4260 ANI_TXDIR_TODS,
4261 7, lim_tx_complete, pFrame, txFlag,
4262 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304263 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304264 psessionEntry->peSessionId, qdf_status));
4265 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004266 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004267 statusCode = eSIR_FAILURE;
4268 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304269 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004270 return statusCode;
4271 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304272 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004273 return eSIR_SUCCESS;
4274 }
4275
4276returnAfterError:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304277 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004278 cds_packet_free((void *)pPacket);
4279 return statusCode;
4280}
4281
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004282#ifdef WLAN_FEATURE_11W
4283/**
4284 * \brief Send SA query request action frame to peer
4285 *
4286 * \sa lim_send_sa_query_request_frame
4287 *
4288 *
4289 * \param pMac The global tpAniSirGlobal object
4290 *
4291 * \param transId Transaction identifier
4292 *
4293 * \param peer The Mac address of the station to which this action frame is addressed
4294 *
4295 * \param psessionEntry The PE session entry
4296 *
4297 * \return eSIR_SUCCESS if setup completes successfully
4298 * eSIR_FAILURE is some problem is encountered
4299 */
4300
4301tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4302 tSirMacAddr peer,
4303 tpPESession psessionEntry)
4304{
4305
4306 tDot11fSaQueryReq frm; /* SA query request action frame */
4307 uint8_t *pFrame;
4308 tSirRetStatus nSirStatus;
4309 tpSirMacMgmtHdr pMacHdr;
4310 uint32_t nBytes, nPayload, nStatus;
4311 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304312 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004313 uint8_t txFlag = 0;
4314 uint8_t smeSessionId = 0;
4315
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304316 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004317 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4318 /* 11w action field is :
4319 action: 0 --> SA Query Request action frame
4320 action: 1 --> SA Query Response action frame */
4321 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4322 /* 11w SA Query Request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304323 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004324
4325 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4326 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004327 pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004328 nStatus);
4329 /* We'll fall back on the worst case scenario: */
4330 nPayload = sizeof(tDot11fSaQueryReq);
4331 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004332 pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)",
4333 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004334 }
4335
4336 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304337 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004338 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304339 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004340 pe_err("Failed to allocate %d bytes for a SA Query Request "
4341 "action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004342 return eSIR_FAILURE;
4343 }
4344 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304345 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004346
4347 /* Copy necessary info to BD */
4348 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4349 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4350
4351 /* Update A3 with the BSSID */
4352 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4353
4354 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4355
4356 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4357 /* in the FC */
4358 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4359
4360 /* Pack 11w SA Query Request frame */
4361 nStatus = dot11f_pack_sa_query_req(pMac,
4362 &frm,
4363 pFrame + sizeof(tSirMacMgmtHdr),
4364 nPayload, &nPayload);
4365
4366 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004367 pe_err("Failed to pack an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004368 nStatus);
4369 /* FIXME - Need to convert to tSirRetStatus */
4370 nSirStatus = eSIR_FAILURE;
4371 goto returnAfterError;
4372 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004373 pe_warn("There were warnings while packing SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004374 nStatus);
4375 }
4376
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004377 pe_debug("Sending an SA Query Request to");
4378 lim_print_mac_addr(pMac, peer, LOGD);
4379 pe_debug("Sending an SA Query Request from ");
4380 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004381
4382 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4383#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304384 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4385 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004386#endif
4387 ) {
4388 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4389 }
4390 smeSessionId = psessionEntry->smeSessionId;
4391
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304392 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004393 pPacket,
4394 (uint16_t) nBytes,
4395 TXRX_FRM_802_11_MGMT,
4396 ANI_TXDIR_TODS,
4397 7, lim_tx_complete, pFrame, txFlag,
4398 smeSessionId, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304399 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004400 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004401 nSirStatus = eSIR_FAILURE;
4402 /* Pkt will be freed up by the callback */
4403 return nSirStatus;
4404 } else {
4405 return eSIR_SUCCESS;
4406 }
4407
4408returnAfterError:
4409 cds_packet_free((void *)pPacket);
4410 return nSirStatus;
4411} /* End lim_send_sa_query_request_frame */
4412
4413/**
4414 * \brief Send SA query response action frame to peer
4415 *
4416 * \sa lim_send_sa_query_response_frame
4417 *
4418 *
4419 * \param pMac The global tpAniSirGlobal object
4420 *
4421 * \param transId Transaction identifier received in SA query request action frame
4422 *
4423 * \param peer The Mac address of the AP to which this action frame is addressed
4424 *
4425 * \param psessionEntry The PE session entry
4426 *
4427 * \return eSIR_SUCCESS if setup completes successfully
4428 * eSIR_FAILURE is some problem is encountered
4429 */
4430
4431tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
4432 uint8_t *transId, tSirMacAddr peer,
4433 tpPESession psessionEntry)
4434{
4435
4436 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
4437 uint8_t *pFrame;
4438 tSirRetStatus nSirStatus;
4439 tpSirMacMgmtHdr pMacHdr;
4440 uint32_t nBytes, nPayload, nStatus;
4441 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304442 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004443 uint8_t txFlag = 0;
4444 uint8_t smeSessionId = 0;
4445
4446 smeSessionId = psessionEntry->smeSessionId;
4447
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304448 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004449 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4450 /*11w action field is :
4451 action: 0 --> SA query request action frame
4452 action: 1 --> SA query response action frame */
4453 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
4454 /*11w SA query response transId is same as
4455 SA query request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304456 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004457
4458 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
4459 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004460 pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004461 nStatus);
4462 /* We'll fall back on the worst case scenario: */
4463 nPayload = sizeof(tDot11fSaQueryRsp);
4464 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004465 pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)",
4466 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004467 }
4468
4469 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304470 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004471 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304472 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004473 pe_err("Failed to allocate %d bytes for a SA query response"
4474 " action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004475 return eSIR_FAILURE;
4476 }
4477 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304478 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004479
4480 /* Copy necessary info to BD */
4481 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4482 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4483
4484 /* Update A3 with the BSSID */
4485 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4486
4487 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4488
4489 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
4490 /* in the FC */
4491 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4492
4493 /* Pack 11w SA query response frame */
4494 nStatus = dot11f_pack_sa_query_rsp(pMac,
4495 &frm,
4496 pFrame + sizeof(tSirMacMgmtHdr),
4497 nPayload, &nPayload);
4498
4499 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004500 pe_err("Failed to pack an SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004501 nStatus);
4502 /* FIXME - Need to convert to tSirRetStatus */
4503 nSirStatus = eSIR_FAILURE;
4504 goto returnAfterError;
4505 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004506 pe_warn("There were warnings while packing SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004507 nStatus);
4508 }
4509
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004510 pe_debug("Sending a SA Query Response to");
Srinivas Girigowdaf936d822017-03-19 23:23:59 -07004511 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004512
4513 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4514#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304515 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4516 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004517#endif
4518 ) {
4519 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4520 }
4521
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304522 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004523 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304524 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004525 pPacket,
4526 (uint16_t) nBytes,
4527 TXRX_FRM_802_11_MGMT,
4528 ANI_TXDIR_TODS,
4529 7, lim_tx_complete, pFrame, txFlag,
4530 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304531 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304532 psessionEntry->peSessionId, qdf_status));
4533 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004534 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004535 nSirStatus = eSIR_FAILURE;
4536 /* Pkt will be freed up by the callback */
4537 return nSirStatus;
4538 } else {
4539 return eSIR_SUCCESS;
4540 }
4541
4542returnAfterError:
4543 cds_packet_free((void *)pPacket);
4544 return nSirStatus;
4545} /* End lim_send_sa_query_response_frame */
4546#endif
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004547
4548/**
4549 * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
4550 * @mac_ctx: mac context
4551 * @peer_mac: Peer MAC address
4552 * @tid: TID for which addba response is being sent
4553 * @session: PE session entry
4554 *
4555 * This function is called when ADDBA request is successful. ADDBA response is
4556 * setup by calling addba_response_setup API and frame is then sent out OTA.
4557 *
4558 * Return: QDF_STATUS
4559 */
4560QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
4561 tSirMacAddr peer_mac, uint16_t tid, tpPESession session)
4562{
4563
4564 tDot11faddba_rsp frm;
4565 uint8_t *frame_ptr;
4566 tpSirMacMgmtHdr mgmt_hdr;
4567 uint32_t num_bytes, payload_size, status;
4568 void *pkt_ptr;
4569 QDF_STATUS qdf_status;
4570 uint8_t tx_flag = 0;
4571 uint8_t sme_sessionid = 0;
4572 uint16_t buff_size, status_code, batimeout;
4573 uint8_t peer_id, dialog_token;
4574 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4575 void *peer, *pdev;
4576
4577 sme_sessionid = session->smeSessionId;
4578
4579 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4580 if (!pdev) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004581 pe_err("pdev is NULL");
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004582 return QDF_STATUS_E_FAILURE;
4583 }
4584
4585 peer = cdp_peer_find_by_addr(soc, pdev, peer_mac, &peer_id);
4586 if (!peer) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004587 pe_err("PEER [%pM] not found", peer_mac);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004588 return QDF_STATUS_E_FAILURE;
4589 }
4590
4591 cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
4592 &status_code, &buff_size, &batimeout);
4593
4594 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4595 frm.Category.category = SIR_MAC_ACTION_BLKACK;
4596 frm.Action.action = SIR_MAC_ADDBA_RSP;
4597
4598 frm.DialogToken.token = dialog_token;
4599 frm.Status.status = status_code;
4600 frm.addba_param_set.tid = tid;
4601 frm.addba_param_set.buff_size = buff_size;
4602 frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE;
4603 frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED;
4604 frm.ba_timeout.timeout = batimeout;
4605
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004606 pe_debug("Sending a ADDBA Response from %pM to %pM",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004607 session->selfMacAddr, peer_mac);
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004608 pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004609 tid, frm.DialogToken.token, frm.Status.status,
4610 frm.addba_param_set.buff_size);
4611
4612 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
4613 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004614 pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004615 status);
4616 /* We'll fall back on the worst case scenario: */
4617 payload_size = sizeof(tDot11faddba_rsp);
4618 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004619 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 -08004620 }
4621
4622 num_bytes = payload_size + sizeof(*mgmt_hdr);
4623 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
4624 (void **)&pkt_ptr);
4625 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004626 pe_err("Failed to allocate %d bytes for a ADDBA response action frame",
4627 num_bytes);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004628 return QDF_STATUS_E_FAILURE;
4629 }
4630 qdf_mem_set(frame_ptr, num_bytes, 0);
4631
4632 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
4633 SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
4634
4635 /* Update A3 with the BSSID */
4636 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
4637 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
4638
4639 /* ADDBA Response is a robust mgmt action frame,
4640 * set the "protect" (aka WEP) bit in the FC
4641 */
4642 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
4643
4644 status = dot11f_pack_addba_rsp(mac_ctx, &frm,
4645 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
4646 &payload_size);
4647
4648 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004649 pe_err("Failed to pack a ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004650 status);
4651 qdf_status = QDF_STATUS_E_FAILURE;
4652 goto error_addba_rsp;
4653 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004654 pe_warn("There were warnings while packing ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004655 status);
4656 }
4657
4658
4659 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
4660#ifdef WLAN_FEATURE_P2P
4661 || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
4662 (session->pePersona == QDF_P2P_GO_MODE)
4663#endif
4664 ) {
4665 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4666 }
4667
4668 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4669 session->peSessionId, mgmt_hdr->fc.subType));
4670 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
4671 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
4672 lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0);
4673 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4674 session->peSessionId, qdf_status));
4675 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004676 pe_err("wma_tx_frame FAILED! Status [%d]",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004677 qdf_status);
4678 qdf_status = QDF_STATUS_E_FAILURE;
4679 /*
4680 * wma_tx_frame free memory in certain cases, free pkt_ptr
4681 * only if not freed already.
4682 */
4683 if (pkt_ptr)
4684 cds_packet_free((void *)pkt_ptr);
4685 return qdf_status;
4686 } else {
4687 return eSIR_SUCCESS;
4688 }
4689
4690error_addba_rsp:
4691 cds_packet_free((void *)pkt_ptr);
4692 return qdf_status;
4693}