blob: a038d01f6b26a35153c8beb9984a2081af843c25 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * \file lim_send_management_frames.c
30 *
31 * \brief Code for preparing and sending 802.11 Management frames
32 *
33 *
34 */
35
36#include "sir_api.h"
37#include "ani_global.h"
38#include "sir_mac_prot_def.h"
39#include "cfg_api.h"
40#include "utils_api.h"
41#include "lim_types.h"
42#include "lim_utils.h"
43#include "lim_security_utils.h"
44#include "lim_prop_exts_utils.h"
45#include "dot11f.h"
46#include "lim_sta_hash_api.h"
47#include "sch_api.h"
48#include "lim_send_messages.h"
49#include "lim_assoc_utils.h"
50#include "lim_ft.h"
51#ifdef WLAN_FEATURE_11W
52#include "wni_cfg.h"
53#endif
54
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080055#include "lim_ft_defs.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080056#include "lim_session.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053057#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053058#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059#include "cds_utils.h"
60#include "sme_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#include "rrm_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
63#include "wma_types.h"
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -080064#include <cdp_txrx_cmn.h>
Tushnim Bhattacharyya45ed04f2017-03-15 10:15:05 -070065#include <cdp_txrx_peer_ops.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080066
67/**
68 *
69 * \brief This function is called to add the sequence number to the
70 * management frames
71 *
72 * \param pMac Pointer to Global MAC structure
73 *
74 * \param pMacHdr Pointer to MAC management header
75 *
76 * The pMacHdr argument points to the MAC management header. The
77 * sequence number stored in the pMac structure will be incremented
78 * and updated to the MAC management header. The start sequence
79 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
80 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
81 * number will roll over.
82 *
83 */
Jeff Johnson38112a32016-10-07 07:30:50 -070084static void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085{
86 if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
87 pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
88 }
89
90 pMac->mgmtSeqNum++;
91
92 pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
93 pMacHdr->seqControl.seqNumHi =
94 ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
95}
96
97/**
98 *
99 * \brief This function is called before sending a p2p action frame
100 * inorder to add sequence numbers to action packets
101 *
102 * \param pMac Pointer to Global MAC structure
103 *
104 * \param pBD Pointer to the frame buffer that needs to be populate
105 *
106 * The pMacHdr argument points to the MAC management header. The
107 * sequence number stored in the pMac structure will be incremented
108 * and updated to the MAC management header. The start sequence
109 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
110 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
111 * number will roll over.
112 *
113 */
114void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
115{
116 tpSirMacMgmtHdr pMacHdr;
117
118 /* / Prepare MAC management header */
119 pMacHdr = (tpSirMacMgmtHdr) (pBD);
120
121 /* Prepare sequence number */
122 lim_add_mgmt_seq_num(pMac, pMacHdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700123 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800124 pMacHdr->seqControl.seqNumLo,
125 pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
126}
127
128/**
129 * lim_populate_mac_header() - Fill in 802.11 header of frame
130 *
131 * @mac_ctx: Pointer to Global MAC structure
132 * @buf: Pointer to the frame buffer that needs to be populate
133 * @type: 802.11 Type of the frame
134 * @sub_type: 802.11 Subtype of the frame
135 * @peer_addr: dst address
136 * @self_mac_addr: local mac address
137 *
138 * This function is called by various LIM modules to prepare the
139 * 802.11 frame MAC header
140 *
141 * The buf argument points to the beginning of the frame buffer to
142 * which - a) The 802.11 MAC header is set b) Following this MAC header
143 * will be the MGMT frame payload The payload itself is populated by the
144 * caller API
145 *
146 * Return: None
147 */
148
149void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
150 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
151 tSirMacAddr self_mac_addr)
152{
153 tpSirMacMgmtHdr mac_hdr;
154
155 /* Prepare MAC management header */
156 mac_hdr = (tpSirMacMgmtHdr) (buf);
157
158 /* Prepare FC */
159 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
160 mac_hdr->fc.type = type;
161 mac_hdr->fc.subType = sub_type;
162
163 /* Prepare Address 1 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530164 qdf_mem_copy((uint8_t *) mac_hdr->da,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800165 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
166
167 /* Prepare Address 2 */
168 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
169
170 /* Prepare Address 3 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530171 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
173
174 /* Prepare sequence number */
175 lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700176 pe_debug("seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177 mac_hdr->seqControl.seqNumLo,
178 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
179}
180
181/**
182 * lim_send_probe_req_mgmt_frame() - send probe request management frame
183 * @mac_ctx: Pointer to Global MAC structure
184 * @ssid: SSID to be sent in Probe Request frame
185 * @bssid: BSSID to be sent in Probe Request frame
186 * @channel: Channel # on which the Probe Request is going out
187 * @self_macaddr: self MAC address
188 * @dot11mode: self dotllmode
189 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
190 * frame
191 * @additional_ie: if additional_ielen is non zero, include this field in the
192 * Probe Request frame
193 *
194 * This function is called by various LIM modules to send Probe Request frame
195 * during active scan/learn phase.
196 * Probe request is sent out in the following scenarios:
197 * --heartbeat failure: session needed
198 * --join req: session needed
199 * --foreground scan: no session
200 * --background scan: no session
201 * --sch_beacon_processing: to get EDCA parameters: session needed
202 *
203 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
204 */
205tSirRetStatus
206lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
207 tSirMacSSid *ssid,
208 tSirMacAddr bssid,
209 uint8_t channel,
210 tSirMacAddr self_macaddr,
211 uint32_t dot11mode,
212 uint32_t additional_ielen, uint8_t *additional_ie)
213{
214 tDot11fProbeRequest pr;
215 uint32_t status, bytes, payload;
216 uint8_t *frame;
217 void *packet;
Kapil Guptac03eb072016-08-09 14:01:36 +0530218 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219 tpPESession pesession;
220 uint8_t sessionid;
221 uint8_t *p2pie = NULL;
222 uint8_t txflag = 0;
223 uint8_t sme_sessionid = 0;
224 bool is_vht_enabled = false;
225 uint8_t txPower;
226 uint16_t addn_ielen = additional_ielen;
Kapil Guptac03eb072016-08-09 14:01:36 +0530227 bool extracted_ext_cap_flag = false;
228 tDot11fIEExtCap extracted_ext_cap;
229 tSirRetStatus sir_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230
231 /* The probe req should not send 11ac capabilieties if band is 2.4GHz,
232 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
233 * is false and dot11mode is 11ac set it to 11n.
234 */
235 if (channel <= SIR_11B_CHANNEL_END &&
236 (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
237 (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
238 WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
239 dot11mode = WNI_CFG_DOT11_MODE_11N;
240 /*
241 * session context may or may not be present, when probe request needs
242 * to be sent out. Following cases exist:
243 * --heartbeat failure: session needed
244 * --join req: session needed
245 * --foreground scan: no session
246 * --background scan: no session
247 * --sch_beacon_processing: to get EDCA parameters: session needed
248 * If session context does not exist, some IEs will be populated from
249 * CFGs, e.g. Supported and Extended rate set IEs
250 */
251 pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
252
253 if (pesession != NULL)
254 sme_sessionid = pesession->smeSessionId;
255
256 /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
257 /* and then hand it off to 'dot11f_pack_probe_request' (for */
258 /* serialization). We start by zero-initializing the structure: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530259 qdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800260
261 /* & delegating to assorted helpers: */
262 populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
263
264 if (addn_ielen && additional_ie)
265 p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
266
267 /*
268 * Don't include 11b rate if it is a P2P serach or probe request is
269 * sent by P2P Client
270 */
271 if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
272 (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
273 mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
274 ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530275 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 )
277 ) {
278 /*
279 * In the below API pass channel number > 14, do that it fills
280 * only 11a rates in supported rates
281 */
282 populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
283 pesession);
284 } else {
285 populate_dot11f_supp_rates(mac_ctx, channel,
286 &pr.SuppRates, pesession);
287
288 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
289 populate_dot11f_ext_supp_rates1(mac_ctx, channel,
290 &pr.ExtSuppRates);
291 }
292 }
293
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800294 /*
295 * Table 7-14 in IEEE Std. 802.11k-2008 says
296 * DS params "can" be present in RRM is disabled and "is" present if
297 * RRM is enabled. It should be ok even if we add it into probe req when
298 * RRM is not enabled.
299 */
300 populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
301 /* Call RRM module to get the tx power for management used. */
302 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
303 populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
304
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305
306 if (pesession != NULL) {
307 pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
308 /* Include HT Capability IE */
309 if (pesession->htCapability)
310 populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
311 } else { /* pesession == NULL */
312 if (IS_DOT11_MODE_HT(dot11mode))
313 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
314 }
315
316 /*
317 * Set channelbonding information as "disabled" when tunned to a
318 * 2.4 GHz channel
319 */
320 if (channel <= SIR_11B_CHANNEL_END) {
321 if (mac_ctx->roam.configParam.channelBondingMode24GHz
322 == PHY_SINGLE_CHANNEL_CENTERED) {
323 pr.HTCaps.supportedChannelWidthSet =
324 eHT_CHANNEL_WIDTH_20MHZ;
325 pr.HTCaps.shortGI40MHz = 0;
326 } else {
327 pr.HTCaps.supportedChannelWidthSet =
328 eHT_CHANNEL_WIDTH_40MHZ;
329 }
330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331 if (pesession != NULL) {
332 pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
333 /* Include VHT Capability IE */
334 if (pesession->vhtCapability) {
335 populate_dot11f_vht_caps(mac_ctx, pesession,
336 &pr.VHTCaps);
337 is_vht_enabled = true;
338 }
339 } else {
340 if (IS_DOT11_MODE_VHT(dot11mode)) {
341 populate_dot11f_vht_caps(mac_ctx, pesession,
342 &pr.VHTCaps);
343 is_vht_enabled = true;
344 }
345 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346 if (pesession != NULL)
347 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
348 pesession);
349
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +0530350 if (mac_ctx->roam.configParam.qcn_ie_support)
351 populate_dot11f_qcn_ie(&pr.QCN_IE);
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +0530352
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800353 if (IS_DOT11_MODE_HE(dot11mode) && NULL != pesession)
354 lim_update_session_he_capable(mac_ctx, pesession);
355
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700356 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800357 populate_dot11f_he_caps(mac_ctx, pesession, &pr.vendor_he_cap);
358
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359 if (addn_ielen) {
Kapil Guptac03eb072016-08-09 14:01:36 +0530360 qdf_mem_zero((uint8_t *)&extracted_ext_cap,
361 sizeof(tDot11fIEExtCap));
362 sir_status = lim_strip_extcap_update_struct(mac_ctx,
363 additional_ie,
364 &addn_ielen,
365 &extracted_ext_cap);
366 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700367 pe_debug("Unable to Stripoff ExtCap IE from Probe Req");
Kapil Guptac03eb072016-08-09 14:01:36 +0530368 } else {
369 struct s_ext_cap *p_ext_cap =
370 (struct s_ext_cap *)
371 extracted_ext_cap.bytes;
372 if (p_ext_cap->interworking_service)
373 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +0800374 extracted_ext_cap.num_bytes =
375 lim_compute_ext_cap_ie_length
376 (&extracted_ext_cap);
Kapil Guptac03eb072016-08-09 14:01:36 +0530377 extracted_ext_cap_flag =
Hu Wang411e0cc2016-10-28 14:56:01 +0800378 (extracted_ext_cap.num_bytes > 0);
Kapil Guptac03eb072016-08-09 14:01:36 +0530379 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380 }
381
Hu Wang411e0cc2016-10-28 14:56:01 +0800382 /*
383 * Extcap IE now support variable length, merge Extcap IE from addn_ie
384 * may change the frame size. Therefore, MUST merge ExtCap IE before
385 * dot11f get packed payload size.
386 */
387 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800388 lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800389
390 /* That's it-- now we pack it. First, how much space are we going to */
391 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
392 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700393 pe_err("Failed to calculate the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800394 status);
395 /* We'll fall back on the worst case scenario: */
396 payload = sizeof(tDot11fProbeRequest);
397 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700398 pe_warn("There were warnings while calculating the packed size for a Probe Request (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800399 status);
400 }
401
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
403
404 /* Ok-- try to allocate some memory: */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530405 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530407 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700408 pe_err("Failed to allocate %d bytes for a Probe Request", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 return eSIR_MEM_ALLOC_FAILED;
410 }
411 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530412 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413
414 /* Next, we fill out the buffer descriptor: */
415 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
416 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
417
418 /* That done, pack the Probe Request: */
419 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
420 sizeof(tSirMacMgmtHdr),
421 payload, &payload);
422 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700423 pe_err("Failed to pack a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424 cds_packet_free((void *)packet);
425 return eSIR_FAILURE; /* allocated! */
426 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700427 pe_warn("There were warnings while packing a Probe Request (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 }
429 /* Append any AddIE if present. */
430 if (addn_ielen) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530431 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800432 additional_ie, addn_ielen);
433 payload += addn_ielen;
434 }
435
436 /* If this probe request is sent during P2P Search State, then we need
437 * to send it at OFDM rate.
438 */
439 if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
440 || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
441 mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
442 /*
443 * For unicast probe req mgmt from Join function we don't set
444 * above variables. So we need to add one more check whether it
445 * is pePersona is P2P_CLIENT or not
446 */
447 || ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530448 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 ) {
450 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
451 }
452
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530453 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800454 wma_tx_frame(mac_ctx, packet,
455 (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
456 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
457 lim_tx_complete, frame, txflag, sme_sessionid,
458 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530459 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700460 pe_err("could not send Probe Request frame!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 /* Pkt will be freed up by the callback */
462 return eSIR_FAILURE;
463 }
464
465 return eSIR_SUCCESS;
466} /* End lim_send_probe_req_mgmt_frame. */
467
Jeff Johnson38112a32016-10-07 07:30:50 -0700468static tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800469 uint8_t *addIE, uint16_t *addnIELen,
470 uint8_t probeReqP2pIe)
471{
472 /* If Probe request doesn't have P2P IE, then take out P2P IE
473 from additional IE */
474 if (!probeReqP2pIe) {
475 uint8_t *tempbuf = NULL;
476 uint16_t tempLen = 0;
477 int left = *addnIELen;
478 uint8_t *ptr = addIE;
479 uint8_t elem_id, elem_len;
480
481 if (NULL == addIE) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700482 pe_err("NULL addIE pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800483 return eSIR_FAILURE;
484 }
485
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530486 tempbuf = qdf_mem_malloc(left);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487 if (NULL == tempbuf) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700488 pe_err("Unable to allocate memory to store addn IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800489 return eSIR_MEM_ALLOC_FAILED;
490 }
491
492 while (left >= 2) {
493 elem_id = ptr[0];
494 elem_len = ptr[1];
495 left -= 2;
496 if (elem_len > left) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700497 pe_err("Invalid IEs eid: %d elem_len: %d left: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800498 elem_id, elem_len, left);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530499 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500 return eSIR_FAILURE;
501 }
502 if (!((SIR_MAC_EID_VENDOR == elem_id) &&
503 (memcmp
504 (&ptr[2], SIR_MAC_P2P_OUI,
505 SIR_MAC_P2P_OUI_SIZE) == 0))) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530506 qdf_mem_copy(tempbuf + tempLen, &ptr[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800507 elem_len + 2);
508 tempLen += (elem_len + 2);
509 }
510 left -= elem_len;
511 ptr += (elem_len + 2);
512 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530513 qdf_mem_copy(addIE, tempbuf, tempLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514 *addnIELen = tempLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530515 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516 }
517 return eSIR_SUCCESS;
518}
519
520/**
521 * lim_send_probe_rsp_mgmt_frame() - Send probe response
522 *
523 * @mac_ctx: Handle for mac context
524 * @peer_macaddr: Mac address of requesting peer
525 * @ssid: SSID for response
526 * @n_staid: Station ID, currently unused.
527 * @pe_session: PE session id
528 * @keepalive: Keep alive flag. Currently unused.
529 * @preq_p2pie: P2P IE in incoming probe request
530 *
531 * Builds and sends probe response frame to the requesting peer
532 *
533 * Return: void
534 */
535
536void
537lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
538 tSirMacAddr peer_macaddr,
539 tpAniSSID ssid,
540 short n_staid,
541 uint8_t keepalive,
542 tpPESession pe_session, uint8_t preq_p2pie)
543{
544 tDot11fProbeResponse *frm;
545 tSirRetStatus sir_status;
Hu Wang411e0cc2016-10-28 14:56:01 +0800546 uint32_t cfg, payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800547 tpSirMacMgmtHdr mac_hdr;
548 uint8_t *frame;
Arif Hussainfbf50682016-06-15 12:57:43 -0700549 void *packet = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530550 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551 uint32_t addn_ie_present = false;
552
553 uint16_t addn_ie_len = 0;
554 uint32_t wps_ap = 0, tmp;
555 uint8_t tx_flag = 0;
556 uint8_t *add_ie = NULL;
557 uint8_t *p2p_ie = NULL;
558 uint8_t noalen = 0;
559 uint8_t total_noalen = 0;
560 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
561 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
562 uint8_t sme_sessionid = 0;
563 bool is_vht_enabled = false;
Padma, Santhosh Kumar92234472017-04-19 18:20:02 +0530564 tDot11fIEExtCap extracted_ext_cap = {0};
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530565 bool extracted_ext_cap_flag = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800566
567 /* We don't answer requests in this case*/
Srinivas Girigowda35b00312017-06-27 21:52:03 -0700568 if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800569 return;
570
571 if (NULL == pe_session)
572 return;
573
574 /*
575 * In case when cac timer is running for this SAP session then
576 * avoid sending probe rsp out. It is violation of dfs specification.
577 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530578 if (((pe_session->pePersona == QDF_SAP_MODE) ||
579 (pe_session->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800580 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530581 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582 FL("CAC timer is running, probe response dropped"));
583 return;
584 }
585 sme_sessionid = pe_session->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530586 frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700588 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 return;
590 }
591
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 /*
593 * Fill out 'frm', after which we'll just hand the struct off to
594 * 'dot11f_pack_probe_response'.
595 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530596 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597
598 /*
599 * Timestamp to be updated by TFP, below.
600 *
601 * Beacon Interval:
602 */
603 if (LIM_IS_AP_ROLE(pe_session)) {
604 frm->BeaconInterval.interval =
605 mac_ctx->sch.schObject.gSchBeaconInterval;
606 } else {
607 sir_status = wlan_cfg_get_int(mac_ctx,
608 WNI_CFG_BEACON_INTERVAL, &cfg);
609 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700610 pe_err("Failed to get WNI_CFG_BEACON_INTERVAL (%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 sir_status);
612 goto err_ret;
613 }
614 frm->BeaconInterval.interval = (uint16_t) cfg;
615 }
616
617 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
618 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
619 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
620 &frm->SuppRates, pe_session);
621
622 populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
623 pe_session->currentOperChannel);
624 populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
625
626 if (LIM_IS_AP_ROLE(pe_session)) {
627 if (pe_session->wps_state != SAP_WPS_DISABLED)
628 populate_dot11f_probe_res_wpsi_es(mac_ctx,
629 &frm->WscProbeRes,
630 pe_session);
631 } else {
632 if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
633 &tmp) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700634 pe_err("Failed to cfg get id %d", WNI_CFG_WPS_ENABLE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635
636 wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
637
638 if (wps_ap)
639 populate_dot11f_wsc_in_probe_res(mac_ctx,
640 &frm->WscProbeRes);
641
642 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
643 eLIM_WSC_ENROLL_BEGIN) {
644 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
645 &frm->WscProbeRes);
646 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
647 eLIM_WSC_ENROLL_IN_PROGRESS;
648 }
649
650 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
651 eLIM_WSC_ENROLL_END) {
652 de_populate_dot11f_wsc_registrar_info_in_probe_res(
653 mac_ctx, &frm->WscProbeRes);
654 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
655 eLIM_WSC_ENROLL_NOOP;
656 }
657 }
658
659 populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
660 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
661
662 if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
663 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
664
665 populate_dot11f_ext_supp_rates(mac_ctx,
666 POPULATE_DOT11F_RATES_OPERATIONAL,
667 &frm->ExtSuppRates, pe_session);
668
669 /* Populate HT IEs, when operating in 11n */
670 if (pe_session->htCapability) {
671 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
672 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
673 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 if (pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700675 pe_debug("Populate VHT IE in Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800676 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
677 populate_dot11f_vht_operation(mac_ctx, pe_session,
678 &frm->VHTOperation);
679 /*
680 * we do not support multi users yet.
681 * populate_dot11f_vht_ext_bss_load( mac_ctx,
682 * &frm.VHTExtBssLoad );
683 */
684 is_vht_enabled = true;
685 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800686
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800687 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -0700688 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800689 populate_dot11f_he_caps(mac_ctx, pe_session,
690 &frm->vendor_he_cap);
691 populate_dot11f_he_operation(mac_ctx, pe_session,
692 &frm->vendor_he_op);
693 }
694
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800695 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
696 pe_session);
697
698 if (pe_session->pLimStartBssReq) {
699 populate_dot11f_wpa(mac_ctx,
700 &(pe_session->pLimStartBssReq->rsnIE),
701 &frm->WPA);
702 populate_dot11f_rsn_opaque(mac_ctx,
703 &(pe_session->pLimStartBssReq->rsnIE),
704 &frm->RSNOpaque);
705 }
706
707 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
708 &frm->WMMCaps, pe_session);
709
710#if defined(FEATURE_WLAN_WAPI)
711 if (pe_session->pLimStartBssReq)
712 populate_dot11f_wapi(mac_ctx,
713 &(pe_session->pLimStartBssReq->rsnIE),
714 &frm->WAPI);
715#endif /* defined(FEATURE_WLAN_WAPI) */
716
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717 if (mac_ctx->lim.gpLimRemainOnChanReq)
718 bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
719 sizeof(tSirRemainOnChnReq));
720 else
721 /*
722 * Only use CFG for non-listen mode. This CFG is not working for
723 * concurrency. In listening mode, probe rsp IEs is passed in
724 * the message from SME to PE.
725 */
726 addn_ie_present =
727 (pe_session->addIeParams.probeRespDataLen != 0);
728
729 if (addn_ie_present) {
730
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530731 add_ie = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800732 pe_session->addIeParams.probeRespDataLen);
733 if (NULL == add_ie) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700734 pe_err("add_ie allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735 goto err_ret;
736 }
737
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530738 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739 pe_session->addIeParams.probeRespData_buff,
740 pe_session->addIeParams.probeRespDataLen);
741 addn_ie_len = pe_session->addIeParams.probeRespDataLen;
742
743 if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
744 add_ie, &addn_ie_len, preq_p2pie)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700745 pe_err("Unable to get addn_ie");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800746 goto err_ret;
747 }
748
749 sir_status = lim_strip_extcap_update_struct(mac_ctx,
750 add_ie, &addn_ie_len,
751 &extracted_ext_cap);
752 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700753 pe_debug("Unable to strip off ExtCap IE");
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530754 } else {
755 extracted_ext_cap_flag = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 }
757
758 bytes = bytes + addn_ie_len;
759
760 if (preq_p2pie)
761 p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
762 addn_ie_len);
763
764 if (p2p_ie != NULL) {
765 /* get NoA attribute stream P2P IE */
766 noalen = lim_get_noa_attr_stream(mac_ctx,
767 noa_stream, pe_session);
768 if (noalen != 0) {
769 total_noalen =
770 lim_build_p2p_ie(mac_ctx, &noa_ie[0],
771 &noa_stream[0], noalen);
772 bytes = bytes + total_noalen;
773 }
774 }
775 }
776
Hu Wang411e0cc2016-10-28 14:56:01 +0800777 /*
778 * Extcap IE now support variable length, merge Extcap IE from addn_ie
779 * may change the frame size. Therefore, MUST merge ExtCap IE before
780 * dot11f get packed payload size.
781 */
782 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800783 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
784 true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800785
786 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
787 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700788 pe_err("Probe Response size error (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800789 status);
790 /* We'll fall back on the worst case scenario: */
791 payload = sizeof(tDot11fProbeResponse);
792 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700793 pe_warn("Probe Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +0800794 status);
795 }
796
797 bytes += payload + sizeof(tSirMacMgmtHdr);
798
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530799 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530801 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700802 pe_err("Probe Response allocation failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 goto err_ret;
804 }
805 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530806 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807
808 /* Next, we fill out the buffer descriptor: */
809 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
810 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
811 pe_session->selfMacAddr);
812
813 mac_hdr = (tpSirMacMgmtHdr) frame;
814
815 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
816
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 /* That done, pack the Probe Response: */
818 status =
819 dot11f_pack_probe_response(mac_ctx, frm,
820 frame + sizeof(tSirMacMgmtHdr),
821 payload, &payload);
822 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700823 pe_err("Probe Response pack failure (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 status);
825 goto err_ret;
826 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700827 pe_warn("Probe Response pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800828 }
829
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700830 pe_debug("Sending Probe Response frame to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +0530831 lim_print_mac_addr(mac_ctx, peer_macaddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800832
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800833 if (mac_ctx->lim.gpLimRemainOnChanReq)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530834 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835 mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
836 (mac_ctx->lim.gpLimRemainOnChanReq->length -
837 sizeof(tSirRemainOnChnReq)));
838
839 if (addn_ie_present)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530840 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841 &add_ie[0], addn_ie_len);
842
843 if (noalen != 0) {
844 if (total_noalen >
845 (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700846 pe_err("Not able to insert NoA, total len=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847 total_noalen);
848 goto err_ret;
849 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530850 qdf_mem_copy(&frame[bytes - (total_noalen)],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851 &noa_ie[0], total_noalen);
852 }
853 }
854
855 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +0530856 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
857 (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800858 )
859 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
860
861 /* Queue Probe Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530862 qdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800863 (uint16_t) bytes,
864 TXRX_FRM_802_11_MGMT,
865 ANI_TXDIR_TODS,
866 7, lim_tx_complete, frame, tx_flag,
867 sme_sessionid, 0);
868
869 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530870 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700871 pe_err("Could not send Probe Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872
873 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530874 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530876 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 return;
878
879err_ret:
880 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530881 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882 if (frm != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530883 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884 if (packet != NULL)
885 cds_packet_free((void *)packet);
886 return;
887
888} /* End lim_send_probe_rsp_mgmt_frame. */
889
890void
891lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
892 tSirMacAddr peerMacAddr,
893 tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
894{
895 uint16_t i;
896 uint8_t *pFrame;
897 tDot11fAddTSRequest AddTSReq;
898 tDot11fWMMAddTSRequest WMMAddTSReq;
899 uint32_t nPayload, nBytes, nStatus;
900 tpSirMacMgmtHdr pMacHdr;
901 void *pPacket;
902#ifdef FEATURE_WLAN_ESE
903 uint32_t phyMode;
904#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530905 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800906 uint8_t txFlag = 0;
907 uint8_t smeSessionId = 0;
908
909 if (NULL == psessionEntry) {
910 return;
911 }
912
913 smeSessionId = psessionEntry->smeSessionId;
914
915 if (!pAddTS->wmeTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530916 qdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800917
918 AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
919 AddTSReq.DialogToken.token = pAddTS->dialogToken;
920 AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
921 if (pAddTS->lleTspecPresent) {
922 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
923 } else {
924 populate_dot11f_wmmtspec(&pAddTS->tspec,
925 &AddTSReq.WMMTSPEC);
926 }
927
928 if (pAddTS->lleTspecPresent) {
929 AddTSReq.num_WMMTCLAS = 0;
930 AddTSReq.num_TCLAS = pAddTS->numTclas;
931 for (i = 0; i < pAddTS->numTclas; ++i) {
932 populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
933 &AddTSReq.TCLAS[i]);
934 }
935 } else {
936 AddTSReq.num_TCLAS = 0;
937 AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
938 for (i = 0; i < pAddTS->numTclas; ++i) {
939 populate_dot11f_wmmtclas(pMac,
940 &pAddTS->tclasInfo[i],
941 &AddTSReq.WMMTCLAS[i]);
942 }
943 }
944
945 if (pAddTS->tclasProcPresent) {
946 if (pAddTS->lleTspecPresent) {
947 AddTSReq.TCLASSPROC.processing =
948 pAddTS->tclasProc;
949 AddTSReq.TCLASSPROC.present = 1;
950 } else {
951 AddTSReq.WMMTCLASPROC.version = 1;
952 AddTSReq.WMMTCLASPROC.processing =
953 pAddTS->tclasProc;
954 AddTSReq.WMMTCLASPROC.present = 1;
955 }
956 }
957
958 nStatus =
959 dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
960 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700961 pe_err("Failed to calculate the packed size for an Add TS Request (0x%08x)",
962 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 /* We'll fall back on the worst case scenario: */
964 nPayload = sizeof(tDot11fAddTSRequest);
965 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700966 pe_warn("There were warnings while calculating the packed size for an Add TS Request (0x%08x)",
967 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800968 }
969 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530970 qdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971
972 WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
973 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
974 WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
975
976 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
977 WMMAddTSReq.StatusCode.statusCode = 0;
978
979 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
980#ifdef FEATURE_WLAN_ESE
981 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
982
983 if (phyMode == WNI_CFG_PHY_MODE_11G
984 || phyMode == WNI_CFG_PHY_MODE_11A) {
985 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
986 } else {
987 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
988 }
989 populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
990 &WMMAddTSReq.ESETrafStrmRateSet,
991 sizeof(uint8_t));
992#endif
993 /* fillWmeTspecIE */
994
995 nStatus =
996 dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
997 &nPayload);
998 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -0700999 pe_err("Failed to calculate the packed size for a WMM Add TS Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001000 nStatus);
1001 /* We'll fall back on the worst case scenario: */
1002 nPayload = sizeof(tDot11fAddTSRequest);
1003 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001004 pe_warn("There were warnings while calculating the packed size for a WMM Add TS Request (0x%08x)",
1005 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001006 }
1007 }
1008
1009 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1010
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301011 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301013 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001014 pe_err("Failed to allocate %d bytes for an Add TS Request",
1015 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001016 return;
1017 }
1018 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301019 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001020
1021 /* Next, we fill out the buffer descriptor: */
1022 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1023 SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
1024 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1025
1026 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1027
1028#ifdef WLAN_FEATURE_11W
1029 lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
1030#endif
1031
1032 /* That done, pack the struct: */
1033 if (!pAddTS->wmeTspecPresent) {
1034 nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
1035 pFrame +
1036 sizeof(tSirMacMgmtHdr),
1037 nPayload, &nPayload);
1038 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001039 pe_err("Failed to pack an Add TS Request "
1040 "(0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001041 cds_packet_free((void *)pPacket);
1042 return; /* allocated! */
1043 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001044 pe_warn("There were warnings while packing an Add TS Request (0x%08x)",
1045 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001046 }
1047 } else {
1048 nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
1049 pFrame +
1050 sizeof(tSirMacMgmtHdr),
1051 nPayload, &nPayload);
1052 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001053 pe_err("Failed to pack a WMM Add TS Request (0x%08x)",
1054 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055 cds_packet_free((void *)pPacket);
1056 return; /* allocated! */
1057 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001058 pe_warn("There were warnings while packing a WMM Add TS Request (0x%08x)",
1059 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001060 }
1061 }
1062
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001063 pe_debug("Sending an Add TS Request frame to");
1064 lim_print_mac_addr(pMac, peerMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001065
1066 if ((SIR_BAND_5_GHZ ==
1067 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301068 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1069 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001070 ) {
1071 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1072 }
1073
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301074 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001075 psessionEntry->peSessionId, pMacHdr->fc.subType));
1076
1077 /* Queue Addts Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301078 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001079 TXRX_FRM_802_11_MGMT,
1080 ANI_TXDIR_TODS,
1081 7, lim_tx_complete, pFrame, txFlag,
1082 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301083 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301084 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001085
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001086 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1087 pe_err("Could not send an Add TS Request (%X",
1088 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089} /* End lim_send_addts_req_action_frame. */
1090
1091/**
1092 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
1093 * @mac_ctx: Handle for mac context
1094 * @status_code: Status code for assoc response frame
1095 * @aid: Association ID
1096 * @peer_addr: Mac address of requesting peer
1097 * @subtype: Assoc/Reassoc
1098 * @sta: Pointer to station node
1099 * @pe_session: PE session id.
1100 *
1101 * Builds and sends association response frame to the requesting peer.
1102 *
1103 * Return: void
1104 */
1105
1106void
1107lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
1108 uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
1109 uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
1110{
1111 static tDot11fAssocResponse frm;
1112 uint8_t *frame;
1113 tpSirMacMgmtHdr mac_hdr;
1114 tSirRetStatus sir_status;
1115 uint8_t lle_mode = 0, addts;
1116 tHalBitVal qos_mode, wme_mode;
Hu Wang411e0cc2016-10-28 14:56:01 +08001117 uint32_t payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001118 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301119 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001120 tUpdateBeaconParams beacon_params;
1121 uint8_t tx_flag = 0;
1122 uint32_t addn_ie_len = 0;
1123 uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
1124 tpSirAssocReq assoc_req = NULL;
1125 uint8_t sme_session = 0;
1126 bool is_vht = false;
1127 uint16_t stripoff_len = 0;
1128 tDot11fIEExtCap extracted_ext_cap;
1129 bool extracted_flag = false;
1130#ifdef WLAN_FEATURE_11W
1131 uint32_t retry_int;
1132 uint32_t max_retries;
1133#endif
1134
1135 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001136 pe_err("pe_session is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001137 return;
1138 }
1139
1140 sme_session = pe_session->smeSessionId;
1141
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301142 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001143
1144 limGetQosMode(pe_session, &qos_mode);
1145 limGetWmeMode(pe_session, &wme_mode);
1146
1147 /*
1148 * An Add TS IE is added only if the AP supports it and
1149 * the requesting STA sent a traffic spec.
1150 */
1151 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
1152
1153 frm.Status.status = status_code;
1154
1155 frm.AID.associd = aid | LIM_AID_MASK;
1156
1157 if (NULL == sta) {
1158 populate_dot11f_supp_rates(mac_ctx,
1159 POPULATE_DOT11F_RATES_OPERATIONAL,
1160 &frm.SuppRates, pe_session);
1161 populate_dot11f_ext_supp_rates(mac_ctx,
1162 POPULATE_DOT11F_RATES_OPERATIONAL,
1163 &frm.ExtSuppRates, pe_session);
1164 } else {
1165 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
1166 &frm.ExtSuppRates,
1167 sta->supportedRates.llbRates,
1168 sta->supportedRates.llaRates);
1169 }
1170
1171 if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
1172 eSIR_SUCCESS == status_code) {
1173 assoc_req = (tpSirAssocReq)
1174 pe_session->parsedAssocReq[sta->assocId];
1175 /*
1176 * populate P2P IE in AssocRsp when assocReq from the peer
1177 * includes P2P IE
1178 */
1179 if (assoc_req != NULL && assoc_req->addIEPresent)
1180 populate_dot11_assoc_res_p2p_ie(mac_ctx,
1181 &frm.P2PAssocRes,
1182 assoc_req);
1183 }
1184
1185 if (NULL != sta) {
1186 if (eHAL_SET == qos_mode) {
1187 if (sta->lleEnabled) {
1188 lle_mode = 1;
1189 populate_dot11f_edca_param_set(mac_ctx,
1190 &frm.EDCAParamSet, pe_session);
1191 }
1192 }
1193
1194 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
1195 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
1196 pe_session);
1197
1198 if (sta->wsmEnabled)
1199 populate_dot11f_wmm_caps(&frm.WMMCaps);
1200 }
1201
1202 if (sta->mlmStaContext.htCapability &&
1203 pe_session->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001204 pe_debug("Populate HT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 populate_dot11f_ht_caps(mac_ctx, pe_session,
1206 &frm.HTCaps);
Krunal Sonief3294b2015-06-12 15:12:19 -07001207 /*
1208 * Check the STA capability and
1209 * update the HTCaps accordingly
1210 */
1211 frm.HTCaps.supportedChannelWidthSet = (
1212 sta->htSupportedChannelWidthSet <
1213 pe_session->htSupportedChannelWidthSet) ?
1214 sta->htSupportedChannelWidthSet :
1215 pe_session->htSupportedChannelWidthSet;
1216 if (!frm.HTCaps.supportedChannelWidthSet)
1217 frm.HTCaps.shortGI40MHz = 0;
1218
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001219 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1220 pe_session);
1221 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001222 pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x",
Agrawal Ashishc38e58d2015-09-16 17:17:29 +05301223 frm.HTCaps.supportedChannelWidthSet,
1224 frm.HTCaps.mimoPowerSave,
1225 frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
1226 frm.HTCaps.shortGI40MHz,
1227 frm.HTCaps.dsssCckMode40MHz,
1228 frm.HTCaps.maxRxAMPDUFactor);
1229
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 if (sta->mlmStaContext.vhtCapability &&
1231 pe_session->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001232 pe_debug("Populate VHT IEs in Assoc Response");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233 populate_dot11f_vht_caps(mac_ctx, pe_session,
1234 &frm.VHTCaps);
1235 populate_dot11f_vht_operation(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301236 &frm.VHTOperation);
1237 is_vht = true;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301238 } else {
Tushnim Bhattacharyya3d17def2017-06-19 11:13:43 -07001239 /*
1240 * 2G-AS platform: SAP associates with HT (11n)clients
1241 * as 2x1 in 2G and 2X2 in 5G
1242 * Non-2G-AS platform: SAP associates with HT (11n)
1243 * clients as 2X2 in 2G and 5G
1244 * 5G-AS: DonÂ’t care
1245 */
1246 if (!policy_mgr_is_hw_dbs_2x2_capable(mac_ctx->psoc) &&
1247 frm.HTCaps.present && mac_ctx->hw_dbs_capable &&
1248 mac_ctx->lteCoexAntShare &&
1249 IS_24G_CH(pe_session->currentOperChannel))
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301250 frm.HTCaps.supportedMCSSet[1] = 0;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301251 }
1252 if (pe_session->vhtCapability &&
1253 pe_session->vendor_vht_sap &&
1254 (assoc_req != NULL) &&
1255 assoc_req->vendor_vht_ie.VHTCaps.present) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001256 pe_debug("Populate Vendor VHT IEs in Assoc Rsponse");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301257 frm.vendor_vht_ie.present = 1;
1258 frm.vendor_vht_ie.type =
1259 pe_session->vendor_specific_vht_ie_type;
1260 frm.vendor_vht_ie.sub_type =
1261 pe_session->vendor_specific_vht_ie_sub_type;
1262
1263 frm.vendor_vht_ie.VHTCaps.present = 1;
1264 populate_dot11f_vht_caps(mac_ctx, pe_session,
1265 &frm.vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 is_vht = true;
1267 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1269 pe_session);
1270
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001271 if (lim_is_sta_he_capable(sta) &&
1272 lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001273 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001274 populate_dot11f_he_caps(mac_ctx, pe_session,
1275 &frm.vendor_he_cap);
1276 populate_dot11f_he_operation(mac_ctx, pe_session,
1277 &frm.vendor_he_op);
1278 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279#ifdef WLAN_FEATURE_11W
1280 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1281 if (wlan_cfg_get_int
1282 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1283 &max_retries) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001284 pe_err("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285 else if (wlan_cfg_get_int
1286 (mac_ctx,
1287 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1288 &retry_int) != eSIR_SUCCESS)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001289 pe_err("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 else
1291 populate_dot11f_timeout_interval(mac_ctx,
1292 &frm.TimeoutInterval,
1293 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1294 (max_retries -
1295 sta->pmfSaQueryRetryCount)
1296 * retry_int);
1297 }
1298#endif
Arif Hussain0c816922017-04-06 15:04:44 -07001299
1300 if (LIM_IS_AP_ROLE(pe_session) && sta->non_ecsa_capable)
1301 pe_session->lim_non_ecsa_cap_num++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302 }
1303
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301304 qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305
1306 if (LIM_IS_AP_ROLE(pe_session) &&
1307 (pe_session->gLimProtectionControl !=
1308 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1309 lim_decide_ap_protection(mac_ctx, peer_addr,
1310 &beacon_params, pe_session);
1311
1312 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1313 pe_session);
1314 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1315 pe_session);
1316
1317 /*
1318 * Populate Do11capabilities after updating session with
1319 * Assos req details
1320 */
1321 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1322
1323 beacon_params.bssIdx = pe_session->bssIdx;
1324
1325 /* Send message to HAL about beacon parameter change. */
1326 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1327 && beacon_params.paramChangeBitmap) {
1328 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1329 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331
1332 if (assoc_req != NULL) {
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001333 addn_ie_len = pe_session->addIeParams.assocRespDataLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334
1335 /* Nonzero length indicates Assoc rsp IE available */
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001336 if (addn_ie_len > 0 &&
1337 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
1338 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301339 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 pe_session->addIeParams.assocRespData_buff,
1341 pe_session->addIeParams.assocRespDataLen);
1342
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301343 qdf_mem_set((uint8_t *) &extracted_ext_cap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 sizeof(extracted_ext_cap), 0);
1345
1346 stripoff_len = addn_ie_len;
1347 sir_status =
1348 lim_strip_extcap_update_struct
1349 (mac_ctx, &add_ie[0], &stripoff_len,
1350 &extracted_ext_cap);
1351 if (eSIR_SUCCESS != sir_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001352 pe_debug("strip off extcap IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 } else {
1354 addn_ie_len = stripoff_len;
1355 extracted_flag = true;
1356 }
1357 bytes = bytes + addn_ie_len;
1358 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001359 pe_debug("addn_ie_len: %d for Assoc Resp: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 addn_ie_len, assoc_req->addIEPresent);
1361 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001362
1363 /*
1364 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1365 * may change the frame size. Therefore, MUST merge ExtCap IE before
1366 * dot11f get packed payload size.
1367 */
1368 if (extracted_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001369 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
1370 true);
Hu Wang411e0cc2016-10-28 14:56:01 +08001371
1372 /* Allocate a buffer for this frame: */
1373 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1374 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001375 pe_err("get Association Response size failure (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001376 status);
1377 return;
1378 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001379 pe_warn("get Association Response size warning (0x%08x)",
Hu Wang411e0cc2016-10-28 14:56:01 +08001380 status);
1381 }
1382
1383 bytes += sizeof(tSirMacMgmtHdr) + payload;
1384
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301385 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001386 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301387 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001388 pe_err("cds_packet_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001389 return;
1390 }
1391 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301392 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393
1394 /* Next, we fill out the buffer descriptor: */
1395 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1396 (LIM_ASSOC == subtype) ?
1397 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1398 peer_addr,
1399 pe_session->selfMacAddr);
1400 mac_hdr = (tpSirMacMgmtHdr) frame;
1401
1402 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001404 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1405 frame + sizeof(tSirMacMgmtHdr),
1406 payload, &payload);
1407 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001408 pe_err("Association Response pack failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001409 status);
1410 cds_packet_free((void *)packet);
1411 return;
1412 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001413 pe_warn("Association Response pack warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001414 status);
1415 }
1416
1417 if (subtype == LIM_ASSOC)
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001418 pe_debug("*** Sending Assoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001419 status_code, aid);
1420 else
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001421 pe_debug("*** Sending ReAssoc Resp status %d aid %d to",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422 status_code, aid);
1423
1424 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1425
1426 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301427 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 &add_ie[0], addn_ie_len);
1429
1430 if ((SIR_BAND_5_GHZ ==
1431 lim_get_rf_band(pe_session->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05301432 (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
1433 (pe_session->pePersona == QDF_P2P_GO_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001434 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1435
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301436 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437 pe_session->peSessionId, mac_hdr->fc.subType));
1438 /* Queue Association Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301439 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001440 TXRX_FRM_802_11_MGMT,
1441 ANI_TXDIR_TODS,
1442 7, lim_tx_complete, frame, tx_flag,
1443 sme_session, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301444 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301445 pe_session->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446
1447 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301448 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001449 pe_err("Could not Send Re/AssocRsp, retCode=%X",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301450 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451
1452 /*
1453 * update the ANI peer station count.
1454 * FIXME_PROTECTION : take care of different type of station
1455 * counter inside this function.
1456 */
1457 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1458
1459}
1460
1461void
1462lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1463 tSirMacAddr peer,
1464 uint8_t wmmTspecPresent,
1465 tSirMacTSInfo *pTsinfo,
1466 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1467{
1468 uint8_t *pFrame;
1469 tpSirMacMgmtHdr pMacHdr;
1470 tDot11fDelTS DelTS;
1471 tDot11fWMMDelTS WMMDelTS;
1472 uint32_t nBytes, nPayload, nStatus;
1473 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301474 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475 uint8_t txFlag = 0;
1476 uint8_t smeSessionId = 0;
1477
1478 if (NULL == psessionEntry) {
1479 return;
1480 }
1481
1482 smeSessionId = psessionEntry->smeSessionId;
1483
1484 if (!wmmTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301485 qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001486
1487 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1488 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1489 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1490
1491 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1492 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001493 pe_err("Failed to calculate the packed size for a Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494 /* We'll fall back on the worst case scenario: */
1495 nPayload = sizeof(tDot11fDelTS);
1496 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001497 pe_warn("There were warnings while calculating the packed size for a Del TS (0x%08x)",
1498 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 }
1500 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301501 qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001502
1503 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1504 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1505 WMMDelTS.DialogToken.token = 0;
1506 WMMDelTS.StatusCode.statusCode = 0;
1507 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1508 nStatus =
1509 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1510 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001511 pe_err("Failed to calculate the packed size for a WMM Del TS (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001512 /* We'll fall back on the worst case scenario: */
1513 nPayload = sizeof(tDot11fDelTS);
1514 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001515 pe_warn("There were warnings while calculating the packed size for a WMM Del TS (0x%08x)",
1516 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001517 }
1518 }
1519
1520 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1521
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301522 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1524 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301525 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001526 pe_err("Failed to allocate %d bytes for an Add TS Response",
1527 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 return;
1529 }
1530 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301531 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532
1533 /* Next, we fill out the buffer descriptor: */
1534 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1535 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1536 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1537
1538 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1539
1540#ifdef WLAN_FEATURE_11W
1541 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1542#endif
1543
1544 /* That done, pack the struct: */
1545 if (!wmmTspecPresent) {
1546 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1547 pFrame + sizeof(tSirMacMgmtHdr),
1548 nPayload, &nPayload);
1549 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001550 pe_err("Failed to pack a Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 nStatus);
1552 cds_packet_free((void *)pPacket);
1553 return; /* allocated! */
1554 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001555 pe_warn("There were warnings while packing a Del TS frame (0x%08x)",
1556 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 }
1558 } else {
1559 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1560 pFrame + sizeof(tSirMacMgmtHdr),
1561 nPayload, &nPayload);
1562 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001563 pe_err("Failed to pack a WMM Del TS frame (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001564 nStatus);
1565 cds_packet_free((void *)pPacket);
1566 return; /* allocated! */
1567 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001568 pe_warn("There were warnings while packing a WMM Del TS frame (0x%08x)",
1569 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 }
1571 }
1572
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001573 pe_debug("Sending DELTS REQ (size %d) to ", nBytes);
1574 lim_print_mac_addr(pMac, pMacHdr->da, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001575
1576 if ((SIR_BAND_5_GHZ ==
1577 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301578 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1579 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580 ) {
1581 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1582 }
1583
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301584 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301586 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 TXRX_FRM_802_11_MGMT,
1588 ANI_TXDIR_TODS,
1589 7, lim_tx_complete, pFrame, txFlag,
1590 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301591 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301592 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001593 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301594 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001595 pe_err("Failed to send Del TS (%X)!", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001596
1597} /* End lim_send_delts_req_action_frame. */
1598
1599/**
1600 * lim_send_assoc_req_mgmt_frame() - Send association request
1601 * @mac_ctx: Handle to MAC context
1602 * @mlm_assoc_req: Association request information
1603 * @pe_session: PE session information
1604 *
1605 * Builds and transmits association request frame to AP.
1606 *
1607 * Return: Void
1608 */
1609
1610void
1611lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1612 tLimMlmAssocReq *mlm_assoc_req,
1613 tpPESession pe_session)
1614{
1615 tDot11fAssocRequest *frm;
1616 uint16_t caps;
1617 uint8_t *frame;
1618 tSirRetStatus sir_status;
1619 tLimMlmAssocCnf assoc_cnf;
Hu Wang411e0cc2016-10-28 14:56:01 +08001620 uint32_t bytes = 0, payload, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001621 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1622 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301623 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624 uint16_t add_ie_len;
1625 uint8_t *add_ie;
1626 uint8_t *wps_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 uint8_t power_caps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628 uint8_t tx_flag = 0;
1629 uint8_t sme_sessionid = 0;
1630 bool vht_enabled = false;
1631 tDot11fIEExtCap extr_ext_cap;
1632 bool extr_ext_flag = true;
1633 tpSirMacMgmtHdr mac_hdr;
Hu Wangfbd279d2016-10-31 18:24:34 +08001634 uint32_t ie_offset = 0;
1635 uint8_t *p_ext_cap = NULL;
1636 tDot11fIEExtCap bcn_ext_cap;
1637 uint8_t *bcn_ie = NULL;
1638 uint32_t bcn_ie_len = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001639
1640 if (NULL == pe_session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001641 pe_err("pe_session is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301642 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 return;
1644 }
1645
1646 sme_sessionid = pe_session->smeSessionId;
1647
1648 /* check this early to avoid unncessary operation */
1649 if (NULL == pe_session->pLimJoinReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001650 pe_err("pe_session->pLimJoinReq is NULL");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301651 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 return;
1653 }
1654 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1655 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1656
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301657 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 if (NULL == frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001659 pe_err("Unable to allocate memory");
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301660 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 return;
1662 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001663 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301665 if (add_ie_len && pe_session->is_ext_caps_present) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301666 qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667 0);
1668 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1669 add_ie, &add_ie_len, &extr_ext_cap);
1670 if (eSIR_SUCCESS != sir_status) {
1671 extr_ext_flag = false;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001672 pe_debug("Unable to Stripoff ExtCap IE from Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673 } else {
1674 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1675 extr_ext_cap.bytes;
1676
1677 if (p_ext_cap->interworking_service)
1678 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +08001679 extr_ext_cap.num_bytes =
1680 lim_compute_ext_cap_ie_length(&extr_ext_cap);
1681 extr_ext_flag = (extr_ext_cap.num_bytes > 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001682 }
1683 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001684 pe_debug("No addn IE or peer dosen't support addnIE for Assoc Req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685 extr_ext_flag = false;
1686 }
1687
1688 caps = mlm_assoc_req->capabilityInfo;
1689#if defined(FEATURE_WLAN_WAPI)
1690 /*
1691 * According to WAPI standard:
1692 * 7.3.1.4 Capability Information field
1693 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1694 * in transmitted Association or Reassociation management frames.
1695 * APs ignore the Privacy subfield within received Association and
1696 * Reassociation management frames.
1697 */
1698 if (pe_session->encryptType == eSIR_ED_WPI)
1699 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1700#endif
1701 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1702
1703 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1704 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1705 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1706 &frm->SuppRates, pe_session);
1707
1708 qos_enabled = (pe_session->limQosEnabled) &&
1709 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1710
1711 wme_enabled = (pe_session->limWmeEnabled) &&
1712 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1713
1714 /* We prefer .11e asociations: */
1715 if (qos_enabled)
1716 wme_enabled = false;
1717
1718 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1719 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1720
1721 if (pe_session->lim11hEnable &&
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07001722 pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001723 power_caps = true;
1724
1725 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1726 LIM_ASSOC, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1728 LIM_ASSOC, pe_session);
1729
1730 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001731 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1732 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1733 if (power_caps == false) {
1734 power_caps = true;
1735 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1736 LIM_ASSOC, pe_session);
1737 }
1738 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739 if (qos_enabled)
Naveen Rawatcd118312016-11-22 10:46:21 -08001740 populate_dot11f_qos_caps_station(mac_ctx, pe_session,
1741 &frm->QOSCapsStation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001742
1743 populate_dot11f_ext_supp_rates(mac_ctx,
1744 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1745 pe_session);
1746
Gupta, Kapil54a16992016-01-13 19:34:02 +05301747 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1748 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1750 pe_session);
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08001751
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752 /*
1753 * The join request *should* contain zero or one of the WPA and RSN
1754 * IEs. The payload send along with the request is a
1755 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1756 * typedef struct sSirRSNie
1757 * {
1758 * uint16_t length;
1759 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1760 * } tSirRSNie, *tpSirRSNie;
1761 * So, we should be able to make the following two calls harmlessly,
1762 * since they do nothing if they don't find the given IE in the
1763 * bytestream with which they're provided.
1764 * The net effect of this will be to faithfully transmit whatever
1765 * security IE is in the join request.
1766 * However, if we're associating for the purpose of WPS
1767 * enrollment, and we've been configured to indicate that by
1768 * eliding the WPA or RSN IE, we just skip this:
1769 */
1770 if (add_ie_len && add_ie)
1771 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1772
1773 if (NULL == wps_ie) {
1774 populate_dot11f_rsn_opaque(mac_ctx,
1775 &(pe_session->pLimJoinReq->rsnIE),
1776 &frm->RSNOpaque);
1777 populate_dot11f_wpa_opaque(mac_ctx,
1778 &(pe_session->pLimJoinReq->rsnIE),
1779 &frm->WPAOpaque);
1780#if defined(FEATURE_WLAN_WAPI)
1781 populate_dot11f_wapi_opaque(mac_ctx,
1782 &(pe_session->pLimJoinReq->rsnIE),
1783 &frm->WAPIOpaque);
1784#endif /* defined(FEATURE_WLAN_WAPI) */
1785 }
1786 /* include WME EDCA IE as well */
1787 if (wme_enabled) {
1788 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1789 pe_session, &frm->WMMInfoStation);
1790
1791 if (wsm_enabled)
1792 populate_dot11f_wmm_caps(&frm->WMMCaps);
1793 }
1794
1795 /*
1796 * Populate HT IEs, when operating in 11n and
1797 * when AP is also operating in 11n mode
1798 */
1799 if (pe_session->htCapability &&
1800 mac_ctx->lim.htCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001801 pe_debug("Populate HT Caps in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001803 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1804 &frm->HTCaps, sizeof(frm->HTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001806 pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x",
Agrawal Ashishc38e58d2015-09-16 17:17:29 +05301807 frm->HTCaps.supportedChannelWidthSet,
1808 frm->HTCaps.mimoPowerSave,
1809 frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
1810 frm->HTCaps.shortGI40MHz,
1811 frm->HTCaps.dsssCckMode40MHz,
1812 frm->HTCaps.maxRxAMPDUFactor);
1813
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001814 if (pe_session->vhtCapability &&
1815 pe_session->vhtCapabilityPresentInBeacon) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001816 pe_debug("Populate VHT IEs in Assoc Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001818 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1819 &frm->VHTCaps, sizeof(frm->VHTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820 vht_enabled = true;
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001821 if (pe_session->enableHtSmps &&
1822 !pe_session->supported_nss_1x1) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001823 pe_err("VHT OP mode IE in Assoc Req");
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001824 populate_dot11f_operating_mode(mac_ctx,
1825 &frm->OperatingMode, pe_session);
1826 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001827 }
1828 if (!vht_enabled &&
1829 pe_session->is_vendor_specific_vhtcaps) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001830 pe_debug("Populate Vendor VHT IEs in Assoc Request");
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301831 frm->vendor_vht_ie.present = 1;
1832 frm->vendor_vht_ie.type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001833 pe_session->vendor_specific_vht_ie_type;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301834 frm->vendor_vht_ie.sub_type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835 pe_session->vendor_specific_vht_ie_sub_type;
1836
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301837 frm->vendor_vht_ie.VHTCaps.present = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001838 populate_dot11f_vht_caps(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301839 &frm->vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001840 vht_enabled = true;
1841 }
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301842 if (pe_session->is_ext_caps_present)
1843 populate_dot11f_ext_cap(mac_ctx, vht_enabled,
1844 &frm->ExtCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845
Selvaraj, Sridhara521aab2017-03-25 16:42:34 +05301846 if (mac_ctx->roam.configParam.qcn_ie_support)
1847 populate_dot11f_qcn_ie(&frm->QCN_IE);
1848
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001849 if (lim_is_session_he_capable(pe_session)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07001850 pe_debug("Populate HE IEs");
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001851 populate_dot11f_he_caps(mac_ctx, pe_session,
1852 &frm->vendor_he_cap);
1853 }
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301854
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001855 if (pe_session->pLimJoinReq->is11Rconnection) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001856 tSirBssDescription *bssdescr;
1857
1858 bssdescr = &pe_session->pLimJoinReq->bssDescription;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001859 pe_debug("mdie = %02x %02x %02x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 (unsigned int) bssdescr->mdie[0],
1861 (unsigned int) bssdescr->mdie[1],
1862 (unsigned int) bssdescr->mdie[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001863 populate_mdie(mac_ctx, &frm->MobilityDomain,
1864 pe_session->pLimJoinReq->bssDescription.mdie);
1865 } else {
1866 /* No 11r IEs dont send any MDIE */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001867 pe_debug("MDIE not present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001869
1870#ifdef FEATURE_WLAN_ESE
1871 /*
1872 * ESE Version IE will be included in association request
1873 * when ESE is enabled on DUT through ini and it is also
1874 * advertised by the peer AP to which we are trying to
1875 * associate to.
1876 */
1877 if (pe_session->is_ese_version_ie_present &&
1878 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1879 populate_dot11f_ese_version(&frm->ESEVersion);
1880 /* For ESE Associations fill the ESE IEs */
1881 if (pe_session->isESEconnection &&
1882 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1883#ifndef FEATURE_DISABLE_RM
1884 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1885#endif
1886 }
1887#endif
1888
Hu Wang411e0cc2016-10-28 14:56:01 +08001889 /*
1890 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1891 * may change the frame size. Therefore, MUST merge ExtCap IE before
1892 * dot11f get packed payload size.
1893 */
1894 if (extr_ext_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001895 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
1896
1897 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
1898 if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
1899 ie_offset = DOT11F_FF_TIMESTAMP_LEN +
1900 DOT11F_FF_BEACONINTERVAL_LEN +
1901 DOT11F_FF_CAPABILITIES_LEN;
1902
1903 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
1904 if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
1905 bcn_ie = pe_session->beacon + ie_offset;
1906 bcn_ie_len = pe_session->bcnLen - ie_offset;
1907 p_ext_cap = lim_get_ie_ptr_new(mac_ctx,
1908 bcn_ie,
1909 bcn_ie_len,
1910 DOT11F_EID_EXTCAP,
1911 ONE_BYTE);
1912 lim_update_extcap_struct(mac_ctx, p_ext_cap,
1913 &bcn_ext_cap);
1914 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
1915 false);
1916 }
1917 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001918
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001919 if (eSIR_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
1920 add_ie, &add_ie_len, &frm->SuppOperatingClasses))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001921 pe_debug("Unable to Stripoff supp op classes IE from Assoc Req");
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001922
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001923 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1924 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001925 pe_err("Association Request packet size failure(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001926 status);
1927 /* We'll fall back on the worst case scenario: */
1928 payload = sizeof(tDot11fAssocRequest);
1929 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001930 pe_warn("Association request packet size warning (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001931 status);
1932 }
1933
1934 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1935
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301936 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001937 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301938 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001939 pe_err("Failed to allocate %d bytes", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001940
1941 pe_session->limMlmState = pe_session->limPrevMlmState;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301942 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 pe_session->peSessionId,
1944 pe_session->limMlmState));
1945
1946 /* Update PE session id */
1947 assoc_cnf.sessionId = pe_session->peSessionId;
1948
1949 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1950
1951 cds_packet_free((void *)packet);
1952
1953 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1954 (uint32_t *) &assoc_cnf);
1955
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301956 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001957 }
1958 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301959 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001960
1961 /* Next, we fill out the buffer descriptor: */
1962 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1963 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1964 pe_session->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 /* That done, pack the Assoc Request: */
1966 status = dot11f_pack_assoc_request(mac_ctx, frm,
1967 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1968 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001969 pe_err("Assoc request pack failure (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001970 cds_packet_free((void *)packet);
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05301971 goto end;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001972 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001973 pe_warn("Assoc request pack warning (0x%08x)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974 }
1975
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001976 pe_debug("Sending Association Request length %d to ", bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001977 if (pe_session->assocReq != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301978 qdf_mem_free(pe_session->assocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001980 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 }
1982
1983 if (add_ie_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301984 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985 add_ie, add_ie_len);
1986 payload += add_ie_len;
1987 }
1988
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301989 pe_session->assocReq = qdf_mem_malloc(payload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990 if (NULL == pe_session->assocReq) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07001991 pe_err("Unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001992 } else {
1993 /*
1994 * Store the Assoc request. This is sent to csr/hdd in
1995 * join cnf response.
1996 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301997 qdf_mem_copy(pe_session->assocReq,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998 frame + sizeof(tSirMacMgmtHdr), payload);
1999 pe_session->assocReqLen = payload;
2000 }
2001
2002 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302003 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
2004 || (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002005 )
2006 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2007
Anurag Chouhan6d760662016-02-20 16:05:43 +05302008 if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
2009 pe_session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2011
2012#ifdef FEATURE_WLAN_DIAG_SUPPORT
2013 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
2014 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2015#endif
2016 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302017 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 pe_session->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302019 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002020 wma_tx_frame(mac_ctx, packet,
2021 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
2022 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2023 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302024 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302025 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302026 pe_session->peSessionId, qdf_status));
2027 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002028 pe_err("Failed to send Association Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302029 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002030 /* Pkt will be freed up by the callback */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031 }
yeshwanth sriram guntuka07831012017-06-30 12:26:57 +05302032end:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002033 /* Free up buffer allocated for mlm_assoc_req */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302034 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002035 mlm_assoc_req = NULL;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302036 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002037 return;
2038}
2039
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040/**
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302041 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302042 * @context: pointer to global mac
2043 * @buf: buffer
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302044 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302045 * @params; tx completion params
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302046 *
2047 * Return: This returns QDF_STATUS
2048 */
2049
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302050static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
2051 qdf_nbuf_t buf,
2052 uint32_t tx_complete,
2053 void *params)
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302054{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302055 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
2056
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002057 pe_debug("tx_complete= %d", tx_complete);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302058 if (tx_complete) {
2059 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
2060 /* 'Change' timer for future activations */
2061 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2062 } else {
2063 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2064 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302065
2066 if (buf)
2067 qdf_nbuf_free(buf);
2068
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302069 return QDF_STATUS_SUCCESS;
2070}
2071
2072/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002073 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2074 *
2075 * @mac_ctx: Pointer to Global MAC structure
2076 * @auth_frame: Pointer to Authentication frame structure
2077 * @peer_addr: MAC address of destination peer
2078 * @wep_bit: wep bit in frame control for Authentication frame3
2079 * @session: PE session information
2080 *
2081 * This function is called by lim_process_mlm_messages(). Authentication frame
2082 * is formatted and sent when this function is called.
2083 *
2084 * Return: void
2085 */
2086
2087void
2088lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2089 tpSirMacAuthFrameBody auth_frame,
2090 tSirMacAddr peer_addr,
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302091 uint8_t wep_challenge_len,
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302092 tpPESession session, bool wait_for_ack)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002093{
2094 uint8_t *frame, *body;
2095 uint32_t frame_len = 0, body_len = 0;
2096 tpSirMacMgmtHdr mac_hdr;
2097 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302098 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 uint8_t tx_flag = 0;
2100 uint8_t sme_sessionid = 0;
2101 uint16_t ft_ies_length = 0;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002102 bool challenge_req = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103
2104 if (NULL == session) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002105 pe_err("Error: psession Entry is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106 return;
2107 }
2108
2109 sme_sessionid = session->smeSessionId;
2110
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302111 if (wep_challenge_len) {
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002112 /*
2113 * Auth frame3 to be sent with encrypted framebody
2114 *
2115 * Allocate buffer for Authenticaton frame of size
2116 * equal to management frame header length plus 2 bytes
2117 * each for auth algorithm number, transaction number,
2118 * status code, 128 bytes for challenge text and
2119 * 4 bytes each for IV & ICV.
2120 */
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002121 pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
2122 MAC_ADDR_ARRAY(peer_addr));
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002123
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302124 body_len = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN;
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002125 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002126
2127 goto alloc_packet;
2128 }
2129
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002130 pe_info("Sending Auth seq# %d status %d (%d) wait_for_ack %d to "
2131 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002132 auth_frame->authTransactionSeqNumber,
2133 auth_frame->authStatusCode,
2134 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302135 wait_for_ack,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002136 MAC_ADDR_ARRAY(peer_addr));
2137
2138 switch (auth_frame->authTransactionSeqNumber) {
2139 case SIR_MAC_AUTH_FRAME_1:
2140 /*
2141 * Allocate buffer for Authenticaton frame of size
2142 * equal to management frame header length plus 2 bytes
2143 * each for auth algorithm number, transaction number
2144 * and status code.
2145 */
2146
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002147 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2148 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2151 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2152 0 != session->ftPEContext.pFTPreAuthReq->
2153 ft_ies_length) {
2154 ft_ies_length = session->ftPEContext.
2155 pFTPreAuthReq->ft_ies_length;
2156 frame_len += ft_ies_length;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002157 pe_debug("Auth frame, FTIES length added=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002158 ft_ies_length);
2159 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002160 pe_debug("Auth frame, Does not contain FTIES!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002161 frame_len += (2 + SIR_MDIE_SIZE);
2162 }
2163 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164 break;
2165
2166 case SIR_MAC_AUTH_FRAME_2:
2167 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2168 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2169 (auth_frame->authStatusCode !=
2170 eSIR_MAC_SUCCESS_STATUS))) {
2171 /*
2172 * Allocate buffer for Authenticaton frame of size
2173 * equal to management frame header length plus
2174 * 2 bytes each for auth algorithm number,
2175 * transaction number and status code.
2176 */
2177
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002178 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2179 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180 } else {
2181 /*
2182 * Shared Key algorithm with challenge text
2183 * to be sent.
2184 *
2185 * Allocate buffer for Authenticaton frame of size
2186 * equal to management frame header length plus
2187 * 2 bytes each for auth algorithm number,
2188 * transaction number, status code and 128 bytes
2189 * for challenge text.
2190 */
2191
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002192 challenge_req = true;
2193 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN +
2194 SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2195 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 }
2197 break;
2198
2199 case SIR_MAC_AUTH_FRAME_3:
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002200 /*
2201 * Auth frame3 to be sent without encrypted framebody
2202 *
2203 * Allocate buffer for Authenticaton frame of size equal
2204 * to management frame header length plus 2 bytes each
2205 * for auth algorithm number, transaction number and
2206 * status code.
2207 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002209 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2210 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002211 break;
2212
2213 case SIR_MAC_AUTH_FRAME_4:
2214 /*
2215 * Allocate buffer for Authenticaton frame of size equal
2216 * to management frame header length plus 2 bytes each
2217 * for auth algorithm number, transaction number and
2218 * status code.
2219 */
2220
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002221 body_len = SIR_MAC_AUTH_FRAME_INFO_LEN;
2222 frame_len = sizeof(tSirMacMgmtHdr) + body_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223
2224 break;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002225 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002226 pe_err("Invalid auth transaction seq num");
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002227 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228 } /* switch (auth_frame->authTransactionSeqNumber) */
2229
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002230alloc_packet:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302231 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002232 (void **)&packet);
2233
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302234 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002235 pe_err("call to bufAlloc failed for AUTH frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002236 return;
2237 }
2238
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302239 qdf_mem_zero(frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002240
2241 /* Prepare BD */
2242 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2243 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2244 mac_hdr = (tpSirMacMgmtHdr) frame;
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302245 if (wep_challenge_len)
2246 mac_hdr->fc.wep = LIM_WEP_IN_FC;
2247 else
2248 mac_hdr->fc.wep = LIM_NO_WEP_IN_FC;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002249
2250 /* Prepare BSSId */
Rajeev Kumarcf835a02016-04-15 15:01:31 -07002251 if (LIM_IS_AP_ROLE(session))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302252 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002253 (uint8_t *) session->bssId,
2254 sizeof(tSirMacAddr));
2255
2256 /* Prepare Authentication frame body */
2257 body = frame + sizeof(tSirMacMgmtHdr);
2258
yeshwanth sriram guntuka343a3f22017-07-27 18:30:18 +05302259 if (wep_challenge_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302260 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002261
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002262 pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002263 MAC_ADDR_ARRAY(mac_hdr->da));
2264
2265 } else {
2266 *((uint16_t *) (body)) =
2267 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2268 body += sizeof(uint16_t);
2269 body_len -= sizeof(uint16_t);
2270
2271 *((uint16_t *) (body)) =
2272 sir_swap_u16if_needed(
2273 auth_frame->authTransactionSeqNumber);
2274 body += sizeof(uint16_t);
2275 body_len -= sizeof(uint16_t);
2276
2277 *((uint16_t *) (body)) =
2278 sir_swap_u16if_needed(auth_frame->authStatusCode);
2279 body += sizeof(uint16_t);
2280 body_len -= sizeof(uint16_t);
Krishna Kumaar Natarajan0517c602017-06-02 14:58:21 -07002281
2282 if (challenge_req) {
2283 if (body_len < SIR_MAC_AUTH_CHALLENGE_BODY_LEN) {
2284 qdf_mem_copy(body, (uint8_t *)&auth_frame->type,
2285 body_len);
2286 pe_err("Incomplete challenge info: length: %d, expected: %d",
2287 body_len,
2288 SIR_MAC_AUTH_CHALLENGE_BODY_LEN);
2289 body += body_len;
2290 body_len = 0;
2291 } else {
2292 /* copy challenge IE id, len, challenge text */
2293 *body = auth_frame->type;
2294 body++;
2295 *body = auth_frame->length;
2296 body++;
2297 qdf_mem_copy(body, auth_frame->challengeText,
2298 SIR_MAC_AUTH_CHALLENGE_LENGTH);
2299 body += SIR_MAC_AUTH_CHALLENGE_LENGTH;
2300
2301 body_len -= SIR_MAC_AUTH_CHALLENGE_BODY_LEN;
2302 }
2303 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002305 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2306 (auth_frame->authTransactionSeqNumber ==
2307 SIR_MAC_AUTH_FRAME_1) &&
2308 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2309
2310 if (ft_ies_length > 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302311 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002312 session->ftPEContext.
2313 pFTPreAuthReq->ft_ies,
2314 ft_ies_length);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002315 pe_debug("Auth1 Frame FTIE is: ");
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002316 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2317 QDF_TRACE_LEVEL_DEBUG,
2318 (uint8_t *) body,
2319 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002320 } else if (NULL != session->ftPEContext.
2321 pFTPreAuthReq->pbssDescription) {
2322 /* MDID attr is 54 */
2323 *body = SIR_MDIE_ELEMENT_ID;
2324 body++;
2325 *body = SIR_MDIE_SIZE;
2326 body++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302327 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002328 &session->ftPEContext.pFTPreAuthReq->
2329 pbssDescription->mdie[0],
2330 SIR_MDIE_SIZE);
2331 }
2332 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002334 pe_debug("*** Sending Auth seq# %d status %d (%d) to "
2335 MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002336 auth_frame->authTransactionSeqNumber,
2337 auth_frame->authStatusCode,
2338 (auth_frame->authStatusCode ==
2339 eSIR_MAC_SUCCESS_STATUS),
2340 MAC_ADDR_ARRAY(mac_hdr->da));
2341 }
Srinivas Girigowdab896a562017-03-16 17:41:26 -07002342 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
2343 QDF_TRACE_LEVEL_DEBUG,
2344 frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002345
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302346 if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
2347 (SIR_BAND_5_GHZ == lim_get_rf_band(
2348 session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002349 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302350 else if ((SIR_BAND_5_GHZ ==
2351 lim_get_rf_band(session->currentOperChannel))
2352 || (session->pePersona == QDF_P2P_CLIENT_MODE)
2353 || (session->pePersona == QDF_P2P_GO_MODE))
2354 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002355
Anurag Chouhan6d760662016-02-20 16:05:43 +05302356 if (session->pePersona == QDF_P2P_CLIENT_MODE ||
2357 session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002358 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2359
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302360 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002361 session->peSessionId, mac_hdr->fc.subType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002362
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302363 if (wait_for_ack) {
2364 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
2365 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
2366 (uint16_t)frame_len,
2367 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2368 7, lim_tx_complete, frame,
2369 lim_auth_tx_complete_cnf,
2370 tx_flag, sme_sessionid, false, 0);
2371 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2372 session->peSessionId, qdf_status));
2373 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002374 pe_err("*** Could not send Auth frame, retCode=%X ***",
2375 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302376 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2377 /* Pkt will be freed up by the callback */
2378 }
2379 } else {
2380 /* Queue Authentication frame in high priority WQ */
2381 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
2382 TXRX_FRM_802_11_MGMT,
2383 ANI_TXDIR_TODS, 7, lim_tx_complete,
2384 frame, tx_flag, sme_sessionid, 0);
2385 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2386 session->peSessionId, qdf_status));
2387 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002388 pe_err("*** Could not send Auth frame, retCode=%X ***",
2389 qdf_status);
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302390 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002391 return;
2392}
2393
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302394QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002395{
2396 uint16_t aid;
2397 tpDphHashNode pStaDs;
2398 tLimMlmDeauthReq *pMlmDeauthReq;
2399 tLimMlmDeauthCnf mlmDeauthCnf;
2400 tpPESession psessionEntry;
2401
2402 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
2403 if (pMlmDeauthReq) {
2404 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
2405 lim_deactivate_and_change_timer(pMac,
2406 eLIM_DEAUTH_ACK_TIMER);
2407 }
2408
2409 psessionEntry = pe_find_session_by_session_id(pMac,
2410 pMlmDeauthReq->sessionId);
2411 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002412 pe_err("session does not exist for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413 mlmDeauthCnf.resultCode =
2414 eSIR_SME_INVALID_PARAMETERS;
2415 goto end;
2416 }
2417
2418 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002419 dph_lookup_hash_entry(pMac,
2420 pMlmDeauthReq->peer_macaddr.bytes,
2421 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002422 &psessionEntry->dph.dphHashTable);
2423 if (pStaDs == NULL) {
2424 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2425 goto end;
2426 }
2427
2428 /* / Receive path cleanup with dummy packet */
2429 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2430 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002431 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
2432 (
Abhishek Singhe0680852015-12-16 14:28:48 +05302433#ifdef FEATURE_WLAN_ESE
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002434 (psessionEntry->isESEconnection) ||
Abhishek Singhe0680852015-12-16 14:28:48 +05302435#endif
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002436 (psessionEntry->isFastRoamIniFeatureEnabled) ||
2437 (psessionEntry->is11Rconnection))) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002438 pe_debug("FT Preauth (%p,%d) Deauth rc %d src = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002439 psessionEntry,
2440 psessionEntry->peSessionId,
2441 pMlmDeauthReq->reasonCode,
2442 pMlmDeauthReq->deauthTrigger);
2443 lim_ft_cleanup(pMac, psessionEntry);
2444 } else {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002445 pe_debug("No FT Preauth Session Cleanup in role %d"
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002446#ifdef FEATURE_WLAN_ESE
2447 " isESE %d"
2448#endif
2449 " isLFR %d"
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002450 " is11r %d, Deauth reason %d Trigger = %d",
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002451 psessionEntry->limSystemRole,
2452#ifdef FEATURE_WLAN_ESE
2453 psessionEntry->isESEconnection,
2454#endif
2455 psessionEntry->isFastRoamIniFeatureEnabled,
2456 psessionEntry->is11Rconnection,
Abhishek Singhe0680852015-12-16 14:28:48 +05302457 pMlmDeauthReq->reasonCode,
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002458 pMlmDeauthReq->deauthTrigger);
2459 }
2460 /* Free up buffer allocated for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302461 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
2463 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302464 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002465end:
Anurag Chouhanc5548422016-02-24 18:33:27 +05302466 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002467 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
2469 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
2470 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
2471
2472 /* Free up buffer allocated */
2473 /* for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302474 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002475
2476 lim_post_sme_message(pMac,
2477 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302478 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002479}
2480
2481/**
2482 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
2483 *
2484 * @mac_ctx: Handle to MAC context
2485 *
2486 * Sends disassoc confirmation to SME. Removes disassoc request stored
2487 * in lim.
2488 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302489 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490 */
2491
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302492QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002493{
2494 uint16_t aid;
2495 tpDphHashNode sta_ds;
2496 tLimMlmDisassocCnf disassoc_cnf;
2497 tpPESession pe_session;
2498 tLimMlmDisassocReq *disassoc_req;
2499
2500 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
2501 if (disassoc_req) {
2502 if (tx_timer_running(
2503 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
2504 lim_deactivate_and_change_timer(mac_ctx,
2505 eLIM_DISASSOC_ACK_TIMER);
2506
2507 pe_session = pe_find_session_by_session_id(
2508 mac_ctx, disassoc_req->sessionId);
2509 if (pe_session == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002510 pe_err("No session for given sessionId");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002511 disassoc_cnf.resultCode =
2512 eSIR_SME_INVALID_PARAMETERS;
2513 goto end;
2514 }
2515
2516 sta_ds = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002517 disassoc_req->peer_macaddr.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002518 &pe_session->dph.dphHashTable);
2519 if (sta_ds == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002520 pe_err("StaDs Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002521 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2522 goto end;
2523 }
2524 /* Receive path cleanup with dummy packet */
2525 if (eSIR_SUCCESS !=
2526 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
2527 disassoc_cnf.resultCode =
2528 eSIR_SME_RESOURCES_UNAVAILABLE;
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002529 pe_err("cleanup_rx_path error");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002530 goto end;
2531 }
Deepak Dhamdhere57c95ff2016-09-30 16:44:44 -07002532 if (LIM_IS_STA_ROLE(pe_session) &&
2533 (disassoc_req->reasonCode !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002535 pe_debug("FT Preauth Session (%p %d) Clean up",
2536 pe_session, pe_session->peSessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002537
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002538 /* Delete FT session if there exists one */
2539 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002540 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002541 /* Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302542 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002543 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302544 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002545 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302546 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002547 }
2548end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302549 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002550 (uint8_t *) disassoc_req->peer_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302551 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002552 disassoc_cnf.aid = disassoc_req->aid;
2553 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
2554
2555 /* Update PE session ID */
2556 disassoc_cnf.sessionId = disassoc_req->sessionId;
2557
2558 if (disassoc_req != NULL) {
2559 /* / Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302560 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002561 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
2562 }
2563
2564 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
2565 (uint32_t *) &disassoc_cnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302566 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002567}
2568
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302569QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
2570 qdf_nbuf_t buf,
2571 uint32_t txCompleteSuccess,
2572 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002573{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302574 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2575
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002576 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302577
2578 if (buf)
2579 qdf_nbuf_free(buf);
2580
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002581 return lim_send_disassoc_cnf(pMac);
2582}
2583
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302584QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
2585 qdf_nbuf_t buf,
2586 uint32_t txCompleteSuccess,
2587 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002588{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302589 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2590
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002591 pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302592
2593 if (buf)
2594 qdf_nbuf_free(buf);
2595
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002596 return lim_send_deauth_cnf(pMac);
2597}
2598
2599/**
2600 * \brief This function is called to send Disassociate frame.
2601 *
2602 *
2603 * \param pMac Pointer to Global MAC structure
2604 *
2605 * \param nReason Indicates the reason that need to be sent in
2606 * Disassociation frame
2607 *
2608 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
2609 * sent
2610 *
2611 *
2612 */
2613
2614void
2615lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
2616 uint16_t nReason,
2617 tSirMacAddr peer,
2618 tpPESession psessionEntry, bool waitForAck)
2619{
2620 tDot11fDisassociation frm;
2621 uint8_t *pFrame;
2622 tpSirMacMgmtHdr pMacHdr;
2623 uint32_t nBytes, nPayload, nStatus;
2624 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302625 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002626 uint8_t txFlag = 0;
2627 uint32_t val = 0;
2628 uint8_t smeSessionId = 0;
2629 if (NULL == psessionEntry) {
2630 return;
2631 }
2632
2633 /*
2634 * In case when cac timer is running for this SAP session then
2635 * avoid sending disassoc out. It is violation of dfs specification.
2636 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302637 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2638 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002639 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302640 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002641 FL
2642 ("CAC timer is running, drop disassoc from going out"));
2643 return;
2644 }
2645 smeSessionId = psessionEntry->smeSessionId;
2646
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302647 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648
2649 frm.Reason.code = nReason;
2650
2651 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
2652 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002653 pe_err("Failed to calculate the packed size for a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002654 nStatus);
2655 /* We'll fall back on the worst case scenario: */
2656 nPayload = sizeof(tDot11fDisassociation);
2657 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002658 pe_warn("There were warnings while calculating the packed size for a Disassociation (0x%08x)",
2659 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002660 }
2661
2662 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2663
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302664 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002665 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302666 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002667 pe_err("Failed to allocate %d bytes for a Disassociation",
2668 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002669 return;
2670 }
2671 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302672 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002673
2674 /* Next, we fill out the buffer descriptor: */
2675 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2676 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
2677 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2678
2679 /* Prepare the BSSID */
2680 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2681
2682#ifdef WLAN_FEATURE_11W
2683 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2684#endif
2685
2686 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
2687 sizeof(tSirMacMgmtHdr),
2688 nPayload, &nPayload);
2689 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002690 pe_err("Failed to pack a Disassociation (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002691 nStatus);
2692 cds_packet_free((void *)pPacket);
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002693 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002694 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002695 pe_warn("There were warnings while packing a Disassociation (0x%08x)",
2696 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002697 }
2698
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002699 pe_debug("***Sessionid %d Sending Disassociation frame with "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002700 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002701 MAC_ADDRESS_STR, psessionEntry->peSessionId, nReason,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002702 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
2703 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2704
2705 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302706 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2707 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002708 ) {
2709 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2710 }
2711
Sushant Kaushik46556062015-12-02 16:57:47 +05302712 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713
2714 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302715 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002716 psessionEntry->peSessionId,
2717 pMacHdr->fc.subType));
2718 /* Queue Disassociation frame in high priority WQ */
2719 /* get the duration from the request */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302720 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002721 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2722 TXRX_FRM_802_11_MGMT,
2723 ANI_TXDIR_TODS, 7, lim_tx_complete,
2724 pFrame, lim_disassoc_tx_complete_cnf,
2725 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302726 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302727 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302728 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729
2730 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2731
2732 if (tx_timer_change
2733 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
2734 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002735 pe_err("Unable to change Disassoc ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002736 return;
2737 } else if (TX_SUCCESS !=
2738 tx_timer_activate(&pMac->lim.limTimers.
2739 gLimDisassocAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002740 pe_err("Unable to activate Disassoc ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002741 lim_deactivate_and_change_timer(pMac,
2742 eLIM_DISASSOC_ACK_TIMER);
2743 return;
2744 }
2745 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302746 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747 psessionEntry->peSessionId,
2748 pMacHdr->fc.subType));
2749 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302750 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002751 TXRX_FRM_802_11_MGMT,
2752 ANI_TXDIR_TODS,
2753 7,
2754 lim_tx_complete, pFrame, txFlag,
2755 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302756 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302757 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302758 psessionEntry->peSessionId, qdf_status));
2759 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002760 pe_err("Failed to send Disassociation (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302761 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762 /* Pkt will be freed up by the callback */
2763 }
2764 }
2765} /* End lim_send_disassoc_mgmt_frame. */
2766
2767/**
2768 * \brief This function is called to send a Deauthenticate frame
2769 *
2770 *
2771 * \param pMac Pointer to global MAC structure
2772 *
2773 * \param nReason Indicates the reason that need to be sent in the
2774 * Deauthenticate frame
2775 *
2776 * \param peeer address of the STA to which the frame is to be sent
2777 *
2778 *
2779 */
2780
2781void
2782lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
2783 uint16_t nReason,
2784 tSirMacAddr peer,
2785 tpPESession psessionEntry, bool waitForAck)
2786{
2787 tDot11fDeAuth frm;
2788 uint8_t *pFrame;
2789 tpSirMacMgmtHdr pMacHdr;
2790 uint32_t nBytes, nPayload, nStatus;
2791 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302792 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002793 uint8_t txFlag = 0;
2794 uint32_t val = 0;
2795#ifdef FEATURE_WLAN_TDLS
2796 uint16_t aid;
2797 tpDphHashNode pStaDs;
2798#endif
2799 uint8_t smeSessionId = 0;
2800
2801 if (NULL == psessionEntry) {
2802 return;
2803 }
2804
2805 /*
2806 * In case when cac timer is running for this SAP session then
2807 * avoid deauth frame out. It is violation of dfs specification.
2808 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302809 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2810 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302812 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002813 FL
2814 ("CAC timer is running, drop the deauth from going out"));
2815 return;
2816 }
2817 smeSessionId = psessionEntry->smeSessionId;
2818
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302819 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002820
2821 frm.Reason.code = nReason;
2822
2823 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
2824 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002825 pe_err("Failed to calculate the packed size for a De-Authentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002826 nStatus);
2827 /* We'll fall back on the worst case scenario: */
2828 nPayload = sizeof(tDot11fDeAuth);
2829 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002830 pe_warn("There were warnings while calculating the packed size for a De-Authentication (0x%08x)",
2831 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002832 }
2833
2834 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2835
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302836 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002837 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302838 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002839 pe_err("Failed to allocate %d bytes for a De-Authentication",
2840 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002841 return;
2842 }
2843 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302844 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002845
2846 /* Next, we fill out the buffer descriptor: */
2847 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2848 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
2849 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2850
2851 /* Prepare the BSSID */
2852 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2853
2854#ifdef WLAN_FEATURE_11W
2855 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2856#endif
2857
2858 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
2859 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
2860 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002861 pe_err("Failed to pack a DeAuthentication (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002862 nStatus);
2863 cds_packet_free((void *)pPacket);
2864 return;
2865 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002866 pe_warn("There were warnings while packing a De-Authentication (0x%08x)",
2867 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002868 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002869 pe_debug("***Sessionid %d Sending Deauth frame with "
2870 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
2871 " ,From " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002872 psessionEntry->peSessionId, nReason, waitForAck,
2873 MAC_ADDR_ARRAY(pMacHdr->da),
2874 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2875
2876 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302877 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2878 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002879 ) {
2880 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2881 }
2882
Sushant Kaushik46556062015-12-02 16:57:47 +05302883 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002884#ifdef FEATURE_WLAN_TDLS
2885 pStaDs =
2886 dph_lookup_hash_entry(pMac, peer, &aid,
2887 &psessionEntry->dph.dphHashTable);
2888#endif
2889
2890 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302891 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002892 psessionEntry->peSessionId,
2893 pMacHdr->fc.subType));
2894 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302895 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2897 TXRX_FRM_802_11_MGMT,
2898 ANI_TXDIR_TODS, 7, lim_tx_complete,
2899 pFrame, lim_deauth_tx_complete_cnf,
2900 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302901 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302902 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302903 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002904 /* Pkt will be freed up by the callback lim_tx_complete */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302905 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002906 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302907 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002908
2909 /* Call lim_process_deauth_ack_timeout which will send
2910 * DeauthCnf for this frame
2911 */
2912 lim_process_deauth_ack_timeout(pMac);
2913 return;
2914 }
2915
2916 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2917
2918 if (tx_timer_change
2919 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
2920 != TX_SUCCESS) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002921 pe_err("Unable to change Deauth ack Timer val");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002922 return;
2923 } else if (TX_SUCCESS !=
2924 tx_timer_activate(&pMac->lim.limTimers.
2925 gLimDeauthAckTimer)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002926 pe_err("Unable to activate Deauth ack Timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002927 lim_deactivate_and_change_timer(pMac,
2928 eLIM_DEAUTH_ACK_TIMER);
2929 return;
2930 }
2931 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302932 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002933 psessionEntry->peSessionId,
2934 pMacHdr->fc.subType));
2935#ifdef FEATURE_WLAN_TDLS
2936 if ((NULL != pStaDs)
2937 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
2938 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302939 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002940 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2941 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
2942 7, lim_tx_complete, pFrame, txFlag,
2943 smeSessionId, 0);
2944 } else {
2945#endif
2946 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302947 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002948 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
2949 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2950 7, lim_tx_complete, pFrame, txFlag,
2951 smeSessionId, 0);
2952#ifdef FEATURE_WLAN_TDLS
2953 }
2954#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302955 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302956 psessionEntry->peSessionId, qdf_status));
2957 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07002958 pe_err("Failed to send De-Authentication (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302959 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002960 /* Pkt will be freed up by the callback */
2961 }
2962 }
2963
2964} /* End lim_send_deauth_mgmt_frame. */
2965
2966#ifdef ANI_SUPPORT_11H
2967/**
2968 * \brief Send a Measurement Report Action frame
2969 *
2970 *
2971 * \param pMac Pointer to the global MAC structure
2972 *
2973 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
2974 *
2975 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
2976 *
2977 *
2978 */
2979
2980tSirRetStatus
2981lim_send_meas_report_frame(tpAniSirGlobal pMac,
2982 tpSirMacMeasReqActionFrame pMeasReqFrame,
2983 tSirMacAddr peer, tpPESession psessionEntry)
2984{
2985 tDot11fMeasurementReport frm;
2986 uint8_t *pFrame;
2987 tSirRetStatus nSirStatus;
2988 tpSirMacMgmtHdr pMacHdr;
2989 uint32_t nBytes, nPayload, nStatus;
2990 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302991 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002992
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302993 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002994
2995 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
2996 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
2997 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
2998
2999 switch (pMeasReqFrame->measReqIE.measType) {
3000 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3001 nSirStatus =
3002 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3003 &frm.MeasurementReport);
3004 break;
3005 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3006 nSirStatus =
3007 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3008 &frm.MeasurementReport);
3009 break;
3010 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3011 nSirStatus =
3012 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3013 &frm.MeasurementReport);
3014 break;
3015 default:
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003016 pe_err("Unknown measurement type %d in limSen"
3017 "dMeasReportFrame",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003018 pMeasReqFrame->measReqIE.measType);
3019 return eSIR_FAILURE;
3020 }
3021
3022 if (eSIR_SUCCESS != nSirStatus)
3023 return eSIR_FAILURE;
3024
3025 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3026 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003027 pe_err("Failed to calculate the packed size for a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003028 nStatus);
3029 /* We'll fall back on the worst case scenario: */
3030 nPayload = sizeof(tDot11fMeasurementReport);
3031 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003032 pe_warn("There were warnings while calculating the packed size for a Measurement Report (0x%08x)",
3033 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003034 }
3035
3036 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3037
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303038 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003039 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3040 (uint16_t) nBytes, (void **)&pFrame,
3041 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303042 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003043 pe_err("Failed to allocate %d bytes for a "
3044 "De-Authentication", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003045 return eSIR_FAILURE;
3046 }
3047 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303048 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003049
3050 /* Next, we fill out the buffer descriptor: */
3051 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3052 SIR_MAC_MGMT_ACTION, peer);
3053 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3054
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303055 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003056
3057#ifdef WLAN_FEATURE_11W
3058 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3059#endif
3060
3061 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3062 sizeof(tSirMacMgmtHdr),
3063 nPayload, &nPayload);
3064 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003065 pe_err("Failed to pack a Measurement Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003066 nStatus);
3067 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3068 (void *)pFrame, (void *)pPacket);
3069 return eSIR_FAILURE; /* allocated! */
3070 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003071 pe_warn("There were warnings while packing a Measurement Report (0x%08x)",
3072 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003073 }
3074
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303075 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003076 ((psessionEntry) ? psessionEntry->
3077 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303078 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003079 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3080 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3081 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303082 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303083 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003084 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303085 qdf_status));
3086 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003087 pe_err("Failed to send a Measurement Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303088 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003089 /* Pkt will be freed up by the callback */
3090 return eSIR_FAILURE; /* just allocated... */
3091 }
3092
3093 return eSIR_SUCCESS;
3094
3095} /* End lim_send_meas_report_frame. */
3096
3097/**
3098 * \brief Send a TPC Request Action frame
3099 *
3100 *
3101 * \param pMac Pointer to the global MAC datastructure
3102 *
3103 * \param peer MAC address to which the frame should be sent
3104 *
3105 *
3106 */
3107
3108void
3109lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3110 tSirMacAddr peer, tpPESession psessionEntry)
3111{
3112 tDot11fTPCRequest frm;
3113 uint8_t *pFrame;
3114 tpSirMacMgmtHdr pMacHdr;
3115 uint32_t nBytes, nPayload, nStatus;
3116 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303117 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003118
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303119 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003120
3121 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3122 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3123 frm.DialogToken.token = 1;
3124 frm.TPCRequest.present = 1;
3125
3126 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3127 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003128 pe_err("Failed to calculate the packed size for a TPC Request (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003129 /* We'll fall back on the worst case scenario: */
3130 nPayload = sizeof(tDot11fTPCRequest);
3131 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003132 pe_warn("There were warnings while calculating the packed size for a TPC Request (0x%08x)",
3133 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003134 }
3135
3136 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3137
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303138 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003139 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3140 (uint16_t) nBytes, (void **)&pFrame,
3141 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303142 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003143 pe_err("Failed to allocate %d bytes for a TPC"
3144 " Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003145 return;
3146 }
3147 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303148 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003149
3150 /* Next, we fill out the buffer descriptor: */
3151 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3152 SIR_MAC_MGMT_ACTION, peer);
3153 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3154
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303155 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003156
3157#ifdef WLAN_FEATURE_11W
3158 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3159#endif
3160
3161 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3162 sizeof(tSirMacMgmtHdr),
3163 nPayload, &nPayload);
3164 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003165 pe_err("Failed to pack a TPC Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003166 nStatus);
3167 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3168 (void *)pFrame, (void *)pPacket);
3169 return; /* allocated! */
3170 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003171 pe_warn("There were warnings while packing a TPC Request (0x%08x)",
3172 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003173 }
3174
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303175 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003176 ((psessionEntry) ? psessionEntry->
3177 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303178 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003179 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3180 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3181 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303182 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303183 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003184 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303185 qdf_status));
3186 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003187 pe_err("Failed to send a TPC Request (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303188 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003189 /* Pkt will be freed up by the callback */
3190 }
3191
3192} /* End lim_send_tpc_request_frame. */
3193
3194/**
3195 * \brief Send a TPC Report Action frame
3196 *
3197 *
3198 * \param pMac Pointer to the global MAC datastructure
3199 *
3200 * \param pTpcReqFrame Pointer to the received TPC Request
3201 *
3202 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3203 *
3204 *
3205 */
3206
3207tSirRetStatus
3208lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3209 tpSirMacTpcReqActionFrame pTpcReqFrame,
3210 tSirMacAddr peer, tpPESession psessionEntry)
3211{
3212 tDot11fTPCReport frm;
3213 uint8_t *pFrame;
3214 tpSirMacMgmtHdr pMacHdr;
3215 uint32_t nBytes, nPayload, nStatus;
3216 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303217 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003218
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303219 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003220
3221 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3222 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3223 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3224
3225 frm.TPCReport.tx_power = 0;
3226 frm.TPCReport.link_margin = 0;
3227 frm.TPCReport.present = 1;
3228
3229 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3230 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003231 pe_err("Failed to calculate the packed size for a TPC Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003232 /* We'll fall back on the worst case scenario: */
3233 nPayload = sizeof(tDot11fTPCReport);
3234 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003235 pe_warn("There were warnings while calculating the packed size for a TPC Report (0x%08x)",
3236 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003237 }
3238
3239 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3240
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303241 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003242 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3243 (uint16_t) nBytes, (void **)&pFrame,
3244 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303245 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003246 pe_err("Failed to allocate %d bytes for a TPC"
3247 " Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003248 return eSIR_FAILURE;
3249 }
3250 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303251 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003252
3253 /* Next, we fill out the buffer descriptor: */
3254 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3255 SIR_MAC_MGMT_ACTION, peer);
3256
3257 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3258
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303259 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003260
3261#ifdef WLAN_FEATURE_11W
3262 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3263#endif
3264
3265 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3266 sizeof(tSirMacMgmtHdr),
3267 nPayload, &nPayload);
3268 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003269 pe_err("Failed to pack a TPC Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003270 nStatus);
3271 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3272 (void *)pFrame, (void *)pPacket);
3273 return eSIR_FAILURE; /* allocated! */
3274 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003275 pe_warn("There were warnings while packing a TPC Report (0x%08x)",
3276 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303278 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279 ((psessionEntry) ? psessionEntry->
3280 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303281 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003282 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3283 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3284 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303285 MTRACE(qdf_trace
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003286 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3287 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3288 qdf_status));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303289 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003290 pe_err("Failed to send a TPC Report (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303291 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003292 /* Pkt will be freed up by the callback */
3293 return eSIR_FAILURE; /* just allocated... */
3294 }
3295
3296 return eSIR_SUCCESS;
3297
3298} /* End lim_send_tpc_report_frame. */
3299#endif /* ANI_SUPPORT_11H */
3300
3301/**
3302 * \brief Send a Channel Switch Announcement
3303 *
3304 *
3305 * \param pMac Pointer to the global MAC datastructure
3306 *
3307 * \param peer MAC address to which this frame will be sent
3308 *
3309 * \param nMode
3310 *
3311 * \param nNewChannel
3312 *
3313 * \param nCount
3314 *
3315 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3316 *
3317 *
3318 */
3319
3320tSirRetStatus
3321lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3322 tSirMacAddr peer,
3323 uint8_t nMode,
3324 uint8_t nNewChannel,
3325 uint8_t nCount, tpPESession psessionEntry)
3326{
3327 tDot11fChannelSwitch frm;
3328 uint8_t *pFrame;
3329 tpSirMacMgmtHdr pMacHdr;
3330 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3331 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303332 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003333 uint8_t txFlag = 0;
3334
3335 uint8_t smeSessionId = 0;
3336
3337 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003338 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003339 return eSIR_FAILURE;
3340 }
3341 smeSessionId = psessionEntry->smeSessionId;
3342
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303343 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003344
3345 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3346 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
3347 frm.ChanSwitchAnn.switchMode = nMode;
3348 frm.ChanSwitchAnn.newChannel = nNewChannel;
3349 frm.ChanSwitchAnn.switchCount = nCount;
3350 frm.ChanSwitchAnn.present = 1;
3351
3352 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
3353 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003354 pe_err("Failed to calculate the packed size for a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003355 nStatus);
3356 /* We'll fall back on the worst case scenario: */
3357 nPayload = sizeof(tDot11fChannelSwitch);
3358 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003359 pe_warn("There were warnings while calculating the packed size for a Channel Switch (0x%08x)",
3360 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003361 }
3362
3363 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3364
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303365 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003366 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3367 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303368 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003369 pe_err("Failed to allocate %d bytes for a TPC Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003370 return eSIR_FAILURE;
3371 }
3372 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303373 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003374
3375 /* Next, we fill out the buffer descriptor: */
3376 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3377 SIR_MAC_MGMT_ACTION, peer,
3378 psessionEntry->selfMacAddr);
3379 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303380 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003381 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3382
3383#ifdef WLAN_FEATURE_11W
3384 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3385#endif
3386
3387 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
3388 sizeof(tSirMacMgmtHdr),
3389 nPayload, &nPayload);
3390 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003391 pe_err("Failed to pack a Channel Switch (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003392 nStatus);
3393 cds_packet_free((void *)pPacket);
3394 return eSIR_FAILURE; /* allocated! */
3395 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003396 pe_warn("There were warnings while packing a Channel Switch (0x%08x)",
3397 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003398 }
3399
3400 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303401 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3402 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003403 ) {
3404 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3405 }
3406
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303407 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003408 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303409 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410 TXRX_FRM_802_11_MGMT,
3411 ANI_TXDIR_TODS,
3412 7, lim_tx_complete, pFrame, txFlag,
3413 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303414 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303415 psessionEntry->peSessionId, qdf_status));
3416 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003417 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303418 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003419 /* Pkt will be freed up by the callback */
3420 return eSIR_FAILURE;
3421 }
3422
3423 return eSIR_SUCCESS;
3424
3425} /* End lim_send_channel_switch_mgmt_frame. */
3426
Abhishek Singh518323d2015-10-19 17:42:01 +05303427/**
3428 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
3429 * action frame over the air .
3430 * @mac_ctx: pointer to global mac structure
3431 * @peer: Destination mac.
3432 * @mode: channel switch mode
3433 * @new_op_class: new op class
3434 * @new_channel: new channel to switch
3435 * @count: channel switch count
3436 *
3437 * This function is called to send ECSA frame.
3438 *
3439 * Return: success if frame is sent else return failure
3440 */
3441
3442tSirRetStatus
3443lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
3444 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
3445 uint8_t new_channel, uint8_t count, tpPESession session_entry)
3446{
3447 tDot11fext_channel_switch_action_frame frm;
3448 uint8_t *frame;
3449 tpSirMacMgmtHdr mac_hdr;
3450 uint32_t num_bytes, n_payload, status;
3451 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303452 QDF_STATUS qdf_status;
Abhishek Singh518323d2015-10-19 17:42:01 +05303453 uint8_t txFlag = 0;
3454 uint8_t sme_session_id = 0;
3455
3456 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003457 pe_err("Session entry is NULL!!!");
Abhishek Singh518323d2015-10-19 17:42:01 +05303458 return eSIR_FAILURE;
3459 }
3460
3461 sme_session_id = session_entry->smeSessionId;
3462
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303463 qdf_mem_set(&frm, sizeof(frm), 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303464
3465 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
3466 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
3467
3468 frm.ext_chan_switch_ann_action.switch_mode = mode;
3469 frm.ext_chan_switch_ann_action.op_class = new_op_class;
3470 frm.ext_chan_switch_ann_action.new_channel = new_channel;
3471 frm.ext_chan_switch_ann_action.switch_count = count;
3472
3473
3474 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
3475 &frm, &n_payload);
3476 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003477 pe_err("Failed to get packed size for Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303478 status);
3479 /* We'll fall back on the worst case scenario*/
3480 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
3481 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003482 pe_warn("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)",
Abhishek Singh518323d2015-10-19 17:42:01 +05303483 status);
3484 }
3485
3486 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3487
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303488 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303489 (void **) &frame, (void **) &packet);
3490
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303491 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003492 pe_err("Failed to allocate %d bytes for a Ext Channel Switch",
Abhishek Singh518323d2015-10-19 17:42:01 +05303493 num_bytes);
3494 return eSIR_FAILURE;
3495 }
3496
3497 /* Paranoia*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303498 qdf_mem_set(frame, num_bytes, 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303499
3500 /* Next, we fill out the buffer descriptor */
3501 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3502 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3503 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303504 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Abhishek Singh518323d2015-10-19 17:42:01 +05303505 (uint8_t *) session_entry->bssId,
3506 sizeof(tSirMacAddr));
3507
3508 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
3509 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3510 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003511 pe_err("Failed to pack a Channel Switch 0x%08x", status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303512 cds_packet_free((void *)packet);
3513 return eSIR_FAILURE;
3514 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003515 pe_warn("There were warnings while packing a Channel Switch 0x%08x",
Abhishek Singh518323d2015-10-19 17:42:01 +05303516 status);
3517 }
3518
3519 if ((SIR_BAND_5_GHZ ==
3520 lim_get_rf_band(session_entry->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05303521 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3522 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303523 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3524 }
3525
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003526 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 +05303527 MAC_ADDR_ARRAY(mac_hdr->da),
3528 frm.ext_chan_switch_ann_action.switch_count,
3529 frm.ext_chan_switch_ann_action.switch_mode,
3530 frm.ext_chan_switch_ann_action.new_channel,
3531 frm.ext_chan_switch_ann_action.op_class);
3532
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303533 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Abhishek Singh518323d2015-10-19 17:42:01 +05303534 session_entry->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303535 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303536 TXRX_FRM_802_11_MGMT,
3537 ANI_TXDIR_TODS,
3538 7,
3539 lim_tx_complete, frame,
3540 txFlag, sme_session_id, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303541 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303542 session_entry->peSessionId, qdf_status));
3543 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003544 pe_err("Failed to send a Ext Channel Switch %X!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303545 qdf_status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303546 /* Pkt will be freed up by the callback */
3547 return eSIR_FAILURE;
3548 }
3549 return eSIR_SUCCESS;
3550} /* End lim_send_extended_chan_switch_action_frame */
3551
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303552
3553/**
3554 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
3555 * sent over the air
3556 *
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303557 * @context: pointer to global mac
3558 * @buf: buffer
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303559 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303560 * @params: tx completion params
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303561 *
3562 * Return: This returns QDF_STATUS
3563 */
3564
3565static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303566 void *context,
3567 qdf_nbuf_t buf,
3568 uint32_t tx_complete,
3569 void *params)
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303570{
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003571 pe_debug("tx_complete: %d", tx_complete);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303572 return QDF_STATUS_SUCCESS;
3573}
3574
3575/**
3576 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
3577 * p2p oper chan change confirm action frame
3578 * @mac_ctx: pointer to global mac structure
3579 * @peer: Destination mac.
3580 * @session_entry: session entry
3581 *
3582 * This function is called to send p2p oper chan change confirm action frame.
3583 *
3584 * Return: success if frame is sent else return failure
3585 */
3586
3587tSirRetStatus
3588lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
3589 tSirMacAddr peer, tpPESession session_entry)
3590{
3591 tDot11fp2p_oper_chan_change_confirm frm;
3592 uint8_t *frame;
3593 tpSirMacMgmtHdr mac_hdr;
3594 uint32_t num_bytes, n_payload, status;
3595 void *packet;
3596 QDF_STATUS qdf_status;
3597 uint8_t tx_flag = 0;
3598 uint8_t sme_session_id = 0;
3599
3600 if (session_entry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003601 pe_err("Session entry is NULL!!!");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303602 return eSIR_FAILURE;
3603 }
3604
3605 sme_session_id = session_entry->smeSessionId;
3606
3607 qdf_mem_set(&frm, sizeof(frm), 0);
3608
3609 frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
3610
3611 qdf_mem_copy(frm.p2p_action_oui.oui_data,
3612 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
3613 frm.p2p_action_subtype.subtype = 0x04;
3614 frm.DialogToken.token = 0x0;
3615
3616 if (session_entry->htCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003617 pe_debug("Populate HT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303618 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
3619 }
3620
3621 if (session_entry->vhtCapability) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003622 pe_debug("Populate VHT Caps in Assoc Request");
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303623 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
3624 populate_dot11f_operating_mode(mac_ctx,
3625 &frm.OperatingMode, session_entry);
3626 }
3627
3628 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
3629 &frm, &n_payload);
3630 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003631 pe_err("Failed to get packed size 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303632 /* We'll fall back on the worst case scenario*/
3633 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
3634 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003635 pe_warn("There were warnings while calculating the packed size (0x%08x)",
3636 status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303637 }
3638
3639 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3640
3641 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
3642 (void **) &frame, (void **) &packet);
3643
3644 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003645 pe_err("Failed to allocate %d bytes", num_bytes);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303646 return eSIR_FAILURE;
3647 }
3648
3649 qdf_mem_set(frame, num_bytes, 0);
3650
3651 /* Next, fill out the buffer descriptor */
3652 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3653 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3654 mac_hdr = (tpSirMacMgmtHdr) frame;
3655 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
3656 (uint8_t *) session_entry->bssId,
3657 sizeof(tSirMacAddr));
3658
3659 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
3660 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3661 if (DOT11F_FAILED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003662 pe_err("Failed to pack 0x%08x", status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303663 cds_packet_free((void *)packet);
3664 return eSIR_FAILURE;
3665 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003666 pe_warn("There were warnings while packing 0x%08x",
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303667 status);
3668 }
3669
3670 if ((SIR_BAND_5_GHZ ==
3671 lim_get_rf_band(session_entry->currentOperChannel)) ||
3672 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3673 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
3674 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3675 }
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003676 pe_debug("Send frame on channel %d to mac "
3677 MAC_ADDRESS_STR, session_entry->currentOperChannel,
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303678 MAC_ADDR_ARRAY(peer));
3679
3680 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3681 session_entry->peSessionId, mac_hdr->fc.subType));
3682
3683 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
3684 (uint16_t)num_bytes,
3685 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3686 7, lim_tx_complete, frame,
3687 lim_oper_chan_change_confirm_tx_complete_cnf,
3688 tx_flag, sme_session_id, false, 0);
3689
3690 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3691 session_entry->peSessionId, qdf_status));
3692 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003693 pe_err("Failed to send status %X!", qdf_status);
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303694 /* Pkt will be freed up by the callback */
3695 return eSIR_FAILURE;
3696 }
3697 return eSIR_SUCCESS;
3698}
3699
3700
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003701tSirRetStatus
3702lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
3703 tSirMacAddr peer,
3704 uint8_t nMode, tpPESession psessionEntry)
3705{
3706 tDot11fOperatingMode frm;
3707 uint8_t *pFrame;
3708 tpSirMacMgmtHdr pMacHdr;
3709 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
3710 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303711 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003712 uint8_t txFlag = 0;
3713
3714 uint8_t smeSessionId = 0;
3715
3716 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003717 pe_err("Session entry is NULL!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003718 return eSIR_FAILURE;
3719 }
3720 smeSessionId = psessionEntry->smeSessionId;
3721
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303722 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003723
3724 frm.Category.category = SIR_MAC_ACTION_VHT;
3725 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
3726 frm.OperatingMode.chanWidth = nMode;
3727 frm.OperatingMode.rxNSS = 0;
3728 frm.OperatingMode.rxNSSType = 0;
3729
3730 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
3731 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003732 pe_err("Failed to calculate the packed size for a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003733 nStatus);
3734 /* We'll fall back on the worst case scenario: */
3735 nPayload = sizeof(tDot11fOperatingMode);
3736 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003737 pe_warn("There were warnings while calculating the packed size for a Operating Mode (0x%08x)",
3738 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003739 }
3740
3741 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3742
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303743 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003744 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3745 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303746 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003747 pe_err("Failed to allocate %d bytes for a Operating Mode Report",
3748 nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003749 return eSIR_FAILURE;
3750 }
3751 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303752 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003753
3754 /* Next, we fill out the buffer descriptor: */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303755 if (psessionEntry->pePersona == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003756 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3757 SIR_MAC_MGMT_ACTION, peer,
3758 psessionEntry->selfMacAddr);
3759 else
3760 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3761 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
3762 psessionEntry->selfMacAddr);
3763 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303764 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003765 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3766 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
3767 sizeof(tSirMacMgmtHdr),
3768 nPayload, &nPayload);
3769 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003770 pe_err("Failed to pack a Operating Mode (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003771 nStatus);
3772 cds_packet_free((void *)pPacket);
3773 return eSIR_FAILURE; /* allocated! */
3774 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003775 pe_warn("There were warnings while packing a Operating Mode (0x%08x)",
3776 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003777 }
3778 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303779 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3780 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003781 ) {
3782 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3783 }
3784
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303785 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003786 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303787 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003788 TXRX_FRM_802_11_MGMT,
3789 ANI_TXDIR_TODS,
3790 7, lim_tx_complete, pFrame, txFlag,
3791 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303792 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303793 psessionEntry->peSessionId, qdf_status));
3794 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003795 pe_err("Failed to send a Channel Switch (%X)!",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303796 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003797 /* Pkt will be freed up by the callback */
3798 return eSIR_FAILURE;
3799 }
3800
3801 return eSIR_SUCCESS;
3802}
3803
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003804/**
3805 * \brief Send a Neighbor Report Request Action frame
3806 *
3807 *
3808 * \param pMac Pointer to the global MAC structure
3809 *
3810 * \param pNeighborReq Address of a tSirMacNeighborReportReq
3811 *
3812 * \param peer mac address of peer station.
3813 *
3814 * \param psessionEntry address of session entry.
3815 *
3816 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3817 *
3818 *
3819 */
3820
3821tSirRetStatus
3822lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
3823 tpSirMacNeighborReportReq pNeighborReq,
3824 tSirMacAddr peer, tpPESession psessionEntry)
3825{
3826 tSirRetStatus statusCode = eSIR_SUCCESS;
3827 tDot11fNeighborReportRequest frm;
3828 uint8_t *pFrame;
3829 tpSirMacMgmtHdr pMacHdr;
3830 uint32_t nBytes, nPayload, nStatus;
3831 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303832 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003833 uint8_t txFlag = 0;
3834 uint8_t smeSessionId = 0;
3835
3836 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003837 pe_err("(psession == NULL) in Request to send Neighbor Report request action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003838 return eSIR_FAILURE;
3839 }
3840 smeSessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303841 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003842
3843 frm.Category.category = SIR_MAC_ACTION_RRM;
3844 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
3845 frm.DialogToken.token = pNeighborReq->dialogToken;
3846
3847 if (pNeighborReq->ssid_present) {
3848 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
3849 }
3850
3851 nStatus =
3852 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
3853 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003854 pe_err("Failed to calculate the packed size for a Neighbor Report Request(0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003855 nStatus);
3856 /* We'll fall back on the worst case scenario: */
3857 nPayload = sizeof(tDot11fNeighborReportRequest);
3858 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003859 pe_warn("There were warnings while calculating the packed size for a Neighbor Report Request(0x%08x)",
3860 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003861 }
3862
3863 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3864
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303865 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003866 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3867 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303868 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003869 pe_err("Failed to allocate %d bytes for a Neighbor "
3870 "Report Request", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871 return eSIR_FAILURE;
3872 }
3873 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303874 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003875
3876 /* Copy necessary info to BD */
3877 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3878 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
3879
3880 /* Update A3 with the BSSID */
3881 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3882
3883 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3884
3885#ifdef WLAN_FEATURE_11W
3886 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3887#endif
3888
3889 /* Now, we're ready to "pack" the frames */
3890 nStatus = dot11f_pack_neighbor_report_request(pMac,
3891 &frm,
3892 pFrame +
3893 sizeof(tSirMacMgmtHdr),
3894 nPayload, &nPayload);
3895
3896 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003897 pe_err("Failed to pack an Neighbor Report Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003898 nStatus);
3899
3900 /* FIXME - Need to convert to tSirRetStatus */
3901 statusCode = eSIR_FAILURE;
3902 goto returnAfterError;
3903 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003904 pe_warn("There were warnings while packing Neighbor Report Request (0x%08x)",
3905 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003906 }
3907
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003908 pe_debug("Sending a Neighbor Report Request to");
Nishank Aggarwal46bd31a2017-03-10 16:23:53 +05303909 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003910
3911 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303912 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3913 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003914 ) {
3915 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3916 }
3917
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303918 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003919 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303920 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003921 pPacket,
3922 (uint16_t) nBytes,
3923 TXRX_FRM_802_11_MGMT,
3924 ANI_TXDIR_TODS,
3925 7, lim_tx_complete, pFrame, txFlag,
3926 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303927 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303928 psessionEntry->peSessionId, qdf_status));
3929 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003930 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003931 statusCode = eSIR_FAILURE;
3932 /* Pkt will be freed up by the callback */
3933 return statusCode;
3934 } else
3935 return eSIR_SUCCESS;
3936
3937returnAfterError:
3938 cds_packet_free((void *)pPacket);
3939
3940 return statusCode;
3941} /* End lim_send_neighbor_report_request_frame. */
3942
3943/**
3944 * \brief Send a Link Report Action frame
3945 *
3946 *
3947 * \param pMac Pointer to the global MAC structure
3948 *
3949 * \param pLinkReport Address of a tSirMacLinkReport
3950 *
3951 * \param peer mac address of peer station.
3952 *
3953 * \param psessionEntry address of session entry.
3954 *
3955 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3956 *
3957 *
3958 */
3959
3960tSirRetStatus
3961lim_send_link_report_action_frame(tpAniSirGlobal pMac,
3962 tpSirMacLinkReport pLinkReport,
3963 tSirMacAddr peer, tpPESession psessionEntry)
3964{
3965 tSirRetStatus statusCode = eSIR_SUCCESS;
3966 tDot11fLinkMeasurementReport frm;
3967 uint8_t *pFrame;
3968 tpSirMacMgmtHdr pMacHdr;
3969 uint32_t nBytes, nPayload, nStatus;
3970 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303971 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003972 uint8_t txFlag = 0;
3973 uint8_t smeSessionId = 0;
3974
3975 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07003976 pe_err("(psession == NULL) in Request to send Link Report action frame");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003977 return eSIR_FAILURE;
3978 }
3979
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303980 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003981
3982 frm.Category.category = SIR_MAC_ACTION_RRM;
3983 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
3984 frm.DialogToken.token = pLinkReport->dialogToken;
3985
3986 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
3987 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
3988 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
3989 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
3990 /* such case this way than changing the frame parser. */
3991 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
3992 frm.TPCEleLen.TPCLen = 2;
3993 frm.TxPower.txPower = pLinkReport->txPower;
3994 frm.LinkMargin.linkMargin = 0;
3995
3996 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
3997 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
3998 frm.RCPI.rcpi = pLinkReport->rcpi;
3999 frm.RSNI.rsni = pLinkReport->rsni;
4000
4001 nStatus =
4002 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4003 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004004 pe_err("Failed to calculate the packed size for a Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004005 /* We'll fall back on the worst case scenario: */
4006 nPayload = sizeof(tDot11fLinkMeasurementReport);
4007 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004008 pe_warn("There were warnings while calculating the packed size for a Link Report (0x%08x)",
4009 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004010 }
4011
4012 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4013
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304014 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004015 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4016 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304017 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004018 pe_err("Failed to allocate %d bytes for a Link "
4019 "Report", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004020 return eSIR_FAILURE;
4021 }
4022 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304023 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004024
4025 /* Copy necessary info to BD */
4026 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4027 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4028
4029 /* Update A3 with the BSSID */
4030 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4031
4032 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4033
4034#ifdef WLAN_FEATURE_11W
4035 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4036#endif
4037
4038 /* Now, we're ready to "pack" the frames */
4039 nStatus = dot11f_pack_link_measurement_report(pMac,
4040 &frm,
4041 pFrame +
4042 sizeof(tSirMacMgmtHdr),
4043 nPayload, &nPayload);
4044
4045 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004046 pe_err("Failed to pack an Link Report (0x%08x)", nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004047
4048 /* FIXME - Need to convert to tSirRetStatus */
4049 statusCode = eSIR_FAILURE;
4050 goto returnAfterError;
4051 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004052 pe_warn("There were warnings while packing Link Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004053 nStatus);
4054 }
4055
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004056 pe_warn("Sending a Link Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004057 lim_print_mac_addr(pMac, peer, LOGW);
4058
4059 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304060 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4061 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004062 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4063 }
4064
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304065 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304067 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004068 pPacket,
4069 (uint16_t) nBytes,
4070 TXRX_FRM_802_11_MGMT,
4071 ANI_TXDIR_TODS,
4072 7, lim_tx_complete, pFrame, txFlag,
4073 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304074 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304075 psessionEntry->peSessionId, qdf_status));
4076 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004077 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004078 statusCode = eSIR_FAILURE;
4079 /* Pkt will be freed up by the callback */
4080 return statusCode;
4081 } else
4082 return eSIR_SUCCESS;
4083
4084returnAfterError:
4085 cds_packet_free((void *)pPacket);
4086
4087 return statusCode;
4088} /* End lim_send_link_report_action_frame. */
4089
4090/**
4091 * \brief Send a Beacon Report Action frame
4092 *
4093 *
4094 * \param pMac Pointer to the global MAC structure
4095 *
4096 * \param dialog_token dialog token to be used in the action frame.
4097 *
4098 * \param num_report number of reports in pRRMReport.
4099 *
4100 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4101 *
4102 * \param peer mac address of peer station.
4103 *
4104 * \param psessionEntry address of session entry.
4105 *
4106 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4107 *
4108 *
4109 */
4110
4111tSirRetStatus
4112lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4113 uint8_t dialog_token,
4114 uint8_t num_report,
4115 tpSirMacRadioMeasureReport pRRMReport,
4116 tSirMacAddr peer,
4117 tpPESession psessionEntry)
4118{
4119 tSirRetStatus statusCode = eSIR_SUCCESS;
4120 uint8_t *pFrame;
4121 tpSirMacMgmtHdr pMacHdr;
4122 uint32_t nBytes, nPayload, nStatus;
4123 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304124 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004125 uint8_t i;
4126 uint8_t txFlag = 0;
4127 uint8_t smeSessionId = 0;
4128
4129 tDot11fRadioMeasurementReport *frm =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304130 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004131 if (!frm) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004132 pe_err("Not enough memory to allocate tDot11fRadioMeasurementReport");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004133 return eSIR_MEM_ALLOC_FAILED;
4134 }
4135
4136 if (psessionEntry == NULL) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004137 pe_err("(psession == NULL) in Request to send Beacon Report action frame");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304138 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004139 return eSIR_FAILURE;
4140 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004142 pe_debug("dialog_token %d num_report %d",
Padma, Santhosh Kumar93ec7d22016-12-26 15:58:37 +05304143 dialog_token, num_report);
4144
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004145 frm->Category.category = SIR_MAC_ACTION_RRM;
4146 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4147 frm->DialogToken.token = dialog_token;
4148
4149 frm->num_MeasurementReport =
4150 (num_report >
4151 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4152 num_report;
4153
4154 for (i = 0; i < frm->num_MeasurementReport; i++) {
4155 frm->MeasurementReport[i].type = pRRMReport[i].type;
4156 frm->MeasurementReport[i].token = pRRMReport[i].token;
4157 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4158 switch (pRRMReport[i].type) {
4159 case SIR_MAC_RRM_BEACON_TYPE:
4160 populate_dot11f_beacon_report(pMac,
4161 &frm->MeasurementReport[i],
4162 &pRRMReport[i].report.
4163 beaconReport);
4164 frm->MeasurementReport[i].incapable =
4165 pRRMReport[i].incapable;
4166 frm->MeasurementReport[i].refused =
4167 pRRMReport[i].refused;
4168 frm->MeasurementReport[i].present = 1;
4169 break;
4170 default:
4171 frm->MeasurementReport[i].incapable =
4172 pRRMReport[i].incapable;
4173 frm->MeasurementReport[i].refused =
4174 pRRMReport[i].refused;
4175 frm->MeasurementReport[i].present = 1;
4176 break;
4177 }
4178 }
4179
4180 nStatus =
4181 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4182 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004183 pe_err("Failed to calculate the packed size for a Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 nStatus);
4185 /* We'll fall back on the worst case scenario: */
4186 nPayload = sizeof(tDot11fLinkMeasurementReport);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304187 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004188 return eSIR_FAILURE;
4189 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004190 pe_warn("There were warnings while calculating the packed size for a Radio Measure Report (0x%08x)",
4191 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004192 }
4193
4194 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4195
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304196 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004197 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4198 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304199 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004200 pe_err("Failed to allocate %d bytes for a Radio Measure "
4201 "Report", nBytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304202 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004203 return eSIR_FAILURE;
4204 }
4205 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304206 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004207
4208 /* Copy necessary info to BD */
4209 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4210 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4211
4212 /* Update A3 with the BSSID */
4213 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4214
4215 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4216
4217#ifdef WLAN_FEATURE_11W
4218 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4219#endif
4220
4221 /* Now, we're ready to "pack" the frames */
4222 nStatus = dot11f_pack_radio_measurement_report(pMac,
4223 frm,
4224 pFrame +
4225 sizeof(tSirMacMgmtHdr),
4226 nPayload, &nPayload);
4227
4228 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004229 pe_err("Failed to pack an Radio Measure Report (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004230 nStatus);
4231
4232 /* FIXME - Need to convert to tSirRetStatus */
4233 statusCode = eSIR_FAILURE;
4234 goto returnAfterError;
4235 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004236 pe_warn("There were warnings while packing Radio Measure Report (0x%08x)",
4237 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004238 }
4239
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004240 pe_warn("Sending a Radio Measure Report to");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004241 lim_print_mac_addr(pMac, peer, LOGW);
4242
4243 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304244 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4245 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004246 ) {
4247 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4248 }
4249
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304250 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004251 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304252 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004253 pPacket,
4254 (uint16_t) nBytes,
4255 TXRX_FRM_802_11_MGMT,
4256 ANI_TXDIR_TODS,
4257 7, lim_tx_complete, pFrame, txFlag,
4258 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304259 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304260 psessionEntry->peSessionId, qdf_status));
4261 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004262 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004263 statusCode = eSIR_FAILURE;
4264 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304265 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004266 return statusCode;
4267 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304268 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004269 return eSIR_SUCCESS;
4270 }
4271
4272returnAfterError:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304273 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004274 cds_packet_free((void *)pPacket);
4275 return statusCode;
4276}
4277
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004278#ifdef WLAN_FEATURE_11W
4279/**
4280 * \brief Send SA query request action frame to peer
4281 *
4282 * \sa lim_send_sa_query_request_frame
4283 *
4284 *
4285 * \param pMac The global tpAniSirGlobal object
4286 *
4287 * \param transId Transaction identifier
4288 *
4289 * \param peer The Mac address of the station to which this action frame is addressed
4290 *
4291 * \param psessionEntry The PE session entry
4292 *
4293 * \return eSIR_SUCCESS if setup completes successfully
4294 * eSIR_FAILURE is some problem is encountered
4295 */
4296
4297tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4298 tSirMacAddr peer,
4299 tpPESession psessionEntry)
4300{
4301
4302 tDot11fSaQueryReq frm; /* SA query request action frame */
4303 uint8_t *pFrame;
4304 tSirRetStatus nSirStatus;
4305 tpSirMacMgmtHdr pMacHdr;
4306 uint32_t nBytes, nPayload, nStatus;
4307 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304308 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004309 uint8_t txFlag = 0;
4310 uint8_t smeSessionId = 0;
4311
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304312 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004313 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4314 /* 11w action field is :
4315 action: 0 --> SA Query Request action frame
4316 action: 1 --> SA Query Response action frame */
4317 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4318 /* 11w SA Query Request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304319 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004320
4321 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4322 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004323 pe_err("Failed to calculate the packed size for an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004324 nStatus);
4325 /* We'll fall back on the worst case scenario: */
4326 nPayload = sizeof(tDot11fSaQueryReq);
4327 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004328 pe_warn("There were warnings while calculating the packed size for an SA Query Request (0x%08x)",
4329 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004330 }
4331
4332 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304333 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004334 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304335 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004336 pe_err("Failed to allocate %d bytes for a SA Query Request "
4337 "action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004338 return eSIR_FAILURE;
4339 }
4340 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304341 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004342
4343 /* Copy necessary info to BD */
4344 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4345 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4346
4347 /* Update A3 with the BSSID */
4348 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4349
4350 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4351
4352 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4353 /* in the FC */
4354 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4355
4356 /* Pack 11w SA Query Request frame */
4357 nStatus = dot11f_pack_sa_query_req(pMac,
4358 &frm,
4359 pFrame + sizeof(tSirMacMgmtHdr),
4360 nPayload, &nPayload);
4361
4362 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004363 pe_err("Failed to pack an SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004364 nStatus);
4365 /* FIXME - Need to convert to tSirRetStatus */
4366 nSirStatus = eSIR_FAILURE;
4367 goto returnAfterError;
4368 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004369 pe_warn("There were warnings while packing SA Query Request (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004370 nStatus);
4371 }
4372
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004373 pe_debug("Sending an SA Query Request to");
4374 lim_print_mac_addr(pMac, peer, LOGD);
4375 pe_debug("Sending an SA Query Request from ");
4376 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004377
4378 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4379#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304380 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4381 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004382#endif
4383 ) {
4384 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4385 }
4386 smeSessionId = psessionEntry->smeSessionId;
4387
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304388 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004389 pPacket,
4390 (uint16_t) nBytes,
4391 TXRX_FRM_802_11_MGMT,
4392 ANI_TXDIR_TODS,
4393 7, lim_tx_complete, pFrame, txFlag,
4394 smeSessionId, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304395 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004396 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004397 nSirStatus = eSIR_FAILURE;
4398 /* Pkt will be freed up by the callback */
4399 return nSirStatus;
4400 } else {
4401 return eSIR_SUCCESS;
4402 }
4403
4404returnAfterError:
4405 cds_packet_free((void *)pPacket);
4406 return nSirStatus;
4407} /* End lim_send_sa_query_request_frame */
4408
4409/**
4410 * \brief Send SA query response action frame to peer
4411 *
4412 * \sa lim_send_sa_query_response_frame
4413 *
4414 *
4415 * \param pMac The global tpAniSirGlobal object
4416 *
4417 * \param transId Transaction identifier received in SA query request action frame
4418 *
4419 * \param peer The Mac address of the AP to which this action frame is addressed
4420 *
4421 * \param psessionEntry The PE session entry
4422 *
4423 * \return eSIR_SUCCESS if setup completes successfully
4424 * eSIR_FAILURE is some problem is encountered
4425 */
4426
4427tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
4428 uint8_t *transId, tSirMacAddr peer,
4429 tpPESession psessionEntry)
4430{
4431
4432 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
4433 uint8_t *pFrame;
4434 tSirRetStatus nSirStatus;
4435 tpSirMacMgmtHdr pMacHdr;
4436 uint32_t nBytes, nPayload, nStatus;
4437 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304438 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004439 uint8_t txFlag = 0;
4440 uint8_t smeSessionId = 0;
4441
4442 smeSessionId = psessionEntry->smeSessionId;
4443
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304444 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004445 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4446 /*11w action field is :
4447 action: 0 --> SA query request action frame
4448 action: 1 --> SA query response action frame */
4449 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
4450 /*11w SA query response transId is same as
4451 SA query request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304452 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004453
4454 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
4455 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004456 pe_err("Failed to calculate the packed size for a SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004457 nStatus);
4458 /* We'll fall back on the worst case scenario: */
4459 nPayload = sizeof(tDot11fSaQueryRsp);
4460 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004461 pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)",
4462 nStatus);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004463 }
4464
4465 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304466 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004467 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304468 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004469 pe_err("Failed to allocate %d bytes for a SA query response"
4470 " action frame", nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004471 return eSIR_FAILURE;
4472 }
4473 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304474 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004475
4476 /* Copy necessary info to BD */
4477 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4478 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4479
4480 /* Update A3 with the BSSID */
4481 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4482
4483 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4484
4485 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
4486 /* in the FC */
4487 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4488
4489 /* Pack 11w SA query response frame */
4490 nStatus = dot11f_pack_sa_query_rsp(pMac,
4491 &frm,
4492 pFrame + sizeof(tSirMacMgmtHdr),
4493 nPayload, &nPayload);
4494
4495 if (DOT11F_FAILED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004496 pe_err("Failed to pack an SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004497 nStatus);
4498 /* FIXME - Need to convert to tSirRetStatus */
4499 nSirStatus = eSIR_FAILURE;
4500 goto returnAfterError;
4501 } else if (DOT11F_WARNED(nStatus)) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004502 pe_warn("There were warnings while packing SA Query Response (0x%08x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004503 nStatus);
4504 }
4505
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004506 pe_debug("Sending a SA Query Response to");
Srinivas Girigowdaf936d822017-03-19 23:23:59 -07004507 lim_print_mac_addr(pMac, peer, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004508
4509 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4510#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304511 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4512 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004513#endif
4514 ) {
4515 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4516 }
4517
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304518 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004519 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304520 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004521 pPacket,
4522 (uint16_t) nBytes,
4523 TXRX_FRM_802_11_MGMT,
4524 ANI_TXDIR_TODS,
4525 7, lim_tx_complete, pFrame, txFlag,
4526 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304527 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304528 psessionEntry->peSessionId, qdf_status));
4529 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda7034a8b2017-03-26 19:52:36 -07004530 pe_err("wma_tx_frame FAILED! Status [%d]", qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004531 nSirStatus = eSIR_FAILURE;
4532 /* Pkt will be freed up by the callback */
4533 return nSirStatus;
4534 } else {
4535 return eSIR_SUCCESS;
4536 }
4537
4538returnAfterError:
4539 cds_packet_free((void *)pPacket);
4540 return nSirStatus;
4541} /* End lim_send_sa_query_response_frame */
4542#endif
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004543
4544/**
4545 * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
4546 * @mac_ctx: mac context
4547 * @peer_mac: Peer MAC address
4548 * @tid: TID for which addba response is being sent
4549 * @session: PE session entry
4550 *
4551 * This function is called when ADDBA request is successful. ADDBA response is
4552 * setup by calling addba_response_setup API and frame is then sent out OTA.
4553 *
4554 * Return: QDF_STATUS
4555 */
4556QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
4557 tSirMacAddr peer_mac, uint16_t tid, tpPESession session)
4558{
4559
4560 tDot11faddba_rsp frm;
4561 uint8_t *frame_ptr;
4562 tpSirMacMgmtHdr mgmt_hdr;
4563 uint32_t num_bytes, payload_size, status;
4564 void *pkt_ptr;
4565 QDF_STATUS qdf_status;
4566 uint8_t tx_flag = 0;
4567 uint8_t sme_sessionid = 0;
4568 uint16_t buff_size, status_code, batimeout;
4569 uint8_t peer_id, dialog_token;
4570 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4571 void *peer, *pdev;
4572
4573 sme_sessionid = session->smeSessionId;
4574
4575 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4576 if (!pdev) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004577 pe_err("pdev is NULL");
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004578 return QDF_STATUS_E_FAILURE;
4579 }
4580
4581 peer = cdp_peer_find_by_addr(soc, pdev, peer_mac, &peer_id);
4582 if (!peer) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004583 pe_err("PEER [%pM] not found", peer_mac);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004584 return QDF_STATUS_E_FAILURE;
4585 }
4586
4587 cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
4588 &status_code, &buff_size, &batimeout);
4589
4590 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4591 frm.Category.category = SIR_MAC_ACTION_BLKACK;
4592 frm.Action.action = SIR_MAC_ADDBA_RSP;
4593
4594 frm.DialogToken.token = dialog_token;
4595 frm.Status.status = status_code;
4596 frm.addba_param_set.tid = tid;
4597 frm.addba_param_set.buff_size = buff_size;
4598 frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE;
4599 frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED;
4600 frm.ba_timeout.timeout = batimeout;
4601
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004602 pe_debug("Sending a ADDBA Response from %pM to %pM",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004603 session->selfMacAddr, peer_mac);
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004604 pe_debug("tid: %d, dialog_token: %d, status: %d, buff_size: %d",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004605 tid, frm.DialogToken.token, frm.Status.status,
4606 frm.addba_param_set.buff_size);
4607
4608 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
4609 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004610 pe_err("Failed to calculate the packed size for a ADDBA Response (0x%08x).",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004611 status);
4612 /* We'll fall back on the worst case scenario: */
4613 payload_size = sizeof(tDot11faddba_rsp);
4614 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004615 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 -08004616 }
4617
4618 num_bytes = payload_size + sizeof(*mgmt_hdr);
4619 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
4620 (void **)&pkt_ptr);
4621 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004622 pe_err("Failed to allocate %d bytes for a ADDBA response action frame",
4623 num_bytes);
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004624 return QDF_STATUS_E_FAILURE;
4625 }
4626 qdf_mem_set(frame_ptr, num_bytes, 0);
4627
4628 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
4629 SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
4630
4631 /* Update A3 with the BSSID */
4632 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
4633 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
4634
4635 /* ADDBA Response is a robust mgmt action frame,
4636 * set the "protect" (aka WEP) bit in the FC
4637 */
4638 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
4639
4640 status = dot11f_pack_addba_rsp(mac_ctx, &frm,
4641 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
4642 &payload_size);
4643
4644 if (DOT11F_FAILED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004645 pe_err("Failed to pack a ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004646 status);
4647 qdf_status = QDF_STATUS_E_FAILURE;
4648 goto error_addba_rsp;
4649 } else if (DOT11F_WARNED(status)) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004650 pe_warn("There were warnings while packing ADDBA Response (0x%08x)",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004651 status);
4652 }
4653
4654
4655 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
4656#ifdef WLAN_FEATURE_P2P
4657 || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
4658 (session->pePersona == QDF_P2P_GO_MODE)
4659#endif
4660 ) {
4661 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4662 }
4663
4664 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4665 session->peSessionId, mgmt_hdr->fc.subType));
4666 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
4667 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
4668 lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0);
4669 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4670 session->peSessionId, qdf_status));
4671 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda28fb0122017-03-26 22:21:20 -07004672 pe_err("wma_tx_frame FAILED! Status [%d]",
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004673 qdf_status);
4674 qdf_status = QDF_STATUS_E_FAILURE;
4675 /*
4676 * wma_tx_frame free memory in certain cases, free pkt_ptr
4677 * only if not freed already.
4678 */
4679 if (pkt_ptr)
4680 cds_packet_free((void *)pkt_ptr);
4681 return qdf_status;
4682 } else {
4683 return eSIR_SUCCESS;
4684 }
4685
4686error_addba_rsp:
4687 cds_packet_free((void *)pkt_ptr);
4688 return qdf_status;
4689}