blob: 6f47847b9b62256f1ca20b6d7204a51f715a1067 [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>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065
66/**
67 *
68 * \brief This function is called to add the sequence number to the
69 * management frames
70 *
71 * \param pMac Pointer to Global MAC structure
72 *
73 * \param pMacHdr Pointer to MAC management header
74 *
75 * The pMacHdr argument points to the MAC management header. The
76 * sequence number stored in the pMac structure will be incremented
77 * and updated to the MAC management header. The start sequence
78 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
79 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
80 * number will roll over.
81 *
82 */
Jeff Johnson38112a32016-10-07 07:30:50 -070083static void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084{
85 if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
86 pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
87 }
88
89 pMac->mgmtSeqNum++;
90
91 pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
92 pMacHdr->seqControl.seqNumHi =
93 ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
94}
95
96/**
97 *
98 * \brief This function is called before sending a p2p action frame
99 * inorder to add sequence numbers to action packets
100 *
101 * \param pMac Pointer to Global MAC structure
102 *
103 * \param pBD Pointer to the frame buffer that needs to be populate
104 *
105 * The pMacHdr argument points to the MAC management header. The
106 * sequence number stored in the pMac structure will be incremented
107 * and updated to the MAC management header. The start sequence
108 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
109 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
110 * number will roll over.
111 *
112 */
113void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
114{
115 tpSirMacMgmtHdr pMacHdr;
116
117 /* / Prepare MAC management header */
118 pMacHdr = (tpSirMacMgmtHdr) (pBD);
119
120 /* Prepare sequence number */
121 lim_add_mgmt_seq_num(pMac, pMacHdr);
122 lim_log(pMac, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
123 pMacHdr->seqControl.seqNumLo,
124 pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
125}
126
127/**
128 * lim_populate_mac_header() - Fill in 802.11 header of frame
129 *
130 * @mac_ctx: Pointer to Global MAC structure
131 * @buf: Pointer to the frame buffer that needs to be populate
132 * @type: 802.11 Type of the frame
133 * @sub_type: 802.11 Subtype of the frame
134 * @peer_addr: dst address
135 * @self_mac_addr: local mac address
136 *
137 * This function is called by various LIM modules to prepare the
138 * 802.11 frame MAC header
139 *
140 * The buf argument points to the beginning of the frame buffer to
141 * which - a) The 802.11 MAC header is set b) Following this MAC header
142 * will be the MGMT frame payload The payload itself is populated by the
143 * caller API
144 *
145 * Return: None
146 */
147
148void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
149 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
150 tSirMacAddr self_mac_addr)
151{
152 tpSirMacMgmtHdr mac_hdr;
153
154 /* Prepare MAC management header */
155 mac_hdr = (tpSirMacMgmtHdr) (buf);
156
157 /* Prepare FC */
158 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
159 mac_hdr->fc.type = type;
160 mac_hdr->fc.subType = sub_type;
161
162 /* Prepare Address 1 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530163 qdf_mem_copy((uint8_t *) mac_hdr->da,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800164 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
165
166 /* Prepare Address 2 */
167 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
168
169 /* Prepare Address 3 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530170 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
172
173 /* Prepare sequence number */
174 lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
175 lim_log(mac_ctx, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
176 mac_hdr->seqControl.seqNumLo,
177 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
178}
179
180/**
181 * lim_send_probe_req_mgmt_frame() - send probe request management frame
182 * @mac_ctx: Pointer to Global MAC structure
183 * @ssid: SSID to be sent in Probe Request frame
184 * @bssid: BSSID to be sent in Probe Request frame
185 * @channel: Channel # on which the Probe Request is going out
186 * @self_macaddr: self MAC address
187 * @dot11mode: self dotllmode
188 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
189 * frame
190 * @additional_ie: if additional_ielen is non zero, include this field in the
191 * Probe Request frame
192 *
193 * This function is called by various LIM modules to send Probe Request frame
194 * during active scan/learn phase.
195 * Probe request is sent out in the following scenarios:
196 * --heartbeat failure: session needed
197 * --join req: session needed
198 * --foreground scan: no session
199 * --background scan: no session
200 * --sch_beacon_processing: to get EDCA parameters: session needed
201 *
202 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
203 */
204tSirRetStatus
205lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
206 tSirMacSSid *ssid,
207 tSirMacAddr bssid,
208 uint8_t channel,
209 tSirMacAddr self_macaddr,
210 uint32_t dot11mode,
211 uint32_t additional_ielen, uint8_t *additional_ie)
212{
213 tDot11fProbeRequest pr;
214 uint32_t status, bytes, payload;
215 uint8_t *frame;
216 void *packet;
Kapil Guptac03eb072016-08-09 14:01:36 +0530217 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800218 tpPESession pesession;
219 uint8_t sessionid;
220 uint8_t *p2pie = NULL;
221 uint8_t txflag = 0;
222 uint8_t sme_sessionid = 0;
223 bool is_vht_enabled = false;
224 uint8_t txPower;
225 uint16_t addn_ielen = additional_ielen;
Kapil Guptac03eb072016-08-09 14:01:36 +0530226 bool extracted_ext_cap_flag = false;
227 tDot11fIEExtCap extracted_ext_cap;
228 tSirRetStatus sir_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229
230 /* The probe req should not send 11ac capabilieties if band is 2.4GHz,
231 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
232 * is false and dot11mode is 11ac set it to 11n.
233 */
234 if (channel <= SIR_11B_CHANNEL_END &&
235 (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
236 (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
237 WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
238 dot11mode = WNI_CFG_DOT11_MODE_11N;
239 /*
240 * session context may or may not be present, when probe request needs
241 * to be sent out. Following cases exist:
242 * --heartbeat failure: session needed
243 * --join req: session needed
244 * --foreground scan: no session
245 * --background scan: no session
246 * --sch_beacon_processing: to get EDCA parameters: session needed
247 * If session context does not exist, some IEs will be populated from
248 * CFGs, e.g. Supported and Extended rate set IEs
249 */
250 pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
251
252 if (pesession != NULL)
253 sme_sessionid = pesession->smeSessionId;
254
255 /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
256 /* and then hand it off to 'dot11f_pack_probe_request' (for */
257 /* serialization). We start by zero-initializing the structure: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530258 qdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800259
260 /* & delegating to assorted helpers: */
261 populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
262
263 if (addn_ielen && additional_ie)
264 p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
265
266 /*
267 * Don't include 11b rate if it is a P2P serach or probe request is
268 * sent by P2P Client
269 */
270 if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
271 (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
272 mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
273 ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530274 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800275 )
276 ) {
277 /*
278 * In the below API pass channel number > 14, do that it fills
279 * only 11a rates in supported rates
280 */
281 populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
282 pesession);
283 } else {
284 populate_dot11f_supp_rates(mac_ctx, channel,
285 &pr.SuppRates, pesession);
286
287 if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
288 populate_dot11f_ext_supp_rates1(mac_ctx, channel,
289 &pr.ExtSuppRates);
290 }
291 }
292
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800293 /*
294 * Table 7-14 in IEEE Std. 802.11k-2008 says
295 * DS params "can" be present in RRM is disabled and "is" present if
296 * RRM is enabled. It should be ok even if we add it into probe req when
297 * RRM is not enabled.
298 */
299 populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
300 /* Call RRM module to get the tx power for management used. */
301 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
302 populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
303
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800304
305 if (pesession != NULL) {
306 pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
307 /* Include HT Capability IE */
308 if (pesession->htCapability)
309 populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
310 } else { /* pesession == NULL */
311 if (IS_DOT11_MODE_HT(dot11mode))
312 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
313 }
314
315 /*
316 * Set channelbonding information as "disabled" when tunned to a
317 * 2.4 GHz channel
318 */
319 if (channel <= SIR_11B_CHANNEL_END) {
320 if (mac_ctx->roam.configParam.channelBondingMode24GHz
321 == PHY_SINGLE_CHANNEL_CENTERED) {
322 pr.HTCaps.supportedChannelWidthSet =
323 eHT_CHANNEL_WIDTH_20MHZ;
324 pr.HTCaps.shortGI40MHz = 0;
325 } else {
326 pr.HTCaps.supportedChannelWidthSet =
327 eHT_CHANNEL_WIDTH_40MHZ;
328 }
329 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800330 if (pesession != NULL) {
331 pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
332 /* Include VHT Capability IE */
333 if (pesession->vhtCapability) {
334 populate_dot11f_vht_caps(mac_ctx, pesession,
335 &pr.VHTCaps);
336 is_vht_enabled = true;
337 }
338 } else {
339 if (IS_DOT11_MODE_VHT(dot11mode)) {
340 populate_dot11f_vht_caps(mac_ctx, pesession,
341 &pr.VHTCaps);
342 is_vht_enabled = true;
343 }
344 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800345 if (pesession != NULL)
346 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
347 pesession);
348
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +0530349 populate_dot11f_qcn_ie(&pr.QCN_IE);
350
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800351 if (IS_DOT11_MODE_HE(dot11mode) && NULL != pesession)
352 lim_update_session_he_capable(mac_ctx, pesession);
353
354 lim_log(mac_ctx, LOG1, FL("Populate HE IEs"));
355 populate_dot11f_he_caps(mac_ctx, pesession, &pr.vendor_he_cap);
356
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800357 if (addn_ielen) {
Kapil Guptac03eb072016-08-09 14:01:36 +0530358 qdf_mem_zero((uint8_t *)&extracted_ext_cap,
359 sizeof(tDot11fIEExtCap));
360 sir_status = lim_strip_extcap_update_struct(mac_ctx,
361 additional_ie,
362 &addn_ielen,
363 &extracted_ext_cap);
364 if (eSIR_SUCCESS != sir_status) {
365 lim_log(mac_ctx, LOG1,
366 FL("Unable to Stripoff ExtCap IE from Probe Req"));
367 } else {
368 struct s_ext_cap *p_ext_cap =
369 (struct s_ext_cap *)
370 extracted_ext_cap.bytes;
371 if (p_ext_cap->interworking_service)
372 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +0800373 extracted_ext_cap.num_bytes =
374 lim_compute_ext_cap_ie_length
375 (&extracted_ext_cap);
Kapil Guptac03eb072016-08-09 14:01:36 +0530376 extracted_ext_cap_flag =
Hu Wang411e0cc2016-10-28 14:56:01 +0800377 (extracted_ext_cap.num_bytes > 0);
Kapil Guptac03eb072016-08-09 14:01:36 +0530378 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 }
380
Hu Wang411e0cc2016-10-28 14:56:01 +0800381 /*
382 * Extcap IE now support variable length, merge Extcap IE from addn_ie
383 * may change the frame size. Therefore, MUST merge ExtCap IE before
384 * dot11f get packed payload size.
385 */
386 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800387 lim_merge_extcap_struct(&pr.ExtCap, &extracted_ext_cap, true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800388
389 /* That's it-- now we pack it. First, how much space are we going to */
390 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
391 if (DOT11F_FAILED(status)) {
392 lim_log(mac_ctx, LOGE,
393 FL("Failed to calculate the packed size for a Probe Request (0x%08x)."),
394 status);
395 /* We'll fall back on the worst case scenario: */
396 payload = sizeof(tDot11fProbeRequest);
397 } else if (DOT11F_WARNED(status)) {
398 lim_log(mac_ctx, LOGW,
399 FL("There were warnings while calculating the packed size for a Probe Request (0x%08x)."),
400 status);
401 }
402
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
404
405 /* Ok-- try to allocate some memory: */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530406 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800407 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530408 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes for a Probe Request."), bytes);
410 return eSIR_MEM_ALLOC_FAILED;
411 }
412 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530413 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414
415 /* Next, we fill out the buffer descriptor: */
416 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
417 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
418
419 /* That done, pack the Probe Request: */
420 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
421 sizeof(tSirMacMgmtHdr),
422 payload, &payload);
423 if (DOT11F_FAILED(status)) {
424 lim_log(mac_ctx, LOGE,
425 FL("Failed to pack a Probe Request (0x%08x)."), status);
426 cds_packet_free((void *)packet);
427 return eSIR_FAILURE; /* allocated! */
428 } else if (DOT11F_WARNED(status)) {
429 lim_log(mac_ctx, LOGW, FL("There were warnings while packing a Probe Request (0x%08x)."), status);
430 }
431 /* Append any AddIE if present. */
432 if (addn_ielen) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530433 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800434 additional_ie, addn_ielen);
435 payload += addn_ielen;
436 }
437
438 /* If this probe request is sent during P2P Search State, then we need
439 * to send it at OFDM rate.
440 */
441 if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
442 || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
443 mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
444 /*
445 * For unicast probe req mgmt from Join function we don't set
446 * above variables. So we need to add one more check whether it
447 * is pePersona is P2P_CLIENT or not
448 */
449 || ((pesession != NULL) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530450 (QDF_P2P_CLIENT_MODE == pesession->pePersona))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800451 ) {
452 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
453 }
454
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530455 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800456 wma_tx_frame(mac_ctx, packet,
457 (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
458 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
459 lim_tx_complete, frame, txflag, sme_sessionid,
460 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530461 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 lim_log(mac_ctx, LOGE,
463 FL("could not send Probe Request frame!"));
464 /* Pkt will be freed up by the callback */
465 return eSIR_FAILURE;
466 }
467
468 return eSIR_SUCCESS;
469} /* End lim_send_probe_req_mgmt_frame. */
470
Jeff Johnson38112a32016-10-07 07:30:50 -0700471static tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800472 uint8_t *addIE, uint16_t *addnIELen,
473 uint8_t probeReqP2pIe)
474{
475 /* If Probe request doesn't have P2P IE, then take out P2P IE
476 from additional IE */
477 if (!probeReqP2pIe) {
478 uint8_t *tempbuf = NULL;
479 uint16_t tempLen = 0;
480 int left = *addnIELen;
481 uint8_t *ptr = addIE;
482 uint8_t elem_id, elem_len;
483
484 if (NULL == addIE) {
485 PELOGE(lim_log(pMac, LOGE, FL(" NULL addIE pointer"));)
486 return eSIR_FAILURE;
487 }
488
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530489 tempbuf = qdf_mem_malloc(left);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490 if (NULL == tempbuf) {
491 PELOGE(lim_log(pMac, LOGE,
492 FL
493 ("Unable to allocate memory to store addn IE"));
494 )
495 return eSIR_MEM_ALLOC_FAILED;
496 }
497
498 while (left >= 2) {
499 elem_id = ptr[0];
500 elem_len = ptr[1];
501 left -= 2;
502 if (elem_len > left) {
503 lim_log(pMac, LOGE,
504 FL
505 ("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
506 elem_id, elem_len, left);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530507 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800508 return eSIR_FAILURE;
509 }
510 if (!((SIR_MAC_EID_VENDOR == elem_id) &&
511 (memcmp
512 (&ptr[2], SIR_MAC_P2P_OUI,
513 SIR_MAC_P2P_OUI_SIZE) == 0))) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530514 qdf_mem_copy(tempbuf + tempLen, &ptr[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800515 elem_len + 2);
516 tempLen += (elem_len + 2);
517 }
518 left -= elem_len;
519 ptr += (elem_len + 2);
520 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530521 qdf_mem_copy(addIE, tempbuf, tempLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522 *addnIELen = tempLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530523 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524 }
525 return eSIR_SUCCESS;
526}
527
528/**
529 * lim_send_probe_rsp_mgmt_frame() - Send probe response
530 *
531 * @mac_ctx: Handle for mac context
532 * @peer_macaddr: Mac address of requesting peer
533 * @ssid: SSID for response
534 * @n_staid: Station ID, currently unused.
535 * @pe_session: PE session id
536 * @keepalive: Keep alive flag. Currently unused.
537 * @preq_p2pie: P2P IE in incoming probe request
538 *
539 * Builds and sends probe response frame to the requesting peer
540 *
541 * Return: void
542 */
543
544void
545lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
546 tSirMacAddr peer_macaddr,
547 tpAniSSID ssid,
548 short n_staid,
549 uint8_t keepalive,
550 tpPESession pe_session, uint8_t preq_p2pie)
551{
552 tDot11fProbeResponse *frm;
553 tSirRetStatus sir_status;
Hu Wang411e0cc2016-10-28 14:56:01 +0800554 uint32_t cfg, payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555 tpSirMacMgmtHdr mac_hdr;
556 uint8_t *frame;
Arif Hussainfbf50682016-06-15 12:57:43 -0700557 void *packet = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530558 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559 uint32_t addn_ie_present = false;
560
561 uint16_t addn_ie_len = 0;
562 uint32_t wps_ap = 0, tmp;
563 uint8_t tx_flag = 0;
564 uint8_t *add_ie = NULL;
565 uint8_t *p2p_ie = NULL;
566 uint8_t noalen = 0;
567 uint8_t total_noalen = 0;
568 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
569 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
570 uint8_t sme_sessionid = 0;
571 bool is_vht_enabled = false;
572 tDot11fIEExtCap extracted_ext_cap;
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530573 bool extracted_ext_cap_flag = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574
575 /* We don't answer requests in this case*/
576 if (ANI_DRIVER_TYPE(mac_ctx) == eDRIVER_TYPE_MFG)
577 return;
578
579 if (NULL == pe_session)
580 return;
581
582 /*
583 * In case when cac timer is running for this SAP session then
584 * avoid sending probe rsp out. It is violation of dfs specification.
585 */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530586 if (((pe_session->pePersona == QDF_SAP_MODE) ||
587 (pe_session->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800588 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530589 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 FL("CAC timer is running, probe response dropped"));
591 return;
592 }
593 sme_sessionid = pe_session->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530594 frm = qdf_mem_malloc(sizeof(tDot11fProbeResponse));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800595 if (NULL == frm) {
596 lim_log(mac_ctx, LOGE,
597 FL("Unable to allocate memory"));
598 return;
599 }
600
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800601 /*
602 * Fill out 'frm', after which we'll just hand the struct off to
603 * 'dot11f_pack_probe_response'.
604 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530605 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800606
607 /*
608 * Timestamp to be updated by TFP, below.
609 *
610 * Beacon Interval:
611 */
612 if (LIM_IS_AP_ROLE(pe_session)) {
613 frm->BeaconInterval.interval =
614 mac_ctx->sch.schObject.gSchBeaconInterval;
615 } else {
616 sir_status = wlan_cfg_get_int(mac_ctx,
617 WNI_CFG_BEACON_INTERVAL, &cfg);
618 if (eSIR_SUCCESS != sir_status) {
619 lim_log(mac_ctx, LOGP,
620 FL("Failed to get WNI_CFG_BEACON_INTERVAL (%d)."),
621 sir_status);
622 goto err_ret;
623 }
624 frm->BeaconInterval.interval = (uint16_t) cfg;
625 }
626
627 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
628 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
629 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
630 &frm->SuppRates, pe_session);
631
632 populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
633 pe_session->currentOperChannel);
634 populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
635
636 if (LIM_IS_AP_ROLE(pe_session)) {
637 if (pe_session->wps_state != SAP_WPS_DISABLED)
638 populate_dot11f_probe_res_wpsi_es(mac_ctx,
639 &frm->WscProbeRes,
640 pe_session);
641 } else {
642 if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
643 &tmp) != eSIR_SUCCESS)
644 lim_log(mac_ctx, LOGP, "Failed to cfg get id %d",
645 WNI_CFG_WPS_ENABLE);
646
647 wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
648
649 if (wps_ap)
650 populate_dot11f_wsc_in_probe_res(mac_ctx,
651 &frm->WscProbeRes);
652
653 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
654 eLIM_WSC_ENROLL_BEGIN) {
655 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
656 &frm->WscProbeRes);
657 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
658 eLIM_WSC_ENROLL_IN_PROGRESS;
659 }
660
661 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
662 eLIM_WSC_ENROLL_END) {
663 de_populate_dot11f_wsc_registrar_info_in_probe_res(
664 mac_ctx, &frm->WscProbeRes);
665 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
666 eLIM_WSC_ENROLL_NOOP;
667 }
668 }
669
670 populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
671 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
672
673 if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
674 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
675
676 populate_dot11f_ext_supp_rates(mac_ctx,
677 POPULATE_DOT11F_RATES_OPERATIONAL,
678 &frm->ExtSuppRates, pe_session);
679
680 /* Populate HT IEs, when operating in 11n */
681 if (pe_session->htCapability) {
682 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
683 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
684 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 if (pe_session->vhtCapability) {
686 lim_log(mac_ctx, LOG1, FL("Populate VHT IE in Probe Response"));
687 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
688 populate_dot11f_vht_operation(mac_ctx, pe_session,
689 &frm->VHTOperation);
690 /*
691 * we do not support multi users yet.
692 * populate_dot11f_vht_ext_bss_load( mac_ctx,
693 * &frm.VHTExtBssLoad );
694 */
695 is_vht_enabled = true;
696 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -0800698 if (lim_is_session_he_capable(pe_session)) {
699 lim_log(mac_ctx, LOG1, FL("Populate HE IEs"));
700 populate_dot11f_he_caps(mac_ctx, pe_session,
701 &frm->vendor_he_cap);
702 populate_dot11f_he_operation(mac_ctx, pe_session,
703 &frm->vendor_he_op);
704 }
705
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800706 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
707 pe_session);
708
709 if (pe_session->pLimStartBssReq) {
710 populate_dot11f_wpa(mac_ctx,
711 &(pe_session->pLimStartBssReq->rsnIE),
712 &frm->WPA);
713 populate_dot11f_rsn_opaque(mac_ctx,
714 &(pe_session->pLimStartBssReq->rsnIE),
715 &frm->RSNOpaque);
716 }
717
718 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
719 &frm->WMMCaps, pe_session);
720
721#if defined(FEATURE_WLAN_WAPI)
722 if (pe_session->pLimStartBssReq)
723 populate_dot11f_wapi(mac_ctx,
724 &(pe_session->pLimStartBssReq->rsnIE),
725 &frm->WAPI);
726#endif /* defined(FEATURE_WLAN_WAPI) */
727
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728 if (mac_ctx->lim.gpLimRemainOnChanReq)
729 bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
730 sizeof(tSirRemainOnChnReq));
731 else
732 /*
733 * Only use CFG for non-listen mode. This CFG is not working for
734 * concurrency. In listening mode, probe rsp IEs is passed in
735 * the message from SME to PE.
736 */
737 addn_ie_present =
738 (pe_session->addIeParams.probeRespDataLen != 0);
739
740 if (addn_ie_present) {
741
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530742 add_ie = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800743 pe_session->addIeParams.probeRespDataLen);
744 if (NULL == add_ie) {
745 lim_log(mac_ctx, LOGE,
746 FL("add_ie allocation failed"));
747 goto err_ret;
748 }
749
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530750 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751 pe_session->addIeParams.probeRespData_buff,
752 pe_session->addIeParams.probeRespDataLen);
753 addn_ie_len = pe_session->addIeParams.probeRespDataLen;
754
755 if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
756 add_ie, &addn_ie_len, preq_p2pie)) {
757 lim_log(mac_ctx, LOGP,
758 FL("Unable to get addn_ie"));
759 goto err_ret;
760 }
761
762 sir_status = lim_strip_extcap_update_struct(mac_ctx,
763 add_ie, &addn_ie_len,
764 &extracted_ext_cap);
765 if (eSIR_SUCCESS != sir_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 lim_log(mac_ctx, LOG1,
767 FL("Unable to strip off ExtCap IE"));
Selvaraj, Sridhar94ece202016-06-23 20:44:09 +0530768 } else {
769 extracted_ext_cap_flag = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 }
771
772 bytes = bytes + addn_ie_len;
773
774 if (preq_p2pie)
775 p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
776 addn_ie_len);
777
778 if (p2p_ie != NULL) {
779 /* get NoA attribute stream P2P IE */
780 noalen = lim_get_noa_attr_stream(mac_ctx,
781 noa_stream, pe_session);
782 if (noalen != 0) {
783 total_noalen =
784 lim_build_p2p_ie(mac_ctx, &noa_ie[0],
785 &noa_stream[0], noalen);
786 bytes = bytes + total_noalen;
787 }
788 }
789 }
790
Hu Wang411e0cc2016-10-28 14:56:01 +0800791 /*
792 * Extcap IE now support variable length, merge Extcap IE from addn_ie
793 * may change the frame size. Therefore, MUST merge ExtCap IE before
794 * dot11f get packed payload size.
795 */
796 if (extracted_ext_cap_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +0800797 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap,
798 true);
Hu Wang411e0cc2016-10-28 14:56:01 +0800799
800 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
801 if (DOT11F_FAILED(status)) {
802 lim_log(mac_ctx, LOGE,
803 FL("Probe Response size error (0x%08x)."),
804 status);
805 /* We'll fall back on the worst case scenario: */
806 payload = sizeof(tDot11fProbeResponse);
807 } else if (DOT11F_WARNED(status)) {
808 lim_log(mac_ctx, LOGW,
809 FL("Probe Response size warning (0x%08x)."),
810 status);
811 }
812
813 bytes += payload + sizeof(tSirMacMgmtHdr);
814
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530815 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800816 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530817 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800818 lim_log(mac_ctx, LOGP, FL("Probe Response allocation failed"));
819 goto err_ret;
820 }
821 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530822 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823
824 /* Next, we fill out the buffer descriptor: */
825 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
826 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
827 pe_session->selfMacAddr);
828
829 mac_hdr = (tpSirMacMgmtHdr) frame;
830
831 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
832
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800833 /* That done, pack the Probe Response: */
834 status =
835 dot11f_pack_probe_response(mac_ctx, frm,
836 frame + sizeof(tSirMacMgmtHdr),
837 payload, &payload);
838 if (DOT11F_FAILED(status)) {
839 lim_log(mac_ctx, LOGE,
840 FL("Probe Response pack failure (0x%08x)."),
841 status);
842 goto err_ret;
843 } else if (DOT11F_WARNED(status)) {
844 lim_log(mac_ctx, LOGW,
845 FL("Probe Response pack warning (0x%08x)."),
846 status);
847 }
848
849 lim_log(mac_ctx, LOG3, FL("Sending Probe Response frame to "));
850 lim_print_mac_addr(mac_ctx, peer_macaddr, LOG3);
851
852 mac_ctx->sys.probeRespond++;
853
854 if (mac_ctx->lim.gpLimRemainOnChanReq)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530855 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800856 mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
857 (mac_ctx->lim.gpLimRemainOnChanReq->length -
858 sizeof(tSirRemainOnChnReq)));
859
860 if (addn_ie_present)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530861 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862 &add_ie[0], addn_ie_len);
863
864 if (noalen != 0) {
865 if (total_noalen >
866 (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
867 lim_log(mac_ctx, LOGE,
868 FL("Not able to insert NoA, total len=%d"),
869 total_noalen);
870 goto err_ret;
871 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530872 qdf_mem_copy(&frame[bytes - (total_noalen)],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873 &noa_ie[0], total_noalen);
874 }
875 }
876
877 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +0530878 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
879 (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800880 )
881 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
882
883 /* Queue Probe Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530884 qdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800885 (uint16_t) bytes,
886 TXRX_FRM_802_11_MGMT,
887 ANI_TXDIR_TODS,
888 7, lim_tx_complete, frame, tx_flag,
889 sme_sessionid, 0);
890
891 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530892 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800893 lim_log(mac_ctx, LOGE, FL("Could not send Probe Response."));
894
895 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530896 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800897
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530898 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800899 return;
900
901err_ret:
902 if (add_ie != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530903 qdf_mem_free(add_ie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800904 if (frm != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530905 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800906 if (packet != NULL)
907 cds_packet_free((void *)packet);
908 return;
909
910} /* End lim_send_probe_rsp_mgmt_frame. */
911
912void
913lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
914 tSirMacAddr peerMacAddr,
915 tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
916{
917 uint16_t i;
918 uint8_t *pFrame;
919 tDot11fAddTSRequest AddTSReq;
920 tDot11fWMMAddTSRequest WMMAddTSReq;
921 uint32_t nPayload, nBytes, nStatus;
922 tpSirMacMgmtHdr pMacHdr;
923 void *pPacket;
924#ifdef FEATURE_WLAN_ESE
925 uint32_t phyMode;
926#endif
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530927 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800928 uint8_t txFlag = 0;
929 uint8_t smeSessionId = 0;
930
931 if (NULL == psessionEntry) {
932 return;
933 }
934
935 smeSessionId = psessionEntry->smeSessionId;
936
937 if (!pAddTS->wmeTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530938 qdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939
940 AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
941 AddTSReq.DialogToken.token = pAddTS->dialogToken;
942 AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
943 if (pAddTS->lleTspecPresent) {
944 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
945 } else {
946 populate_dot11f_wmmtspec(&pAddTS->tspec,
947 &AddTSReq.WMMTSPEC);
948 }
949
950 if (pAddTS->lleTspecPresent) {
951 AddTSReq.num_WMMTCLAS = 0;
952 AddTSReq.num_TCLAS = pAddTS->numTclas;
953 for (i = 0; i < pAddTS->numTclas; ++i) {
954 populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
955 &AddTSReq.TCLAS[i]);
956 }
957 } else {
958 AddTSReq.num_TCLAS = 0;
959 AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
960 for (i = 0; i < pAddTS->numTclas; ++i) {
961 populate_dot11f_wmmtclas(pMac,
962 &pAddTS->tclasInfo[i],
963 &AddTSReq.WMMTCLAS[i]);
964 }
965 }
966
967 if (pAddTS->tclasProcPresent) {
968 if (pAddTS->lleTspecPresent) {
969 AddTSReq.TCLASSPROC.processing =
970 pAddTS->tclasProc;
971 AddTSReq.TCLASSPROC.present = 1;
972 } else {
973 AddTSReq.WMMTCLASPROC.version = 1;
974 AddTSReq.WMMTCLASPROC.processing =
975 pAddTS->tclasProc;
976 AddTSReq.WMMTCLASPROC.present = 1;
977 }
978 }
979
980 nStatus =
981 dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
982 if (DOT11F_FAILED(nStatus)) {
983 lim_log(pMac, LOGP,
984 FL("Failed to calculate the packed size f"
985 "or an Add TS Request (0x%08x)."), nStatus);
986 /* We'll fall back on the worst case scenario: */
987 nPayload = sizeof(tDot11fAddTSRequest);
988 } else if (DOT11F_WARNED(nStatus)) {
989 lim_log(pMac, LOGW,
990 FL("There were warnings while calculating"
991 "the packed size for an Add TS Request"
992 " (0x%08x)."), nStatus);
993 }
994 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530995 qdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996
997 WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
998 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
999 WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
1000
1001 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
1002 WMMAddTSReq.StatusCode.statusCode = 0;
1003
1004 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
1005#ifdef FEATURE_WLAN_ESE
1006 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
1007
1008 if (phyMode == WNI_CFG_PHY_MODE_11G
1009 || phyMode == WNI_CFG_PHY_MODE_11A) {
1010 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
1011 } else {
1012 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
1013 }
1014 populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
1015 &WMMAddTSReq.ESETrafStrmRateSet,
1016 sizeof(uint8_t));
1017#endif
1018 /* fillWmeTspecIE */
1019
1020 nStatus =
1021 dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
1022 &nPayload);
1023 if (DOT11F_FAILED(nStatus)) {
1024 lim_log(pMac, LOGP,
1025 FL("Failed to calculate the packed size f"
1026 "or a WMM Add TS Request (0x%08x)."),
1027 nStatus);
1028 /* We'll fall back on the worst case scenario: */
1029 nPayload = sizeof(tDot11fAddTSRequest);
1030 } else if (DOT11F_WARNED(nStatus)) {
1031 lim_log(pMac, LOGW,
1032 FL("There were warnings while calculating"
1033 "the packed size for a WMM Add TS Requ"
1034 "est (0x%08x)."), nStatus);
1035 }
1036 }
1037
1038 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1039
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301040 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001041 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301042 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001043 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
1044 "d TS Request."), nBytes);
1045 return;
1046 }
1047 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301048 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049
1050 /* Next, we fill out the buffer descriptor: */
1051 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1052 SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
1053 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1054
1055 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1056
1057#ifdef WLAN_FEATURE_11W
1058 lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
1059#endif
1060
1061 /* That done, pack the struct: */
1062 if (!pAddTS->wmeTspecPresent) {
1063 nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
1064 pFrame +
1065 sizeof(tSirMacMgmtHdr),
1066 nPayload, &nPayload);
1067 if (DOT11F_FAILED(nStatus)) {
1068 lim_log(pMac, LOGE,
1069 FL("Failed to pack an Add TS Request "
1070 "(0x%08x)."), nStatus);
1071 cds_packet_free((void *)pPacket);
1072 return; /* allocated! */
1073 } else if (DOT11F_WARNED(nStatus)) {
1074 lim_log(pMac, LOGW,
1075 FL("There were warnings while packing "
1076 "an Add TS Request (0x%08x)."), nStatus);
1077 }
1078 } else {
1079 nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
1080 pFrame +
1081 sizeof(tSirMacMgmtHdr),
1082 nPayload, &nPayload);
1083 if (DOT11F_FAILED(nStatus)) {
1084 lim_log(pMac, LOGE,
1085 FL("Failed to pack a WMM Add TS Reque"
1086 "st (0x%08x)."), nStatus);
1087 cds_packet_free((void *)pPacket);
1088 return; /* allocated! */
1089 } else if (DOT11F_WARNED(nStatus)) {
1090 lim_log(pMac, LOGW,
1091 FL("There were warnings while packing "
1092 "a WMM Add TS Request (0x%08x)."), nStatus);
1093 }
1094 }
1095
1096 PELOG3(lim_log(pMac, LOG3, FL("Sending an Add TS Request frame to "));
1097 lim_print_mac_addr(pMac, peerMacAddr, LOG3);
1098 )
1099
1100 if ((SIR_BAND_5_GHZ ==
1101 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301102 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1103 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001104 ) {
1105 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1106 }
1107
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301108 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001109 psessionEntry->peSessionId, pMacHdr->fc.subType));
1110
1111 /* Queue Addts Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301112 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001113 TXRX_FRM_802_11_MGMT,
1114 ANI_TXDIR_TODS,
1115 7, lim_tx_complete, pFrame, txFlag,
1116 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301117 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301118 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001119
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301120 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 lim_log(pMac, LOGE, FL("*** Could not send an Add TS Request"
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301122 " (%X) ***"), qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001123 /* Pkt will be freed up by the callback */
1124 }
1125
1126} /* End lim_send_addts_req_action_frame. */
1127
1128/**
1129 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
1130 * @mac_ctx: Handle for mac context
1131 * @status_code: Status code for assoc response frame
1132 * @aid: Association ID
1133 * @peer_addr: Mac address of requesting peer
1134 * @subtype: Assoc/Reassoc
1135 * @sta: Pointer to station node
1136 * @pe_session: PE session id.
1137 *
1138 * Builds and sends association response frame to the requesting peer.
1139 *
1140 * Return: void
1141 */
1142
1143void
1144lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
1145 uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
1146 uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
1147{
1148 static tDot11fAssocResponse frm;
1149 uint8_t *frame;
1150 tpSirMacMgmtHdr mac_hdr;
1151 tSirRetStatus sir_status;
1152 uint8_t lle_mode = 0, addts;
1153 tHalBitVal qos_mode, wme_mode;
Hu Wang411e0cc2016-10-28 14:56:01 +08001154 uint32_t payload, bytes = 0, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001155 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301156 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 tUpdateBeaconParams beacon_params;
1158 uint8_t tx_flag = 0;
1159 uint32_t addn_ie_len = 0;
1160 uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
1161 tpSirAssocReq assoc_req = NULL;
1162 uint8_t sme_session = 0;
1163 bool is_vht = false;
1164 uint16_t stripoff_len = 0;
1165 tDot11fIEExtCap extracted_ext_cap;
1166 bool extracted_flag = false;
1167#ifdef WLAN_FEATURE_11W
1168 uint32_t retry_int;
1169 uint32_t max_retries;
1170#endif
1171
1172 if (NULL == pe_session) {
1173 lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
1174 return;
1175 }
1176
1177 sme_session = pe_session->smeSessionId;
1178
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301179 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001180
1181 limGetQosMode(pe_session, &qos_mode);
1182 limGetWmeMode(pe_session, &wme_mode);
1183
1184 /*
1185 * An Add TS IE is added only if the AP supports it and
1186 * the requesting STA sent a traffic spec.
1187 */
1188 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
1189
1190 frm.Status.status = status_code;
1191
1192 frm.AID.associd = aid | LIM_AID_MASK;
1193
1194 if (NULL == sta) {
1195 populate_dot11f_supp_rates(mac_ctx,
1196 POPULATE_DOT11F_RATES_OPERATIONAL,
1197 &frm.SuppRates, pe_session);
1198 populate_dot11f_ext_supp_rates(mac_ctx,
1199 POPULATE_DOT11F_RATES_OPERATIONAL,
1200 &frm.ExtSuppRates, pe_session);
1201 } else {
1202 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
1203 &frm.ExtSuppRates,
1204 sta->supportedRates.llbRates,
1205 sta->supportedRates.llaRates);
1206 }
1207
1208 if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
1209 eSIR_SUCCESS == status_code) {
1210 assoc_req = (tpSirAssocReq)
1211 pe_session->parsedAssocReq[sta->assocId];
1212 /*
1213 * populate P2P IE in AssocRsp when assocReq from the peer
1214 * includes P2P IE
1215 */
1216 if (assoc_req != NULL && assoc_req->addIEPresent)
1217 populate_dot11_assoc_res_p2p_ie(mac_ctx,
1218 &frm.P2PAssocRes,
1219 assoc_req);
1220 }
1221
1222 if (NULL != sta) {
1223 if (eHAL_SET == qos_mode) {
1224 if (sta->lleEnabled) {
1225 lle_mode = 1;
1226 populate_dot11f_edca_param_set(mac_ctx,
1227 &frm.EDCAParamSet, pe_session);
1228 }
1229 }
1230
1231 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
1232 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
1233 pe_session);
1234
1235 if (sta->wsmEnabled)
1236 populate_dot11f_wmm_caps(&frm.WMMCaps);
1237 }
1238
1239 if (sta->mlmStaContext.htCapability &&
1240 pe_session->htCapability) {
1241 lim_log(mac_ctx, LOG1,
1242 FL("Populate HT IEs in Assoc Response"));
1243 populate_dot11f_ht_caps(mac_ctx, pe_session,
1244 &frm.HTCaps);
Krunal Sonief3294b2015-06-12 15:12:19 -07001245 /*
1246 * Check the STA capability and
1247 * update the HTCaps accordingly
1248 */
1249 frm.HTCaps.supportedChannelWidthSet = (
1250 sta->htSupportedChannelWidthSet <
1251 pe_session->htSupportedChannelWidthSet) ?
1252 sta->htSupportedChannelWidthSet :
1253 pe_session->htSupportedChannelWidthSet;
1254 if (!frm.HTCaps.supportedChannelWidthSet)
1255 frm.HTCaps.shortGI40MHz = 0;
1256
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1258 pe_session);
1259 }
Agrawal Ashishc38e58d2015-09-16 17:17:29 +05301260 lim_log(mac_ctx, LOG1,
1261 FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"),
1262 frm.HTCaps.supportedChannelWidthSet,
1263 frm.HTCaps.mimoPowerSave,
1264 frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz,
1265 frm.HTCaps.shortGI40MHz,
1266 frm.HTCaps.dsssCckMode40MHz,
1267 frm.HTCaps.maxRxAMPDUFactor);
1268
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 if (sta->mlmStaContext.vhtCapability &&
1270 pe_session->vhtCapability) {
1271 lim_log(mac_ctx, LOG1,
1272 FL("Populate VHT IEs in Assoc Response"));
1273 populate_dot11f_vht_caps(mac_ctx, pe_session,
1274 &frm.VHTCaps);
1275 populate_dot11f_vht_operation(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301276 &frm.VHTOperation);
1277 is_vht = true;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301278 } else {
1279 /* Advertise 1x1 if either is HT-STA */
1280 if (frm.HTCaps.present && mac_ctx->hw_dbs_capable)
1281 frm.HTCaps.supportedMCSSet[1] = 0;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301282 }
1283 if (pe_session->vhtCapability &&
1284 pe_session->vendor_vht_sap &&
1285 (assoc_req != NULL) &&
1286 assoc_req->vendor_vht_ie.VHTCaps.present) {
1287 lim_log(mac_ctx, LOG1,
1288 FL("Populate Vendor VHT IEs in Assoc Rsponse"));
1289 frm.vendor_vht_ie.present = 1;
1290 frm.vendor_vht_ie.type =
1291 pe_session->vendor_specific_vht_ie_type;
1292 frm.vendor_vht_ie.sub_type =
1293 pe_session->vendor_specific_vht_ie_sub_type;
1294
1295 frm.vendor_vht_ie.VHTCaps.present = 1;
1296 populate_dot11f_vht_caps(mac_ctx, pe_session,
1297 &frm.vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001298 is_vht = true;
1299 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001300 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1301 pe_session);
1302
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001303 if (lim_is_sta_he_capable(sta) &&
1304 lim_is_session_he_capable(pe_session)) {
1305 lim_log(mac_ctx, LOG1, FL("Populate HE IEs"));
1306 populate_dot11f_he_caps(mac_ctx, pe_session,
1307 &frm.vendor_he_cap);
1308 populate_dot11f_he_operation(mac_ctx, pe_session,
1309 &frm.vendor_he_op);
1310 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311#ifdef WLAN_FEATURE_11W
1312 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1313 if (wlan_cfg_get_int
1314 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1315 &max_retries) != eSIR_SUCCESS)
1316 lim_log(mac_ctx, LOGE,
1317 FL("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure"));
1318 else if (wlan_cfg_get_int
1319 (mac_ctx,
1320 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1321 &retry_int) != eSIR_SUCCESS)
1322 lim_log(mac_ctx, LOGE,
1323 FL("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure"));
1324 else
1325 populate_dot11f_timeout_interval(mac_ctx,
1326 &frm.TimeoutInterval,
1327 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1328 (max_retries -
1329 sta->pmfSaQueryRetryCount)
1330 * retry_int);
1331 }
1332#endif
1333 }
1334
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301335 qdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336
1337 if (LIM_IS_AP_ROLE(pe_session) &&
1338 (pe_session->gLimProtectionControl !=
1339 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1340 lim_decide_ap_protection(mac_ctx, peer_addr,
1341 &beacon_params, pe_session);
1342
1343 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1344 pe_session);
1345 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1346 pe_session);
1347
1348 /*
1349 * Populate Do11capabilities after updating session with
1350 * Assos req details
1351 */
1352 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1353
1354 beacon_params.bssIdx = pe_session->bssIdx;
1355
1356 /* Send message to HAL about beacon parameter change. */
1357 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1358 && beacon_params.paramChangeBitmap) {
1359 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1360 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1361 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362
1363 if (assoc_req != NULL) {
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001364 addn_ie_len = pe_session->addIeParams.assocRespDataLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001365
1366 /* Nonzero length indicates Assoc rsp IE available */
Krishna Kumaar Natarajane4e3a142016-04-01 16:27:51 -07001367 if (addn_ie_len > 0 &&
1368 addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN &&
1369 (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301370 qdf_mem_copy(add_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001371 pe_session->addIeParams.assocRespData_buff,
1372 pe_session->addIeParams.assocRespDataLen);
1373
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301374 qdf_mem_set((uint8_t *) &extracted_ext_cap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001375 sizeof(extracted_ext_cap), 0);
1376
1377 stripoff_len = addn_ie_len;
1378 sir_status =
1379 lim_strip_extcap_update_struct
1380 (mac_ctx, &add_ie[0], &stripoff_len,
1381 &extracted_ext_cap);
1382 if (eSIR_SUCCESS != sir_status) {
1383 lim_log(mac_ctx, LOG1,
1384 FL("strip off extcap IE failed"));
1385 } else {
1386 addn_ie_len = stripoff_len;
1387 extracted_flag = true;
1388 }
1389 bytes = bytes + addn_ie_len;
1390 }
1391 lim_log(mac_ctx, LOG1,
1392 FL("addn_ie_len = %d for Assoc Resp : %d"),
1393 addn_ie_len, assoc_req->addIEPresent);
1394 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001395
1396 /*
1397 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1398 * may change the frame size. Therefore, MUST merge ExtCap IE before
1399 * dot11f get packed payload size.
1400 */
1401 if (extracted_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001402 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap,
1403 true);
Hu Wang411e0cc2016-10-28 14:56:01 +08001404
1405 /* Allocate a buffer for this frame: */
1406 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1407 if (DOT11F_FAILED(status)) {
1408 lim_log(mac_ctx, LOGE,
1409 FL("get Association Response size failure (0x%08x)."),
1410 status);
1411 return;
1412 } else if (DOT11F_WARNED(status)) {
1413 lim_log(mac_ctx, LOGW,
1414 FL("get Association Response size warning (0x%08x)."),
1415 status);
1416 }
1417
1418 bytes += sizeof(tSirMacMgmtHdr) + payload;
1419
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301420 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001421 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301422 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001423 lim_log(mac_ctx, LOGP, FL("cds_packet_alloc failed."));
1424 return;
1425 }
1426 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301427 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428
1429 /* Next, we fill out the buffer descriptor: */
1430 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1431 (LIM_ASSOC == subtype) ?
1432 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1433 peer_addr,
1434 pe_session->selfMacAddr);
1435 mac_hdr = (tpSirMacMgmtHdr) frame;
1436
1437 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1438
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1440 frame + sizeof(tSirMacMgmtHdr),
1441 payload, &payload);
1442 if (DOT11F_FAILED(status)) {
1443 lim_log(mac_ctx, LOGE,
1444 FL("Association Response pack failure(0x%08x)."),
1445 status);
1446 cds_packet_free((void *)packet);
1447 return;
1448 } else if (DOT11F_WARNED(status)) {
1449 lim_log(mac_ctx, LOGW,
1450 FL("Association Response pack warning (0x%08x)."),
1451 status);
1452 }
1453
1454 if (subtype == LIM_ASSOC)
1455 lim_log(mac_ctx, LOG1,
1456 FL("*** Sending Assoc Resp status %d aid %d to "),
1457 status_code, aid);
1458 else
1459 lim_log(mac_ctx, LOG1,
1460 FL("*** Sending ReAssoc Resp status %d aid %d to "),
1461 status_code, aid);
1462
1463 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1464
1465 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301466 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 &add_ie[0], addn_ie_len);
1468
1469 if ((SIR_BAND_5_GHZ ==
1470 lim_get_rf_band(pe_session->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05301471 (pe_session->pePersona == QDF_P2P_CLIENT_MODE) ||
1472 (pe_session->pePersona == QDF_P2P_GO_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001473 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1474
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301475 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 pe_session->peSessionId, mac_hdr->fc.subType));
1477 /* Queue Association Response frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301478 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 TXRX_FRM_802_11_MGMT,
1480 ANI_TXDIR_TODS,
1481 7, lim_tx_complete, frame, tx_flag,
1482 sme_session, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301483 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301484 pe_session->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001485
1486 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301487 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488 lim_log(mac_ctx, LOGE,
1489 FL("*** Could not Send Re/AssocRsp, retCode=%X ***"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301490 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001491
1492 /*
1493 * update the ANI peer station count.
1494 * FIXME_PROTECTION : take care of different type of station
1495 * counter inside this function.
1496 */
1497 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1498
1499}
1500
1501void
1502lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1503 tSirMacAddr peer,
1504 uint8_t wmmTspecPresent,
1505 tSirMacTSInfo *pTsinfo,
1506 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1507{
1508 uint8_t *pFrame;
1509 tpSirMacMgmtHdr pMacHdr;
1510 tDot11fDelTS DelTS;
1511 tDot11fWMMDelTS WMMDelTS;
1512 uint32_t nBytes, nPayload, nStatus;
1513 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301514 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001515 uint8_t txFlag = 0;
1516 uint8_t smeSessionId = 0;
1517
1518 if (NULL == psessionEntry) {
1519 return;
1520 }
1521
1522 smeSessionId = psessionEntry->smeSessionId;
1523
1524 if (!wmmTspecPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301525 qdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526
1527 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1528 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1529 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1530
1531 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1532 if (DOT11F_FAILED(nStatus)) {
1533 lim_log(pMac, LOGP,
1534 FL("Failed to calculate the packed si"
1535 "ze for a Del TS (0x%08x)."), nStatus);
1536 /* We'll fall back on the worst case scenario: */
1537 nPayload = sizeof(tDot11fDelTS);
1538 } else if (DOT11F_WARNED(nStatus)) {
1539 lim_log(pMac, LOGW,
1540 FL("There were warnings while calcula"
1541 "ting the packed size for a Del TS"
1542 " (0x%08x)."), nStatus);
1543 }
1544 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301545 qdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001546
1547 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1548 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1549 WMMDelTS.DialogToken.token = 0;
1550 WMMDelTS.StatusCode.statusCode = 0;
1551 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1552 nStatus =
1553 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1554 if (DOT11F_FAILED(nStatus)) {
1555 lim_log(pMac, LOGP,
1556 FL("Failed to calculate the packed si"
1557 "ze for a WMM Del TS (0x%08x)."), nStatus);
1558 /* We'll fall back on the worst case scenario: */
1559 nPayload = sizeof(tDot11fDelTS);
1560 } else if (DOT11F_WARNED(nStatus)) {
1561 lim_log(pMac, LOGW,
1562 FL("There were warnings while calcula"
1563 "ting the packed size for a WMM De"
1564 "l TS (0x%08x)."), nStatus);
1565 }
1566 }
1567
1568 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1569
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301570 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001571 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1572 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301573 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001574 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
1575 "d TS Response."), nBytes);
1576 return;
1577 }
1578 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301579 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580
1581 /* Next, we fill out the buffer descriptor: */
1582 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1583 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1584 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1585
1586 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1587
1588#ifdef WLAN_FEATURE_11W
1589 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1590#endif
1591
1592 /* That done, pack the struct: */
1593 if (!wmmTspecPresent) {
1594 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1595 pFrame + sizeof(tSirMacMgmtHdr),
1596 nPayload, &nPayload);
1597 if (DOT11F_FAILED(nStatus)) {
1598 lim_log(pMac, LOGE,
1599 FL("Failed to pack a Del TS frame (0x%08x)."),
1600 nStatus);
1601 cds_packet_free((void *)pPacket);
1602 return; /* allocated! */
1603 } else if (DOT11F_WARNED(nStatus)) {
1604 lim_log(pMac, LOGW,
1605 FL("There were warnings while packing "
1606 "a Del TS frame (0x%08x)."), nStatus);
1607 }
1608 } else {
1609 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1610 pFrame + sizeof(tSirMacMgmtHdr),
1611 nPayload, &nPayload);
1612 if (DOT11F_FAILED(nStatus)) {
1613 lim_log(pMac, LOGE,
1614 FL
1615 ("Failed to pack a WMM Del TS frame (0x%08x)."),
1616 nStatus);
1617 cds_packet_free((void *)pPacket);
1618 return; /* allocated! */
1619 } else if (DOT11F_WARNED(nStatus)) {
1620 lim_log(pMac, LOGW,
1621 FL("There were warnings while packing "
1622 "a WMM Del TS frame (0x%08x)."), nStatus);
1623 }
1624 }
1625
1626 PELOG1(lim_log
1627 (pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes);
1628 lim_print_mac_addr(pMac, pMacHdr->da, LOG1);
1629 )
1630
1631 if ((SIR_BAND_5_GHZ ==
1632 lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05301633 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE)
1634 || (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 ) {
1636 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1637 }
1638
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301639 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301641 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642 TXRX_FRM_802_11_MGMT,
1643 ANI_TXDIR_TODS,
1644 7, lim_tx_complete, pFrame, txFlag,
1645 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301646 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301647 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648 /* Pkt will be freed up by the callback */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301649 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 lim_log(pMac, LOGE, FL("Failed to send Del TS (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301651 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652
1653} /* End lim_send_delts_req_action_frame. */
1654
1655/**
1656 * lim_send_assoc_req_mgmt_frame() - Send association request
1657 * @mac_ctx: Handle to MAC context
1658 * @mlm_assoc_req: Association request information
1659 * @pe_session: PE session information
1660 *
1661 * Builds and transmits association request frame to AP.
1662 *
1663 * Return: Void
1664 */
1665
1666void
1667lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1668 tLimMlmAssocReq *mlm_assoc_req,
1669 tpPESession pe_session)
1670{
1671 tDot11fAssocRequest *frm;
1672 uint16_t caps;
1673 uint8_t *frame;
1674 tSirRetStatus sir_status;
1675 tLimMlmAssocCnf assoc_cnf;
Hu Wang411e0cc2016-10-28 14:56:01 +08001676 uint32_t bytes = 0, payload, status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1678 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301679 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 uint16_t add_ie_len;
1681 uint8_t *add_ie;
1682 uint8_t *wps_ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001683 uint8_t power_caps = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001684 uint8_t tx_flag = 0;
1685 uint8_t sme_sessionid = 0;
1686 bool vht_enabled = false;
1687 tDot11fIEExtCap extr_ext_cap;
1688 bool extr_ext_flag = true;
1689 tpSirMacMgmtHdr mac_hdr;
Hu Wangfbd279d2016-10-31 18:24:34 +08001690 uint32_t ie_offset = 0;
1691 uint8_t *p_ext_cap = NULL;
1692 tDot11fIEExtCap bcn_ext_cap;
1693 uint8_t *bcn_ie = NULL;
1694 uint32_t bcn_ie_len = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695
1696 if (NULL == pe_session) {
1697 lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
1698 return;
1699 }
1700
1701 sme_sessionid = pe_session->smeSessionId;
1702
1703 /* check this early to avoid unncessary operation */
1704 if (NULL == pe_session->pLimJoinReq) {
1705 lim_log(mac_ctx, LOGE, FL("pe_session->pLimJoinReq is NULL"));
1706 return;
1707 }
1708 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1709 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1710
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301711 frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001712 if (NULL == frm) {
1713 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
1714 return;
1715 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001716 qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301718 if (add_ie_len && pe_session->is_ext_caps_present) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301719 qdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 0);
1721 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1722 add_ie, &add_ie_len, &extr_ext_cap);
1723 if (eSIR_SUCCESS != sir_status) {
1724 extr_ext_flag = false;
1725 lim_log(mac_ctx, LOG1,
1726 FL("Unable to Stripoff ExtCap IE from Assoc Req"));
1727 } else {
1728 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1729 extr_ext_cap.bytes;
1730
1731 if (p_ext_cap->interworking_service)
1732 p_ext_cap->qos_map = 1;
Hu Wang411e0cc2016-10-28 14:56:01 +08001733 extr_ext_cap.num_bytes =
1734 lim_compute_ext_cap_ie_length(&extr_ext_cap);
1735 extr_ext_flag = (extr_ext_cap.num_bytes > 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001736 }
1737 } else {
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301738 lim_log(mac_ctx, LOG1,
1739 FL("No addn IE or peer dosen't support addnIE for Assoc Req"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740 extr_ext_flag = false;
1741 }
1742
1743 caps = mlm_assoc_req->capabilityInfo;
1744#if defined(FEATURE_WLAN_WAPI)
1745 /*
1746 * According to WAPI standard:
1747 * 7.3.1.4 Capability Information field
1748 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1749 * in transmitted Association or Reassociation management frames.
1750 * APs ignore the Privacy subfield within received Association and
1751 * Reassociation management frames.
1752 */
1753 if (pe_session->encryptType == eSIR_ED_WPI)
1754 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1755#endif
1756 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1757
1758 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1759 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1760 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1761 &frm->SuppRates, pe_session);
1762
1763 qos_enabled = (pe_session->limQosEnabled) &&
1764 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1765
1766 wme_enabled = (pe_session->limWmeEnabled) &&
1767 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1768
1769 /* We prefer .11e asociations: */
1770 if (qos_enabled)
1771 wme_enabled = false;
1772
1773 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1774 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1775
1776 if (pe_session->lim11hEnable &&
1777 pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778 power_caps = true;
1779
1780 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1781 LIM_ASSOC, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001782 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1783 LIM_ASSOC, pe_session);
1784
1785 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1787 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1788 if (power_caps == false) {
1789 power_caps = true;
1790 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1791 LIM_ASSOC, pe_session);
1792 }
1793 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001794 if (qos_enabled)
Naveen Rawatcd118312016-11-22 10:46:21 -08001795 populate_dot11f_qos_caps_station(mac_ctx, pe_session,
1796 &frm->QOSCapsStation);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001797
1798 populate_dot11f_ext_supp_rates(mac_ctx,
1799 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1800 pe_session);
1801
Gupta, Kapil54a16992016-01-13 19:34:02 +05301802 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1803 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1805 pe_session);
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08001806
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807 /*
1808 * The join request *should* contain zero or one of the WPA and RSN
1809 * IEs. The payload send along with the request is a
1810 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1811 * typedef struct sSirRSNie
1812 * {
1813 * uint16_t length;
1814 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1815 * } tSirRSNie, *tpSirRSNie;
1816 * So, we should be able to make the following two calls harmlessly,
1817 * since they do nothing if they don't find the given IE in the
1818 * bytestream with which they're provided.
1819 * The net effect of this will be to faithfully transmit whatever
1820 * security IE is in the join request.
1821 * However, if we're associating for the purpose of WPS
1822 * enrollment, and we've been configured to indicate that by
1823 * eliding the WPA or RSN IE, we just skip this:
1824 */
1825 if (add_ie_len && add_ie)
1826 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1827
1828 if (NULL == wps_ie) {
1829 populate_dot11f_rsn_opaque(mac_ctx,
1830 &(pe_session->pLimJoinReq->rsnIE),
1831 &frm->RSNOpaque);
1832 populate_dot11f_wpa_opaque(mac_ctx,
1833 &(pe_session->pLimJoinReq->rsnIE),
1834 &frm->WPAOpaque);
1835#if defined(FEATURE_WLAN_WAPI)
1836 populate_dot11f_wapi_opaque(mac_ctx,
1837 &(pe_session->pLimJoinReq->rsnIE),
1838 &frm->WAPIOpaque);
1839#endif /* defined(FEATURE_WLAN_WAPI) */
1840 }
1841 /* include WME EDCA IE as well */
1842 if (wme_enabled) {
1843 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1844 pe_session, &frm->WMMInfoStation);
1845
1846 if (wsm_enabled)
1847 populate_dot11f_wmm_caps(&frm->WMMCaps);
1848 }
1849
1850 /*
1851 * Populate HT IEs, when operating in 11n and
1852 * when AP is also operating in 11n mode
1853 */
1854 if (pe_session->htCapability &&
1855 mac_ctx->lim.htCapabilityPresentInBeacon) {
1856 lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
1857 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001858 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1859 &frm->HTCaps, sizeof(frm->HTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 }
Agrawal Ashishc38e58d2015-09-16 17:17:29 +05301861 lim_log(mac_ctx, LOG1,
1862 FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, short GI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"),
1863 frm->HTCaps.supportedChannelWidthSet,
1864 frm->HTCaps.mimoPowerSave,
1865 frm->HTCaps.greenField, frm->HTCaps.shortGI20MHz,
1866 frm->HTCaps.shortGI40MHz,
1867 frm->HTCaps.dsssCckMode40MHz,
1868 frm->HTCaps.maxRxAMPDUFactor);
1869
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001870 if (pe_session->vhtCapability &&
1871 pe_session->vhtCapabilityPresentInBeacon) {
1872 lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request"));
1873 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
Naveen Rawata410c5a2016-09-19 14:22:33 -07001874 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1875 &frm->VHTCaps, sizeof(frm->VHTCaps));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001876 vht_enabled = true;
Kiran Kumar Lokere1d4094e2016-08-31 19:04:04 -07001877 if (pe_session->enableHtSmps &&
1878 !pe_session->supported_nss_1x1) {
1879 lim_log(mac_ctx, LOGE, FL(
1880 "VHT OP mode IE in Assoc Req"));
1881 populate_dot11f_operating_mode(mac_ctx,
1882 &frm->OperatingMode, pe_session);
1883 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001884 }
1885 if (!vht_enabled &&
1886 pe_session->is_vendor_specific_vhtcaps) {
1887 lim_log(mac_ctx, LOG1,
1888 FL("Populate Vendor VHT IEs in Assoc Request"));
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301889 frm->vendor_vht_ie.present = 1;
1890 frm->vendor_vht_ie.type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001891 pe_session->vendor_specific_vht_ie_type;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301892 frm->vendor_vht_ie.sub_type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001893 pe_session->vendor_specific_vht_ie_sub_type;
1894
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301895 frm->vendor_vht_ie.VHTCaps.present = 1;
Kiran Kumar Lokere7599d492017-02-12 17:21:59 -08001896 pe_session->vht_config.su_beam_formee = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001897 populate_dot11f_vht_caps(mac_ctx, pe_session,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301898 &frm->vendor_vht_ie.VHTCaps);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001899 vht_enabled = true;
1900 }
Agrawal Ashish0f94b572016-02-22 13:27:06 +05301901 if (pe_session->is_ext_caps_present)
1902 populate_dot11f_ext_cap(mac_ctx, vht_enabled,
1903 &frm->ExtCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001904
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301905 populate_dot11f_qcn_ie(&frm->QCN_IE);
Krishna Kumaar Natarajan0103ef82017-02-17 18:15:56 -08001906 if (lim_is_session_he_capable(pe_session)) {
1907 lim_log(mac_ctx, LOG1, FL("Populate HE IEs"));
1908 populate_dot11f_he_caps(mac_ctx, pe_session,
1909 &frm->vendor_he_cap);
1910 }
Selvaraj, Sridharc2fe7a32017-02-02 19:20:16 +05301911
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001912 if (pe_session->pLimJoinReq->is11Rconnection) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001913 tSirBssDescription *bssdescr;
1914
1915 bssdescr = &pe_session->pLimJoinReq->bssDescription;
1916 lim_log(mac_ctx, LOG1, FL("mdie = %02x %02x %02x"),
1917 (unsigned int) bssdescr->mdie[0],
1918 (unsigned int) bssdescr->mdie[1],
1919 (unsigned int) bssdescr->mdie[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001920 populate_mdie(mac_ctx, &frm->MobilityDomain,
1921 pe_session->pLimJoinReq->bssDescription.mdie);
1922 } else {
1923 /* No 11r IEs dont send any MDIE */
1924 lim_log(mac_ctx, LOG1, FL("MDIE not present"));
1925 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001926
1927#ifdef FEATURE_WLAN_ESE
1928 /*
1929 * ESE Version IE will be included in association request
1930 * when ESE is enabled on DUT through ini and it is also
1931 * advertised by the peer AP to which we are trying to
1932 * associate to.
1933 */
1934 if (pe_session->is_ese_version_ie_present &&
1935 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1936 populate_dot11f_ese_version(&frm->ESEVersion);
1937 /* For ESE Associations fill the ESE IEs */
1938 if (pe_session->isESEconnection &&
1939 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1940#ifndef FEATURE_DISABLE_RM
1941 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1942#endif
1943 }
1944#endif
1945
Hu Wang411e0cc2016-10-28 14:56:01 +08001946 /*
1947 * Extcap IE now support variable length, merge Extcap IE from addn_ie
1948 * may change the frame size. Therefore, MUST merge ExtCap IE before
1949 * dot11f get packed payload size.
1950 */
1951 if (extr_ext_flag)
Hu Wangfbd279d2016-10-31 18:24:34 +08001952 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap, true);
1953
1954 /* Clear the bits in EXTCAP IE if AP not advertise it in beacon */
1955 if (frm->ExtCap.present && pe_session->is_ext_caps_present) {
1956 ie_offset = DOT11F_FF_TIMESTAMP_LEN +
1957 DOT11F_FF_BEACONINTERVAL_LEN +
1958 DOT11F_FF_CAPABILITIES_LEN;
1959
1960 qdf_mem_zero((uint8_t *)&bcn_ext_cap, sizeof(tDot11fIEExtCap));
1961 if (pe_session->beacon && pe_session->bcnLen > ie_offset) {
1962 bcn_ie = pe_session->beacon + ie_offset;
1963 bcn_ie_len = pe_session->bcnLen - ie_offset;
1964 p_ext_cap = lim_get_ie_ptr_new(mac_ctx,
1965 bcn_ie,
1966 bcn_ie_len,
1967 DOT11F_EID_EXTCAP,
1968 ONE_BYTE);
1969 lim_update_extcap_struct(mac_ctx, p_ext_cap,
1970 &bcn_ext_cap);
1971 lim_merge_extcap_struct(&frm->ExtCap, &bcn_ext_cap,
1972 false);
1973 }
1974 }
Hu Wang411e0cc2016-10-28 14:56:01 +08001975
Arif Hussain6cec6bc2017-02-14 13:46:26 -08001976 if (eSIR_SUCCESS != lim_strip_supp_op_class_update_struct(mac_ctx,
1977 add_ie, &add_ie_len, &frm->SuppOperatingClasses))
1978 lim_log(mac_ctx, LOG1,
1979 FL("Unable to Stripoff supp op classes IE from Assoc Req"));
1980
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1982 if (DOT11F_FAILED(status)) {
1983 lim_log(mac_ctx, LOGP,
1984 FL("Association Request packet size failure(0x%08x)."),
1985 status);
1986 /* We'll fall back on the worst case scenario: */
1987 payload = sizeof(tDot11fAssocRequest);
1988 } else if (DOT11F_WARNED(status)) {
1989 lim_log(mac_ctx, LOGW,
1990 FL("Association request packet size warning (0x%08x)."),
1991 status);
1992 }
1993
1994 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1995
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301996 qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001997 (void **)&packet);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301998 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999 lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes."),
2000 bytes);
2001
2002 pe_session->limMlmState = pe_session->limPrevMlmState;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302003 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002004 pe_session->peSessionId,
2005 pe_session->limMlmState));
2006
2007 /* Update PE session id */
2008 assoc_cnf.sessionId = pe_session->peSessionId;
2009
2010 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
2011
2012 cds_packet_free((void *)packet);
2013
2014 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
2015 (uint32_t *) &assoc_cnf);
2016
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302017 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 return;
2019 }
2020 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302021 qdf_mem_set(frame, bytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002022
2023 /* Next, we fill out the buffer descriptor: */
2024 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2025 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
2026 pe_session->selfMacAddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002027 /* That done, pack the Assoc Request: */
2028 status = dot11f_pack_assoc_request(mac_ctx, frm,
2029 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
2030 if (DOT11F_FAILED(status)) {
2031 lim_log(mac_ctx, LOGE,
2032 FL("Assoc request pack failure (0x%08x)"), status);
2033 cds_packet_free((void *)packet);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302034 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002035 return;
2036 } else if (DOT11F_WARNED(status)) {
2037 lim_log(mac_ctx, LOGW,
2038 FL("Assoc request pack warning (0x%08x)"), status);
2039 }
2040
2041 lim_log(mac_ctx, LOG1,
2042 FL("*** Sending Association Request length %d to "), bytes);
2043 if (pe_session->assocReq != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302044 qdf_mem_free(pe_session->assocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002045 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002046 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047 }
2048
2049 if (add_ie_len) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302050 qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002051 add_ie, add_ie_len);
2052 payload += add_ie_len;
2053 }
2054
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302055 pe_session->assocReq = qdf_mem_malloc(payload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002056 if (NULL == pe_session->assocReq) {
2057 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
2058 } else {
2059 /*
2060 * Store the Assoc request. This is sent to csr/hdd in
2061 * join cnf response.
2062 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302063 qdf_mem_copy(pe_session->assocReq,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002064 frame + sizeof(tSirMacMgmtHdr), payload);
2065 pe_session->assocReqLen = payload;
2066 }
2067
2068 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302069 || (pe_session->pePersona == QDF_P2P_CLIENT_MODE)
2070 || (pe_session->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002071 )
2072 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2073
Anurag Chouhan6d760662016-02-20 16:05:43 +05302074 if (pe_session->pePersona == QDF_P2P_CLIENT_MODE ||
2075 pe_session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002076 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2077
2078#ifdef FEATURE_WLAN_DIAG_SUPPORT
2079 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
2080 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2081#endif
2082 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302083 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002084 pe_session->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302085 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086 wma_tx_frame(mac_ctx, packet,
2087 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
2088 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2089 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302090 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302091 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302092 pe_session->peSessionId, qdf_status));
2093 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002094 lim_log(mac_ctx, LOGE,
2095 FL("Failed to send Association Request (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302096 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302098 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 return;
2100 }
2101 /* Free up buffer allocated for mlm_assoc_req */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302102 qdf_mem_free(mlm_assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103 mlm_assoc_req = NULL;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302104 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002105 return;
2106}
2107
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002108/**
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302109 * lim_auth_tx_complete_cnf()- Confirmation for auth sent over the air
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302110 * @context: pointer to global mac
2111 * @buf: buffer
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302112 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302113 * @params; tx completion params
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302114 *
2115 * Return: This returns QDF_STATUS
2116 */
2117
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302118static QDF_STATUS lim_auth_tx_complete_cnf(void *context,
2119 qdf_nbuf_t buf,
2120 uint32_t tx_complete,
2121 void *params)
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302122{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302123 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
2124
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302125 lim_log(mac_ctx, LOG1,
2126 FL("tx_complete= %d"), tx_complete);
2127 if (tx_complete) {
2128 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_SUCCESS;
2129 /* 'Change' timer for future activations */
2130 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2131 } else {
2132 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2133 }
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302134
2135 if (buf)
2136 qdf_nbuf_free(buf);
2137
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302138 return QDF_STATUS_SUCCESS;
2139}
2140
2141/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002142 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2143 *
2144 * @mac_ctx: Pointer to Global MAC structure
2145 * @auth_frame: Pointer to Authentication frame structure
2146 * @peer_addr: MAC address of destination peer
2147 * @wep_bit: wep bit in frame control for Authentication frame3
2148 * @session: PE session information
2149 *
2150 * This function is called by lim_process_mlm_messages(). Authentication frame
2151 * is formatted and sent when this function is called.
2152 *
2153 * Return: void
2154 */
2155
2156void
2157lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2158 tpSirMacAuthFrameBody auth_frame,
2159 tSirMacAddr peer_addr,
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302160 uint8_t wep_bit,
2161 tpPESession session, bool wait_for_ack)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002162{
2163 uint8_t *frame, *body;
2164 uint32_t frame_len = 0, body_len = 0;
2165 tpSirMacMgmtHdr mac_hdr;
2166 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302167 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002168 uint8_t tx_flag = 0;
2169 uint8_t sme_sessionid = 0;
2170 uint16_t ft_ies_length = 0;
2171
2172 if (NULL == session) {
2173 lim_log(mac_ctx, LOGE, FL("Error: psession Entry is NULL"));
2174 return;
2175 }
2176
2177 sme_sessionid = session->smeSessionId;
2178
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002179 if (wep_bit == LIM_WEP_IN_FC) {
2180 /*
2181 * Auth frame3 to be sent with encrypted framebody
2182 *
2183 * Allocate buffer for Authenticaton frame of size
2184 * equal to management frame header length plus 2 bytes
2185 * each for auth algorithm number, transaction number,
2186 * status code, 128 bytes for challenge text and
2187 * 4 bytes each for IV & ICV.
2188 */
2189 lim_log(mac_ctx, LOG1,
2190 FL("Sending encrypted auth frame to " MAC_ADDRESS_STR
2191 "- wait_for_ack %d"), MAC_ADDR_ARRAY(peer_addr),
2192 wait_for_ack);
2193
2194 frame_len = sizeof(tSirMacMgmtHdr) + LIM_ENCR_AUTH_BODY_LEN;
2195 body_len = LIM_ENCR_AUTH_BODY_LEN;
2196
2197 goto alloc_packet;
2198 }
2199
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 lim_log(mac_ctx, LOG1,
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302201 FL("Sending Auth seq# %d status %d (%d) wait_for_ack %d to "
2202 MAC_ADDRESS_STR),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002203 auth_frame->authTransactionSeqNumber,
2204 auth_frame->authStatusCode,
2205 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302206 wait_for_ack,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002207 MAC_ADDR_ARRAY(peer_addr));
2208
2209 switch (auth_frame->authTransactionSeqNumber) {
2210 case SIR_MAC_AUTH_FRAME_1:
2211 /*
2212 * Allocate buffer for Authenticaton frame of size
2213 * equal to management frame header length plus 2 bytes
2214 * each for auth algorithm number, transaction number
2215 * and status code.
2216 */
2217
2218 frame_len = sizeof(tSirMacMgmtHdr) +
2219 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2220 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2221
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002222 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2223 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2224 0 != session->ftPEContext.pFTPreAuthReq->
2225 ft_ies_length) {
2226 ft_ies_length = session->ftPEContext.
2227 pFTPreAuthReq->ft_ies_length;
2228 frame_len += ft_ies_length;
2229 lim_log(mac_ctx, LOG3,
2230 FL("Auth frame, FTIES length added=%d"),
2231 ft_ies_length);
2232 } else {
2233 lim_log(mac_ctx, LOG3,
2234 FL("Auth frame, Does not contain FTIES!!!"));
2235 frame_len += (2 + SIR_MDIE_SIZE);
2236 }
2237 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002238 break;
2239
2240 case SIR_MAC_AUTH_FRAME_2:
2241 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2242 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2243 (auth_frame->authStatusCode !=
2244 eSIR_MAC_SUCCESS_STATUS))) {
2245 /*
2246 * Allocate buffer for Authenticaton frame of size
2247 * equal to management frame header length plus
2248 * 2 bytes each for auth algorithm number,
2249 * transaction number and status code.
2250 */
2251
2252 frame_len = sizeof(tSirMacMgmtHdr) +
2253 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2254 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2255 } else {
2256 /*
2257 * Shared Key algorithm with challenge text
2258 * to be sent.
2259 *
2260 * Allocate buffer for Authenticaton frame of size
2261 * equal to management frame header length plus
2262 * 2 bytes each for auth algorithm number,
2263 * transaction number, status code and 128 bytes
2264 * for challenge text.
2265 */
2266
2267 frame_len = sizeof(tSirMacMgmtHdr) +
2268 sizeof(tSirMacAuthFrame);
2269 body_len = sizeof(tSirMacAuthFrameBody);
2270 }
2271 break;
2272
2273 case SIR_MAC_AUTH_FRAME_3:
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002274 /*
2275 * Auth frame3 to be sent without encrypted framebody
2276 *
2277 * Allocate buffer for Authenticaton frame of size equal
2278 * to management frame header length plus 2 bytes each
2279 * for auth algorithm number, transaction number and
2280 * status code.
2281 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002282
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002283 frame_len = sizeof(tSirMacMgmtHdr) +
2284 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2285 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002286 break;
2287
2288 case SIR_MAC_AUTH_FRAME_4:
2289 /*
2290 * Allocate buffer for Authenticaton frame of size equal
2291 * to management frame header length plus 2 bytes each
2292 * for auth algorithm number, transaction number and
2293 * status code.
2294 */
2295
2296 frame_len = sizeof(tSirMacMgmtHdr) +
2297 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2298 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2299
2300 break;
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002301 default:
2302 lim_log(mac_ctx, LOGE, FL("Invalid auth transaction seq num."));
2303 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 } /* switch (auth_frame->authTransactionSeqNumber) */
2305
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002306alloc_packet:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302307 qdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002308 (void **)&packet);
2309
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302310 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002311 lim_log(mac_ctx, LOGP,
2312 FL("call to bufAlloc failed for AUTH frame"));
2313 return;
2314 }
2315
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302316 qdf_mem_zero(frame, frame_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002317
2318 /* Prepare BD */
2319 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2320 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2321 mac_hdr = (tpSirMacMgmtHdr) frame;
2322 mac_hdr->fc.wep = wep_bit;
2323
2324 /* Prepare BSSId */
Rajeev Kumarcf835a02016-04-15 15:01:31 -07002325 if (LIM_IS_AP_ROLE(session))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302326 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002327 (uint8_t *) session->bssId,
2328 sizeof(tSirMacAddr));
2329
2330 /* Prepare Authentication frame body */
2331 body = frame + sizeof(tSirMacMgmtHdr);
2332
2333 if (wep_bit == LIM_WEP_IN_FC) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302334 qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002335
2336 lim_log(mac_ctx, LOG1,
Krishna Kumaar Natarajan7e6a23c2016-04-05 14:45:24 -07002337 FL("Sending Auth seq# 3 to " MAC_ADDRESS_STR),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002338 MAC_ADDR_ARRAY(mac_hdr->da));
2339
2340 } else {
2341 *((uint16_t *) (body)) =
2342 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2343 body += sizeof(uint16_t);
2344 body_len -= sizeof(uint16_t);
2345
2346 *((uint16_t *) (body)) =
2347 sir_swap_u16if_needed(
2348 auth_frame->authTransactionSeqNumber);
2349 body += sizeof(uint16_t);
2350 body_len -= sizeof(uint16_t);
2351
2352 *((uint16_t *) (body)) =
2353 sir_swap_u16if_needed(auth_frame->authStatusCode);
2354 body += sizeof(uint16_t);
2355 body_len -= sizeof(uint16_t);
2356 if (body_len <= (sizeof(auth_frame->type) +
2357 sizeof(auth_frame->length) +
2358 sizeof(auth_frame->challengeText)))
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302359 qdf_mem_copy(body, (uint8_t *) &auth_frame->type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002360 body_len);
2361
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002362 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2363 (auth_frame->authTransactionSeqNumber ==
2364 SIR_MAC_AUTH_FRAME_1) &&
2365 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2366
2367 if (ft_ies_length > 0) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302368 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002369 session->ftPEContext.
2370 pFTPreAuthReq->ft_ies,
2371 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 lim_log(mac_ctx, LOG2,
2373 FL("Auth1 Frame FTIE is: "));
2374 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
2375 (uint8_t *) body,
2376 ft_ies_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002377 } else if (NULL != session->ftPEContext.
2378 pFTPreAuthReq->pbssDescription) {
2379 /* MDID attr is 54 */
2380 *body = SIR_MDIE_ELEMENT_ID;
2381 body++;
2382 *body = SIR_MDIE_SIZE;
2383 body++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302384 qdf_mem_copy(body,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002385 &session->ftPEContext.pFTPreAuthReq->
2386 pbssDescription->mdie[0],
2387 SIR_MDIE_SIZE);
2388 }
2389 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390
2391 lim_log(mac_ctx, LOG1,
2392 FL("*** Sending Auth seq# %d status %d (%d) to "
2393 MAC_ADDRESS_STR),
2394 auth_frame->authTransactionSeqNumber,
2395 auth_frame->authStatusCode,
2396 (auth_frame->authStatusCode ==
2397 eSIR_MAC_SUCCESS_STATUS),
2398 MAC_ADDR_ARRAY(mac_hdr->da));
2399 }
2400 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2, frame, frame_len);
2401
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302402 if ((NULL != session->ftPEContext.pFTPreAuthReq) &&
2403 (SIR_BAND_5_GHZ == lim_get_rf_band(
2404 session->ftPEContext.pFTPreAuthReq->preAuthchannelNum)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Deepthi Gowri1de51e32016-09-01 15:47:28 +05302406 else if ((SIR_BAND_5_GHZ ==
2407 lim_get_rf_band(session->currentOperChannel))
2408 || (session->pePersona == QDF_P2P_CLIENT_MODE)
2409 || (session->pePersona == QDF_P2P_GO_MODE))
2410 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002411
Anurag Chouhan6d760662016-02-20 16:05:43 +05302412 if (session->pePersona == QDF_P2P_CLIENT_MODE ||
2413 session->pePersona == QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002414 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2415
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302416 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002417 session->peSessionId, mac_hdr->fc.subType));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002418
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +05302419 if (wait_for_ack) {
2420 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
2421 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
2422 (uint16_t)frame_len,
2423 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
2424 7, lim_tx_complete, frame,
2425 lim_auth_tx_complete_cnf,
2426 tx_flag, sme_sessionid, false, 0);
2427 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2428 session->peSessionId, qdf_status));
2429 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
2430 lim_log(mac_ctx, LOGE,
2431 FL("*** Could not send Auth frame, retCode=%X ***"),
2432 qdf_status);
2433 mac_ctx->auth_ack_status = LIM_AUTH_ACK_RCD_FAILURE;
2434 /* Pkt will be freed up by the callback */
2435 }
2436 } else {
2437 /* Queue Authentication frame in high priority WQ */
2438 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
2439 TXRX_FRM_802_11_MGMT,
2440 ANI_TXDIR_TODS, 7, lim_tx_complete,
2441 frame, tx_flag, sme_sessionid, 0);
2442 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2443 session->peSessionId, qdf_status));
2444 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
2445 lim_log(mac_ctx, LOGE,
2446 FL("*** Could not send Auth frame, retCode=%X ***"),
2447 qdf_status);
2448 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002449 return;
2450}
2451
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302452QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002453{
2454 uint16_t aid;
2455 tpDphHashNode pStaDs;
2456 tLimMlmDeauthReq *pMlmDeauthReq;
2457 tLimMlmDeauthCnf mlmDeauthCnf;
2458 tpPESession psessionEntry;
2459
2460 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
2461 if (pMlmDeauthReq) {
2462 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
2463 lim_deactivate_and_change_timer(pMac,
2464 eLIM_DEAUTH_ACK_TIMER);
2465 }
2466
2467 psessionEntry = pe_find_session_by_session_id(pMac,
2468 pMlmDeauthReq->sessionId);
2469 if (psessionEntry == NULL) {
2470 PELOGE(lim_log(pMac, LOGE,
2471 FL
2472 ("session does not exist for given sessionId"));
2473 )
2474 mlmDeauthCnf.resultCode =
2475 eSIR_SME_INVALID_PARAMETERS;
2476 goto end;
2477 }
2478
2479 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002480 dph_lookup_hash_entry(pMac,
2481 pMlmDeauthReq->peer_macaddr.bytes,
2482 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002483 &psessionEntry->dph.dphHashTable);
2484 if (pStaDs == NULL) {
2485 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2486 goto end;
2487 }
2488
2489 /* / Receive path cleanup with dummy packet */
2490 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2491 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002492 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
2493 (
Abhishek Singhe0680852015-12-16 14:28:48 +05302494#ifdef FEATURE_WLAN_ESE
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002495 (psessionEntry->isESEconnection) ||
Abhishek Singhe0680852015-12-16 14:28:48 +05302496#endif
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002497 (psessionEntry->isFastRoamIniFeatureEnabled) ||
2498 (psessionEntry->is11Rconnection))) {
2499 lim_log(pMac, LOGE,
2500 FL("FT Preauth (%p,%d) Deauth rc %d src = %d"),
2501 psessionEntry,
2502 psessionEntry->peSessionId,
2503 pMlmDeauthReq->reasonCode,
2504 pMlmDeauthReq->deauthTrigger);
2505 lim_ft_cleanup(pMac, psessionEntry);
2506 } else {
2507 lim_log(pMac, LOGE,
2508 FL("No FT Preauth Session Cleanup in role %d"
2509#ifdef FEATURE_WLAN_ESE
2510 " isESE %d"
2511#endif
2512 " isLFR %d"
2513 " is11r %d, Deauth reason %d Trigger = %d"),
2514 psessionEntry->limSystemRole,
2515#ifdef FEATURE_WLAN_ESE
2516 psessionEntry->isESEconnection,
2517#endif
2518 psessionEntry->isFastRoamIniFeatureEnabled,
2519 psessionEntry->is11Rconnection,
Abhishek Singhe0680852015-12-16 14:28:48 +05302520 pMlmDeauthReq->reasonCode,
Deepak Dhamdhere262d95a2016-01-10 16:36:53 -08002521 pMlmDeauthReq->deauthTrigger);
2522 }
2523 /* Free up buffer allocated for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302524 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002525 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
2526 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302527 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528end:
Anurag Chouhanc5548422016-02-24 18:33:27 +05302529 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002530 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002531 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
2532 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
2533 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
2534
2535 /* Free up buffer allocated */
2536 /* for mlmDeauthReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302537 qdf_mem_free(pMlmDeauthReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002538
2539 lim_post_sme_message(pMac,
2540 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302541 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002542}
2543
2544/**
2545 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
2546 *
2547 * @mac_ctx: Handle to MAC context
2548 *
2549 * Sends disassoc confirmation to SME. Removes disassoc request stored
2550 * in lim.
2551 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302552 * Return: QDF_STATUS_SUCCESS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002553 */
2554
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302555QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002556{
2557 uint16_t aid;
2558 tpDphHashNode sta_ds;
2559 tLimMlmDisassocCnf disassoc_cnf;
2560 tpPESession pe_session;
2561 tLimMlmDisassocReq *disassoc_req;
2562
2563 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
2564 if (disassoc_req) {
2565 if (tx_timer_running(
2566 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
2567 lim_deactivate_and_change_timer(mac_ctx,
2568 eLIM_DISASSOC_ACK_TIMER);
2569
2570 pe_session = pe_find_session_by_session_id(
2571 mac_ctx, disassoc_req->sessionId);
2572 if (pe_session == NULL) {
2573 lim_log(mac_ctx, LOGE,
2574 FL("No session for given sessionId"));
2575 disassoc_cnf.resultCode =
2576 eSIR_SME_INVALID_PARAMETERS;
2577 goto end;
2578 }
2579
2580 sta_ds = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002581 disassoc_req->peer_macaddr.bytes, &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002582 &pe_session->dph.dphHashTable);
2583 if (sta_ds == NULL) {
2584 lim_log(mac_ctx, LOGE, FL("StaDs Null"));
2585 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2586 goto end;
2587 }
2588 /* Receive path cleanup with dummy packet */
2589 if (eSIR_SUCCESS !=
2590 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
2591 disassoc_cnf.resultCode =
2592 eSIR_SME_RESOURCES_UNAVAILABLE;
2593 lim_log(mac_ctx, LOGE, FL("cleanup_rx_path error"));
2594 goto end;
2595 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002596 if (LIM_IS_STA_ROLE(pe_session) && (
2597#ifdef FEATURE_WLAN_ESE
2598 (pe_session->isESEconnection) ||
2599#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002600 (pe_session->isFastRoamIniFeatureEnabled) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002601 (pe_session->is11Rconnection)) &&
2602 (disassoc_req->reasonCode !=
2603 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowdaf2599dd2015-11-16 18:20:46 -08002604 lim_log(mac_ctx, LOG1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002605 FL("FT Preauth Session (%p,%d) Clean up"),
2606 pe_session, pe_session->peSessionId);
2607
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002608 /* Delete FT session if there exists one */
2609 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002610 } else {
2611 lim_log(mac_ctx, LOGE,
2612 FL("No FT Preauth Session Clean up in role %d"
2613#ifdef FEATURE_WLAN_ESE
2614 " isESE %d"
2615#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 " isLFR %d"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002617 " is11r %d reason %d"),
2618 GET_LIM_SYSTEM_ROLE(pe_session),
2619#ifdef FEATURE_WLAN_ESE
2620 pe_session->isESEconnection,
2621#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002622 pe_session->isFastRoamIniFeatureEnabled,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002623 pe_session->is11Rconnection,
2624 disassoc_req->reasonCode);
2625 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002626 /* Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302627 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002628 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302629 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002630 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302631 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002632 }
2633end:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302634 qdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
Srinivas Girigowdadd3c5132016-01-05 19:41:27 -08002635 (uint8_t *) disassoc_req->peer_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302636 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002637 disassoc_cnf.aid = disassoc_req->aid;
2638 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
2639
2640 /* Update PE session ID */
2641 disassoc_cnf.sessionId = disassoc_req->sessionId;
2642
2643 if (disassoc_req != NULL) {
2644 /* / Free up buffer allocated for mlmDisassocReq */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302645 qdf_mem_free(disassoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002646 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
2647 }
2648
2649 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
2650 (uint32_t *) &disassoc_cnf);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302651 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652}
2653
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302654QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
2655 qdf_nbuf_t buf,
2656 uint32_t txCompleteSuccess,
2657 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002658{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302659 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2660
Mahesh A Saptasagarfb335422016-07-21 18:32:51 +05302661 lim_log(pMac, LOG1,
2662 FL("txCompleteSuccess: %d"), txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302663
2664 if (buf)
2665 qdf_nbuf_free(buf);
2666
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667 return lim_send_disassoc_cnf(pMac);
2668}
2669
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302670QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
2671 qdf_nbuf_t buf,
2672 uint32_t txCompleteSuccess,
2673 void *params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002674{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05302675 tpAniSirGlobal pMac = (tpAniSirGlobal)context;
2676
Mahesh A Saptasagarfb335422016-07-21 18:32:51 +05302677 lim_log(pMac, LOG1,
2678 FL("txCompleteSuccess: %d"), txCompleteSuccess);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05302679
2680 if (buf)
2681 qdf_nbuf_free(buf);
2682
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002683 return lim_send_deauth_cnf(pMac);
2684}
2685
2686/**
2687 * \brief This function is called to send Disassociate frame.
2688 *
2689 *
2690 * \param pMac Pointer to Global MAC structure
2691 *
2692 * \param nReason Indicates the reason that need to be sent in
2693 * Disassociation frame
2694 *
2695 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
2696 * sent
2697 *
2698 *
2699 */
2700
2701void
2702lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
2703 uint16_t nReason,
2704 tSirMacAddr peer,
2705 tpPESession psessionEntry, bool waitForAck)
2706{
2707 tDot11fDisassociation frm;
2708 uint8_t *pFrame;
2709 tpSirMacMgmtHdr pMacHdr;
2710 uint32_t nBytes, nPayload, nStatus;
2711 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302712 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713 uint8_t txFlag = 0;
2714 uint32_t val = 0;
2715 uint8_t smeSessionId = 0;
2716 if (NULL == psessionEntry) {
2717 return;
2718 }
2719
2720 /*
2721 * In case when cac timer is running for this SAP session then
2722 * avoid sending disassoc out. It is violation of dfs specification.
2723 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302724 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2725 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002726 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302727 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728 FL
2729 ("CAC timer is running, drop disassoc from going out"));
2730 return;
2731 }
2732 smeSessionId = psessionEntry->smeSessionId;
2733
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302734 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002735
2736 frm.Reason.code = nReason;
2737
2738 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
2739 if (DOT11F_FAILED(nStatus)) {
2740 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
2741 "or a Disassociation (0x%08x)."),
2742 nStatus);
2743 /* We'll fall back on the worst case scenario: */
2744 nPayload = sizeof(tDot11fDisassociation);
2745 } else if (DOT11F_WARNED(nStatus)) {
2746 lim_log(pMac, LOGW, FL("There were warnings while calculating "
2747 "the packed size for a Disassociation "
2748 "(0x%08x)."), nStatus);
2749 }
2750
2751 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2752
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302753 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002754 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302755 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002756 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Dis"
2757 "association."), nBytes);
2758 return;
2759 }
2760 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302761 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762
2763 /* Next, we fill out the buffer descriptor: */
2764 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2765 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
2766 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2767
2768 /* Prepare the BSSID */
2769 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2770
2771#ifdef WLAN_FEATURE_11W
2772 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2773#endif
2774
2775 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
2776 sizeof(tSirMacMgmtHdr),
2777 nPayload, &nPayload);
2778 if (DOT11F_FAILED(nStatus)) {
2779 lim_log(pMac, LOGE,
2780 FL("Failed to pack a Disassociation (0x%08x)."),
2781 nStatus);
2782 cds_packet_free((void *)pPacket);
2783 return; /* allocated! */
2784 } else if (DOT11F_WARNED(nStatus)) {
2785 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
2786 "isassociation (0x%08x)."), nStatus);
2787 }
2788
2789 lim_log(pMac, LOG1,
2790 FL("***Sessionid %d Sending Disassociation frame with "
2791 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
2792 MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason,
2793 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
2794 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2795
2796 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302797 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2798 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799 ) {
2800 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2801 }
2802
Sushant Kaushik46556062015-12-02 16:57:47 +05302803 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002804
2805 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302806 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002807 psessionEntry->peSessionId,
2808 pMacHdr->fc.subType));
2809 /* Queue Disassociation frame in high priority WQ */
2810 /* get the duration from the request */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302811 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002812 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2813 TXRX_FRM_802_11_MGMT,
2814 ANI_TXDIR_TODS, 7, lim_tx_complete,
2815 pFrame, lim_disassoc_tx_complete_cnf,
2816 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302817 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302818 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302819 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002820
2821 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
2822
2823 if (tx_timer_change
2824 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
2825 != TX_SUCCESS) {
2826 lim_log(pMac, LOGP,
2827 FL("Unable to change Disassoc ack Timer val"));
2828 return;
2829 } else if (TX_SUCCESS !=
2830 tx_timer_activate(&pMac->lim.limTimers.
2831 gLimDisassocAckTimer)) {
2832 lim_log(pMac, LOGP,
2833 FL("Unable to activate Disassoc ack Timer"));
2834 lim_deactivate_and_change_timer(pMac,
2835 eLIM_DISASSOC_ACK_TIMER);
2836 return;
2837 }
2838 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302839 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002840 psessionEntry->peSessionId,
2841 pMacHdr->fc.subType));
2842 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302843 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002844 TXRX_FRM_802_11_MGMT,
2845 ANI_TXDIR_TODS,
2846 7,
2847 lim_tx_complete, pFrame, txFlag,
2848 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302849 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302850 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302851 psessionEntry->peSessionId, qdf_status));
2852 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002853 lim_log(pMac, LOGE,
2854 FL("Failed to send Disassociation (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302855 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002856 /* Pkt will be freed up by the callback */
2857 }
2858 }
2859} /* End lim_send_disassoc_mgmt_frame. */
2860
2861/**
2862 * \brief This function is called to send a Deauthenticate frame
2863 *
2864 *
2865 * \param pMac Pointer to global MAC structure
2866 *
2867 * \param nReason Indicates the reason that need to be sent in the
2868 * Deauthenticate frame
2869 *
2870 * \param peeer address of the STA to which the frame is to be sent
2871 *
2872 *
2873 */
2874
2875void
2876lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
2877 uint16_t nReason,
2878 tSirMacAddr peer,
2879 tpPESession psessionEntry, bool waitForAck)
2880{
2881 tDot11fDeAuth frm;
2882 uint8_t *pFrame;
2883 tpSirMacMgmtHdr pMacHdr;
2884 uint32_t nBytes, nPayload, nStatus;
2885 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302886 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002887 uint8_t txFlag = 0;
2888 uint32_t val = 0;
2889#ifdef FEATURE_WLAN_TDLS
2890 uint16_t aid;
2891 tpDphHashNode pStaDs;
2892#endif
2893 uint8_t smeSessionId = 0;
2894
2895 if (NULL == psessionEntry) {
2896 return;
2897 }
2898
2899 /*
2900 * In case when cac timer is running for this SAP session then
2901 * avoid deauth frame out. It is violation of dfs specification.
2902 */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302903 if (((psessionEntry->pePersona == QDF_SAP_MODE) ||
2904 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002905 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302906 QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907 FL
2908 ("CAC timer is running, drop the deauth from going out"));
2909 return;
2910 }
2911 smeSessionId = psessionEntry->smeSessionId;
2912
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302913 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002914
2915 frm.Reason.code = nReason;
2916
2917 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
2918 if (DOT11F_FAILED(nStatus)) {
2919 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
2920 "or a De-Authentication (0x%08x)."),
2921 nStatus);
2922 /* We'll fall back on the worst case scenario: */
2923 nPayload = sizeof(tDot11fDeAuth);
2924 } else if (DOT11F_WARNED(nStatus)) {
2925 lim_log(pMac, LOGW, FL("There were warnings while calculating "
2926 "the packed size for a De-Authentication "
2927 "(0x%08x)."), nStatus);
2928 }
2929
2930 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
2931
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302932 qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002933 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302934 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002935 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
2936 "Authentication."), nBytes);
2937 return;
2938 }
2939 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302940 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002941
2942 /* Next, we fill out the buffer descriptor: */
2943 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2944 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
2945 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2946
2947 /* Prepare the BSSID */
2948 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
2949
2950#ifdef WLAN_FEATURE_11W
2951 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
2952#endif
2953
2954 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
2955 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
2956 if (DOT11F_FAILED(nStatus)) {
2957 lim_log(pMac, LOGE,
2958 FL("Failed to pack a DeAuthentication (0x%08x)."),
2959 nStatus);
2960 cds_packet_free((void *)pPacket);
2961 return;
2962 } else if (DOT11F_WARNED(nStatus)) {
2963 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
2964 "e-Authentication (0x%08x)."), nStatus);
2965 }
2966 lim_log(pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with "
2967 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
2968 " ,From " MAC_ADDRESS_STR),
2969 psessionEntry->peSessionId, nReason, waitForAck,
2970 MAC_ADDR_ARRAY(pMacHdr->da),
2971 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
2972
2973 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05302974 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
2975 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002976 ) {
2977 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2978 }
2979
Sushant Kaushik46556062015-12-02 16:57:47 +05302980 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002981#ifdef FEATURE_WLAN_TDLS
2982 pStaDs =
2983 dph_lookup_hash_entry(pMac, peer, &aid,
2984 &psessionEntry->dph.dphHashTable);
2985#endif
2986
2987 if (waitForAck) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302988 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002989 psessionEntry->peSessionId,
2990 pMacHdr->fc.subType));
2991 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302992 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002993 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
2994 TXRX_FRM_802_11_MGMT,
2995 ANI_TXDIR_TODS, 7, lim_tx_complete,
2996 pFrame, lim_deauth_tx_complete_cnf,
2997 txFlag, smeSessionId, false, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302998 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05302999 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303000 psessionEntry->peSessionId, qdf_status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003001 /* Pkt will be freed up by the callback lim_tx_complete */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303002 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003003 lim_log(pMac, LOGE,
3004 FL("Failed to send De-Authentication (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303005 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003006
3007 /* Call lim_process_deauth_ack_timeout which will send
3008 * DeauthCnf for this frame
3009 */
3010 lim_process_deauth_ack_timeout(pMac);
3011 return;
3012 }
3013
3014 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
3015
3016 if (tx_timer_change
3017 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
3018 != TX_SUCCESS) {
3019 lim_log(pMac, LOGP,
3020 FL("Unable to change Deauth ack Timer val"));
3021 return;
3022 } else if (TX_SUCCESS !=
3023 tx_timer_activate(&pMac->lim.limTimers.
3024 gLimDeauthAckTimer)) {
3025 lim_log(pMac, LOGP,
3026 FL("Unable to activate Deauth ack Timer"));
3027 lim_deactivate_and_change_timer(pMac,
3028 eLIM_DEAUTH_ACK_TIMER);
3029 return;
3030 }
3031 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303032 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003033 psessionEntry->peSessionId,
3034 pMacHdr->fc.subType));
3035#ifdef FEATURE_WLAN_TDLS
3036 if ((NULL != pStaDs)
3037 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
3038 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303039 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003040 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3041 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
3042 7, lim_tx_complete, pFrame, txFlag,
3043 smeSessionId, 0);
3044 } else {
3045#endif
3046 /* Queue Disassociation frame in high priority WQ */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303047 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003048 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3049 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3050 7, lim_tx_complete, pFrame, txFlag,
3051 smeSessionId, 0);
3052#ifdef FEATURE_WLAN_TDLS
3053 }
3054#endif
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303055 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303056 psessionEntry->peSessionId, qdf_status));
3057 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003058 lim_log(pMac, LOGE,
3059 FL("Failed to send De-Authentication (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303060 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003061 /* Pkt will be freed up by the callback */
3062 }
3063 }
3064
3065} /* End lim_send_deauth_mgmt_frame. */
3066
3067#ifdef ANI_SUPPORT_11H
3068/**
3069 * \brief Send a Measurement Report Action frame
3070 *
3071 *
3072 * \param pMac Pointer to the global MAC structure
3073 *
3074 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
3075 *
3076 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3077 *
3078 *
3079 */
3080
3081tSirRetStatus
3082lim_send_meas_report_frame(tpAniSirGlobal pMac,
3083 tpSirMacMeasReqActionFrame pMeasReqFrame,
3084 tSirMacAddr peer, tpPESession psessionEntry)
3085{
3086 tDot11fMeasurementReport frm;
3087 uint8_t *pFrame;
3088 tSirRetStatus nSirStatus;
3089 tpSirMacMgmtHdr pMacHdr;
3090 uint32_t nBytes, nPayload, nStatus;
3091 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303092 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003093
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303094 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095
3096 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3097 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3098 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3099
3100 switch (pMeasReqFrame->measReqIE.measType) {
3101 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3102 nSirStatus =
3103 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3104 &frm.MeasurementReport);
3105 break;
3106 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3107 nSirStatus =
3108 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3109 &frm.MeasurementReport);
3110 break;
3111 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3112 nSirStatus =
3113 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3114 &frm.MeasurementReport);
3115 break;
3116 default:
3117 lim_log(pMac, LOGE, FL("Unknown measurement type %d in limSen"
3118 "dMeasReportFrame."),
3119 pMeasReqFrame->measReqIE.measType);
3120 return eSIR_FAILURE;
3121 }
3122
3123 if (eSIR_SUCCESS != nSirStatus)
3124 return eSIR_FAILURE;
3125
3126 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3127 if (DOT11F_FAILED(nStatus)) {
3128 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3129 "or a Measurement Report (0x%08x)."),
3130 nStatus);
3131 /* We'll fall back on the worst case scenario: */
3132 nPayload = sizeof(tDot11fMeasurementReport);
3133 } else if (DOT11F_WARNED(nStatus)) {
3134 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3135 "the packed size for a Measurement Rep"
3136 "ort (0x%08x)."), nStatus);
3137 }
3138
3139 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3140
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303141 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003142 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3143 (uint16_t) nBytes, (void **)&pFrame,
3144 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303145 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003146 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
3147 "Authentication."), nBytes);
3148 return eSIR_FAILURE;
3149 }
3150 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303151 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003152
3153 /* Next, we fill out the buffer descriptor: */
3154 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3155 SIR_MAC_MGMT_ACTION, peer);
3156 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3157
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303158 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003159
3160#ifdef WLAN_FEATURE_11W
3161 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3162#endif
3163
3164 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3165 sizeof(tSirMacMgmtHdr),
3166 nPayload, &nPayload);
3167 if (DOT11F_FAILED(nStatus)) {
3168 lim_log(pMac, LOGE,
3169 FL("Failed to pack a Measurement Report (0x%08x)."),
3170 nStatus);
3171 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3172 (void *)pFrame, (void *)pPacket);
3173 return eSIR_FAILURE; /* allocated! */
3174 } else if (DOT11F_WARNED(nStatus)) {
3175 lim_log(pMac, LOGW, FL("There were warnings while packing a M"
3176 "easurement Report (0x%08x)."), nStatus);
3177 }
3178
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303179 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003180 ((psessionEntry) ? psessionEntry->
3181 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303182 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003183 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3184 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3185 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303186 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303187 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003188 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303189 qdf_status));
3190 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003191 lim_log(pMac, LOGE,
3192 FL("Failed to send a Measurement Report (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303193 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003194 /* Pkt will be freed up by the callback */
3195 return eSIR_FAILURE; /* just allocated... */
3196 }
3197
3198 return eSIR_SUCCESS;
3199
3200} /* End lim_send_meas_report_frame. */
3201
3202/**
3203 * \brief Send a TPC Request Action frame
3204 *
3205 *
3206 * \param pMac Pointer to the global MAC datastructure
3207 *
3208 * \param peer MAC address to which the frame should be sent
3209 *
3210 *
3211 */
3212
3213void
3214lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3215 tSirMacAddr peer, tpPESession psessionEntry)
3216{
3217 tDot11fTPCRequest frm;
3218 uint8_t *pFrame;
3219 tpSirMacMgmtHdr pMacHdr;
3220 uint32_t nBytes, nPayload, nStatus;
3221 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303222 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003223
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303224 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225
3226 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3227 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3228 frm.DialogToken.token = 1;
3229 frm.TPCRequest.present = 1;
3230
3231 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3232 if (DOT11F_FAILED(nStatus)) {
3233 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3234 "or a TPC Request (0x%08x)."), nStatus);
3235 /* We'll fall back on the worst case scenario: */
3236 nPayload = sizeof(tDot11fTPCRequest);
3237 } else if (DOT11F_WARNED(nStatus)) {
3238 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3239 "the packed size for a TPC Request (0x"
3240 "%08x)."), nStatus);
3241 }
3242
3243 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3244
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303245 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003246 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3247 (uint16_t) nBytes, (void **)&pFrame,
3248 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303249 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003250 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3251 " Request."), nBytes);
3252 return;
3253 }
3254 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303255 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003256
3257 /* Next, we fill out the buffer descriptor: */
3258 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3259 SIR_MAC_MGMT_ACTION, peer);
3260 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3261
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303262 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003263
3264#ifdef WLAN_FEATURE_11W
3265 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3266#endif
3267
3268 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3269 sizeof(tSirMacMgmtHdr),
3270 nPayload, &nPayload);
3271 if (DOT11F_FAILED(nStatus)) {
3272 lim_log(pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."),
3273 nStatus);
3274 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3275 (void *)pFrame, (void *)pPacket);
3276 return; /* allocated! */
3277 } else if (DOT11F_WARNED(nStatus)) {
3278 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3279 "PC Request (0x%08x)."), nStatus);
3280 }
3281
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303282 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003283 ((psessionEntry) ? psessionEntry->
3284 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303285 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003286 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3287 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3288 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303289 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303290 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003291 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303292 qdf_status));
3293 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003294 lim_log(pMac, LOGE,
3295 FL("Failed to send a TPC Request (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303296 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003297 /* Pkt will be freed up by the callback */
3298 }
3299
3300} /* End lim_send_tpc_request_frame. */
3301
3302/**
3303 * \brief Send a TPC Report Action frame
3304 *
3305 *
3306 * \param pMac Pointer to the global MAC datastructure
3307 *
3308 * \param pTpcReqFrame Pointer to the received TPC Request
3309 *
3310 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3311 *
3312 *
3313 */
3314
3315tSirRetStatus
3316lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3317 tpSirMacTpcReqActionFrame pTpcReqFrame,
3318 tSirMacAddr peer, tpPESession psessionEntry)
3319{
3320 tDot11fTPCReport frm;
3321 uint8_t *pFrame;
3322 tpSirMacMgmtHdr pMacHdr;
3323 uint32_t nBytes, nPayload, nStatus;
3324 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303325 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003326
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303327 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003328
3329 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3330 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3331 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3332
3333 frm.TPCReport.tx_power = 0;
3334 frm.TPCReport.link_margin = 0;
3335 frm.TPCReport.present = 1;
3336
3337 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3338 if (DOT11F_FAILED(nStatus)) {
3339 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3340 "or a TPC Report (0x%08x)."), nStatus);
3341 /* We'll fall back on the worst case scenario: */
3342 nPayload = sizeof(tDot11fTPCReport);
3343 } else if (DOT11F_WARNED(nStatus)) {
3344 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3345 "the packed size for a TPC Report (0x"
3346 "%08x)."), nStatus);
3347 }
3348
3349 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3350
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303351 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003352 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3353 (uint16_t) nBytes, (void **)&pFrame,
3354 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303355 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003356 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3357 " Report."), nBytes);
3358 return eSIR_FAILURE;
3359 }
3360 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303361 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003362
3363 /* Next, we fill out the buffer descriptor: */
3364 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3365 SIR_MAC_MGMT_ACTION, peer);
3366
3367 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3368
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303369 qdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003370
3371#ifdef WLAN_FEATURE_11W
3372 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3373#endif
3374
3375 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3376 sizeof(tSirMacMgmtHdr),
3377 nPayload, &nPayload);
3378 if (DOT11F_FAILED(nStatus)) {
3379 lim_log(pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."),
3380 nStatus);
3381 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3382 (void *)pFrame, (void *)pPacket);
3383 return eSIR_FAILURE; /* allocated! */
3384 } else if (DOT11F_WARNED(nStatus)) {
3385 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3386 "PC Report (0x%08x)."), nStatus);
3387 }
3388
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303389 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003390 ((psessionEntry) ? psessionEntry->
3391 peSessionId : NO_SESSION), pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303392 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003393 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3394 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3395 lim_tx_complete, pFrame, 0, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303396 MTRACE(qdf_trace
Anurag Chouhan6d760662016-02-20 16:05:43 +05303397 (QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003398 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303399 qdf_status));
3400 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003401 lim_log(pMac, LOGE,
3402 FL("Failed to send a TPC Report (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303403 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003404 /* Pkt will be freed up by the callback */
3405 return eSIR_FAILURE; /* just allocated... */
3406 }
3407
3408 return eSIR_SUCCESS;
3409
3410} /* End lim_send_tpc_report_frame. */
3411#endif /* ANI_SUPPORT_11H */
3412
3413/**
3414 * \brief Send a Channel Switch Announcement
3415 *
3416 *
3417 * \param pMac Pointer to the global MAC datastructure
3418 *
3419 * \param peer MAC address to which this frame will be sent
3420 *
3421 * \param nMode
3422 *
3423 * \param nNewChannel
3424 *
3425 * \param nCount
3426 *
3427 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3428 *
3429 *
3430 */
3431
3432tSirRetStatus
3433lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3434 tSirMacAddr peer,
3435 uint8_t nMode,
3436 uint8_t nNewChannel,
3437 uint8_t nCount, tpPESession psessionEntry)
3438{
3439 tDot11fChannelSwitch frm;
3440 uint8_t *pFrame;
3441 tpSirMacMgmtHdr pMacHdr;
3442 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3443 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303444 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003445 uint8_t txFlag = 0;
3446
3447 uint8_t smeSessionId = 0;
3448
3449 if (psessionEntry == NULL) {
3450 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
3451 return eSIR_FAILURE;
3452 }
3453 smeSessionId = psessionEntry->smeSessionId;
3454
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303455 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003456
3457 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3458 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
3459 frm.ChanSwitchAnn.switchMode = nMode;
3460 frm.ChanSwitchAnn.newChannel = nNewChannel;
3461 frm.ChanSwitchAnn.switchCount = nCount;
3462 frm.ChanSwitchAnn.present = 1;
3463
3464 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
3465 if (DOT11F_FAILED(nStatus)) {
3466 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3467 "or a Channel Switch (0x%08x)."),
3468 nStatus);
3469 /* We'll fall back on the worst case scenario: */
3470 nPayload = sizeof(tDot11fChannelSwitch);
3471 } else if (DOT11F_WARNED(nStatus)) {
3472 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3473 "the packed size for a Channel Switch (0x"
3474 "%08x)."), nStatus);
3475 }
3476
3477 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3478
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303479 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003480 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3481 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303482 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003483 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3484 " Report."), nBytes);
3485 return eSIR_FAILURE;
3486 }
3487 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303488 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003489
3490 /* Next, we fill out the buffer descriptor: */
3491 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3492 SIR_MAC_MGMT_ACTION, peer,
3493 psessionEntry->selfMacAddr);
3494 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303495 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003496 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3497
3498#ifdef WLAN_FEATURE_11W
3499 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3500#endif
3501
3502 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
3503 sizeof(tSirMacMgmtHdr),
3504 nPayload, &nPayload);
3505 if (DOT11F_FAILED(nStatus)) {
3506 lim_log(pMac, LOGE,
3507 FL("Failed to pack a Channel Switch (0x%08x)."),
3508 nStatus);
3509 cds_packet_free((void *)pPacket);
3510 return eSIR_FAILURE; /* allocated! */
3511 } else if (DOT11F_WARNED(nStatus)) {
3512 lim_log(pMac, LOGW, FL("There were warnings while packing a C"
3513 "hannel Switch (0x%08x)."), nStatus);
3514 }
3515
3516 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303517 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3518 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003519 ) {
3520 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3521 }
3522
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303523 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003524 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303525 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003526 TXRX_FRM_802_11_MGMT,
3527 ANI_TXDIR_TODS,
3528 7, lim_tx_complete, pFrame, txFlag,
3529 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303530 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303531 psessionEntry->peSessionId, qdf_status));
3532 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003533 lim_log(pMac, LOGE,
3534 FL("Failed to send a Channel Switch (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303535 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003536 /* Pkt will be freed up by the callback */
3537 return eSIR_FAILURE;
3538 }
3539
3540 return eSIR_SUCCESS;
3541
3542} /* End lim_send_channel_switch_mgmt_frame. */
3543
Abhishek Singh518323d2015-10-19 17:42:01 +05303544/**
3545 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
3546 * action frame over the air .
3547 * @mac_ctx: pointer to global mac structure
3548 * @peer: Destination mac.
3549 * @mode: channel switch mode
3550 * @new_op_class: new op class
3551 * @new_channel: new channel to switch
3552 * @count: channel switch count
3553 *
3554 * This function is called to send ECSA frame.
3555 *
3556 * Return: success if frame is sent else return failure
3557 */
3558
3559tSirRetStatus
3560lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
3561 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
3562 uint8_t new_channel, uint8_t count, tpPESession session_entry)
3563{
3564 tDot11fext_channel_switch_action_frame frm;
3565 uint8_t *frame;
3566 tpSirMacMgmtHdr mac_hdr;
3567 uint32_t num_bytes, n_payload, status;
3568 void *packet;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303569 QDF_STATUS qdf_status;
Abhishek Singh518323d2015-10-19 17:42:01 +05303570 uint8_t txFlag = 0;
3571 uint8_t sme_session_id = 0;
3572
3573 if (session_entry == NULL) {
3574 lim_log(mac_ctx, LOGE, FL("Session entry is NULL!!!"));
3575 return eSIR_FAILURE;
3576 }
3577
3578 sme_session_id = session_entry->smeSessionId;
3579
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303580 qdf_mem_set(&frm, sizeof(frm), 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303581
3582 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
3583 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
3584
3585 frm.ext_chan_switch_ann_action.switch_mode = mode;
3586 frm.ext_chan_switch_ann_action.op_class = new_op_class;
3587 frm.ext_chan_switch_ann_action.new_channel = new_channel;
3588 frm.ext_chan_switch_ann_action.switch_count = count;
3589
3590
3591 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
3592 &frm, &n_payload);
3593 if (DOT11F_FAILED(status)) {
3594 lim_log(mac_ctx, LOGP,
3595 FL("Failed to get packed size for Channel Switch 0x%08x."),
3596 status);
3597 /* We'll fall back on the worst case scenario*/
3598 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
3599 } else if (DOT11F_WARNED(status)) {
3600 lim_log(mac_ctx, LOGW,
3601 FL("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)."),
3602 status);
3603 }
3604
3605 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3606
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303607 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303608 (void **) &frame, (void **) &packet);
3609
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303610 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303611 lim_log(mac_ctx, LOGP,
3612 FL("Failed to allocate %d bytes for a Ext Channel Switch."),
3613 num_bytes);
3614 return eSIR_FAILURE;
3615 }
3616
3617 /* Paranoia*/
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303618 qdf_mem_set(frame, num_bytes, 0);
Abhishek Singh518323d2015-10-19 17:42:01 +05303619
3620 /* Next, we fill out the buffer descriptor */
3621 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3622 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3623 mac_hdr = (tpSirMacMgmtHdr) frame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303624 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
Abhishek Singh518323d2015-10-19 17:42:01 +05303625 (uint8_t *) session_entry->bssId,
3626 sizeof(tSirMacAddr));
3627
3628 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
3629 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3630 if (DOT11F_FAILED(status)) {
3631 lim_log(mac_ctx, LOGE,
3632 FL("Failed to pack a Channel Switch 0x%08x."),
3633 status);
3634 cds_packet_free((void *)packet);
3635 return eSIR_FAILURE;
3636 } else if (DOT11F_WARNED(status)) {
3637 lim_log(mac_ctx, LOGW,
3638 FL("There were warnings while packing a Channel Switch 0x%08x."),
3639 status);
3640 }
3641
3642 if ((SIR_BAND_5_GHZ ==
3643 lim_get_rf_band(session_entry->currentOperChannel)) ||
Anurag Chouhan6d760662016-02-20 16:05:43 +05303644 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3645 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303646 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3647 }
3648
3649 lim_log(mac_ctx, LOG1,
3650 FL("Send Ext channel Switch to :"MAC_ADDRESS_STR" with swcount %d, swmode %d , newchannel %d newops %d"),
3651 MAC_ADDR_ARRAY(mac_hdr->da),
3652 frm.ext_chan_switch_ann_action.switch_count,
3653 frm.ext_chan_switch_ann_action.switch_mode,
3654 frm.ext_chan_switch_ann_action.new_channel,
3655 frm.ext_chan_switch_ann_action.op_class);
3656
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303657 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Abhishek Singh518323d2015-10-19 17:42:01 +05303658 session_entry->peSessionId, mac_hdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303659 qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
Abhishek Singh518323d2015-10-19 17:42:01 +05303660 TXRX_FRM_802_11_MGMT,
3661 ANI_TXDIR_TODS,
3662 7,
3663 lim_tx_complete, frame,
3664 txFlag, sme_session_id, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303665 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303666 session_entry->peSessionId, qdf_status));
3667 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Abhishek Singh518323d2015-10-19 17:42:01 +05303668 lim_log(mac_ctx, LOGE,
3669 FL("Failed to send a Ext Channel Switch %X!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303670 qdf_status);
Abhishek Singh518323d2015-10-19 17:42:01 +05303671 /* Pkt will be freed up by the callback */
3672 return eSIR_FAILURE;
3673 }
3674 return eSIR_SUCCESS;
3675} /* End lim_send_extended_chan_switch_action_frame */
3676
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303677
3678/**
3679 * lim_oper_chan_change_confirm_tx_complete_cnf()- Confirmation for oper_chan_change_confirm
3680 * sent over the air
3681 *
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303682 * @context: pointer to global mac
3683 * @buf: buffer
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303684 * @tx_complete : Sent status
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303685 * @params: tx completion params
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303686 *
3687 * Return: This returns QDF_STATUS
3688 */
3689
3690static QDF_STATUS lim_oper_chan_change_confirm_tx_complete_cnf(
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303691 void *context,
3692 qdf_nbuf_t buf,
3693 uint32_t tx_complete,
3694 void *params)
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303695{
Himanshu Agarwal2fdf77a2016-12-29 11:41:00 +05303696 tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
3697
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303698 lim_log(mac_ctx, LOG1,
3699 FL(" tx_complete= %d"), tx_complete);
Himanshu Agarwal8b472bc2017-01-20 20:49:41 +05303700
3701 if (buf)
3702 qdf_nbuf_free(buf);
3703
Abhishek Singh5695e2a2016-10-28 10:39:12 +05303704 return QDF_STATUS_SUCCESS;
3705}
3706
3707/**
3708 * lim_p2p_oper_chan_change_confirm_action_frame()- function to send
3709 * p2p oper chan change confirm action frame
3710 * @mac_ctx: pointer to global mac structure
3711 * @peer: Destination mac.
3712 * @session_entry: session entry
3713 *
3714 * This function is called to send p2p oper chan change confirm action frame.
3715 *
3716 * Return: success if frame is sent else return failure
3717 */
3718
3719tSirRetStatus
3720lim_p2p_oper_chan_change_confirm_action_frame(tpAniSirGlobal mac_ctx,
3721 tSirMacAddr peer, tpPESession session_entry)
3722{
3723 tDot11fp2p_oper_chan_change_confirm frm;
3724 uint8_t *frame;
3725 tpSirMacMgmtHdr mac_hdr;
3726 uint32_t num_bytes, n_payload, status;
3727 void *packet;
3728 QDF_STATUS qdf_status;
3729 uint8_t tx_flag = 0;
3730 uint8_t sme_session_id = 0;
3731
3732 if (session_entry == NULL) {
3733 lim_log(mac_ctx, LOGE, FL("Session entry is NULL!!!"));
3734 return eSIR_FAILURE;
3735 }
3736
3737 sme_session_id = session_entry->smeSessionId;
3738
3739 qdf_mem_set(&frm, sizeof(frm), 0);
3740
3741 frm.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY;
3742
3743 qdf_mem_copy(frm.p2p_action_oui.oui_data,
3744 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
3745 frm.p2p_action_subtype.subtype = 0x04;
3746 frm.DialogToken.token = 0x0;
3747
3748 if (session_entry->htCapability) {
3749 lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
3750 populate_dot11f_ht_caps(mac_ctx, session_entry, &frm.HTCaps);
3751 }
3752
3753 if (session_entry->vhtCapability) {
3754 lim_log(mac_ctx, LOG1, FL("Populate VHT Caps in Assoc Request"));
3755 populate_dot11f_vht_caps(mac_ctx, session_entry, &frm.VHTCaps);
3756 populate_dot11f_operating_mode(mac_ctx,
3757 &frm.OperatingMode, session_entry);
3758 }
3759
3760 status = dot11f_get_packed_p2p_oper_chan_change_confirmSize(mac_ctx,
3761 &frm, &n_payload);
3762 if (DOT11F_FAILED(status)) {
3763 lim_log(mac_ctx, LOGP,
3764 FL("Failed to get packed size 0x%08x."),
3765 status);
3766 /* We'll fall back on the worst case scenario*/
3767 n_payload = sizeof(tDot11fp2p_oper_chan_change_confirm);
3768 } else if (DOT11F_WARNED(status)) {
3769 lim_log(mac_ctx, LOGW,
3770 FL("There were warnings while calculating the packed size (0x%08x)."),
3771 status);
3772 }
3773
3774 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
3775
3776 qdf_status = cds_packet_alloc((uint16_t)num_bytes,
3777 (void **) &frame, (void **) &packet);
3778
3779 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3780 lim_log(mac_ctx, LOGP,
3781 FL("Failed to allocate %d bytes."),
3782 num_bytes);
3783 return eSIR_FAILURE;
3784 }
3785
3786 qdf_mem_set(frame, num_bytes, 0);
3787
3788 /* Next, fill out the buffer descriptor */
3789 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
3790 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
3791 mac_hdr = (tpSirMacMgmtHdr) frame;
3792 qdf_mem_copy((uint8_t *) mac_hdr->bssId,
3793 (uint8_t *) session_entry->bssId,
3794 sizeof(tSirMacAddr));
3795
3796 status = dot11f_pack_p2p_oper_chan_change_confirm(mac_ctx, &frm,
3797 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
3798 if (DOT11F_FAILED(status)) {
3799 lim_log(mac_ctx, LOGE,
3800 FL("Failed to pack 0x%08x."),
3801 status);
3802 cds_packet_free((void *)packet);
3803 return eSIR_FAILURE;
3804 } else if (DOT11F_WARNED(status)) {
3805 lim_log(mac_ctx, LOGW,
3806 FL("There were warnings while packing 0x%08x."),
3807 status);
3808 }
3809
3810 if ((SIR_BAND_5_GHZ ==
3811 lim_get_rf_band(session_entry->currentOperChannel)) ||
3812 (session_entry->pePersona == QDF_P2P_CLIENT_MODE) ||
3813 (session_entry->pePersona == QDF_P2P_GO_MODE)) {
3814 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3815 }
3816 lim_log(mac_ctx, LOG1, FL("Send frame on channel %d to mac "
3817 MAC_ADDRESS_STR), session_entry->currentOperChannel,
3818 MAC_ADDR_ARRAY(peer));
3819
3820 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3821 session_entry->peSessionId, mac_hdr->fc.subType));
3822
3823 qdf_status = wma_tx_frameWithTxComplete(mac_ctx, packet,
3824 (uint16_t)num_bytes,
3825 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3826 7, lim_tx_complete, frame,
3827 lim_oper_chan_change_confirm_tx_complete_cnf,
3828 tx_flag, sme_session_id, false, 0);
3829
3830 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3831 session_entry->peSessionId, qdf_status));
3832 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3833 lim_log(mac_ctx, LOGE,
3834 FL("Failed to send status %X!"),
3835 qdf_status);
3836 /* Pkt will be freed up by the callback */
3837 return eSIR_FAILURE;
3838 }
3839 return eSIR_SUCCESS;
3840}
3841
3842
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003843tSirRetStatus
3844lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
3845 tSirMacAddr peer,
3846 uint8_t nMode, tpPESession psessionEntry)
3847{
3848 tDot11fOperatingMode frm;
3849 uint8_t *pFrame;
3850 tpSirMacMgmtHdr pMacHdr;
3851 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
3852 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303853 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003854 uint8_t txFlag = 0;
3855
3856 uint8_t smeSessionId = 0;
3857
3858 if (psessionEntry == NULL) {
3859 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
3860 return eSIR_FAILURE;
3861 }
3862 smeSessionId = psessionEntry->smeSessionId;
3863
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303864 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003865
3866 frm.Category.category = SIR_MAC_ACTION_VHT;
3867 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
3868 frm.OperatingMode.chanWidth = nMode;
3869 frm.OperatingMode.rxNSS = 0;
3870 frm.OperatingMode.rxNSSType = 0;
3871
3872 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
3873 if (DOT11F_FAILED(nStatus)) {
3874 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3875 "or a Operating Mode (0x%08x)."),
3876 nStatus);
3877 /* We'll fall back on the worst case scenario: */
3878 nPayload = sizeof(tDot11fOperatingMode);
3879 } else if (DOT11F_WARNED(nStatus)) {
3880 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3881 "the packed size for a Operating Mode (0x"
3882 "%08x)."), nStatus);
3883 }
3884
3885 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3886
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303887 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003888 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3889 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303890 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003891 lim_log(pMac, LOGP,
3892 FL("Failed to allocate %d bytes for a Operating Mode"
3893 " Report."), nBytes);
3894 return eSIR_FAILURE;
3895 }
3896 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303897 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003898
3899 /* Next, we fill out the buffer descriptor: */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303900 if (psessionEntry->pePersona == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003901 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3902 SIR_MAC_MGMT_ACTION, peer,
3903 psessionEntry->selfMacAddr);
3904 else
3905 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3906 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
3907 psessionEntry->selfMacAddr);
3908 pMacHdr = (tpSirMacMgmtHdr) pFrame;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303909 qdf_mem_copy((uint8_t *) pMacHdr->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003910 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
3911 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
3912 sizeof(tSirMacMgmtHdr),
3913 nPayload, &nPayload);
3914 if (DOT11F_FAILED(nStatus)) {
3915 lim_log(pMac, LOGE,
3916 FL("Failed to pack a Operating Mode (0x%08x)."),
3917 nStatus);
3918 cds_packet_free((void *)pPacket);
3919 return eSIR_FAILURE; /* allocated! */
3920 } else if (DOT11F_WARNED(nStatus)) {
3921 lim_log(pMac, LOGW,
3922 FL("There were warnings while packing a Operating Mode"
3923 " (0x%08x)."), nStatus);
3924 }
3925 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05303926 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
3927 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003928 ) {
3929 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3930 }
3931
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303932 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003933 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303934 qdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003935 TXRX_FRM_802_11_MGMT,
3936 ANI_TXDIR_TODS,
3937 7, lim_tx_complete, pFrame, txFlag,
3938 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303939 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303940 psessionEntry->peSessionId, qdf_status));
3941 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003942 lim_log(pMac, LOGE,
3943 FL("Failed to send a Channel Switch (%X)!"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303944 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003945 /* Pkt will be freed up by the callback */
3946 return eSIR_FAILURE;
3947 }
3948
3949 return eSIR_SUCCESS;
3950}
3951
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003952/**
3953 * \brief Send a Neighbor Report Request Action frame
3954 *
3955 *
3956 * \param pMac Pointer to the global MAC structure
3957 *
3958 * \param pNeighborReq Address of a tSirMacNeighborReportReq
3959 *
3960 * \param peer mac address of peer station.
3961 *
3962 * \param psessionEntry address of session entry.
3963 *
3964 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3965 *
3966 *
3967 */
3968
3969tSirRetStatus
3970lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
3971 tpSirMacNeighborReportReq pNeighborReq,
3972 tSirMacAddr peer, tpPESession psessionEntry)
3973{
3974 tSirRetStatus statusCode = eSIR_SUCCESS;
3975 tDot11fNeighborReportRequest frm;
3976 uint8_t *pFrame;
3977 tpSirMacMgmtHdr pMacHdr;
3978 uint32_t nBytes, nPayload, nStatus;
3979 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303980 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003981 uint8_t txFlag = 0;
3982 uint8_t smeSessionId = 0;
3983
3984 if (psessionEntry == NULL) {
3985 lim_log(pMac, LOGE,
3986 FL
3987 ("(psession == NULL) in Request to send Neighbor Report request action frame"));
3988 return eSIR_FAILURE;
3989 }
3990 smeSessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303991 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003992
3993 frm.Category.category = SIR_MAC_ACTION_RRM;
3994 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
3995 frm.DialogToken.token = pNeighborReq->dialogToken;
3996
3997 if (pNeighborReq->ssid_present) {
3998 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
3999 }
4000
4001 nStatus =
4002 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
4003 if (DOT11F_FAILED(nStatus)) {
4004 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4005 "or a Neighbor Report Request(0x%08x)."),
4006 nStatus);
4007 /* We'll fall back on the worst case scenario: */
4008 nPayload = sizeof(tDot11fNeighborReportRequest);
4009 } else if (DOT11F_WARNED(nStatus)) {
4010 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4011 "the packed size for a Neighbor Rep"
4012 "ort Request(0x%08x)."), nStatus);
4013 }
4014
4015 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4016
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304017 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004018 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4019 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304020 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004021 lim_log(pMac, LOGP,
4022 FL("Failed to allocate %d bytes for a Neighbor "
4023 "Report Request."), nBytes);
4024 return eSIR_FAILURE;
4025 }
4026 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304027 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004028
4029 /* Copy necessary info to BD */
4030 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4031 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4032
4033 /* Update A3 with the BSSID */
4034 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4035
4036 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4037
4038#ifdef WLAN_FEATURE_11W
4039 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4040#endif
4041
4042 /* Now, we're ready to "pack" the frames */
4043 nStatus = dot11f_pack_neighbor_report_request(pMac,
4044 &frm,
4045 pFrame +
4046 sizeof(tSirMacMgmtHdr),
4047 nPayload, &nPayload);
4048
4049 if (DOT11F_FAILED(nStatus)) {
4050 lim_log(pMac, LOGE,
4051 FL
4052 ("Failed to pack an Neighbor Report Request (0x%08x)."),
4053 nStatus);
4054
4055 /* FIXME - Need to convert to tSirRetStatus */
4056 statusCode = eSIR_FAILURE;
4057 goto returnAfterError;
4058 } else if (DOT11F_WARNED(nStatus)) {
4059 lim_log(pMac, LOGW,
4060 FL("There were warnings while packing Neighbor Report "
4061 "Request (0x%08x)."), nStatus);
4062 }
4063
4064 lim_log(pMac, LOGW, FL("Sending a Neighbor Report Request to "));
4065 lim_print_mac_addr(pMac, peer, LOGW);
4066
4067 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304068 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4069 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004070 ) {
4071 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4072 }
4073
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304074 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004075 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304076 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004077 pPacket,
4078 (uint16_t) nBytes,
4079 TXRX_FRM_802_11_MGMT,
4080 ANI_TXDIR_TODS,
4081 7, lim_tx_complete, pFrame, txFlag,
4082 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304083 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304084 psessionEntry->peSessionId, qdf_status));
4085 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004086 PELOGE(lim_log
4087 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304088 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004089 )
4090 statusCode = eSIR_FAILURE;
4091 /* Pkt will be freed up by the callback */
4092 return statusCode;
4093 } else
4094 return eSIR_SUCCESS;
4095
4096returnAfterError:
4097 cds_packet_free((void *)pPacket);
4098
4099 return statusCode;
4100} /* End lim_send_neighbor_report_request_frame. */
4101
4102/**
4103 * \brief Send a Link Report Action frame
4104 *
4105 *
4106 * \param pMac Pointer to the global MAC structure
4107 *
4108 * \param pLinkReport Address of a tSirMacLinkReport
4109 *
4110 * \param peer mac address of peer station.
4111 *
4112 * \param psessionEntry address of session entry.
4113 *
4114 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4115 *
4116 *
4117 */
4118
4119tSirRetStatus
4120lim_send_link_report_action_frame(tpAniSirGlobal pMac,
4121 tpSirMacLinkReport pLinkReport,
4122 tSirMacAddr peer, tpPESession psessionEntry)
4123{
4124 tSirRetStatus statusCode = eSIR_SUCCESS;
4125 tDot11fLinkMeasurementReport frm;
4126 uint8_t *pFrame;
4127 tpSirMacMgmtHdr pMacHdr;
4128 uint32_t nBytes, nPayload, nStatus;
4129 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304130 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004131 uint8_t txFlag = 0;
4132 uint8_t smeSessionId = 0;
4133
4134 if (psessionEntry == NULL) {
4135 lim_log(pMac, LOGE,
4136 FL
4137 ("(psession == NULL) in Request to send Link Report action frame"));
4138 return eSIR_FAILURE;
4139 }
4140
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304141 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004142
4143 frm.Category.category = SIR_MAC_ACTION_RRM;
4144 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
4145 frm.DialogToken.token = pLinkReport->dialogToken;
4146
4147 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
4148 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
4149 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
4150 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
4151 /* such case this way than changing the frame parser. */
4152 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
4153 frm.TPCEleLen.TPCLen = 2;
4154 frm.TxPower.txPower = pLinkReport->txPower;
4155 frm.LinkMargin.linkMargin = 0;
4156
4157 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4158 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4159 frm.RCPI.rcpi = pLinkReport->rcpi;
4160 frm.RSNI.rsni = pLinkReport->rsni;
4161
4162 nStatus =
4163 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4164 if (DOT11F_FAILED(nStatus)) {
4165 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4166 "or a Link Report (0x%08x)."), nStatus);
4167 /* We'll fall back on the worst case scenario: */
4168 nPayload = sizeof(tDot11fLinkMeasurementReport);
4169 } else if (DOT11F_WARNED(nStatus)) {
4170 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4171 "the packed size for a Link Rep"
4172 "ort (0x%08x)."), nStatus);
4173 }
4174
4175 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4176
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304177 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004178 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4179 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304180 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004181 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Link "
4182 "Report."), nBytes);
4183 return eSIR_FAILURE;
4184 }
4185 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304186 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004187
4188 /* Copy necessary info to BD */
4189 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4190 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4191
4192 /* Update A3 with the BSSID */
4193 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4194
4195 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4196
4197#ifdef WLAN_FEATURE_11W
4198 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4199#endif
4200
4201 /* Now, we're ready to "pack" the frames */
4202 nStatus = dot11f_pack_link_measurement_report(pMac,
4203 &frm,
4204 pFrame +
4205 sizeof(tSirMacMgmtHdr),
4206 nPayload, &nPayload);
4207
4208 if (DOT11F_FAILED(nStatus)) {
4209 lim_log(pMac, LOGE,
4210 FL("Failed to pack an Link Report (0x%08x)."), nStatus);
4211
4212 /* FIXME - Need to convert to tSirRetStatus */
4213 statusCode = eSIR_FAILURE;
4214 goto returnAfterError;
4215 } else if (DOT11F_WARNED(nStatus)) {
4216 lim_log(pMac, LOGW,
4217 FL
4218 ("There were warnings while packing Link Report (0x%08x)."),
4219 nStatus);
4220 }
4221
4222 lim_log(pMac, LOGW, FL("Sending a Link Report to "));
4223 lim_print_mac_addr(pMac, peer, LOGW);
4224
4225 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304226 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4227 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004228 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4229 }
4230
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304231 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004232 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304233 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004234 pPacket,
4235 (uint16_t) nBytes,
4236 TXRX_FRM_802_11_MGMT,
4237 ANI_TXDIR_TODS,
4238 7, lim_tx_complete, pFrame, txFlag,
4239 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304240 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304241 psessionEntry->peSessionId, qdf_status));
4242 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004243 PELOGE(lim_log
4244 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304245 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004246 )
4247 statusCode = eSIR_FAILURE;
4248 /* Pkt will be freed up by the callback */
4249 return statusCode;
4250 } else
4251 return eSIR_SUCCESS;
4252
4253returnAfterError:
4254 cds_packet_free((void *)pPacket);
4255
4256 return statusCode;
4257} /* End lim_send_link_report_action_frame. */
4258
4259/**
4260 * \brief Send a Beacon Report Action frame
4261 *
4262 *
4263 * \param pMac Pointer to the global MAC structure
4264 *
4265 * \param dialog_token dialog token to be used in the action frame.
4266 *
4267 * \param num_report number of reports in pRRMReport.
4268 *
4269 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4270 *
4271 * \param peer mac address of peer station.
4272 *
4273 * \param psessionEntry address of session entry.
4274 *
4275 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4276 *
4277 *
4278 */
4279
4280tSirRetStatus
4281lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4282 uint8_t dialog_token,
4283 uint8_t num_report,
4284 tpSirMacRadioMeasureReport pRRMReport,
4285 tSirMacAddr peer,
4286 tpPESession psessionEntry)
4287{
4288 tSirRetStatus statusCode = eSIR_SUCCESS;
4289 uint8_t *pFrame;
4290 tpSirMacMgmtHdr pMacHdr;
4291 uint32_t nBytes, nPayload, nStatus;
4292 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304293 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004294 uint8_t i;
4295 uint8_t txFlag = 0;
4296 uint8_t smeSessionId = 0;
4297
4298 tDot11fRadioMeasurementReport *frm =
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304299 qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004300 if (!frm) {
4301 lim_log(pMac, LOGE,
4302 FL
4303 ("Not enough memory to allocate tDot11fRadioMeasurementReport"));
4304 return eSIR_MEM_ALLOC_FAILED;
4305 }
4306
4307 if (psessionEntry == NULL) {
4308 lim_log(pMac, LOGE,
4309 FL
4310 ("(psession == NULL) in Request to send Beacon Report action frame"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304311 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004312 return eSIR_FAILURE;
4313 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004314
Padma, Santhosh Kumar93ec7d22016-12-26 15:58:37 +05304315 lim_log(pMac, LOG1, FL("dialog_token %d num_report %d"),
4316 dialog_token, num_report);
4317
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004318 frm->Category.category = SIR_MAC_ACTION_RRM;
4319 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4320 frm->DialogToken.token = dialog_token;
4321
4322 frm->num_MeasurementReport =
4323 (num_report >
4324 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4325 num_report;
4326
4327 for (i = 0; i < frm->num_MeasurementReport; i++) {
4328 frm->MeasurementReport[i].type = pRRMReport[i].type;
4329 frm->MeasurementReport[i].token = pRRMReport[i].token;
4330 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4331 switch (pRRMReport[i].type) {
4332 case SIR_MAC_RRM_BEACON_TYPE:
4333 populate_dot11f_beacon_report(pMac,
4334 &frm->MeasurementReport[i],
4335 &pRRMReport[i].report.
4336 beaconReport);
4337 frm->MeasurementReport[i].incapable =
4338 pRRMReport[i].incapable;
4339 frm->MeasurementReport[i].refused =
4340 pRRMReport[i].refused;
4341 frm->MeasurementReport[i].present = 1;
4342 break;
4343 default:
4344 frm->MeasurementReport[i].incapable =
4345 pRRMReport[i].incapable;
4346 frm->MeasurementReport[i].refused =
4347 pRRMReport[i].refused;
4348 frm->MeasurementReport[i].present = 1;
4349 break;
4350 }
4351 }
4352
4353 nStatus =
4354 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4355 if (DOT11F_FAILED(nStatus)) {
4356 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4357 "or a Radio Measure Report (0x%08x)."),
4358 nStatus);
4359 /* We'll fall back on the worst case scenario: */
4360 nPayload = sizeof(tDot11fLinkMeasurementReport);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304361 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004362 return eSIR_FAILURE;
4363 } else if (DOT11F_WARNED(nStatus)) {
4364 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4365 "the packed size for a Radio Measure Rep"
4366 "ort (0x%08x)."), nStatus);
4367 }
4368
4369 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4370
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304371 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004372 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4373 (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304374 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004375 lim_log(pMac, LOGP,
4376 FL("Failed to allocate %d bytes for a Radio Measure "
4377 "Report."), nBytes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304378 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004379 return eSIR_FAILURE;
4380 }
4381 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304382 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004383
4384 /* Copy necessary info to BD */
4385 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4386 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4387
4388 /* Update A3 with the BSSID */
4389 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4390
4391 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4392
4393#ifdef WLAN_FEATURE_11W
4394 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4395#endif
4396
4397 /* Now, we're ready to "pack" the frames */
4398 nStatus = dot11f_pack_radio_measurement_report(pMac,
4399 frm,
4400 pFrame +
4401 sizeof(tSirMacMgmtHdr),
4402 nPayload, &nPayload);
4403
4404 if (DOT11F_FAILED(nStatus)) {
4405 lim_log(pMac, LOGE,
4406 FL("Failed to pack an Radio Measure Report (0x%08x)."),
4407 nStatus);
4408
4409 /* FIXME - Need to convert to tSirRetStatus */
4410 statusCode = eSIR_FAILURE;
4411 goto returnAfterError;
4412 } else if (DOT11F_WARNED(nStatus)) {
4413 lim_log(pMac, LOGW,
4414 FL("There were warnings while packing Radio "
4415 "Measure Report (0x%08x)."), nStatus);
4416 }
4417
4418 lim_log(pMac, LOGW, FL("Sending a Radio Measure Report to "));
4419 lim_print_mac_addr(pMac, peer, LOGW);
4420
4421 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
Anurag Chouhan6d760662016-02-20 16:05:43 +05304422 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4423 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004424 ) {
4425 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4426 }
4427
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304428 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004429 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304430 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004431 pPacket,
4432 (uint16_t) nBytes,
4433 TXRX_FRM_802_11_MGMT,
4434 ANI_TXDIR_TODS,
4435 7, lim_tx_complete, pFrame, txFlag,
4436 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304437 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304438 psessionEntry->peSessionId, qdf_status));
4439 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004440 PELOGE(lim_log
4441 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304442 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004443 )
4444 statusCode = eSIR_FAILURE;
4445 /* Pkt will be freed up by the callback */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304446 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004447 return statusCode;
4448 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304449 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004450 return eSIR_SUCCESS;
4451 }
4452
4453returnAfterError:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304454 qdf_mem_free(frm);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004455 cds_packet_free((void *)pPacket);
4456 return statusCode;
4457}
4458
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004459#ifdef WLAN_FEATURE_11W
4460/**
4461 * \brief Send SA query request action frame to peer
4462 *
4463 * \sa lim_send_sa_query_request_frame
4464 *
4465 *
4466 * \param pMac The global tpAniSirGlobal object
4467 *
4468 * \param transId Transaction identifier
4469 *
4470 * \param peer The Mac address of the station to which this action frame is addressed
4471 *
4472 * \param psessionEntry The PE session entry
4473 *
4474 * \return eSIR_SUCCESS if setup completes successfully
4475 * eSIR_FAILURE is some problem is encountered
4476 */
4477
4478tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4479 tSirMacAddr peer,
4480 tpPESession psessionEntry)
4481{
4482
4483 tDot11fSaQueryReq frm; /* SA query request action frame */
4484 uint8_t *pFrame;
4485 tSirRetStatus nSirStatus;
4486 tpSirMacMgmtHdr pMacHdr;
4487 uint32_t nBytes, nPayload, nStatus;
4488 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304489 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004490 uint8_t txFlag = 0;
4491 uint8_t smeSessionId = 0;
4492
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304493 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004494 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4495 /* 11w action field is :
4496 action: 0 --> SA Query Request action frame
4497 action: 1 --> SA Query Response action frame */
4498 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4499 /* 11w SA Query Request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304500 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004501
4502 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4503 if (DOT11F_FAILED(nStatus)) {
4504 lim_log(pMac, LOGP, FL("Failed to calculate the packed size "
4505 "for an SA Query Request (0x%08x)."),
4506 nStatus);
4507 /* We'll fall back on the worst case scenario: */
4508 nPayload = sizeof(tDot11fSaQueryReq);
4509 } else if (DOT11F_WARNED(nStatus)) {
4510 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4511 "the packed size for an SA Query Request"
4512 " (0x%08x)."), nStatus);
4513 }
4514
4515 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304516 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004517 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304518 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004519 lim_log(pMac, LOGP,
4520 FL("Failed to allocate %d bytes for a SA Query Request "
4521 "action frame"), nBytes);
4522 return eSIR_FAILURE;
4523 }
4524 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304525 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004526
4527 /* Copy necessary info to BD */
4528 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4529 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4530
4531 /* Update A3 with the BSSID */
4532 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4533
4534 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4535
4536 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4537 /* in the FC */
4538 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4539
4540 /* Pack 11w SA Query Request frame */
4541 nStatus = dot11f_pack_sa_query_req(pMac,
4542 &frm,
4543 pFrame + sizeof(tSirMacMgmtHdr),
4544 nPayload, &nPayload);
4545
4546 if (DOT11F_FAILED(nStatus)) {
4547 lim_log(pMac, LOGE,
4548 FL("Failed to pack an SA Query Request (0x%08x)."),
4549 nStatus);
4550 /* FIXME - Need to convert to tSirRetStatus */
4551 nSirStatus = eSIR_FAILURE;
4552 goto returnAfterError;
4553 } else if (DOT11F_WARNED(nStatus)) {
4554 lim_log(pMac, LOGW,
4555 FL
4556 ("There were warnings while packing SA Query Request (0x%08x)."),
4557 nStatus);
4558 }
4559
4560 lim_log(pMac, LOG1, FL("Sending an SA Query Request to "));
4561 lim_print_mac_addr(pMac, peer, LOG1);
4562 lim_log(pMac, LOG1, FL("Sending an SA Query Request from "));
4563 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOG1);
4564
4565 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4566#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304567 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4568 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004569#endif
4570 ) {
4571 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4572 }
4573 smeSessionId = psessionEntry->smeSessionId;
4574
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304575 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004576 pPacket,
4577 (uint16_t) nBytes,
4578 TXRX_FRM_802_11_MGMT,
4579 ANI_TXDIR_TODS,
4580 7, lim_tx_complete, pFrame, txFlag,
4581 smeSessionId, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304582 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004583 PELOGE(lim_log
4584 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304585 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004586 )
4587 nSirStatus = eSIR_FAILURE;
4588 /* Pkt will be freed up by the callback */
4589 return nSirStatus;
4590 } else {
4591 return eSIR_SUCCESS;
4592 }
4593
4594returnAfterError:
4595 cds_packet_free((void *)pPacket);
4596 return nSirStatus;
4597} /* End lim_send_sa_query_request_frame */
4598
4599/**
4600 * \brief Send SA query response action frame to peer
4601 *
4602 * \sa lim_send_sa_query_response_frame
4603 *
4604 *
4605 * \param pMac The global tpAniSirGlobal object
4606 *
4607 * \param transId Transaction identifier received in SA query request action frame
4608 *
4609 * \param peer The Mac address of the AP to which this action frame is addressed
4610 *
4611 * \param psessionEntry The PE session entry
4612 *
4613 * \return eSIR_SUCCESS if setup completes successfully
4614 * eSIR_FAILURE is some problem is encountered
4615 */
4616
4617tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
4618 uint8_t *transId, tSirMacAddr peer,
4619 tpPESession psessionEntry)
4620{
4621
4622 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
4623 uint8_t *pFrame;
4624 tSirRetStatus nSirStatus;
4625 tpSirMacMgmtHdr pMacHdr;
4626 uint32_t nBytes, nPayload, nStatus;
4627 void *pPacket;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304628 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004629 uint8_t txFlag = 0;
4630 uint8_t smeSessionId = 0;
4631
4632 smeSessionId = psessionEntry->smeSessionId;
4633
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304634 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004635 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4636 /*11w action field is :
4637 action: 0 --> SA query request action frame
4638 action: 1 --> SA query response action frame */
4639 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
4640 /*11w SA query response transId is same as
4641 SA query request transId */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304642 qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004643
4644 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
4645 if (DOT11F_FAILED(nStatus)) {
4646 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4647 "or a SA Query Response (0x%08x)."),
4648 nStatus);
4649 /* We'll fall back on the worst case scenario: */
4650 nPayload = sizeof(tDot11fSaQueryRsp);
4651 } else if (DOT11F_WARNED(nStatus)) {
4652 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4653 "the packed size for an SA Query Response"
4654 " (0x%08x)."), nStatus);
4655 }
4656
4657 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304658 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004659 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304660 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004661 lim_log(pMac, LOGP,
4662 FL("Failed to allocate %d bytes for a SA query response"
4663 " action frame"), nBytes);
4664 return eSIR_FAILURE;
4665 }
4666 /* Paranoia: */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304667 qdf_mem_set(pFrame, nBytes, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004668
4669 /* Copy necessary info to BD */
4670 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4671 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4672
4673 /* Update A3 with the BSSID */
4674 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4675
4676 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4677
4678 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
4679 /* in the FC */
4680 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4681
4682 /* Pack 11w SA query response frame */
4683 nStatus = dot11f_pack_sa_query_rsp(pMac,
4684 &frm,
4685 pFrame + sizeof(tSirMacMgmtHdr),
4686 nPayload, &nPayload);
4687
4688 if (DOT11F_FAILED(nStatus)) {
4689 lim_log(pMac, LOGE,
4690 FL("Failed to pack an SA Query Response (0x%08x)."),
4691 nStatus);
4692 /* FIXME - Need to convert to tSirRetStatus */
4693 nSirStatus = eSIR_FAILURE;
4694 goto returnAfterError;
4695 } else if (DOT11F_WARNED(nStatus)) {
4696 lim_log(pMac, LOGW,
4697 FL
4698 ("There were warnings while packing SA Query Response (0x%08x)."),
4699 nStatus);
4700 }
4701
4702 lim_log(pMac, LOG1, FL("Sending a SA Query Response to "));
4703 lim_print_mac_addr(pMac, peer, LOGW);
4704
4705 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4706#ifdef WLAN_FEATURE_P2P
Anurag Chouhan6d760662016-02-20 16:05:43 +05304707 || (psessionEntry->pePersona == QDF_P2P_CLIENT_MODE) ||
4708 (psessionEntry->pePersona == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004709#endif
4710 ) {
4711 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4712 }
4713
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304714 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004715 psessionEntry->peSessionId, pMacHdr->fc.subType));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304716 qdf_status = wma_tx_frame(pMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004717 pPacket,
4718 (uint16_t) nBytes,
4719 TXRX_FRM_802_11_MGMT,
4720 ANI_TXDIR_TODS,
4721 7, lim_tx_complete, pFrame, txFlag,
4722 smeSessionId, 0);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304723 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304724 psessionEntry->peSessionId, qdf_status));
4725 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004726 PELOGE(lim_log
4727 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304728 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004729 )
4730 nSirStatus = eSIR_FAILURE;
4731 /* Pkt will be freed up by the callback */
4732 return nSirStatus;
4733 } else {
4734 return eSIR_SUCCESS;
4735 }
4736
4737returnAfterError:
4738 cds_packet_free((void *)pPacket);
4739 return nSirStatus;
4740} /* End lim_send_sa_query_response_frame */
4741#endif
Krishna Kumaar Natarajan48a6b4c2017-01-06 16:30:55 -08004742
4743/**
4744 * lim_send_addba_response_frame(): Send ADDBA response action frame to peer
4745 * @mac_ctx: mac context
4746 * @peer_mac: Peer MAC address
4747 * @tid: TID for which addba response is being sent
4748 * @session: PE session entry
4749 *
4750 * This function is called when ADDBA request is successful. ADDBA response is
4751 * setup by calling addba_response_setup API and frame is then sent out OTA.
4752 *
4753 * Return: QDF_STATUS
4754 */
4755QDF_STATUS lim_send_addba_response_frame(tpAniSirGlobal mac_ctx,
4756 tSirMacAddr peer_mac, uint16_t tid, tpPESession session)
4757{
4758
4759 tDot11faddba_rsp frm;
4760 uint8_t *frame_ptr;
4761 tpSirMacMgmtHdr mgmt_hdr;
4762 uint32_t num_bytes, payload_size, status;
4763 void *pkt_ptr;
4764 QDF_STATUS qdf_status;
4765 uint8_t tx_flag = 0;
4766 uint8_t sme_sessionid = 0;
4767 uint16_t buff_size, status_code, batimeout;
4768 uint8_t peer_id, dialog_token;
4769 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4770 void *peer, *pdev;
4771
4772 sme_sessionid = session->smeSessionId;
4773
4774 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
4775 if (!pdev) {
4776 lim_log(mac_ctx, LOGE, FL("pdev is NULL"));
4777 return QDF_STATUS_E_FAILURE;
4778 }
4779
4780 peer = cdp_peer_find_by_addr(soc, pdev, peer_mac, &peer_id);
4781 if (!peer) {
4782 lim_log(mac_ctx, LOGE, FL("PEER [%pM] not found"), peer_mac);
4783 return QDF_STATUS_E_FAILURE;
4784 }
4785
4786 cdp_addba_responsesetup(soc, peer, tid, &dialog_token,
4787 &status_code, &buff_size, &batimeout);
4788
4789 qdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4790 frm.Category.category = SIR_MAC_ACTION_BLKACK;
4791 frm.Action.action = SIR_MAC_ADDBA_RSP;
4792
4793 frm.DialogToken.token = dialog_token;
4794 frm.Status.status = status_code;
4795 frm.addba_param_set.tid = tid;
4796 frm.addba_param_set.buff_size = buff_size;
4797 frm.addba_param_set.amsdu_supp = SIR_MAC_BA_POLICY_IMMEDIATE;
4798 frm.addba_param_set.policy = SIR_MAC_BA_AMSDU_SUPPORTED;
4799 frm.ba_timeout.timeout = batimeout;
4800
4801 lim_log(mac_ctx, LOG1, FL("Sending a ADDBA Response from %pM to %pM"),
4802 session->selfMacAddr, peer_mac);
4803 lim_log(mac_ctx, LOG1, FL("tid: %d, dialog_token: %d, status: %d, buff_size: %d"),
4804 tid, frm.DialogToken.token, frm.Status.status,
4805 frm.addba_param_set.buff_size);
4806
4807 status = dot11f_get_packed_addba_rsp_size(mac_ctx, &frm, &payload_size);
4808 if (DOT11F_FAILED(status)) {
4809 lim_log(mac_ctx, LOGP, FL("Failed to calculate the packed size for a ADDBA Response (0x%08x)."),
4810 status);
4811 /* We'll fall back on the worst case scenario: */
4812 payload_size = sizeof(tDot11faddba_rsp);
4813 } else if (DOT11F_WARNED(status)) {
4814 lim_log(mac_ctx, LOGW, FL("There were warnings while calculating the packed size for a ADDBA Response (0x%08x)."), status);
4815 }
4816
4817 num_bytes = payload_size + sizeof(*mgmt_hdr);
4818 qdf_status = cds_packet_alloc(num_bytes, (void **)&frame_ptr,
4819 (void **)&pkt_ptr);
4820 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
4821 lim_log(mac_ctx, LOGP,
4822 FL("Failed to allocate %d bytes for a ADDBA response action frame"), num_bytes);
4823 return QDF_STATUS_E_FAILURE;
4824 }
4825 qdf_mem_set(frame_ptr, num_bytes, 0);
4826
4827 lim_populate_mac_header(mac_ctx, frame_ptr, SIR_MAC_MGMT_FRAME,
4828 SIR_MAC_MGMT_ACTION, peer_mac, session->selfMacAddr);
4829
4830 /* Update A3 with the BSSID */
4831 mgmt_hdr = (tpSirMacMgmtHdr) frame_ptr;
4832 sir_copy_mac_addr(mgmt_hdr->bssId, session->bssId);
4833
4834 /* ADDBA Response is a robust mgmt action frame,
4835 * set the "protect" (aka WEP) bit in the FC
4836 */
4837 lim_set_protected_bit(mac_ctx, session, peer_mac, mgmt_hdr);
4838
4839 status = dot11f_pack_addba_rsp(mac_ctx, &frm,
4840 frame_ptr + sizeof(tSirMacMgmtHdr), payload_size,
4841 &payload_size);
4842
4843 if (DOT11F_FAILED(status)) {
4844 lim_log(mac_ctx, LOGE,
4845 FL("Failed to pack a ADDBA Response (0x%08x)."),
4846 status);
4847 qdf_status = QDF_STATUS_E_FAILURE;
4848 goto error_addba_rsp;
4849 } else if (DOT11F_WARNED(status)) {
4850 lim_log(mac_ctx, LOGW, FL("There were warnings while packing ADDBA Response (0x%08x)."),
4851 status);
4852 }
4853
4854
4855 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
4856#ifdef WLAN_FEATURE_P2P
4857 || (session->pePersona == QDF_P2P_CLIENT_MODE) ||
4858 (session->pePersona == QDF_P2P_GO_MODE)
4859#endif
4860 ) {
4861 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4862 }
4863
4864 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4865 session->peSessionId, mgmt_hdr->fc.subType));
4866 qdf_status = wma_tx_frame(mac_ctx, pkt_ptr, (uint16_t) num_bytes,
4867 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
4868 lim_tx_complete, frame_ptr, tx_flag, sme_sessionid, 0);
4869 MTRACE(qdf_trace(QDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4870 session->peSessionId, qdf_status));
4871 if (QDF_STATUS_SUCCESS != qdf_status) {
4872 lim_log(mac_ctx, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4873 qdf_status);
4874 qdf_status = QDF_STATUS_E_FAILURE;
4875 /*
4876 * wma_tx_frame free memory in certain cases, free pkt_ptr
4877 * only if not freed already.
4878 */
4879 if (pkt_ptr)
4880 cds_packet_free((void *)pkt_ptr);
4881 return qdf_status;
4882 } else {
4883 return eSIR_SUCCESS;
4884 }
4885
4886error_addba_rsp:
4887 cds_packet_free((void *)pkt_ptr);
4888 return qdf_status;
4889}