blob: a8df2cca966d5c054ba33b37751fa907acb2bd69 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08002 * Copyright (c) 2011-2016 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
55#ifdef WLAN_FEATURE_VOWIFI_11R
56#include "lim_ft_defs.h"
57#endif
58#include "lim_session.h"
59#include "cdf_types.h"
60#include "cdf_trace.h"
61#include "cds_utils.h"
62#include "sme_trace.h"
63#if defined WLAN_FEATURE_VOWIFI
64#include "rrm_api.h"
65#endif
66
67#include "wma_types.h"
68
69/**
70 *
71 * \brief This function is called to add the sequence number to the
72 * management frames
73 *
74 * \param pMac Pointer to Global MAC structure
75 *
76 * \param pMacHdr Pointer to MAC management header
77 *
78 * The pMacHdr argument points to the MAC management header. The
79 * sequence number stored in the pMac structure will be incremented
80 * and updated to the MAC management header. The start sequence
81 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
82 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
83 * number will roll over.
84 *
85 */
86void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
87{
88 if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
89 pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
90 }
91
92 pMac->mgmtSeqNum++;
93
94 pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
95 pMacHdr->seqControl.seqNumHi =
96 ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
97}
98
99/**
100 *
101 * \brief This function is called before sending a p2p action frame
102 * inorder to add sequence numbers to action packets
103 *
104 * \param pMac Pointer to Global MAC structure
105 *
106 * \param pBD Pointer to the frame buffer that needs to be populate
107 *
108 * The pMacHdr argument points to the MAC management header. The
109 * sequence number stored in the pMac structure will be incremented
110 * and updated to the MAC management header. The start sequence
111 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
112 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
113 * number will roll over.
114 *
115 */
116void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
117{
118 tpSirMacMgmtHdr pMacHdr;
119
120 /* / Prepare MAC management header */
121 pMacHdr = (tpSirMacMgmtHdr) (pBD);
122
123 /* Prepare sequence number */
124 lim_add_mgmt_seq_num(pMac, pMacHdr);
125 lim_log(pMac, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
126 pMacHdr->seqControl.seqNumLo,
127 pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
128}
129
130/**
131 * lim_populate_mac_header() - Fill in 802.11 header of frame
132 *
133 * @mac_ctx: Pointer to Global MAC structure
134 * @buf: Pointer to the frame buffer that needs to be populate
135 * @type: 802.11 Type of the frame
136 * @sub_type: 802.11 Subtype of the frame
137 * @peer_addr: dst address
138 * @self_mac_addr: local mac address
139 *
140 * This function is called by various LIM modules to prepare the
141 * 802.11 frame MAC header
142 *
143 * The buf argument points to the beginning of the frame buffer to
144 * which - a) The 802.11 MAC header is set b) Following this MAC header
145 * will be the MGMT frame payload The payload itself is populated by the
146 * caller API
147 *
148 * Return: None
149 */
150
151void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
152 uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
153 tSirMacAddr self_mac_addr)
154{
155 tpSirMacMgmtHdr mac_hdr;
156
157 /* Prepare MAC management header */
158 mac_hdr = (tpSirMacMgmtHdr) (buf);
159
160 /* Prepare FC */
161 mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
162 mac_hdr->fc.type = type;
163 mac_hdr->fc.subType = sub_type;
164
165 /* Prepare Address 1 */
166 cdf_mem_copy((uint8_t *) mac_hdr->da,
167 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
168
169 /* Prepare Address 2 */
170 sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
171
172 /* Prepare Address 3 */
173 cdf_mem_copy((uint8_t *) mac_hdr->bssId,
174 (uint8_t *) peer_addr, sizeof(tSirMacAddr));
175
176 /* Prepare sequence number */
177 lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
178 lim_log(mac_ctx, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
179 mac_hdr->seqControl.seqNumLo,
180 mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
181}
182
183/**
184 * lim_send_probe_req_mgmt_frame() - send probe request management frame
185 * @mac_ctx: Pointer to Global MAC structure
186 * @ssid: SSID to be sent in Probe Request frame
187 * @bssid: BSSID to be sent in Probe Request frame
188 * @channel: Channel # on which the Probe Request is going out
189 * @self_macaddr: self MAC address
190 * @dot11mode: self dotllmode
191 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
192 * frame
193 * @additional_ie: if additional_ielen is non zero, include this field in the
194 * Probe Request frame
195 *
196 * This function is called by various LIM modules to send Probe Request frame
197 * during active scan/learn phase.
198 * Probe request is sent out in the following scenarios:
199 * --heartbeat failure: session needed
200 * --join req: session needed
201 * --foreground scan: no session
202 * --background scan: no session
203 * --sch_beacon_processing: to get EDCA parameters: session needed
204 *
205 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
206 */
207tSirRetStatus
208lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
209 tSirMacSSid *ssid,
210 tSirMacAddr bssid,
211 uint8_t channel,
212 tSirMacAddr self_macaddr,
213 uint32_t dot11mode,
214 uint32_t additional_ielen, uint8_t *additional_ie)
215{
216 tDot11fProbeRequest pr;
217 uint32_t status, bytes, payload;
218 uint8_t *frame;
219 void *packet;
220 CDF_STATUS cdf_status, extcap_status;
221 tpPESession pesession;
222 uint8_t sessionid;
223 uint8_t *p2pie = NULL;
224 uint8_t txflag = 0;
225 uint8_t sme_sessionid = 0;
226 bool is_vht_enabled = false;
227 uint8_t txPower;
228 uint16_t addn_ielen = additional_ielen;
229
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: */
258 cdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
259
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) &&
274 (CDF_P2P_CLIENT_MODE == pesession->pePersona))
275 )
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
293#if defined WLAN_FEATURE_VOWIFI
294 /*
295 * Table 7-14 in IEEE Std. 802.11k-2008 says
296 * DS params "can" be present in RRM is disabled and "is" present if
297 * RRM is enabled. It should be ok even if we add it into probe req when
298 * RRM is not enabled.
299 */
300 populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
301 /* Call RRM module to get the tx power for management used. */
302 txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
303 populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
304
305#endif
306
307 if (pesession != NULL) {
308 pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
309 /* Include HT Capability IE */
310 if (pesession->htCapability)
311 populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
312 } else { /* pesession == NULL */
313 if (IS_DOT11_MODE_HT(dot11mode))
314 populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
315 }
316
317 /*
318 * Set channelbonding information as "disabled" when tunned to a
319 * 2.4 GHz channel
320 */
321 if (channel <= SIR_11B_CHANNEL_END) {
322 if (mac_ctx->roam.configParam.channelBondingMode24GHz
323 == PHY_SINGLE_CHANNEL_CENTERED) {
324 pr.HTCaps.supportedChannelWidthSet =
325 eHT_CHANNEL_WIDTH_20MHZ;
326 pr.HTCaps.shortGI40MHz = 0;
327 } else {
328 pr.HTCaps.supportedChannelWidthSet =
329 eHT_CHANNEL_WIDTH_40MHZ;
330 }
331 }
332#ifdef WLAN_FEATURE_11AC
333 if (pesession != NULL) {
334 pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
335 /* Include VHT Capability IE */
336 if (pesession->vhtCapability) {
337 populate_dot11f_vht_caps(mac_ctx, pesession,
338 &pr.VHTCaps);
339 is_vht_enabled = true;
340 }
341 } else {
342 if (IS_DOT11_MODE_VHT(dot11mode)) {
343 populate_dot11f_vht_caps(mac_ctx, pesession,
344 &pr.VHTCaps);
345 is_vht_enabled = true;
346 }
347 }
348#endif
349 if (pesession != NULL)
350 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
351 pesession);
352
353 /* That's it-- now we pack it. First, how much space are we going to */
354 status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
355 if (DOT11F_FAILED(status)) {
356 lim_log(mac_ctx, LOGP, FL("Failed to calculate the packed size for a Probe Request (0x%08x)."), status);
357 /* We'll fall back on the worst case scenario: */
358 payload = sizeof(tDot11fProbeRequest);
359 } else if (DOT11F_WARNED(status)) {
360 lim_log(mac_ctx, LOGW,
361 FL("There were warnings while calculating the packed size for a Probe Request (0x%08x)."), status);
362 }
363
364 /* Strip extended capability IE (if present). FW will add that IE */
365 if (addn_ielen) {
366 extcap_status = lim_strip_extcap_ie(mac_ctx, additional_ie,
367 &addn_ielen, NULL);
368 if (CDF_STATUS_SUCCESS != extcap_status)
369 lim_log(mac_ctx, LOGE,
370 FL("Error:%d stripping extcap IE"), extcap_status);
371 }
372
373 bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
374
375 /* Ok-- try to allocate some memory: */
376 cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
377 (void **)&packet);
378 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
379 lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes for a Probe Request."), bytes);
380 return eSIR_MEM_ALLOC_FAILED;
381 }
382 /* Paranoia: */
383 cdf_mem_set(frame, bytes, 0);
384
385 /* Next, we fill out the buffer descriptor: */
386 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
387 SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
388
389 /* That done, pack the Probe Request: */
390 status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
391 sizeof(tSirMacMgmtHdr),
392 payload, &payload);
393 if (DOT11F_FAILED(status)) {
394 lim_log(mac_ctx, LOGE,
395 FL("Failed to pack a Probe Request (0x%08x)."), status);
396 cds_packet_free((void *)packet);
397 return eSIR_FAILURE; /* allocated! */
398 } else if (DOT11F_WARNED(status)) {
399 lim_log(mac_ctx, LOGW, FL("There were warnings while packing a Probe Request (0x%08x)."), status);
400 }
401 /* Append any AddIE if present. */
402 if (addn_ielen) {
403 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
404 additional_ie, addn_ielen);
405 payload += addn_ielen;
406 }
407
408 /* If this probe request is sent during P2P Search State, then we need
409 * to send it at OFDM rate.
410 */
411 if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
412 || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
413 mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
414 /*
415 * For unicast probe req mgmt from Join function we don't set
416 * above variables. So we need to add one more check whether it
417 * is pePersona is P2P_CLIENT or not
418 */
419 || ((pesession != NULL) &&
420 (CDF_P2P_CLIENT_MODE == pesession->pePersona))
421 ) {
422 txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
423 }
424
425 cdf_status =
426 wma_tx_frame(mac_ctx, packet,
427 (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
428 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
429 lim_tx_complete, frame, txflag, sme_sessionid,
430 0);
431 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
432 lim_log(mac_ctx, LOGE,
433 FL("could not send Probe Request frame!"));
434 /* Pkt will be freed up by the callback */
435 return eSIR_FAILURE;
436 }
437
438 return eSIR_SUCCESS;
439} /* End lim_send_probe_req_mgmt_frame. */
440
441tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
442 uint8_t *addIE, uint16_t *addnIELen,
443 uint8_t probeReqP2pIe)
444{
445 /* If Probe request doesn't have P2P IE, then take out P2P IE
446 from additional IE */
447 if (!probeReqP2pIe) {
448 uint8_t *tempbuf = NULL;
449 uint16_t tempLen = 0;
450 int left = *addnIELen;
451 uint8_t *ptr = addIE;
452 uint8_t elem_id, elem_len;
453
454 if (NULL == addIE) {
455 PELOGE(lim_log(pMac, LOGE, FL(" NULL addIE pointer"));)
456 return eSIR_FAILURE;
457 }
458
459 tempbuf = cdf_mem_malloc(left);
460 if (NULL == tempbuf) {
461 PELOGE(lim_log(pMac, LOGE,
462 FL
463 ("Unable to allocate memory to store addn IE"));
464 )
465 return eSIR_MEM_ALLOC_FAILED;
466 }
467
468 while (left >= 2) {
469 elem_id = ptr[0];
470 elem_len = ptr[1];
471 left -= 2;
472 if (elem_len > left) {
473 lim_log(pMac, LOGE,
474 FL
475 ("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
476 elem_id, elem_len, left);
477 cdf_mem_free(tempbuf);
478 return eSIR_FAILURE;
479 }
480 if (!((SIR_MAC_EID_VENDOR == elem_id) &&
481 (memcmp
482 (&ptr[2], SIR_MAC_P2P_OUI,
483 SIR_MAC_P2P_OUI_SIZE) == 0))) {
484 cdf_mem_copy(tempbuf + tempLen, &ptr[0],
485 elem_len + 2);
486 tempLen += (elem_len + 2);
487 }
488 left -= elem_len;
489 ptr += (elem_len + 2);
490 }
491 cdf_mem_copy(addIE, tempbuf, tempLen);
492 *addnIELen = tempLen;
493 cdf_mem_free(tempbuf);
494 }
495 return eSIR_SUCCESS;
496}
497
498/**
499 * lim_send_probe_rsp_mgmt_frame() - Send probe response
500 *
501 * @mac_ctx: Handle for mac context
502 * @peer_macaddr: Mac address of requesting peer
503 * @ssid: SSID for response
504 * @n_staid: Station ID, currently unused.
505 * @pe_session: PE session id
506 * @keepalive: Keep alive flag. Currently unused.
507 * @preq_p2pie: P2P IE in incoming probe request
508 *
509 * Builds and sends probe response frame to the requesting peer
510 *
511 * Return: void
512 */
513
514void
515lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
516 tSirMacAddr peer_macaddr,
517 tpAniSSID ssid,
518 short n_staid,
519 uint8_t keepalive,
520 tpPESession pe_session, uint8_t preq_p2pie)
521{
522 tDot11fProbeResponse *frm;
523 tSirRetStatus sir_status;
524 uint32_t cfg, payload, bytes, status;
525 tpSirMacMgmtHdr mac_hdr;
526 uint8_t *frame;
527 void *packet;
528 CDF_STATUS cdf_status;
529 uint32_t addn_ie_present = false;
530
531 uint16_t addn_ie_len = 0;
532 uint32_t wps_ap = 0, tmp;
533 uint8_t tx_flag = 0;
534 uint8_t *add_ie = NULL;
535 uint8_t *p2p_ie = NULL;
536 uint8_t noalen = 0;
537 uint8_t total_noalen = 0;
538 uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
539 uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
540 uint8_t sme_sessionid = 0;
541 bool is_vht_enabled = false;
542 tDot11fIEExtCap extracted_ext_cap;
543 bool extracted_ext_cap_flag = true;
544
545 /* We don't answer requests in this case*/
546 if (ANI_DRIVER_TYPE(mac_ctx) == eDRIVER_TYPE_MFG)
547 return;
548
549 if (NULL == pe_session)
550 return;
551
552 /*
553 * In case when cac timer is running for this SAP session then
554 * avoid sending probe rsp out. It is violation of dfs specification.
555 */
556 if (((pe_session->pePersona == CDF_SAP_MODE) ||
557 (pe_session->pePersona == CDF_P2P_GO_MODE)) &&
558 (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
559 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
560 FL("CAC timer is running, probe response dropped"));
561 return;
562 }
563 sme_sessionid = pe_session->smeSessionId;
564 frm = cdf_mem_malloc(sizeof(tDot11fProbeResponse));
565 if (NULL == frm) {
566 lim_log(mac_ctx, LOGE,
567 FL("Unable to allocate memory"));
568 return;
569 }
570
571 cdf_mem_zero(&extracted_ext_cap, sizeof(extracted_ext_cap));
572
573 /*
574 * Fill out 'frm', after which we'll just hand the struct off to
575 * 'dot11f_pack_probe_response'.
576 */
577 cdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
578
579 /*
580 * Timestamp to be updated by TFP, below.
581 *
582 * Beacon Interval:
583 */
584 if (LIM_IS_AP_ROLE(pe_session)) {
585 frm->BeaconInterval.interval =
586 mac_ctx->sch.schObject.gSchBeaconInterval;
587 } else {
588 sir_status = wlan_cfg_get_int(mac_ctx,
589 WNI_CFG_BEACON_INTERVAL, &cfg);
590 if (eSIR_SUCCESS != sir_status) {
591 lim_log(mac_ctx, LOGP,
592 FL("Failed to get WNI_CFG_BEACON_INTERVAL (%d)."),
593 sir_status);
594 goto err_ret;
595 }
596 frm->BeaconInterval.interval = (uint16_t) cfg;
597 }
598
599 populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
600 populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
601 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
602 &frm->SuppRates, pe_session);
603
604 populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
605 pe_session->currentOperChannel);
606 populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
607
608 if (LIM_IS_AP_ROLE(pe_session)) {
609 if (pe_session->wps_state != SAP_WPS_DISABLED)
610 populate_dot11f_probe_res_wpsi_es(mac_ctx,
611 &frm->WscProbeRes,
612 pe_session);
613 } else {
614 if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
615 &tmp) != eSIR_SUCCESS)
616 lim_log(mac_ctx, LOGP, "Failed to cfg get id %d",
617 WNI_CFG_WPS_ENABLE);
618
619 wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
620
621 if (wps_ap)
622 populate_dot11f_wsc_in_probe_res(mac_ctx,
623 &frm->WscProbeRes);
624
625 if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
626 eLIM_WSC_ENROLL_BEGIN) {
627 populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
628 &frm->WscProbeRes);
629 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
630 eLIM_WSC_ENROLL_IN_PROGRESS;
631 }
632
633 if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
634 eLIM_WSC_ENROLL_END) {
635 de_populate_dot11f_wsc_registrar_info_in_probe_res(
636 mac_ctx, &frm->WscProbeRes);
637 mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
638 eLIM_WSC_ENROLL_NOOP;
639 }
640 }
641
642 populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
643 populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
644
645 if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
646 populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
647
648 populate_dot11f_ext_supp_rates(mac_ctx,
649 POPULATE_DOT11F_RATES_OPERATIONAL,
650 &frm->ExtSuppRates, pe_session);
651
652 /* Populate HT IEs, when operating in 11n */
653 if (pe_session->htCapability) {
654 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
655 populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
656 }
657#ifdef WLAN_FEATURE_11AC
658 if (pe_session->vhtCapability) {
659 lim_log(mac_ctx, LOG1, FL("Populate VHT IE in Probe Response"));
660 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
661 populate_dot11f_vht_operation(mac_ctx, pe_session,
662 &frm->VHTOperation);
663 /*
664 * we do not support multi users yet.
665 * populate_dot11f_vht_ext_bss_load( mac_ctx,
666 * &frm.VHTExtBssLoad );
667 */
668 is_vht_enabled = true;
669 }
670#endif
671
672 populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
673 pe_session);
674
675 if (pe_session->pLimStartBssReq) {
676 populate_dot11f_wpa(mac_ctx,
677 &(pe_session->pLimStartBssReq->rsnIE),
678 &frm->WPA);
679 populate_dot11f_rsn_opaque(mac_ctx,
680 &(pe_session->pLimStartBssReq->rsnIE),
681 &frm->RSNOpaque);
682 }
683
684 populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
685 &frm->WMMCaps, pe_session);
686
687#if defined(FEATURE_WLAN_WAPI)
688 if (pe_session->pLimStartBssReq)
689 populate_dot11f_wapi(mac_ctx,
690 &(pe_session->pLimStartBssReq->rsnIE),
691 &frm->WAPI);
692#endif /* defined(FEATURE_WLAN_WAPI) */
693
694 status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
695 if (DOT11F_FAILED(status)) {
696 lim_log(mac_ctx, LOGP,
697 FL("Probe Response size error (0x%08x)."),
698 status);
699 /* We'll fall back on the worst case scenario: */
700 payload = sizeof(tDot11fProbeResponse);
701 } else if (DOT11F_WARNED(status)) {
702 lim_log(mac_ctx, LOGW,
703 FL("Probe Response size warning (0x%08x)."),
704 status);
705 }
706
707 bytes = payload + sizeof(tSirMacMgmtHdr);
708
709 if (mac_ctx->lim.gpLimRemainOnChanReq)
710 bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
711 sizeof(tSirRemainOnChnReq));
712 else
713 /*
714 * Only use CFG for non-listen mode. This CFG is not working for
715 * concurrency. In listening mode, probe rsp IEs is passed in
716 * the message from SME to PE.
717 */
718 addn_ie_present =
719 (pe_session->addIeParams.probeRespDataLen != 0);
720
721 if (addn_ie_present) {
722
723 add_ie = cdf_mem_malloc(
724 pe_session->addIeParams.probeRespDataLen);
725 if (NULL == add_ie) {
726 lim_log(mac_ctx, LOGE,
727 FL("add_ie allocation failed"));
728 goto err_ret;
729 }
730
731 cdf_mem_copy(add_ie,
732 pe_session->addIeParams.probeRespData_buff,
733 pe_session->addIeParams.probeRespDataLen);
734 addn_ie_len = pe_session->addIeParams.probeRespDataLen;
735
736 if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
737 add_ie, &addn_ie_len, preq_p2pie)) {
738 lim_log(mac_ctx, LOGP,
739 FL("Unable to get addn_ie"));
740 goto err_ret;
741 }
742
743 sir_status = lim_strip_extcap_update_struct(mac_ctx,
744 add_ie, &addn_ie_len,
745 &extracted_ext_cap);
746 if (eSIR_SUCCESS != sir_status) {
747 extracted_ext_cap_flag = false;
748 lim_log(mac_ctx, LOG1,
749 FL("Unable to strip off ExtCap IE"));
750 }
751
752 bytes = bytes + addn_ie_len;
753
754 if (preq_p2pie)
755 p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
756 addn_ie_len);
757
758 if (p2p_ie != NULL) {
759 /* get NoA attribute stream P2P IE */
760 noalen = lim_get_noa_attr_stream(mac_ctx,
761 noa_stream, pe_session);
762 if (noalen != 0) {
763 total_noalen =
764 lim_build_p2p_ie(mac_ctx, &noa_ie[0],
765 &noa_stream[0], noalen);
766 bytes = bytes + total_noalen;
767 }
768 }
769 }
770
771 cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
772 (void **)&packet);
773 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
774 lim_log(mac_ctx, LOGP, FL("Probe Response allocation failed"));
775 goto err_ret;
776 }
777 /* Paranoia: */
778 cdf_mem_set(frame, bytes, 0);
779
780 /* Next, we fill out the buffer descriptor: */
781 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
782 SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
783 pe_session->selfMacAddr);
784
785 mac_hdr = (tpSirMacMgmtHdr) frame;
786
787 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
788
789 /* merge ExtCap IE */
790 if (extracted_ext_cap_flag)
791 lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap);
792
793 /* That done, pack the Probe Response: */
794 status =
795 dot11f_pack_probe_response(mac_ctx, frm,
796 frame + sizeof(tSirMacMgmtHdr),
797 payload, &payload);
798 if (DOT11F_FAILED(status)) {
799 lim_log(mac_ctx, LOGE,
800 FL("Probe Response pack failure (0x%08x)."),
801 status);
802 goto err_ret;
803 } else if (DOT11F_WARNED(status)) {
804 lim_log(mac_ctx, LOGW,
805 FL("Probe Response pack warning (0x%08x)."),
806 status);
807 }
808
809 lim_log(mac_ctx, LOG3, FL("Sending Probe Response frame to "));
810 lim_print_mac_addr(mac_ctx, peer_macaddr, LOG3);
811
812 mac_ctx->sys.probeRespond++;
813
814 if (mac_ctx->lim.gpLimRemainOnChanReq)
815 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
816 mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
817 (mac_ctx->lim.gpLimRemainOnChanReq->length -
818 sizeof(tSirRemainOnChnReq)));
819
820 if (addn_ie_present)
821 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
822 &add_ie[0], addn_ie_len);
823
824 if (noalen != 0) {
825 if (total_noalen >
826 (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
827 lim_log(mac_ctx, LOGE,
828 FL("Not able to insert NoA, total len=%d"),
829 total_noalen);
830 goto err_ret;
831 } else {
832 cdf_mem_copy(&frame[bytes - (total_noalen)],
833 &noa_ie[0], total_noalen);
834 }
835 }
836
837 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
838 || (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
839 (pe_session->pePersona == CDF_P2P_GO_MODE)
840 )
841 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
842
843 /* Queue Probe Response frame in high priority WQ */
844 cdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
845 (uint16_t) bytes,
846 TXRX_FRM_802_11_MGMT,
847 ANI_TXDIR_TODS,
848 7, lim_tx_complete, frame, tx_flag,
849 sme_sessionid, 0);
850
851 /* Pkt will be freed up by the callback */
852 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
853 lim_log(mac_ctx, LOGE, FL("Could not send Probe Response."));
854
855 if (add_ie != NULL)
856 cdf_mem_free(add_ie);
857
858 cdf_mem_free(frm);
859 return;
860
861err_ret:
862 if (add_ie != NULL)
863 cdf_mem_free(add_ie);
864 if (frm != NULL)
865 cdf_mem_free(frm);
866 if (packet != NULL)
867 cds_packet_free((void *)packet);
868 return;
869
870} /* End lim_send_probe_rsp_mgmt_frame. */
871
872void
873lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
874 tSirMacAddr peerMacAddr,
875 tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
876{
877 uint16_t i;
878 uint8_t *pFrame;
879 tDot11fAddTSRequest AddTSReq;
880 tDot11fWMMAddTSRequest WMMAddTSReq;
881 uint32_t nPayload, nBytes, nStatus;
882 tpSirMacMgmtHdr pMacHdr;
883 void *pPacket;
884#ifdef FEATURE_WLAN_ESE
885 uint32_t phyMode;
886#endif
887 CDF_STATUS cdf_status;
888 uint8_t txFlag = 0;
889 uint8_t smeSessionId = 0;
890
891 if (NULL == psessionEntry) {
892 return;
893 }
894
895 smeSessionId = psessionEntry->smeSessionId;
896
897 if (!pAddTS->wmeTspecPresent) {
898 cdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
899
900 AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
901 AddTSReq.DialogToken.token = pAddTS->dialogToken;
902 AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
903 if (pAddTS->lleTspecPresent) {
904 populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
905 } else {
906 populate_dot11f_wmmtspec(&pAddTS->tspec,
907 &AddTSReq.WMMTSPEC);
908 }
909
910 if (pAddTS->lleTspecPresent) {
911 AddTSReq.num_WMMTCLAS = 0;
912 AddTSReq.num_TCLAS = pAddTS->numTclas;
913 for (i = 0; i < pAddTS->numTclas; ++i) {
914 populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
915 &AddTSReq.TCLAS[i]);
916 }
917 } else {
918 AddTSReq.num_TCLAS = 0;
919 AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
920 for (i = 0; i < pAddTS->numTclas; ++i) {
921 populate_dot11f_wmmtclas(pMac,
922 &pAddTS->tclasInfo[i],
923 &AddTSReq.WMMTCLAS[i]);
924 }
925 }
926
927 if (pAddTS->tclasProcPresent) {
928 if (pAddTS->lleTspecPresent) {
929 AddTSReq.TCLASSPROC.processing =
930 pAddTS->tclasProc;
931 AddTSReq.TCLASSPROC.present = 1;
932 } else {
933 AddTSReq.WMMTCLASPROC.version = 1;
934 AddTSReq.WMMTCLASPROC.processing =
935 pAddTS->tclasProc;
936 AddTSReq.WMMTCLASPROC.present = 1;
937 }
938 }
939
940 nStatus =
941 dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
942 if (DOT11F_FAILED(nStatus)) {
943 lim_log(pMac, LOGP,
944 FL("Failed to calculate the packed size f"
945 "or an Add TS Request (0x%08x)."), nStatus);
946 /* We'll fall back on the worst case scenario: */
947 nPayload = sizeof(tDot11fAddTSRequest);
948 } else if (DOT11F_WARNED(nStatus)) {
949 lim_log(pMac, LOGW,
950 FL("There were warnings while calculating"
951 "the packed size for an Add TS Request"
952 " (0x%08x)."), nStatus);
953 }
954 } else {
955 cdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
956
957 WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
958 WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
959 WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
960
961 /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
962 WMMAddTSReq.StatusCode.statusCode = 0;
963
964 populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
965#ifdef FEATURE_WLAN_ESE
966 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
967
968 if (phyMode == WNI_CFG_PHY_MODE_11G
969 || phyMode == WNI_CFG_PHY_MODE_11A) {
970 pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
971 } else {
972 pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
973 }
974 populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
975 &WMMAddTSReq.ESETrafStrmRateSet,
976 sizeof(uint8_t));
977#endif
978 /* fillWmeTspecIE */
979
980 nStatus =
981 dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
982 &nPayload);
983 if (DOT11F_FAILED(nStatus)) {
984 lim_log(pMac, LOGP,
985 FL("Failed to calculate the packed size f"
986 "or a WMM Add TS Request (0x%08x)."),
987 nStatus);
988 /* We'll fall back on the worst case scenario: */
989 nPayload = sizeof(tDot11fAddTSRequest);
990 } else if (DOT11F_WARNED(nStatus)) {
991 lim_log(pMac, LOGW,
992 FL("There were warnings while calculating"
993 "the packed size for a WMM Add TS Requ"
994 "est (0x%08x)."), nStatus);
995 }
996 }
997
998 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
999
1000 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1001 (void **)&pPacket);
1002 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1003 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
1004 "d TS Request."), nBytes);
1005 return;
1006 }
1007 /* Paranoia: */
1008 cdf_mem_set(pFrame, nBytes, 0);
1009
1010 /* Next, we fill out the buffer descriptor: */
1011 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1012 SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
1013 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1014
1015 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1016
1017#ifdef WLAN_FEATURE_11W
1018 lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
1019#endif
1020
1021 /* That done, pack the struct: */
1022 if (!pAddTS->wmeTspecPresent) {
1023 nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
1024 pFrame +
1025 sizeof(tSirMacMgmtHdr),
1026 nPayload, &nPayload);
1027 if (DOT11F_FAILED(nStatus)) {
1028 lim_log(pMac, LOGE,
1029 FL("Failed to pack an Add TS Request "
1030 "(0x%08x)."), nStatus);
1031 cds_packet_free((void *)pPacket);
1032 return; /* allocated! */
1033 } else if (DOT11F_WARNED(nStatus)) {
1034 lim_log(pMac, LOGW,
1035 FL("There were warnings while packing "
1036 "an Add TS Request (0x%08x)."), nStatus);
1037 }
1038 } else {
1039 nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
1040 pFrame +
1041 sizeof(tSirMacMgmtHdr),
1042 nPayload, &nPayload);
1043 if (DOT11F_FAILED(nStatus)) {
1044 lim_log(pMac, LOGE,
1045 FL("Failed to pack a WMM Add TS Reque"
1046 "st (0x%08x)."), nStatus);
1047 cds_packet_free((void *)pPacket);
1048 return; /* allocated! */
1049 } else if (DOT11F_WARNED(nStatus)) {
1050 lim_log(pMac, LOGW,
1051 FL("There were warnings while packing "
1052 "a WMM Add TS Request (0x%08x)."), nStatus);
1053 }
1054 }
1055
1056 PELOG3(lim_log(pMac, LOG3, FL("Sending an Add TS Request frame to "));
1057 lim_print_mac_addr(pMac, peerMacAddr, LOG3);
1058 )
1059
1060 if ((SIR_BAND_5_GHZ ==
1061 lim_get_rf_band(psessionEntry->currentOperChannel))
1062 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE)
1063 || (psessionEntry->pePersona == CDF_P2P_GO_MODE)
1064 ) {
1065 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1066 }
1067
1068 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
1069 psessionEntry->peSessionId, pMacHdr->fc.subType));
1070
1071 /* Queue Addts Response frame in high priority WQ */
1072 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
1073 TXRX_FRM_802_11_MGMT,
1074 ANI_TXDIR_TODS,
1075 7, lim_tx_complete, pFrame, txFlag,
1076 smeSessionId, 0);
1077 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
1078 psessionEntry->peSessionId, cdf_status));
1079
1080 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1081 lim_log(pMac, LOGE, FL("*** Could not send an Add TS Request"
1082 " (%X) ***"), cdf_status);
1083 /* Pkt will be freed up by the callback */
1084 }
1085
1086} /* End lim_send_addts_req_action_frame. */
1087
1088/**
1089 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
1090 * @mac_ctx: Handle for mac context
1091 * @status_code: Status code for assoc response frame
1092 * @aid: Association ID
1093 * @peer_addr: Mac address of requesting peer
1094 * @subtype: Assoc/Reassoc
1095 * @sta: Pointer to station node
1096 * @pe_session: PE session id.
1097 *
1098 * Builds and sends association response frame to the requesting peer.
1099 *
1100 * Return: void
1101 */
1102
1103void
1104lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
1105 uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
1106 uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
1107{
1108 static tDot11fAssocResponse frm;
1109 uint8_t *frame;
1110 tpSirMacMgmtHdr mac_hdr;
1111 tSirRetStatus sir_status;
1112 uint8_t lle_mode = 0, addts;
1113 tHalBitVal qos_mode, wme_mode;
1114 uint32_t payload, bytes, status;
1115 void *packet;
1116 CDF_STATUS cdf_status;
1117 tUpdateBeaconParams beacon_params;
1118 uint8_t tx_flag = 0;
1119 uint32_t addn_ie_len = 0;
1120 uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
1121 tpSirAssocReq assoc_req = NULL;
1122 uint8_t sme_session = 0;
1123 bool is_vht = false;
1124 uint16_t stripoff_len = 0;
1125 tDot11fIEExtCap extracted_ext_cap;
1126 bool extracted_flag = false;
1127#ifdef WLAN_FEATURE_11W
1128 uint32_t retry_int;
1129 uint32_t max_retries;
1130#endif
1131
1132 if (NULL == pe_session) {
1133 lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
1134 return;
1135 }
1136
1137 sme_session = pe_session->smeSessionId;
1138
1139 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
1140
1141 limGetQosMode(pe_session, &qos_mode);
1142 limGetWmeMode(pe_session, &wme_mode);
1143
1144 /*
1145 * An Add TS IE is added only if the AP supports it and
1146 * the requesting STA sent a traffic spec.
1147 */
1148 addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
1149
1150 frm.Status.status = status_code;
1151
1152 frm.AID.associd = aid | LIM_AID_MASK;
1153
1154 if (NULL == sta) {
1155 populate_dot11f_supp_rates(mac_ctx,
1156 POPULATE_DOT11F_RATES_OPERATIONAL,
1157 &frm.SuppRates, pe_session);
1158 populate_dot11f_ext_supp_rates(mac_ctx,
1159 POPULATE_DOT11F_RATES_OPERATIONAL,
1160 &frm.ExtSuppRates, pe_session);
1161 } else {
1162 populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
1163 &frm.ExtSuppRates,
1164 sta->supportedRates.llbRates,
1165 sta->supportedRates.llaRates);
1166 }
1167
1168 if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
1169 eSIR_SUCCESS == status_code) {
1170 assoc_req = (tpSirAssocReq)
1171 pe_session->parsedAssocReq[sta->assocId];
1172 /*
1173 * populate P2P IE in AssocRsp when assocReq from the peer
1174 * includes P2P IE
1175 */
1176 if (assoc_req != NULL && assoc_req->addIEPresent)
1177 populate_dot11_assoc_res_p2p_ie(mac_ctx,
1178 &frm.P2PAssocRes,
1179 assoc_req);
1180 }
1181
1182 if (NULL != sta) {
1183 if (eHAL_SET == qos_mode) {
1184 if (sta->lleEnabled) {
1185 lle_mode = 1;
1186 populate_dot11f_edca_param_set(mac_ctx,
1187 &frm.EDCAParamSet, pe_session);
1188 }
1189 }
1190
1191 if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
1192 populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
1193 pe_session);
1194
1195 if (sta->wsmEnabled)
1196 populate_dot11f_wmm_caps(&frm.WMMCaps);
1197 }
1198
1199 if (sta->mlmStaContext.htCapability &&
1200 pe_session->htCapability) {
1201 lim_log(mac_ctx, LOG1,
1202 FL("Populate HT IEs in Assoc Response"));
1203 populate_dot11f_ht_caps(mac_ctx, pe_session,
1204 &frm.HTCaps);
Krunal Sonief3294b2015-06-12 15:12:19 -07001205 /*
1206 * Check the STA capability and
1207 * update the HTCaps accordingly
1208 */
1209 frm.HTCaps.supportedChannelWidthSet = (
1210 sta->htSupportedChannelWidthSet <
1211 pe_session->htSupportedChannelWidthSet) ?
1212 sta->htSupportedChannelWidthSet :
1213 pe_session->htSupportedChannelWidthSet;
1214 if (!frm.HTCaps.supportedChannelWidthSet)
1215 frm.HTCaps.shortGI40MHz = 0;
1216
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001217 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1218 pe_session);
1219 }
1220#ifdef WLAN_FEATURE_11AC
1221 if (sta->mlmStaContext.vhtCapability &&
1222 pe_session->vhtCapability) {
1223 lim_log(mac_ctx, LOG1,
1224 FL("Populate VHT IEs in Assoc Response"));
1225 populate_dot11f_vht_caps(mac_ctx, pe_session,
1226 &frm.VHTCaps);
1227 populate_dot11f_vht_operation(mac_ctx, pe_session,
1228 &frm.VHTOperation);
1229 is_vht = true;
1230 }
1231#endif
1232
1233 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1234 pe_session);
1235
1236#ifdef WLAN_FEATURE_11W
1237 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1238 if (wlan_cfg_get_int
1239 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1240 &max_retries) != eSIR_SUCCESS)
1241 lim_log(mac_ctx, LOGE,
1242 FL("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure"));
1243 else if (wlan_cfg_get_int
1244 (mac_ctx,
1245 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1246 &retry_int) != eSIR_SUCCESS)
1247 lim_log(mac_ctx, LOGE,
1248 FL("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure"));
1249 else
1250 populate_dot11f_timeout_interval(mac_ctx,
1251 &frm.TimeoutInterval,
1252 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1253 (max_retries -
1254 sta->pmfSaQueryRetryCount)
1255 * retry_int);
1256 }
1257#endif
1258 }
1259
1260 cdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
1261
1262 if (LIM_IS_AP_ROLE(pe_session) &&
1263 (pe_session->gLimProtectionControl !=
1264 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1265 lim_decide_ap_protection(mac_ctx, peer_addr,
1266 &beacon_params, pe_session);
1267
1268 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1269 pe_session);
1270 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1271 pe_session);
1272
1273 /*
1274 * Populate Do11capabilities after updating session with
1275 * Assos req details
1276 */
1277 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1278
1279 beacon_params.bssIdx = pe_session->bssIdx;
1280
1281 /* Send message to HAL about beacon parameter change. */
1282 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1283 && beacon_params.paramChangeBitmap) {
1284 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1285 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1286 }
1287 /* Allocate a buffer for this frame: */
1288 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1289 if (DOT11F_FAILED(status)) {
1290 lim_log(mac_ctx, LOGE,
1291 FL("get Association Response size failure (0x%08x)."),
1292 status);
1293 return;
1294 } else if (DOT11F_WARNED(status)) {
1295 lim_log(mac_ctx, LOGW,
1296 FL("get Association Response size warning (0x%08x)."),
1297 status);
1298 }
1299
1300 bytes = sizeof(tSirMacMgmtHdr) + payload;
1301
1302 if (assoc_req != NULL) {
1303 addn_ie_len = (pe_session->addIeParams.assocRespDataLen != 0);
1304
1305 /* Nonzero length indicates Assoc rsp IE available */
1306 if (addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN
1307 && (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
1308 cdf_mem_copy(add_ie,
1309 pe_session->addIeParams.assocRespData_buff,
1310 pe_session->addIeParams.assocRespDataLen);
1311
1312 cdf_mem_set((uint8_t *) &extracted_ext_cap,
1313 sizeof(extracted_ext_cap), 0);
1314
1315 stripoff_len = addn_ie_len;
1316 sir_status =
1317 lim_strip_extcap_update_struct
1318 (mac_ctx, &add_ie[0], &stripoff_len,
1319 &extracted_ext_cap);
1320 if (eSIR_SUCCESS != sir_status) {
1321 lim_log(mac_ctx, LOG1,
1322 FL("strip off extcap IE failed"));
1323 } else {
1324 addn_ie_len = stripoff_len;
1325 extracted_flag = true;
1326 }
1327 bytes = bytes + addn_ie_len;
1328 }
1329 lim_log(mac_ctx, LOG1,
1330 FL("addn_ie_len = %d for Assoc Resp : %d"),
1331 addn_ie_len, assoc_req->addIEPresent);
1332 }
1333 cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
1334 (void **)&packet);
1335 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1336 lim_log(mac_ctx, LOGP, FL("cds_packet_alloc failed."));
1337 return;
1338 }
1339 /* Paranoia: */
1340 cdf_mem_set(frame, bytes, 0);
1341
1342 /* Next, we fill out the buffer descriptor: */
1343 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1344 (LIM_ASSOC == subtype) ?
1345 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1346 peer_addr,
1347 pe_session->selfMacAddr);
1348 mac_hdr = (tpSirMacMgmtHdr) frame;
1349
1350 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1351
1352 /* merge the ExtCap struct */
1353 if (extracted_flag)
1354 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap);
1355 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1356 frame + sizeof(tSirMacMgmtHdr),
1357 payload, &payload);
1358 if (DOT11F_FAILED(status)) {
1359 lim_log(mac_ctx, LOGE,
1360 FL("Association Response pack failure(0x%08x)."),
1361 status);
1362 cds_packet_free((void *)packet);
1363 return;
1364 } else if (DOT11F_WARNED(status)) {
1365 lim_log(mac_ctx, LOGW,
1366 FL("Association Response pack warning (0x%08x)."),
1367 status);
1368 }
1369
1370 if (subtype == LIM_ASSOC)
1371 lim_log(mac_ctx, LOG1,
1372 FL("*** Sending Assoc Resp status %d aid %d to "),
1373 status_code, aid);
1374 else
1375 lim_log(mac_ctx, LOG1,
1376 FL("*** Sending ReAssoc Resp status %d aid %d to "),
1377 status_code, aid);
1378
1379 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1380
1381 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
1382 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
1383 &add_ie[0], addn_ie_len);
1384
1385 if ((SIR_BAND_5_GHZ ==
1386 lim_get_rf_band(pe_session->currentOperChannel)) ||
1387 (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
1388 (pe_session->pePersona == CDF_P2P_GO_MODE))
1389 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1390
1391 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
1392 pe_session->peSessionId, mac_hdr->fc.subType));
1393 /* Queue Association Response frame in high priority WQ */
1394 cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
1395 TXRX_FRM_802_11_MGMT,
1396 ANI_TXDIR_TODS,
1397 7, lim_tx_complete, frame, tx_flag,
1398 sme_session, 0);
1399 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
1400 pe_session->peSessionId, cdf_status));
1401
1402 /* Pkt will be freed up by the callback */
1403 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1404 lim_log(mac_ctx, LOGE,
1405 FL("*** Could not Send Re/AssocRsp, retCode=%X ***"),
1406 cdf_status);
1407
1408 /*
1409 * update the ANI peer station count.
1410 * FIXME_PROTECTION : take care of different type of station
1411 * counter inside this function.
1412 */
1413 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1414
1415}
1416
1417void
1418lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1419 tSirMacAddr peer,
1420 uint8_t wmmTspecPresent,
1421 tSirMacTSInfo *pTsinfo,
1422 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1423{
1424 uint8_t *pFrame;
1425 tpSirMacMgmtHdr pMacHdr;
1426 tDot11fDelTS DelTS;
1427 tDot11fWMMDelTS WMMDelTS;
1428 uint32_t nBytes, nPayload, nStatus;
1429 void *pPacket;
1430 CDF_STATUS cdf_status;
1431 uint8_t txFlag = 0;
1432 uint8_t smeSessionId = 0;
1433
1434 if (NULL == psessionEntry) {
1435 return;
1436 }
1437
1438 smeSessionId = psessionEntry->smeSessionId;
1439
1440 if (!wmmTspecPresent) {
1441 cdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
1442
1443 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1444 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1445 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1446
1447 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1448 if (DOT11F_FAILED(nStatus)) {
1449 lim_log(pMac, LOGP,
1450 FL("Failed to calculate the packed si"
1451 "ze for a Del TS (0x%08x)."), nStatus);
1452 /* We'll fall back on the worst case scenario: */
1453 nPayload = sizeof(tDot11fDelTS);
1454 } else if (DOT11F_WARNED(nStatus)) {
1455 lim_log(pMac, LOGW,
1456 FL("There were warnings while calcula"
1457 "ting the packed size for a Del TS"
1458 " (0x%08x)."), nStatus);
1459 }
1460 } else {
1461 cdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
1462
1463 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1464 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1465 WMMDelTS.DialogToken.token = 0;
1466 WMMDelTS.StatusCode.statusCode = 0;
1467 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1468 nStatus =
1469 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1470 if (DOT11F_FAILED(nStatus)) {
1471 lim_log(pMac, LOGP,
1472 FL("Failed to calculate the packed si"
1473 "ze for a WMM Del TS (0x%08x)."), nStatus);
1474 /* We'll fall back on the worst case scenario: */
1475 nPayload = sizeof(tDot11fDelTS);
1476 } else if (DOT11F_WARNED(nStatus)) {
1477 lim_log(pMac, LOGW,
1478 FL("There were warnings while calcula"
1479 "ting the packed size for a WMM De"
1480 "l TS (0x%08x)."), nStatus);
1481 }
1482 }
1483
1484 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1485
1486 cdf_status =
1487 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1488 (void **)&pPacket);
1489 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1490 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
1491 "d TS Response."), nBytes);
1492 return;
1493 }
1494 /* Paranoia: */
1495 cdf_mem_set(pFrame, nBytes, 0);
1496
1497 /* Next, we fill out the buffer descriptor: */
1498 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1499 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1500 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1501
1502 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1503
1504#ifdef WLAN_FEATURE_11W
1505 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1506#endif
1507
1508 /* That done, pack the struct: */
1509 if (!wmmTspecPresent) {
1510 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1511 pFrame + sizeof(tSirMacMgmtHdr),
1512 nPayload, &nPayload);
1513 if (DOT11F_FAILED(nStatus)) {
1514 lim_log(pMac, LOGE,
1515 FL("Failed to pack a Del TS frame (0x%08x)."),
1516 nStatus);
1517 cds_packet_free((void *)pPacket);
1518 return; /* allocated! */
1519 } else if (DOT11F_WARNED(nStatus)) {
1520 lim_log(pMac, LOGW,
1521 FL("There were warnings while packing "
1522 "a Del TS frame (0x%08x)."), nStatus);
1523 }
1524 } else {
1525 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1526 pFrame + sizeof(tSirMacMgmtHdr),
1527 nPayload, &nPayload);
1528 if (DOT11F_FAILED(nStatus)) {
1529 lim_log(pMac, LOGE,
1530 FL
1531 ("Failed to pack a WMM Del TS frame (0x%08x)."),
1532 nStatus);
1533 cds_packet_free((void *)pPacket);
1534 return; /* allocated! */
1535 } else if (DOT11F_WARNED(nStatus)) {
1536 lim_log(pMac, LOGW,
1537 FL("There were warnings while packing "
1538 "a WMM Del TS frame (0x%08x)."), nStatus);
1539 }
1540 }
1541
1542 PELOG1(lim_log
1543 (pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes);
1544 lim_print_mac_addr(pMac, pMacHdr->da, LOG1);
1545 )
1546
1547 if ((SIR_BAND_5_GHZ ==
1548 lim_get_rf_band(psessionEntry->currentOperChannel))
1549 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE)
1550 || (psessionEntry->pePersona == CDF_P2P_GO_MODE)
1551 ) {
1552 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1553 }
1554
1555 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
1556 psessionEntry->peSessionId, pMacHdr->fc.subType));
1557 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
1558 TXRX_FRM_802_11_MGMT,
1559 ANI_TXDIR_TODS,
1560 7, lim_tx_complete, pFrame, txFlag,
1561 smeSessionId, 0);
1562 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
1563 psessionEntry->peSessionId, cdf_status));
1564 /* Pkt will be freed up by the callback */
1565 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1566 lim_log(pMac, LOGE, FL("Failed to send Del TS (%X)!"),
1567 cdf_status);
1568
1569} /* End lim_send_delts_req_action_frame. */
1570
1571/**
1572 * lim_send_assoc_req_mgmt_frame() - Send association request
1573 * @mac_ctx: Handle to MAC context
1574 * @mlm_assoc_req: Association request information
1575 * @pe_session: PE session information
1576 *
1577 * Builds and transmits association request frame to AP.
1578 *
1579 * Return: Void
1580 */
1581
1582void
1583lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1584 tLimMlmAssocReq *mlm_assoc_req,
1585 tpPESession pe_session)
1586{
1587 tDot11fAssocRequest *frm;
1588 uint16_t caps;
1589 uint8_t *frame;
1590 tSirRetStatus sir_status;
1591 tLimMlmAssocCnf assoc_cnf;
1592 uint32_t bytes, payload, status;
1593 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1594 void *packet;
1595 CDF_STATUS cdf_status;
1596 uint16_t add_ie_len;
1597 uint8_t *add_ie;
1598 uint8_t *wps_ie = NULL;
1599#if defined WLAN_FEATURE_VOWIFI
1600 uint8_t power_caps = false;
1601#endif
1602 uint8_t tx_flag = 0;
1603 uint8_t sme_sessionid = 0;
1604 bool vht_enabled = false;
1605 tDot11fIEExtCap extr_ext_cap;
1606 bool extr_ext_flag = true;
1607 tpSirMacMgmtHdr mac_hdr;
1608
1609 if (NULL == pe_session) {
1610 lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
1611 return;
1612 }
1613
1614 sme_sessionid = pe_session->smeSessionId;
1615
1616 /* check this early to avoid unncessary operation */
1617 if (NULL == pe_session->pLimJoinReq) {
1618 lim_log(mac_ctx, LOGE, FL("pe_session->pLimJoinReq is NULL"));
1619 return;
1620 }
1621 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1622 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1623
1624 frm = cdf_mem_malloc(sizeof(tDot11fAssocRequest));
1625 if (NULL == frm) {
1626 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
1627 return;
1628 }
1629
1630 cdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
1631
1632 if (add_ie_len) {
1633 cdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
1634 0);
1635 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1636 add_ie, &add_ie_len, &extr_ext_cap);
1637 if (eSIR_SUCCESS != sir_status) {
1638 extr_ext_flag = false;
1639 lim_log(mac_ctx, LOG1,
1640 FL("Unable to Stripoff ExtCap IE from Assoc Req"));
1641 } else {
1642 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1643 extr_ext_cap.bytes;
1644
1645 if (p_ext_cap->interworking_service)
1646 p_ext_cap->qos_map = 1;
1647 else {
1648 /*
1649 * No need to merge the EXT Cap from Supplicant
1650 * if interworkingService is not set, as currently
1651 * driver is only interested in interworkingService
1652 * capability from supplicant. if in future any other
1653 * EXT Cap info is required from supplicant
1654 * it needs to be handled here.
1655 */
1656 extr_ext_flag = false;
1657 }
1658 }
1659 } else {
1660 lim_log(mac_ctx, LOG1, FL("No additional IE for Assoc Req"));
1661 extr_ext_flag = false;
1662 }
1663
1664 caps = mlm_assoc_req->capabilityInfo;
1665#if defined(FEATURE_WLAN_WAPI)
1666 /*
1667 * According to WAPI standard:
1668 * 7.3.1.4 Capability Information field
1669 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1670 * in transmitted Association or Reassociation management frames.
1671 * APs ignore the Privacy subfield within received Association and
1672 * Reassociation management frames.
1673 */
1674 if (pe_session->encryptType == eSIR_ED_WPI)
1675 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1676#endif
1677 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1678
1679 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1680 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1681 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1682 &frm->SuppRates, pe_session);
1683
1684 qos_enabled = (pe_session->limQosEnabled) &&
1685 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1686
1687 wme_enabled = (pe_session->limWmeEnabled) &&
1688 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1689
1690 /* We prefer .11e asociations: */
1691 if (qos_enabled)
1692 wme_enabled = false;
1693
1694 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1695 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1696
1697 if (pe_session->lim11hEnable &&
1698 pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
1699#if defined WLAN_FEATURE_VOWIFI
1700 power_caps = true;
1701
1702 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1703 LIM_ASSOC, pe_session);
1704#endif
1705 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1706 LIM_ASSOC, pe_session);
1707
1708 }
1709#if defined WLAN_FEATURE_VOWIFI
1710 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1711 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1712 if (power_caps == false) {
1713 power_caps = true;
1714 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1715 LIM_ASSOC, pe_session);
1716 }
1717 }
1718#endif
1719
1720 if (qos_enabled)
1721 populate_dot11f_qos_caps_station(mac_ctx, &frm->QOSCapsStation);
1722
1723 populate_dot11f_ext_supp_rates(mac_ctx,
1724 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1725 pe_session);
1726
1727#if defined WLAN_FEATURE_VOWIFI
Krishna Kumaar Natarajand26e9e72015-11-03 11:49:03 -08001728 if (mac_ctx->rrm.rrmPEContext.rrmEnable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001729 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1730 pe_session);
1731#endif
1732 /*
1733 * The join request *should* contain zero or one of the WPA and RSN
1734 * IEs. The payload send along with the request is a
1735 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1736 * typedef struct sSirRSNie
1737 * {
1738 * uint16_t length;
1739 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1740 * } tSirRSNie, *tpSirRSNie;
1741 * So, we should be able to make the following two calls harmlessly,
1742 * since they do nothing if they don't find the given IE in the
1743 * bytestream with which they're provided.
1744 * The net effect of this will be to faithfully transmit whatever
1745 * security IE is in the join request.
1746 * However, if we're associating for the purpose of WPS
1747 * enrollment, and we've been configured to indicate that by
1748 * eliding the WPA or RSN IE, we just skip this:
1749 */
1750 if (add_ie_len && add_ie)
1751 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1752
1753 if (NULL == wps_ie) {
1754 populate_dot11f_rsn_opaque(mac_ctx,
1755 &(pe_session->pLimJoinReq->rsnIE),
1756 &frm->RSNOpaque);
1757 populate_dot11f_wpa_opaque(mac_ctx,
1758 &(pe_session->pLimJoinReq->rsnIE),
1759 &frm->WPAOpaque);
1760#if defined(FEATURE_WLAN_WAPI)
1761 populate_dot11f_wapi_opaque(mac_ctx,
1762 &(pe_session->pLimJoinReq->rsnIE),
1763 &frm->WAPIOpaque);
1764#endif /* defined(FEATURE_WLAN_WAPI) */
1765 }
1766 /* include WME EDCA IE as well */
1767 if (wme_enabled) {
1768 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1769 pe_session, &frm->WMMInfoStation);
1770
1771 if (wsm_enabled)
1772 populate_dot11f_wmm_caps(&frm->WMMCaps);
1773 }
1774
1775 /*
1776 * Populate HT IEs, when operating in 11n and
1777 * when AP is also operating in 11n mode
1778 */
1779 if (pe_session->htCapability &&
1780 mac_ctx->lim.htCapabilityPresentInBeacon) {
1781 lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
1782 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
1783 }
1784#ifdef WLAN_FEATURE_11AC
1785 if (pe_session->vhtCapability &&
1786 pe_session->vhtCapabilityPresentInBeacon) {
1787 lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request"));
1788 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
1789 vht_enabled = true;
1790 }
1791 if (!vht_enabled &&
1792 pe_session->is_vendor_specific_vhtcaps) {
1793 lim_log(mac_ctx, LOG1,
1794 FL("Populate Vendor VHT IEs in Assoc Request"));
1795 frm->vendor2_ie.present = 1;
1796 frm->vendor2_ie.type =
1797 pe_session->vendor_specific_vht_ie_type;
1798 frm->vendor2_ie.sub_type =
1799 pe_session->vendor_specific_vht_ie_sub_type;
1800
1801 frm->vendor2_ie.VHTCaps.present = 1;
1802 populate_dot11f_vht_caps(mac_ctx, pe_session,
1803 &frm->vendor2_ie.VHTCaps);
1804 vht_enabled = true;
1805 }
1806
1807#endif
1808
1809 populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap, pe_session);
1810
1811#if defined WLAN_FEATURE_VOWIFI_11R
1812 if (pe_session->pLimJoinReq->is11Rconnection) {
1813#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
1814 tSirBssDescription *bssdescr;
1815
1816 bssdescr = &pe_session->pLimJoinReq->bssDescription;
1817 lim_log(mac_ctx, LOG1, FL("mdie = %02x %02x %02x"),
1818 (unsigned int) bssdescr->mdie[0],
1819 (unsigned int) bssdescr->mdie[1],
1820 (unsigned int) bssdescr->mdie[2]);
1821#endif
1822 populate_mdie(mac_ctx, &frm->MobilityDomain,
1823 pe_session->pLimJoinReq->bssDescription.mdie);
1824 } else {
1825 /* No 11r IEs dont send any MDIE */
1826 lim_log(mac_ctx, LOG1, FL("MDIE not present"));
1827 }
1828#endif
1829
1830#ifdef FEATURE_WLAN_ESE
1831 /*
1832 * ESE Version IE will be included in association request
1833 * when ESE is enabled on DUT through ini and it is also
1834 * advertised by the peer AP to which we are trying to
1835 * associate to.
1836 */
1837 if (pe_session->is_ese_version_ie_present &&
1838 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1839 populate_dot11f_ese_version(&frm->ESEVersion);
1840 /* For ESE Associations fill the ESE IEs */
1841 if (pe_session->isESEconnection &&
1842 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1843#ifndef FEATURE_DISABLE_RM
1844 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1845#endif
1846 }
1847#endif
1848
1849 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1850 if (DOT11F_FAILED(status)) {
1851 lim_log(mac_ctx, LOGP,
1852 FL("Association Request packet size failure(0x%08x)."),
1853 status);
1854 /* We'll fall back on the worst case scenario: */
1855 payload = sizeof(tDot11fAssocRequest);
1856 } else if (DOT11F_WARNED(status)) {
1857 lim_log(mac_ctx, LOGW,
1858 FL("Association request packet size warning (0x%08x)."),
1859 status);
1860 }
1861
1862 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1863
1864 cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
1865 (void **)&packet);
1866 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1867 lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes."),
1868 bytes);
1869
1870 pe_session->limMlmState = pe_session->limPrevMlmState;
1871 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
1872 pe_session->peSessionId,
1873 pe_session->limMlmState));
1874
1875 /* Update PE session id */
1876 assoc_cnf.sessionId = pe_session->peSessionId;
1877
1878 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1879
1880 cds_packet_free((void *)packet);
1881
1882 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1883 (uint32_t *) &assoc_cnf);
1884
1885 cdf_mem_free(frm);
1886 return;
1887 }
1888 /* Paranoia: */
1889 cdf_mem_set(frame, bytes, 0);
1890
1891 /* Next, we fill out the buffer descriptor: */
1892 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1893 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1894 pe_session->selfMacAddr);
1895 /* merge the ExtCap struct */
1896 if (extr_ext_flag)
1897 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap);
1898 /* That done, pack the Assoc Request: */
1899 status = dot11f_pack_assoc_request(mac_ctx, frm,
1900 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1901 if (DOT11F_FAILED(status)) {
1902 lim_log(mac_ctx, LOGE,
1903 FL("Assoc request pack failure (0x%08x)"), status);
1904 cds_packet_free((void *)packet);
1905 cdf_mem_free(frm);
1906 return;
1907 } else if (DOT11F_WARNED(status)) {
1908 lim_log(mac_ctx, LOGW,
1909 FL("Assoc request pack warning (0x%08x)"), status);
1910 }
1911
1912 lim_log(mac_ctx, LOG1,
1913 FL("*** Sending Association Request length %d to "), bytes);
1914 if (pe_session->assocReq != NULL) {
1915 cdf_mem_free(pe_session->assocReq);
1916 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001917 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001918 }
1919
1920 if (add_ie_len) {
1921 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
1922 add_ie, add_ie_len);
1923 payload += add_ie_len;
1924 }
1925
1926 pe_session->assocReq = cdf_mem_malloc(payload);
1927 if (NULL == pe_session->assocReq) {
1928 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
1929 } else {
1930 /*
1931 * Store the Assoc request. This is sent to csr/hdd in
1932 * join cnf response.
1933 */
1934 cdf_mem_copy(pe_session->assocReq,
1935 frame + sizeof(tSirMacMgmtHdr), payload);
1936 pe_session->assocReqLen = payload;
1937 }
1938
1939 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
1940 || (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
1941 || (pe_session->pePersona == CDF_P2P_GO_MODE)
1942 )
1943 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1944
Sushant Kaushik46556062015-12-02 16:57:47 +05301945 if (pe_session->pePersona == CDF_P2P_CLIENT_MODE ||
1946 pe_session->pePersona == CDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001947 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
1948
1949#ifdef FEATURE_WLAN_DIAG_SUPPORT
1950 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
1951 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
1952#endif
1953 mac_hdr = (tpSirMacMgmtHdr) frame;
1954 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
1955 pe_session->peSessionId, mac_hdr->fc.subType));
1956 cdf_status =
1957 wma_tx_frame(mac_ctx, packet,
1958 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
1959 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
1960 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
1961 MTRACE(cdf_trace
1962 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
1963 pe_session->peSessionId, cdf_status));
1964 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1965 lim_log(mac_ctx, LOGE,
1966 FL("Failed to send Association Request (%X)!"),
1967 cdf_status);
1968 /* Pkt will be freed up by the callback */
1969 cdf_mem_free(frm);
1970 return;
1971 }
1972 /* Free up buffer allocated for mlm_assoc_req */
1973 cdf_mem_free(mlm_assoc_req);
1974 mlm_assoc_req = NULL;
1975 cdf_mem_free(frm);
1976 return;
1977}
1978
1979#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
1980/**
1981 * lim_send_reassoc_req_with_ft_ies_mgmt_frame() - Send Reassoc Req with FTIEs.
1982 *
1983 * @mac_ctx: Handle to mac context
1984 * @mlm_reassoc_req: Original reassoc request
1985 * @pe_session: PE session information
1986 *
1987 * It builds a reassoc request with FT IEs and sends it to AP through WMA.
1988 * Then it creates assoc request and stores it for sending after join
1989 * confirmation.
1990 *
1991 * Return: void
1992 */
1993
1994void
1995lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal mac_ctx,
1996 tLimMlmReassocReq *mlm_reassoc_req,
1997 tpPESession pe_session)
1998{
1999 static tDot11fReAssocRequest frm;
2000 uint16_t caps;
2001 uint8_t *frame;
2002 uint32_t bytes, payload, status;
2003 uint8_t qos_enabled, wme_enabled, wsm_enabled;
2004 void *packet;
2005 CDF_STATUS cdf_status;
2006#if defined WLAN_FEATURE_VOWIFI
2007 uint8_t power_caps_populated = false;
2008#endif
2009 uint16_t ft_ies_length = 0;
2010 uint8_t *body;
2011 uint16_t add_ie_len;
2012 uint8_t *add_ie;
2013#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2014 uint8_t *wps_ie = NULL;
2015#endif
2016 uint8_t tx_flag = 0;
2017 uint8_t sme_sessionid = 0;
2018 bool vht_enabled = false;
2019 tpSirMacMgmtHdr mac_hdr;
2020 tftSMEContext *ft_sme_context;
2021
2022 if (NULL == pe_session)
2023 return;
2024
2025 sme_sessionid = pe_session->smeSessionId;
2026
2027 /* check this early to avoid unncessary operation */
2028 if (NULL == pe_session->pLimReAssocReq)
2029 return;
2030
2031 add_ie_len = pe_session->pLimReAssocReq->addIEAssoc.length;
2032 add_ie = pe_session->pLimReAssocReq->addIEAssoc.addIEdata;
2033 lim_log(mac_ctx, LOG1,
2034 FL("called in state (%d)."), pe_session->limMlmState);
2035
2036 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
2037
2038 caps = mlm_reassoc_req->capabilityInfo;
2039#if defined(FEATURE_WLAN_WAPI)
2040 /*
2041 * According to WAPI standard:
2042 * 7.3.1.4 Capability Information field
2043 * In WAPI, non-AP STAs within an ESS set the Privacy subfield
2044 * to 0 in transmitted Association or Reassociation management
2045 * frames. APs ignore the Privacy subfield within received
2046 * Association and Reassociation management frames.
2047 */
2048 if (pe_session->encryptType == eSIR_ED_WPI)
2049 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
2050#endif
2051 swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);
2052
2053 frm.ListenInterval.interval = mlm_reassoc_req->listenInterval;
2054
2055 /*
2056 * Get the old bssid of the older AP.
2057 * The previous ap bssid is stored in the FT Session
2058 * while creating the PE FT Session for reassociation.
2059 */
2060 cdf_mem_copy((uint8_t *)frm.CurrentAPAddress.mac,
2061 pe_session->prev_ap_bssid, sizeof(tSirMacAddr));
2062
2063 populate_dot11f_ssid2(mac_ctx, &frm.SSID);
2064 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
2065 &frm.SuppRates, pe_session);
2066
2067 qos_enabled = (pe_session->limQosEnabled) &&
2068 SIR_MAC_GET_QOS(pe_session->limReassocBssCaps);
2069
2070 wme_enabled = (pe_session->limWmeEnabled) &&
2071 LIM_BSS_CAPS_GET(WME, pe_session->limReassocBssQosCaps);
2072
2073 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
2074 LIM_BSS_CAPS_GET(WSM, pe_session->limReassocBssQosCaps);
2075
2076 if (pe_session->lim11hEnable &&
2077 pe_session->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
2078#if defined WLAN_FEATURE_VOWIFI
2079 power_caps_populated = true;
2080
2081 populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
2082 LIM_REASSOC, pe_session);
2083 populate_dot11f_supp_channels(mac_ctx, &frm.SuppChannels,
2084 LIM_REASSOC, pe_session);
2085#endif
2086 }
2087#if defined WLAN_FEATURE_VOWIFI
2088 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
2089 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
2090 if (power_caps_populated == false) {
2091 power_caps_populated = true;
2092 populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
2093 LIM_REASSOC, pe_session);
2094 }
2095 }
2096#endif
2097
2098 if (qos_enabled)
2099 populate_dot11f_qos_caps_station(mac_ctx, &frm.QOSCapsStation);
2100
2101 populate_dot11f_ext_supp_rates(mac_ctx,
2102 POPULATE_DOT11F_RATES_OPERATIONAL, &frm.ExtSuppRates,
2103 pe_session);
2104
2105#if defined WLAN_FEATURE_VOWIFI
Krishna Kumaar Natarajand26e9e72015-11-03 11:49:03 -08002106 if (mac_ctx->rrm.rrmPEContext.rrmEnable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002107 populate_dot11f_rrm_ie(mac_ctx, &frm.RRMEnabledCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002108#endif
2109
2110 /*
2111 * Ideally this should be enabled for 11r also. But 11r does
2112 * not follow the usual norm of using the Opaque object
2113 * for rsnie and fties. Instead we just add the rsnie and fties
2114 * at the end of the pack routine for 11r.
2115 * This should ideally! be fixed.
2116 */
2117#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2118 /*
2119 * The join request *should* contain zero or one of the WPA and RSN
2120 * IEs. The payload send along with the request is a
2121 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
2122 *
2123 * typedef struct sSirRSNie
2124 * {
2125 * uint16_t length;
2126 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
2127 * } tSirRSNie, *tpSirRSNie;
2128 *
2129 * So, we should be able to make the following two calls harmlessly,
2130 * since they do nothing if they don't find the given IE in the
2131 * bytestream with which they're provided.
2132 *
2133 * The net effect of this will be to faithfully transmit whatever
2134 * security IE is in the join request.
2135
2136 * However, if we're associating for the purpose of WPS
2137 * enrollment, and we've been configured to indicate that by
2138 * eliding the WPA or RSN IE, we just skip this:
2139 */
2140 if (!pe_session->is11Rconnection) {
2141 if (add_ie_len && add_ie)
2142 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
2143 if (NULL == wps_ie) {
2144 populate_dot11f_rsn_opaque(mac_ctx,
2145 &(pe_session->pLimReAssocReq->rsnIE),
2146 &frm.RSNOpaque);
2147 populate_dot11f_wpa_opaque(mac_ctx,
2148 &(pe_session->pLimReAssocReq->rsnIE),
2149 &frm.WPAOpaque);
2150 }
2151#ifdef FEATURE_WLAN_ESE
2152 if (pe_session->pLimReAssocReq->cckmIE.length) {
2153 populate_dot11f_ese_cckm_opaque(mac_ctx,
2154 &(pe_session->pLimReAssocReq->cckmIE),
2155 &frm.ESECckmOpaque);
2156 }
2157#endif
2158 }
2159#ifdef FEATURE_WLAN_ESE
2160 /*
2161 * ESE Version IE will be included in re-association request
2162 * when ESE is enabled on DUT through ini and it is also
2163 * advertised by the peer AP to which we are trying to
2164 * associate to.
2165 */
2166 if (pe_session->is_ese_version_ie_present &&
2167 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
2168 populate_dot11f_ese_version(&frm.ESEVersion);
2169 /* For ESE Associations fill the ESE IEs */
2170 if (pe_session->isESEconnection &&
2171 pe_session->pLimReAssocReq->isESEFeatureIniEnabled) {
2172#ifndef FEATURE_DISABLE_RM
2173 populate_dot11f_ese_rad_mgmt_cap(&frm.ESERadMgmtCap);
2174#endif
2175 }
2176#endif /* FEATURE_WLAN_ESE */
2177#endif /* FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
2178
2179 /* include WME EDCA IE as well */
2180 if (wme_enabled) {
2181 populate_dot11f_wmm_info_station_per_session(mac_ctx,
2182 pe_session, &frm.WMMInfoStation);
2183 if (wsm_enabled)
2184 populate_dot11f_wmm_caps(&frm.WMMCaps);
2185#ifdef FEATURE_WLAN_ESE
2186 if (pe_session->isESEconnection) {
2187 uint32_t phymode;
2188 uint8_t rate;
2189
2190 populate_dot11f_re_assoc_tspec(mac_ctx, &frm,
2191 pe_session);
2192
2193 /*
2194 * Populate the TSRS IE if TSPEC is included in
2195 * the reassoc request
2196 */
2197 lim_get_phy_mode(mac_ctx, &phymode, pe_session);
2198 if (phymode == WNI_CFG_PHY_MODE_11G ||
2199 phymode == WNI_CFG_PHY_MODE_11A)
2200 rate = TSRS_11AG_RATE_6MBPS;
2201 else
2202 rate = TSRS_11B_RATE_5_5MBPS;
2203
2204 if (pe_session->pLimReAssocReq->eseTspecInfo.
2205 numTspecs) {
2206 tSirMacESETSRSIE tsrs_ie;
2207
2208 tsrs_ie.tsid = 0;
2209 tsrs_ie.rates[0] = rate;
2210 populate_dot11_tsrsie(mac_ctx, &tsrs_ie,
2211 &frm.ESETrafStrmRateSet,
2212 sizeof(uint8_t));
2213 }
2214 }
2215#endif
2216 }
2217
2218 ft_sme_context = &mac_ctx->roam.roamSession[sme_sessionid].ftSmeContext;
2219 if (pe_session->htCapability &&
2220 mac_ctx->lim.htCapabilityPresentInBeacon) {
2221 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm.HTCaps);
2222 }
2223#if defined WLAN_FEATURE_VOWIFI_11R
2224 if (pe_session->pLimReAssocReq->bssDescription.mdiePresent &&
2225 (ft_sme_context->addMDIE == true)
2226#if defined FEATURE_WLAN_ESE
2227 && !pe_session->isESEconnection
2228#endif
2229 ) {
2230 populate_mdie(mac_ctx, &frm.MobilityDomain,
2231 pe_session->pLimReAssocReq->bssDescription.mdie);
2232 }
2233#endif
2234
2235#ifdef WLAN_FEATURE_11AC
2236 if (pe_session->vhtCapability &&
2237 pe_session->vhtCapabilityPresentInBeacon) {
2238 lim_log(mac_ctx, LOG1,
2239 FL("Populate VHT IEs in Re-Assoc Request"));
2240 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm.VHTCaps);
2241 vht_enabled = true;
2242 populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm.ExtCap,
2243 pe_session);
2244 }
2245 if (!vht_enabled &&
2246 pe_session->is_vendor_specific_vhtcaps) {
2247 lim_log(mac_ctx, LOG1,
2248 FL("Populate Vendor VHT IEs in Re-Assoc Request"));
2249 frm.vendor2_ie.present = 1;
2250 frm.vendor2_ie.type =
2251 pe_session->vendor_specific_vht_ie_type;
2252 frm.vendor2_ie.sub_type =
2253 pe_session->vendor_specific_vht_ie_sub_type;
2254 frm.vendor2_ie.VHTCaps.present = 1;
2255 populate_dot11f_vht_caps(mac_ctx, pe_session,
2256 &frm.vendor2_ie.VHTCaps);
2257 vht_enabled = true;
2258 }
2259#endif
2260
2261 status = dot11f_get_packed_re_assoc_request_size(mac_ctx, &frm,
2262 &payload);
2263 if (DOT11F_FAILED(status)) {
2264 lim_log(mac_ctx, LOGP,
2265 FL("Failure in size calculation (0x%08x)."), status);
2266 /* We'll fall back on the worst case scenario: */
2267 payload = sizeof(tDot11fReAssocRequest);
2268 } else if (DOT11F_WARNED(status)) {
2269 lim_log(mac_ctx, LOGW,
2270 FL("Warnings in size calculation(0x%08x)."), status);
2271 }
2272
2273 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
2274
2275#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
2276 lim_log(mac_ctx, LOG1, FL("FT IE Reassoc Req (%d)."),
2277 ft_sme_context->reassoc_ft_ies_length);
2278#endif
2279
2280#if defined WLAN_FEATURE_VOWIFI_11R
2281 if (pe_session->is11Rconnection)
2282 ft_ies_length = ft_sme_context->reassoc_ft_ies_length;
2283#endif
2284
2285 cdf_status = cds_packet_alloc((uint16_t) bytes + ft_ies_length,
2286 (void **)&frame, (void **)&packet);
2287 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2288 pe_session->limMlmState = pe_session->limPrevMlmState;
2289 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
2290 pe_session->peSessionId,
2291 pe_session->limMlmState));
2292 lim_log(mac_ctx, LOGP, FL("Failed to alloc memory %d"), bytes);
2293 goto end;
2294 }
2295 /* Paranoia: */
2296 cdf_mem_set(frame, bytes + ft_ies_length, 0);
2297
2298#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2299 lim_print_mac_addr(mac_ctx, pe_session->limReAssocbssId, LOG1);
2300#endif
2301 /* Next, we fill out the buffer descriptor: */
2302 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2303 SIR_MAC_MGMT_REASSOC_REQ, pe_session->limReAssocbssId,
2304 pe_session->selfMacAddr);
2305 mac_hdr = (tpSirMacMgmtHdr) frame;
2306 /* That done, pack the ReAssoc Request: */
2307 status = dot11f_pack_re_assoc_request(mac_ctx, &frm, frame +
2308 sizeof(tSirMacMgmtHdr),
2309 payload, &payload);
2310 if (DOT11F_FAILED(status)) {
2311 lim_log(mac_ctx, LOGE, FL("Failure in pack (0x%08x)."), status);
2312 cds_packet_free((void *)packet);
2313 goto end;
2314 } else if (DOT11F_WARNED(status)) {
2315 lim_log(mac_ctx, LOGW, FL("Warnings in pack (0x%08x)."),
2316 status);
2317 }
2318
2319 lim_log(mac_ctx, LOG3,
2320 FL("*** Sending Re-Assoc Request length %d %d to "),
2321 bytes, payload);
2322
2323 if (pe_session->assocReq != NULL) {
2324 cdf_mem_free(pe_session->assocReq);
2325 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002326 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002327 }
2328
2329 if (add_ie_len) {
2330 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
2331 add_ie, add_ie_len);
2332 payload += add_ie_len;
2333 }
2334
2335 pe_session->assocReq = cdf_mem_malloc(payload);
2336 if (NULL == pe_session->assocReq) {
2337 lim_log(mac_ctx, LOGE, FL("Failed to alloc memory"));
2338 } else {
2339 /*
2340 * Store the Assoc request. This is sent to csr/hdd in
2341 * join cnf response.
2342 */
2343 cdf_mem_copy(pe_session->assocReq,
2344 frame + sizeof(tSirMacMgmtHdr), payload);
2345 pe_session->assocReqLen = payload;
2346 }
2347
2348 if (pe_session->is11Rconnection && ft_sme_context->reassoc_ft_ies) {
2349 int i = 0;
2350
2351 body = frame + bytes;
2352 for (i = 0; i < ft_ies_length; i++) {
2353 *body = ft_sme_context->reassoc_ft_ies[i];
2354 body++;
2355 }
2356 }
2357#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
2358 PELOGE(lim_log(mac_ctx, LOG1, FL("Re-assoc Req Frame is: "));
2359 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG1,
2360 (uint8_t *) frame, (bytes + ft_ies_length));
2361 )
2362#endif
2363 if ((SIR_BAND_5_GHZ ==
2364 lim_get_rf_band(pe_session->currentOperChannel)) ||
2365 (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
2366 (pe_session->pePersona == CDF_P2P_GO_MODE)) {
2367 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2368 }
2369
2370 if (NULL != pe_session->assocReq) {
2371 cdf_mem_free(pe_session->assocReq);
2372 pe_session->assocReq = NULL;
Sreelakshmi Konamki3b8ba612015-12-02 18:13:22 +05302373 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002374 }
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002375 if (ft_ies_length) {
2376 pe_session->assocReq = cdf_mem_malloc(ft_ies_length);
2377 if (NULL == pe_session->assocReq) {
2378 lim_log(mac_ctx,
2379 LOGE, FL("Failed to alloc memory for FT IEs"));
2380 pe_session->assocReqLen = 0;
2381 } else {
2382 /*
2383 * Store the FT IEs. This is sent to csr/hdd in
2384 * join cnf response.
2385 */
2386 cdf_mem_copy(pe_session->assocReq,
2387 ft_sme_context->reassoc_ft_ies, ft_ies_length);
2388 pe_session->assocReqLen = ft_ies_length;
2389 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390 } else {
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002391 lim_log(mac_ctx, LOG1, FL("FT IEs not present"));
Naveen Rawat83102ef2015-11-03 10:42:34 -08002392 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002393 }
2394
2395#ifdef FEATURE_WLAN_DIAG_SUPPORT
2396 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_START_EVENT,
2397 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2398#endif
2399 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
2400 pe_session->peSessionId, mac_hdr->fc.subType));
2401 cdf_status = wma_tx_frame(mac_ctx, packet,
2402 (uint16_t) (bytes + ft_ies_length),
2403 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2404 lim_tx_complete, frame, tx_flag, sme_sessionid,
2405 0);
2406 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2407 pe_session->peSessionId, cdf_status));
2408 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2409 lim_log(mac_ctx, LOGE,
2410 FL("Failed to send Re-Assoc Request (%X)!"),
2411 cdf_status);
2412 }
2413
2414end:
2415 /* Free up buffer allocated for mlmAssocReq */
2416 cdf_mem_free(mlm_reassoc_req);
2417 pe_session->pLimMlmReassocReq = NULL;
2418
2419}
2420
2421void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
2422 tLimMlmReassocReq *pMlmReassocReq,
2423 tpPESession psessionEntry)
2424{
2425 tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
2426 tLimMlmReassocReq *pTmpMlmReassocReq = NULL;
2427 if (NULL == pTmpMlmReassocReq) {
2428 pTmpMlmReassocReq = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
2429 if (NULL == pTmpMlmReassocReq)
2430 goto end;
2431 cdf_mem_set(pTmpMlmReassocReq, sizeof(tLimMlmReassocReq), 0);
2432 cdf_mem_copy(pTmpMlmReassocReq, pMlmReassocReq,
2433 sizeof(tLimMlmReassocReq));
2434 }
2435 /* Prepare and send Reassociation request frame */
2436 /* start reassoc timer. */
2437 pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
2438 psessionEntry->peSessionId;
2439 /* Start reassociation failure timer */
2440 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE,
2441 psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
2442 if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
2443 != TX_SUCCESS) {
2444 /* Could not start reassoc failure timer. */
2445 /* Log error */
2446 lim_log(pMac, LOGP,
2447 FL("could not start Reassociation failure timer"));
2448 /* Return Reassoc confirm with */
2449 /* Resources Unavailable */
2450 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
2451 mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2452 goto end;
2453 }
2454
2455 lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac, pTmpMlmReassocReq,
2456 psessionEntry);
2457 return;
2458
2459end:
2460 /* Free up buffer allocated for reassocReq */
2461 if (pMlmReassocReq != NULL) {
2462 cdf_mem_free(pMlmReassocReq);
2463 pMlmReassocReq = NULL;
2464 }
2465 if (pTmpMlmReassocReq != NULL) {
2466 cdf_mem_free(pTmpMlmReassocReq);
2467 pTmpMlmReassocReq = NULL;
2468 }
2469 mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
2470 mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2471 /* Update PE sessio Id */
2472 mlmReassocCnf.sessionId = psessionEntry->peSessionId;
2473
2474 lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
2475 (uint32_t *) &mlmReassocCnf);
2476}
2477
2478#endif /* WLAN_FEATURE_VOWIFI_11R */
2479
2480void
2481lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal pMac,
2482 tLimMlmReassocReq *pMlmReassocReq,
2483 tpPESession psessionEntry)
2484{
2485 static tDot11fReAssocRequest frm;
2486 uint16_t caps;
2487 uint8_t *pFrame;
2488 uint32_t nBytes, nPayload, nStatus;
2489 uint8_t fQosEnabled, fWmeEnabled, fWsmEnabled;
2490 void *pPacket;
2491 CDF_STATUS cdf_status;
2492 uint16_t nAddIELen;
2493 uint8_t *pAddIE;
2494 uint8_t *wpsIe = NULL;
2495 uint8_t txFlag = 0;
2496#if defined WLAN_FEATURE_VOWIFI
2497 uint8_t PowerCapsPopulated = false;
2498#endif
2499 uint8_t smeSessionId = 0;
2500 bool isVHTEnabled = false;
2501 tpSirMacMgmtHdr pMacHdr;
2502
2503 if (NULL == psessionEntry) {
2504 return;
2505 }
2506
2507 smeSessionId = psessionEntry->smeSessionId;
2508
2509 /* check this early to avoid unncessary operation */
2510 if (NULL == psessionEntry->pLimReAssocReq) {
2511 return;
2512 }
2513 nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
2514 pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;
2515
2516 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
2517
2518 caps = pMlmReassocReq->capabilityInfo;
2519#if defined(FEATURE_WLAN_WAPI)
2520 /* CR: 262463 :
2521 According to WAPI standard:
2522 7.3.1.4 Capability Information field
2523 In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
2524 Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
2525 Reassociation management frames. */
2526 if (psessionEntry->encryptType == eSIR_ED_WPI)
2527 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
2528#endif
2529 swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);
2530
2531 frm.ListenInterval.interval = pMlmReassocReq->listenInterval;
2532
2533 cdf_mem_copy((uint8_t *) frm.CurrentAPAddress.mac,
2534 (uint8_t *) psessionEntry->bssId, 6);
2535
2536 populate_dot11f_ssid2(pMac, &frm.SSID);
2537 populate_dot11f_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2538 &frm.SuppRates, psessionEntry);
2539
2540 fQosEnabled = (psessionEntry->limQosEnabled) &&
2541 SIR_MAC_GET_QOS(psessionEntry->limReassocBssCaps);
2542
2543 fWmeEnabled = (psessionEntry->limWmeEnabled) &&
2544 LIM_BSS_CAPS_GET(WME, psessionEntry->limReassocBssQosCaps);
2545
2546 fWsmEnabled = (psessionEntry->limWsmEnabled) && fWmeEnabled &&
2547 LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);
2548
2549 if (psessionEntry->lim11hEnable &&
2550 psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
2551#if defined WLAN_FEATURE_VOWIFI
2552 PowerCapsPopulated = true;
2553 populate_dot11f_power_caps(pMac, &frm.PowerCaps, LIM_REASSOC,
2554 psessionEntry);
2555 populate_dot11f_supp_channels(pMac, &frm.SuppChannels, LIM_REASSOC,
2556 psessionEntry);
2557#endif
2558 }
2559#if defined WLAN_FEATURE_VOWIFI
2560 if (pMac->rrm.rrmPEContext.rrmEnable &&
2561 SIR_MAC_GET_RRM(psessionEntry->limCurrentBssCaps)) {
2562 if (PowerCapsPopulated == false) {
2563 PowerCapsPopulated = true;
2564 populate_dot11f_power_caps(pMac, &frm.PowerCaps,
2565 LIM_REASSOC, psessionEntry);
2566 }
2567 }
2568#endif
2569
2570 if (fQosEnabled)
2571 populate_dot11f_qos_caps_station(pMac, &frm.QOSCapsStation);
2572
2573 populate_dot11f_ext_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2574 &frm.ExtSuppRates, psessionEntry);
2575
2576#if defined WLAN_FEATURE_VOWIFI
Krishna Kumaar Natarajand26e9e72015-11-03 11:49:03 -08002577 if (pMac->rrm.rrmPEContext.rrmEnable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002578 populate_dot11f_rrm_ie(pMac, &frm.RRMEnabledCap, psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002579#endif
2580 /* The join request *should* contain zero or one of the WPA and RSN */
2581 /* IEs. The payload send along with the request is a */
2582 /* 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': */
2583
2584 /* typedef struct sSirRSNie */
2585 /* { */
2586 /* uint16_t length; */
2587 /* uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
2588 /* } tSirRSNie, *tpSirRSNie; */
2589
2590 /* So, we should be able to make the following two calls harmlessly, */
2591 /* since they do nothing if they don't find the given IE in the */
2592 /* bytestream with which they're provided. */
2593
2594 /* The net effect of this will be to faithfully transmit whatever */
2595 /* security IE is in the join request. */
2596
2597 /**However*, if we're associating for the purpose of WPS */
2598 /* enrollment, and we've been configured to indicate that by */
2599 /* eliding the WPA or RSN IE, we just skip this: */
2600 if (nAddIELen && pAddIE) {
2601 wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
2602 }
2603 if (NULL == wpsIe) {
2604 populate_dot11f_rsn_opaque(pMac,
2605 &(psessionEntry->pLimReAssocReq->rsnIE),
2606 &frm.RSNOpaque);
2607 populate_dot11f_wpa_opaque(pMac,
2608 &(psessionEntry->pLimReAssocReq->rsnIE),
2609 &frm.WPAOpaque);
2610#if defined(FEATURE_WLAN_WAPI)
2611 populate_dot11f_wapi_opaque(pMac,
2612 &(psessionEntry->pLimReAssocReq->
2613 rsnIE), &frm.WAPIOpaque);
2614#endif /* defined(FEATURE_WLAN_WAPI) */
2615 }
2616 /* include WME EDCA IE as well */
2617 if (fWmeEnabled) {
2618 populate_dot11f_wmm_info_station_per_session(pMac,
2619 psessionEntry,
2620 &frm.WMMInfoStation);
2621
2622 if (fWsmEnabled)
2623 populate_dot11f_wmm_caps(&frm.WMMCaps);
2624 }
2625
2626 if (psessionEntry->htCapability &&
2627 pMac->lim.htCapabilityPresentInBeacon) {
2628 populate_dot11f_ht_caps(pMac, psessionEntry, &frm.HTCaps);
2629 }
2630#ifdef WLAN_FEATURE_11AC
2631 if (psessionEntry->vhtCapability &&
2632 psessionEntry->vhtCapabilityPresentInBeacon) {
2633 lim_log(pMac, LOGW, FL("Populate VHT IEs in Re-Assoc Request"));
2634 populate_dot11f_vht_caps(pMac, psessionEntry, &frm.VHTCaps);
2635 isVHTEnabled = true;
2636 }
2637#endif
2638
2639 populate_dot11f_ext_cap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry);
2640
2641 nStatus = dot11f_get_packed_re_assoc_request_size(pMac, &frm, &nPayload);
2642 if (DOT11F_FAILED(nStatus)) {
2643 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
2644 "or a Re-Association Request (0x%08x)."),
2645 nStatus);
2646 /* We'll fall back on the worst case scenario: */
2647 nPayload = sizeof(tDot11fReAssocRequest);
2648 } else if (DOT11F_WARNED(nStatus)) {
2649 lim_log(pMac, LOGW, FL("There were warnings while calculating "
2650 "the packed size for a Re-Association Re "
2651 "quest(0x%08x)."), nStatus);
2652 }
2653
2654 nBytes = nPayload + sizeof(tSirMacMgmtHdr) + nAddIELen;
2655
2656 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
2657 (void **)&pPacket);
2658 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2659 psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
2660 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
2661 psessionEntry->peSessionId,
2662 psessionEntry->limMlmState));
2663 lim_log(pMac, LOGP,
2664 FL("Failed to allocate %d bytes for a Re-As"
2665 "sociation Request."), nBytes);
2666 goto end;
2667 }
2668 /* Paranoia: */
2669 cdf_mem_set(pFrame, nBytes, 0);
2670
2671 /* Next, we fill out the buffer descriptor: */
2672 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2673 SIR_MAC_MGMT_REASSOC_REQ, psessionEntry->limReAssocbssId,
2674 psessionEntry->selfMacAddr);
2675 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2676
2677 /* That done, pack the Probe Request: */
2678 nStatus = dot11f_pack_re_assoc_request(pMac, &frm, pFrame +
2679 sizeof(tSirMacMgmtHdr),
2680 nPayload, &nPayload);
2681 if (DOT11F_FAILED(nStatus)) {
2682 lim_log(pMac, LOGE, FL("Failed to pack a Re-Association Reque"
2683 "st (0x%08x)."), nStatus);
2684 cds_packet_free((void *)pPacket);
2685 goto end;
2686 } else if (DOT11F_WARNED(nStatus)) {
2687 lim_log(pMac, LOGW, FL("There were warnings while packing a R"
2688 "e-Association Request (0x%08x)."),
2689 nStatus);
2690 }
2691
2692 PELOG1(lim_log
2693 (pMac, LOG1,
2694 FL("*** Sending Re-Association Request length %d" "to "),
2695 nBytes);
2696 )
2697
2698 if (psessionEntry->assocReq != NULL) {
2699 cdf_mem_free(psessionEntry->assocReq);
2700 psessionEntry->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002701 psessionEntry->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002702 }
2703
2704 if (nAddIELen) {
2705 cdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
2706 pAddIE, nAddIELen);
2707 nPayload += nAddIELen;
2708 }
2709
2710 psessionEntry->assocReq = cdf_mem_malloc(nPayload);
2711 if (NULL == psessionEntry->assocReq) {
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002712 lim_log(pMac, LOGE, FL("Unable to allocate mem for assoc req"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713 } else {
2714 /* Store the Assoc request. This is sent to csr/hdd in join cnf response. */
2715 cdf_mem_copy(psessionEntry->assocReq,
2716 pFrame + sizeof(tSirMacMgmtHdr), nPayload);
2717 psessionEntry->assocReqLen = nPayload;
2718 }
2719
2720 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
2721 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
2722 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
2723 ) {
2724 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2725 }
2726
Sushant Kaushik46556062015-12-02 16:57:47 +05302727 if (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE ||
2728 psessionEntry->pePersona == CDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002729 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002730
2731#ifdef FEATURE_WLAN_DIAG_SUPPORT
2732 lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT,
2733 psessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
2734#endif
2735 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
2736 psessionEntry->peSessionId, pMacHdr->fc.subType));
2737 cdf_status =
2738 wma_tx_frame(pMac, pPacket,
2739 (uint16_t) (sizeof(tSirMacMgmtHdr) + nPayload),
2740 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2741 lim_tx_complete, pFrame, txFlag, smeSessionId, 0);
2742 MTRACE(cdf_trace
2743 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2744 psessionEntry->peSessionId, cdf_status));
2745 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2746 lim_log(pMac, LOGE,
2747 FL("Failed to send Re-Association Request (%X)!"),
2748 cdf_status);
2749 /* Pkt will be freed up by the callback */
2750 }
2751
2752end:
2753 /* Free up buffer allocated for mlmAssocReq */
2754 cdf_mem_free(pMlmReassocReq);
2755 psessionEntry->pLimMlmReassocReq = NULL;
2756
2757} /* lim_send_reassoc_req_mgmt_frame */
2758
2759/**
2760 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2761 *
2762 * @mac_ctx: Pointer to Global MAC structure
2763 * @auth_frame: Pointer to Authentication frame structure
2764 * @peer_addr: MAC address of destination peer
2765 * @wep_bit: wep bit in frame control for Authentication frame3
2766 * @session: PE session information
2767 *
2768 * This function is called by lim_process_mlm_messages(). Authentication frame
2769 * is formatted and sent when this function is called.
2770 *
2771 * Return: void
2772 */
2773
2774void
2775lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2776 tpSirMacAuthFrameBody auth_frame,
2777 tSirMacAddr peer_addr,
2778 uint8_t wep_bit, tpPESession session)
2779{
2780 uint8_t *frame, *body;
2781 uint32_t frame_len = 0, body_len = 0;
2782 tpSirMacMgmtHdr mac_hdr;
2783 void *packet;
2784 CDF_STATUS cdf_status;
2785 uint8_t tx_flag = 0;
2786 uint8_t sme_sessionid = 0;
2787 uint16_t ft_ies_length = 0;
2788
2789 if (NULL == session) {
2790 lim_log(mac_ctx, LOGE, FL("Error: psession Entry is NULL"));
2791 return;
2792 }
2793
2794 sme_sessionid = session->smeSessionId;
2795
2796 lim_log(mac_ctx, LOG1,
2797 FL("Sending Auth seq# %d status %d (%d) to " MAC_ADDRESS_STR),
2798 auth_frame->authTransactionSeqNumber,
2799 auth_frame->authStatusCode,
2800 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
2801 MAC_ADDR_ARRAY(peer_addr));
2802
2803 switch (auth_frame->authTransactionSeqNumber) {
2804 case SIR_MAC_AUTH_FRAME_1:
2805 /*
2806 * Allocate buffer for Authenticaton frame of size
2807 * equal to management frame header length plus 2 bytes
2808 * each for auth algorithm number, transaction number
2809 * and status code.
2810 */
2811
2812 frame_len = sizeof(tSirMacMgmtHdr) +
2813 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2814 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2815
2816#if defined WLAN_FEATURE_VOWIFI_11R
2817 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2818 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2819 0 != session->ftPEContext.pFTPreAuthReq->
2820 ft_ies_length) {
2821 ft_ies_length = session->ftPEContext.
2822 pFTPreAuthReq->ft_ies_length;
2823 frame_len += ft_ies_length;
2824 lim_log(mac_ctx, LOG3,
2825 FL("Auth frame, FTIES length added=%d"),
2826 ft_ies_length);
2827 } else {
2828 lim_log(mac_ctx, LOG3,
2829 FL("Auth frame, Does not contain FTIES!!!"));
2830 frame_len += (2 + SIR_MDIE_SIZE);
2831 }
2832 }
2833#endif
2834 break;
2835
2836 case SIR_MAC_AUTH_FRAME_2:
2837 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2838 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2839 (auth_frame->authStatusCode !=
2840 eSIR_MAC_SUCCESS_STATUS))) {
2841 /*
2842 * Allocate buffer for Authenticaton frame of size
2843 * equal to management frame header length plus
2844 * 2 bytes each for auth algorithm number,
2845 * transaction number and status code.
2846 */
2847
2848 frame_len = sizeof(tSirMacMgmtHdr) +
2849 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2850 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2851 } else {
2852 /*
2853 * Shared Key algorithm with challenge text
2854 * to be sent.
2855 *
2856 * Allocate buffer for Authenticaton frame of size
2857 * equal to management frame header length plus
2858 * 2 bytes each for auth algorithm number,
2859 * transaction number, status code and 128 bytes
2860 * for challenge text.
2861 */
2862
2863 frame_len = sizeof(tSirMacMgmtHdr) +
2864 sizeof(tSirMacAuthFrame);
2865 body_len = sizeof(tSirMacAuthFrameBody);
2866 }
2867 break;
2868
2869 case SIR_MAC_AUTH_FRAME_3:
2870 if (wep_bit == LIM_WEP_IN_FC) {
2871 /*
2872 * Auth frame3 to be sent with encrypted framebody
2873 *
2874 * Allocate buffer for Authenticaton frame of size
2875 * equal to management frame header length plus 2 bytes
2876 * each for auth algorithm number, transaction number,
2877 * status code, 128 bytes for challenge text and
2878 * 4 bytes each for IV & ICV.
2879 */
2880
2881 frame_len = sizeof(tSirMacMgmtHdr) +
2882 LIM_ENCR_AUTH_BODY_LEN;
2883 body_len = LIM_ENCR_AUTH_BODY_LEN;
2884 } else {
2885
2886 /*
2887 * Auth frame3 to be sent without encrypted framebody
2888 *
2889 * Allocate buffer for Authenticaton frame of size equal
2890 * to management frame header length plus 2 bytes each
2891 * for auth algorithm number, transaction number and
2892 * status code.
2893 */
2894
2895 frame_len = sizeof(tSirMacMgmtHdr) +
2896 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2897 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2898 }
2899 break;
2900
2901 case SIR_MAC_AUTH_FRAME_4:
2902 /*
2903 * Allocate buffer for Authenticaton frame of size equal
2904 * to management frame header length plus 2 bytes each
2905 * for auth algorithm number, transaction number and
2906 * status code.
2907 */
2908
2909 frame_len = sizeof(tSirMacMgmtHdr) +
2910 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2911 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2912
2913 break;
2914 } /* switch (auth_frame->authTransactionSeqNumber) */
2915
2916 cdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
2917 (void **)&packet);
2918
2919 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2920 lim_log(mac_ctx, LOGP,
2921 FL("call to bufAlloc failed for AUTH frame"));
2922 return;
2923 }
2924
2925 cdf_mem_zero(frame, frame_len);
2926
2927 /* Prepare BD */
2928 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2929 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2930 mac_hdr = (tpSirMacMgmtHdr) frame;
2931 mac_hdr->fc.wep = wep_bit;
2932
2933 /* Prepare BSSId */
2934 if (LIM_IS_AP_ROLE(session) ||
2935 LIM_IS_BT_AMP_AP_ROLE(session))
2936 cdf_mem_copy((uint8_t *) mac_hdr->bssId,
2937 (uint8_t *) session->bssId,
2938 sizeof(tSirMacAddr));
2939
2940 /* Prepare Authentication frame body */
2941 body = frame + sizeof(tSirMacMgmtHdr);
2942
2943 if (wep_bit == LIM_WEP_IN_FC) {
2944 cdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
2945
2946 lim_log(mac_ctx, LOG1,
2947 FL("*** Sending Auth seq# 3 status %d (%d) to"
2948 MAC_ADDRESS_STR),
2949 auth_frame->authStatusCode,
2950 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
2951 MAC_ADDR_ARRAY(mac_hdr->da));
2952
2953 } else {
2954 *((uint16_t *) (body)) =
2955 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2956 body += sizeof(uint16_t);
2957 body_len -= sizeof(uint16_t);
2958
2959 *((uint16_t *) (body)) =
2960 sir_swap_u16if_needed(
2961 auth_frame->authTransactionSeqNumber);
2962 body += sizeof(uint16_t);
2963 body_len -= sizeof(uint16_t);
2964
2965 *((uint16_t *) (body)) =
2966 sir_swap_u16if_needed(auth_frame->authStatusCode);
2967 body += sizeof(uint16_t);
2968 body_len -= sizeof(uint16_t);
2969 if (body_len <= (sizeof(auth_frame->type) +
2970 sizeof(auth_frame->length) +
2971 sizeof(auth_frame->challengeText)))
2972 cdf_mem_copy(body, (uint8_t *) &auth_frame->type,
2973 body_len);
2974
2975#if defined WLAN_FEATURE_VOWIFI_11R
2976 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2977 (auth_frame->authTransactionSeqNumber ==
2978 SIR_MAC_AUTH_FRAME_1) &&
2979 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2980
2981 if (ft_ies_length > 0) {
2982 cdf_mem_copy(body,
2983 session->ftPEContext.
2984 pFTPreAuthReq->ft_ies,
2985 ft_ies_length);
2986#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
2987 lim_log(mac_ctx, LOG2,
2988 FL("Auth1 Frame FTIE is: "));
2989 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
2990 (uint8_t *) body,
2991 ft_ies_length);
2992#endif
2993 } else if (NULL != session->ftPEContext.
2994 pFTPreAuthReq->pbssDescription) {
2995 /* MDID attr is 54 */
2996 *body = SIR_MDIE_ELEMENT_ID;
2997 body++;
2998 *body = SIR_MDIE_SIZE;
2999 body++;
3000 cdf_mem_copy(body,
3001 &session->ftPEContext.pFTPreAuthReq->
3002 pbssDescription->mdie[0],
3003 SIR_MDIE_SIZE);
3004 }
3005 }
3006#endif
3007
3008 lim_log(mac_ctx, LOG1,
3009 FL("*** Sending Auth seq# %d status %d (%d) to "
3010 MAC_ADDRESS_STR),
3011 auth_frame->authTransactionSeqNumber,
3012 auth_frame->authStatusCode,
3013 (auth_frame->authStatusCode ==
3014 eSIR_MAC_SUCCESS_STATUS),
3015 MAC_ADDR_ARRAY(mac_hdr->da));
3016 }
3017 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2, frame, frame_len);
3018
3019 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
3020 || (session->pePersona == CDF_P2P_CLIENT_MODE)
3021 || (session->pePersona == CDF_P2P_GO_MODE)
3022#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
3023 || ((NULL != session->ftPEContext.pFTPreAuthReq) &&
3024 (SIR_BAND_5_GHZ ==
3025 lim_get_rf_band(session->ftPEContext.pFTPreAuthReq->
3026 preAuthchannelNum)))
3027#endif
3028 )
3029 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3030
3031
Sushant Kaushik46556062015-12-02 16:57:47 +05303032 if (session->pePersona == CDF_P2P_CLIENT_MODE ||
3033 session->pePersona == CDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003034 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
3035
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003036 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3037 session->peSessionId, mac_hdr->fc.subType));
3038 /* Queue Authentication frame in high priority WQ */
3039 cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
3040 TXRX_FRM_802_11_MGMT,
3041 ANI_TXDIR_TODS, 7, lim_tx_complete,
3042 frame, tx_flag, sme_sessionid, 0);
3043 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3044 session->peSessionId, cdf_status));
3045 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
3046 lim_log(mac_ctx, LOGE,
3047 FL("*** Could not send Auth frame, retCode=%X ***"),
3048 cdf_status);
3049
3050 return;
3051}
3052
3053CDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
3054{
3055 uint16_t aid;
3056 tpDphHashNode pStaDs;
3057 tLimMlmDeauthReq *pMlmDeauthReq;
3058 tLimMlmDeauthCnf mlmDeauthCnf;
3059 tpPESession psessionEntry;
3060
3061 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
3062 if (pMlmDeauthReq) {
3063 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
3064 lim_deactivate_and_change_timer(pMac,
3065 eLIM_DEAUTH_ACK_TIMER);
3066 }
3067
3068 psessionEntry = pe_find_session_by_session_id(pMac,
3069 pMlmDeauthReq->sessionId);
3070 if (psessionEntry == NULL) {
3071 PELOGE(lim_log(pMac, LOGE,
3072 FL
3073 ("session does not exist for given sessionId"));
3074 )
3075 mlmDeauthCnf.resultCode =
3076 eSIR_SME_INVALID_PARAMETERS;
3077 goto end;
3078 }
3079
3080 pStaDs =
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08003081 dph_lookup_hash_entry(pMac,
3082 pMlmDeauthReq->peer_macaddr.bytes,
3083 &aid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003084 &psessionEntry->dph.dphHashTable);
3085 if (pStaDs == NULL) {
3086 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
3087 goto end;
3088 }
3089
3090 /* / Receive path cleanup with dummy packet */
3091 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
3092 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Abhishek Singhe0680852015-12-16 14:28:48 +05303093#ifdef WLAN_FEATURE_VOWIFI_11R
3094 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
3095 (
3096#ifdef FEATURE_WLAN_ESE
3097 (psessionEntry->isESEconnection) ||
3098#endif
3099#ifdef FEATURE_WLAN_LFR
3100 (psessionEntry->isFastRoamIniFeatureEnabled) ||
3101#endif
3102 (psessionEntry->is11Rconnection))) {
3103 PELOGE(lim_log(pMac, LOGE,
3104 FL("FT Preauth Session (%p,%d) Cleanup Deauth reason %d Trigger = %d"),
3105 psessionEntry, psessionEntry->peSessionId,
3106 pMlmDeauthReq->reasonCode,
3107 pMlmDeauthReq->deauthTrigger););
3108 lim_ft_cleanup(pMac, psessionEntry);
3109 } else {
3110 PELOGE(lim_log(pMac, LOGE,
3111 FL("No FT Preauth Session Cleanup in role %d"
3112#ifdef FEATURE_WLAN_ESE
3113 " isESE %d"
3114#endif
3115#ifdef FEATURE_WLAN_LFR
3116 " isLFR %d"
3117#endif
3118 " is11r %d, Deauth reason %d Trigger = %d"),
3119 psessionEntry->limSystemRole,
3120#ifdef FEATURE_WLAN_ESE
3121 psessionEntry->isESEconnection,
3122#endif
3123#ifdef FEATURE_WLAN_LFR
3124 psessionEntry->isFastRoamIniFeatureEnabled,
3125#endif
3126 psessionEntry->is11Rconnection,
3127 pMlmDeauthReq->reasonCode,
3128 pMlmDeauthReq->deauthTrigger););
3129 }
3130#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003131 /* / Free up buffer allocated for mlmDeauthReq */
3132 cdf_mem_free(pMlmDeauthReq);
3133 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
3134 }
3135 return CDF_STATUS_SUCCESS;
3136end:
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08003137 cdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
3138 &pMlmDeauthReq->peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003139 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
3140 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
3141 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
3142
3143 /* Free up buffer allocated */
3144 /* for mlmDeauthReq */
3145 cdf_mem_free(pMlmDeauthReq);
3146
3147 lim_post_sme_message(pMac,
3148 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
3149 return CDF_STATUS_SUCCESS;
3150}
3151
3152/**
3153 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
3154 *
3155 * @mac_ctx: Handle to MAC context
3156 *
3157 * Sends disassoc confirmation to SME. Removes disassoc request stored
3158 * in lim.
3159 *
3160 * Return: CDF_STATUS_SUCCESS
3161 */
3162
3163CDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
3164{
3165 uint16_t aid;
3166 tpDphHashNode sta_ds;
3167 tLimMlmDisassocCnf disassoc_cnf;
3168 tpPESession pe_session;
3169 tLimMlmDisassocReq *disassoc_req;
3170
3171 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
3172 if (disassoc_req) {
3173 if (tx_timer_running(
3174 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
3175 lim_deactivate_and_change_timer(mac_ctx,
3176 eLIM_DISASSOC_ACK_TIMER);
3177
3178 pe_session = pe_find_session_by_session_id(
3179 mac_ctx, disassoc_req->sessionId);
3180 if (pe_session == NULL) {
3181 lim_log(mac_ctx, LOGE,
3182 FL("No session for given sessionId"));
3183 disassoc_cnf.resultCode =
3184 eSIR_SME_INVALID_PARAMETERS;
3185 goto end;
3186 }
3187
3188 sta_ds = dph_lookup_hash_entry(mac_ctx,
3189 disassoc_req->peerMacAddr, &aid,
3190 &pe_session->dph.dphHashTable);
3191 if (sta_ds == NULL) {
3192 lim_log(mac_ctx, LOGE, FL("StaDs Null"));
3193 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
3194 goto end;
3195 }
3196 /* Receive path cleanup with dummy packet */
3197 if (eSIR_SUCCESS !=
3198 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
3199 disassoc_cnf.resultCode =
3200 eSIR_SME_RESOURCES_UNAVAILABLE;
3201 lim_log(mac_ctx, LOGE, FL("cleanup_rx_path error"));
3202 goto end;
3203 }
3204#ifdef WLAN_FEATURE_VOWIFI_11R
3205 if (LIM_IS_STA_ROLE(pe_session) && (
3206#ifdef FEATURE_WLAN_ESE
3207 (pe_session->isESEconnection) ||
3208#endif
3209#ifdef FEATURE_WLAN_LFR
3210 (pe_session->isFastRoamIniFeatureEnabled) ||
3211#endif
3212 (pe_session->is11Rconnection)) &&
3213 (disassoc_req->reasonCode !=
3214 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowdaf2599dd2015-11-16 18:20:46 -08003215 lim_log(mac_ctx, LOG1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003216 FL("FT Preauth Session (%p,%d) Clean up"),
3217 pe_session, pe_session->peSessionId);
3218
3219#if defined WLAN_FEATURE_VOWIFI_11R
3220 /* Delete FT session if there exists one */
3221 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
3222#endif
3223 } else {
3224 lim_log(mac_ctx, LOGE,
3225 FL("No FT Preauth Session Clean up in role %d"
3226#ifdef FEATURE_WLAN_ESE
3227 " isESE %d"
3228#endif
3229#ifdef FEATURE_WLAN_LFR
3230 " isLFR %d"
3231#endif
3232 " is11r %d reason %d"),
3233 GET_LIM_SYSTEM_ROLE(pe_session),
3234#ifdef FEATURE_WLAN_ESE
3235 pe_session->isESEconnection,
3236#endif
3237#ifdef FEATURE_WLAN_LFR
3238 pe_session->isFastRoamIniFeatureEnabled,
3239#endif
3240 pe_session->is11Rconnection,
3241 disassoc_req->reasonCode);
3242 }
3243#endif
3244 /* Free up buffer allocated for mlmDisassocReq */
3245 cdf_mem_free(disassoc_req);
3246 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
3247 return CDF_STATUS_SUCCESS;
3248 } else {
3249 return CDF_STATUS_SUCCESS;
3250 }
3251end:
3252 cdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
3253 (uint8_t *) disassoc_req->peerMacAddr,
3254 sizeof(tSirMacAddr));
3255 disassoc_cnf.aid = disassoc_req->aid;
3256 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
3257
3258 /* Update PE session ID */
3259 disassoc_cnf.sessionId = disassoc_req->sessionId;
3260
3261 if (disassoc_req != NULL) {
3262 /* / Free up buffer allocated for mlmDisassocReq */
3263 cdf_mem_free(disassoc_req);
3264 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
3265 }
3266
3267 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
3268 (uint32_t *) &disassoc_cnf);
3269 return CDF_STATUS_SUCCESS;
3270}
3271
3272CDF_STATUS lim_disassoc_tx_complete_cnf(tpAniSirGlobal pMac,
3273 uint32_t txCompleteSuccess)
3274{
3275 return lim_send_disassoc_cnf(pMac);
3276}
3277
3278CDF_STATUS lim_deauth_tx_complete_cnf(tpAniSirGlobal pMac,
3279 uint32_t txCompleteSuccess)
3280{
3281 return lim_send_deauth_cnf(pMac);
3282}
3283
3284/**
3285 * \brief This function is called to send Disassociate frame.
3286 *
3287 *
3288 * \param pMac Pointer to Global MAC structure
3289 *
3290 * \param nReason Indicates the reason that need to be sent in
3291 * Disassociation frame
3292 *
3293 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
3294 * sent
3295 *
3296 *
3297 */
3298
3299void
3300lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
3301 uint16_t nReason,
3302 tSirMacAddr peer,
3303 tpPESession psessionEntry, bool waitForAck)
3304{
3305 tDot11fDisassociation frm;
3306 uint8_t *pFrame;
3307 tpSirMacMgmtHdr pMacHdr;
3308 uint32_t nBytes, nPayload, nStatus;
3309 void *pPacket;
3310 CDF_STATUS cdf_status;
3311 uint8_t txFlag = 0;
3312 uint32_t val = 0;
3313 uint8_t smeSessionId = 0;
3314 if (NULL == psessionEntry) {
3315 return;
3316 }
3317
3318 /*
3319 * In case when cac timer is running for this SAP session then
3320 * avoid sending disassoc out. It is violation of dfs specification.
3321 */
3322 if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
3323 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
3324 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
3325 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
3326 FL
3327 ("CAC timer is running, drop disassoc from going out"));
3328 return;
3329 }
3330 smeSessionId = psessionEntry->smeSessionId;
3331
3332 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3333
3334 frm.Reason.code = nReason;
3335
3336 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
3337 if (DOT11F_FAILED(nStatus)) {
3338 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3339 "or a Disassociation (0x%08x)."),
3340 nStatus);
3341 /* We'll fall back on the worst case scenario: */
3342 nPayload = sizeof(tDot11fDisassociation);
3343 } else if (DOT11F_WARNED(nStatus)) {
3344 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3345 "the packed size for a Disassociation "
3346 "(0x%08x)."), nStatus);
3347 }
3348
3349 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3350
3351 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3352 (void **)&pPacket);
3353 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3354 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Dis"
3355 "association."), nBytes);
3356 return;
3357 }
3358 /* Paranoia: */
3359 cdf_mem_set(pFrame, nBytes, 0);
3360
3361 /* Next, we fill out the buffer descriptor: */
3362 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3363 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
3364 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3365
3366 /* Prepare the BSSID */
3367 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3368
3369#ifdef WLAN_FEATURE_11W
3370 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3371#endif
3372
3373 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
3374 sizeof(tSirMacMgmtHdr),
3375 nPayload, &nPayload);
3376 if (DOT11F_FAILED(nStatus)) {
3377 lim_log(pMac, LOGE,
3378 FL("Failed to pack a Disassociation (0x%08x)."),
3379 nStatus);
3380 cds_packet_free((void *)pPacket);
3381 return; /* allocated! */
3382 } else if (DOT11F_WARNED(nStatus)) {
3383 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
3384 "isassociation (0x%08x)."), nStatus);
3385 }
3386
3387 lim_log(pMac, LOG1,
3388 FL("***Sessionid %d Sending Disassociation frame with "
3389 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
3390 MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason,
3391 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
3392 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
3393
3394 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
3395 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3396 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
3397 ) {
3398 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3399 }
3400
Sushant Kaushik46556062015-12-02 16:57:47 +05303401 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003402
3403 if (waitForAck) {
3404 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3405 psessionEntry->peSessionId,
3406 pMacHdr->fc.subType));
3407 /* Queue Disassociation frame in high priority WQ */
3408 /* get the duration from the request */
3409 cdf_status =
3410 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
3411 TXRX_FRM_802_11_MGMT,
3412 ANI_TXDIR_TODS, 7, lim_tx_complete,
3413 pFrame, lim_disassoc_tx_complete_cnf,
3414 txFlag, smeSessionId, false, 0);
3415 MTRACE(cdf_trace
3416 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3417 psessionEntry->peSessionId, cdf_status));
3418
3419 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
3420
3421 if (tx_timer_change
3422 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
3423 != TX_SUCCESS) {
3424 lim_log(pMac, LOGP,
3425 FL("Unable to change Disassoc ack Timer val"));
3426 return;
3427 } else if (TX_SUCCESS !=
3428 tx_timer_activate(&pMac->lim.limTimers.
3429 gLimDisassocAckTimer)) {
3430 lim_log(pMac, LOGP,
3431 FL("Unable to activate Disassoc ack Timer"));
3432 lim_deactivate_and_change_timer(pMac,
3433 eLIM_DISASSOC_ACK_TIMER);
3434 return;
3435 }
3436 } else {
3437 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3438 psessionEntry->peSessionId,
3439 pMacHdr->fc.subType));
3440 /* Queue Disassociation frame in high priority WQ */
3441 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3442 TXRX_FRM_802_11_MGMT,
3443 ANI_TXDIR_TODS,
3444 7,
3445 lim_tx_complete, pFrame, txFlag,
3446 smeSessionId, 0);
3447 MTRACE(cdf_trace
3448 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3449 psessionEntry->peSessionId, cdf_status));
3450 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3451 lim_log(pMac, LOGE,
3452 FL("Failed to send Disassociation (%X)!"),
3453 cdf_status);
3454 /* Pkt will be freed up by the callback */
3455 }
3456 }
3457} /* End lim_send_disassoc_mgmt_frame. */
3458
3459/**
3460 * \brief This function is called to send a Deauthenticate frame
3461 *
3462 *
3463 * \param pMac Pointer to global MAC structure
3464 *
3465 * \param nReason Indicates the reason that need to be sent in the
3466 * Deauthenticate frame
3467 *
3468 * \param peeer address of the STA to which the frame is to be sent
3469 *
3470 *
3471 */
3472
3473void
3474lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
3475 uint16_t nReason,
3476 tSirMacAddr peer,
3477 tpPESession psessionEntry, bool waitForAck)
3478{
3479 tDot11fDeAuth frm;
3480 uint8_t *pFrame;
3481 tpSirMacMgmtHdr pMacHdr;
3482 uint32_t nBytes, nPayload, nStatus;
3483 void *pPacket;
3484 CDF_STATUS cdf_status;
3485 uint8_t txFlag = 0;
3486 uint32_t val = 0;
3487#ifdef FEATURE_WLAN_TDLS
3488 uint16_t aid;
3489 tpDphHashNode pStaDs;
3490#endif
3491 uint8_t smeSessionId = 0;
3492
3493 if (NULL == psessionEntry) {
3494 return;
3495 }
3496
3497 /*
3498 * In case when cac timer is running for this SAP session then
3499 * avoid deauth frame out. It is violation of dfs specification.
3500 */
3501 if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
3502 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
3503 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
3504 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
3505 FL
3506 ("CAC timer is running, drop the deauth from going out"));
3507 return;
3508 }
3509 smeSessionId = psessionEntry->smeSessionId;
3510
3511 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3512
3513 frm.Reason.code = nReason;
3514
3515 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
3516 if (DOT11F_FAILED(nStatus)) {
3517 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3518 "or a De-Authentication (0x%08x)."),
3519 nStatus);
3520 /* We'll fall back on the worst case scenario: */
3521 nPayload = sizeof(tDot11fDeAuth);
3522 } else if (DOT11F_WARNED(nStatus)) {
3523 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3524 "the packed size for a De-Authentication "
3525 "(0x%08x)."), nStatus);
3526 }
3527
3528 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3529
3530 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3531 (void **)&pPacket);
3532 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3533 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
3534 "Authentication."), nBytes);
3535 return;
3536 }
3537 /* Paranoia: */
3538 cdf_mem_set(pFrame, nBytes, 0);
3539
3540 /* Next, we fill out the buffer descriptor: */
3541 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3542 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
3543 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3544
3545 /* Prepare the BSSID */
3546 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3547
3548#ifdef WLAN_FEATURE_11W
3549 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3550#endif
3551
3552 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
3553 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
3554 if (DOT11F_FAILED(nStatus)) {
3555 lim_log(pMac, LOGE,
3556 FL("Failed to pack a DeAuthentication (0x%08x)."),
3557 nStatus);
3558 cds_packet_free((void *)pPacket);
3559 return;
3560 } else if (DOT11F_WARNED(nStatus)) {
3561 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
3562 "e-Authentication (0x%08x)."), nStatus);
3563 }
3564 lim_log(pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with "
3565 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
3566 " ,From " MAC_ADDRESS_STR),
3567 psessionEntry->peSessionId, nReason, waitForAck,
3568 MAC_ADDR_ARRAY(pMacHdr->da),
3569 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
3570
3571 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
3572 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3573 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
3574 ) {
3575 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3576 }
3577
Sushant Kaushik46556062015-12-02 16:57:47 +05303578 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003579#ifdef FEATURE_WLAN_TDLS
3580 pStaDs =
3581 dph_lookup_hash_entry(pMac, peer, &aid,
3582 &psessionEntry->dph.dphHashTable);
3583#endif
3584
3585 if (waitForAck) {
3586 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3587 psessionEntry->peSessionId,
3588 pMacHdr->fc.subType));
3589 /* Queue Disassociation frame in high priority WQ */
3590 cdf_status =
3591 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
3592 TXRX_FRM_802_11_MGMT,
3593 ANI_TXDIR_TODS, 7, lim_tx_complete,
3594 pFrame, lim_deauth_tx_complete_cnf,
3595 txFlag, smeSessionId, false, 0);
3596 MTRACE(cdf_trace
3597 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3598 psessionEntry->peSessionId, cdf_status));
3599 /* Pkt will be freed up by the callback lim_tx_complete */
3600 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3601 lim_log(pMac, LOGE,
3602 FL("Failed to send De-Authentication (%X)!"),
3603 cdf_status);
3604
3605 /* Call lim_process_deauth_ack_timeout which will send
3606 * DeauthCnf for this frame
3607 */
3608 lim_process_deauth_ack_timeout(pMac);
3609 return;
3610 }
3611
3612 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
3613
3614 if (tx_timer_change
3615 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
3616 != TX_SUCCESS) {
3617 lim_log(pMac, LOGP,
3618 FL("Unable to change Deauth ack Timer val"));
3619 return;
3620 } else if (TX_SUCCESS !=
3621 tx_timer_activate(&pMac->lim.limTimers.
3622 gLimDeauthAckTimer)) {
3623 lim_log(pMac, LOGP,
3624 FL("Unable to activate Deauth ack Timer"));
3625 lim_deactivate_and_change_timer(pMac,
3626 eLIM_DEAUTH_ACK_TIMER);
3627 return;
3628 }
3629 } else {
3630 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3631 psessionEntry->peSessionId,
3632 pMacHdr->fc.subType));
3633#ifdef FEATURE_WLAN_TDLS
3634 if ((NULL != pStaDs)
3635 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
3636 /* Queue Disassociation frame in high priority WQ */
3637 cdf_status =
3638 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3639 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
3640 7, lim_tx_complete, pFrame, txFlag,
3641 smeSessionId, 0);
3642 } else {
3643#endif
3644 /* Queue Disassociation frame in high priority WQ */
3645 cdf_status =
3646 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3647 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3648 7, lim_tx_complete, pFrame, txFlag,
3649 smeSessionId, 0);
3650#ifdef FEATURE_WLAN_TDLS
3651 }
3652#endif
3653 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3654 psessionEntry->peSessionId, cdf_status));
3655 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3656 lim_log(pMac, LOGE,
3657 FL("Failed to send De-Authentication (%X)!"),
3658 cdf_status);
3659 /* Pkt will be freed up by the callback */
3660 }
3661 }
3662
3663} /* End lim_send_deauth_mgmt_frame. */
3664
3665#ifdef ANI_SUPPORT_11H
3666/**
3667 * \brief Send a Measurement Report Action frame
3668 *
3669 *
3670 * \param pMac Pointer to the global MAC structure
3671 *
3672 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
3673 *
3674 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3675 *
3676 *
3677 */
3678
3679tSirRetStatus
3680lim_send_meas_report_frame(tpAniSirGlobal pMac,
3681 tpSirMacMeasReqActionFrame pMeasReqFrame,
3682 tSirMacAddr peer, tpPESession psessionEntry)
3683{
3684 tDot11fMeasurementReport frm;
3685 uint8_t *pFrame;
3686 tSirRetStatus nSirStatus;
3687 tpSirMacMgmtHdr pMacHdr;
3688 uint32_t nBytes, nPayload, nStatus;
3689 void *pPacket;
3690 CDF_STATUS cdf_status;
3691
3692 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3693
3694 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3695 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3696 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3697
3698 switch (pMeasReqFrame->measReqIE.measType) {
3699 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3700 nSirStatus =
3701 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3702 &frm.MeasurementReport);
3703 break;
3704 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3705 nSirStatus =
3706 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3707 &frm.MeasurementReport);
3708 break;
3709 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3710 nSirStatus =
3711 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3712 &frm.MeasurementReport);
3713 break;
3714 default:
3715 lim_log(pMac, LOGE, FL("Unknown measurement type %d in limSen"
3716 "dMeasReportFrame."),
3717 pMeasReqFrame->measReqIE.measType);
3718 return eSIR_FAILURE;
3719 }
3720
3721 if (eSIR_SUCCESS != nSirStatus)
3722 return eSIR_FAILURE;
3723
3724 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3725 if (DOT11F_FAILED(nStatus)) {
3726 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3727 "or a Measurement Report (0x%08x)."),
3728 nStatus);
3729 /* We'll fall back on the worst case scenario: */
3730 nPayload = sizeof(tDot11fMeasurementReport);
3731 } else if (DOT11F_WARNED(nStatus)) {
3732 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3733 "the packed size for a Measurement Rep"
3734 "ort (0x%08x)."), nStatus);
3735 }
3736
3737 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3738
3739 cdf_status =
3740 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3741 (uint16_t) nBytes, (void **)&pFrame,
3742 (void **)&pPacket);
3743 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3744 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
3745 "Authentication."), nBytes);
3746 return eSIR_FAILURE;
3747 }
3748 /* Paranoia: */
3749 cdf_mem_set(pFrame, nBytes, 0);
3750
3751 /* Next, we fill out the buffer descriptor: */
3752 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3753 SIR_MAC_MGMT_ACTION, peer);
3754 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3755
3756 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3757
3758#ifdef WLAN_FEATURE_11W
3759 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3760#endif
3761
3762 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3763 sizeof(tSirMacMgmtHdr),
3764 nPayload, &nPayload);
3765 if (DOT11F_FAILED(nStatus)) {
3766 lim_log(pMac, LOGE,
3767 FL("Failed to pack a Measurement Report (0x%08x)."),
3768 nStatus);
3769 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3770 (void *)pFrame, (void *)pPacket);
3771 return eSIR_FAILURE; /* allocated! */
3772 } else if (DOT11F_WARNED(nStatus)) {
3773 lim_log(pMac, LOGW, FL("There were warnings while packing a M"
3774 "easurement Report (0x%08x)."), nStatus);
3775 }
3776
3777 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3778 ((psessionEntry) ? psessionEntry->
3779 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3780 cdf_status =
3781 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3782 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3783 lim_tx_complete, pFrame, 0, 0);
3784 MTRACE(cdf_trace
3785 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3786 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3787 cdf_status));
3788 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3789 lim_log(pMac, LOGE,
3790 FL("Failed to send a Measurement Report (%X)!"),
3791 cdf_status);
3792 /* Pkt will be freed up by the callback */
3793 return eSIR_FAILURE; /* just allocated... */
3794 }
3795
3796 return eSIR_SUCCESS;
3797
3798} /* End lim_send_meas_report_frame. */
3799
3800/**
3801 * \brief Send a TPC Request Action frame
3802 *
3803 *
3804 * \param pMac Pointer to the global MAC datastructure
3805 *
3806 * \param peer MAC address to which the frame should be sent
3807 *
3808 *
3809 */
3810
3811void
3812lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3813 tSirMacAddr peer, tpPESession psessionEntry)
3814{
3815 tDot11fTPCRequest frm;
3816 uint8_t *pFrame;
3817 tpSirMacMgmtHdr pMacHdr;
3818 uint32_t nBytes, nPayload, nStatus;
3819 void *pPacket;
3820 CDF_STATUS cdf_status;
3821
3822 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3823
3824 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3825 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3826 frm.DialogToken.token = 1;
3827 frm.TPCRequest.present = 1;
3828
3829 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3830 if (DOT11F_FAILED(nStatus)) {
3831 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3832 "or a TPC Request (0x%08x)."), nStatus);
3833 /* We'll fall back on the worst case scenario: */
3834 nPayload = sizeof(tDot11fTPCRequest);
3835 } else if (DOT11F_WARNED(nStatus)) {
3836 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3837 "the packed size for a TPC Request (0x"
3838 "%08x)."), nStatus);
3839 }
3840
3841 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3842
3843 cdf_status =
3844 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3845 (uint16_t) nBytes, (void **)&pFrame,
3846 (void **)&pPacket);
3847 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3848 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3849 " Request."), nBytes);
3850 return;
3851 }
3852 /* Paranoia: */
3853 cdf_mem_set(pFrame, nBytes, 0);
3854
3855 /* Next, we fill out the buffer descriptor: */
3856 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3857 SIR_MAC_MGMT_ACTION, peer);
3858 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3859
3860 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3861
3862#ifdef WLAN_FEATURE_11W
3863 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3864#endif
3865
3866 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3867 sizeof(tSirMacMgmtHdr),
3868 nPayload, &nPayload);
3869 if (DOT11F_FAILED(nStatus)) {
3870 lim_log(pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."),
3871 nStatus);
3872 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3873 (void *)pFrame, (void *)pPacket);
3874 return; /* allocated! */
3875 } else if (DOT11F_WARNED(nStatus)) {
3876 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3877 "PC Request (0x%08x)."), nStatus);
3878 }
3879
3880 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3881 ((psessionEntry) ? psessionEntry->
3882 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3883 cdf_status =
3884 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3885 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3886 lim_tx_complete, pFrame, 0, 0);
3887 MTRACE(cdf_trace
3888 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3889 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3890 cdf_status));
3891 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3892 lim_log(pMac, LOGE,
3893 FL("Failed to send a TPC Request (%X)!"),
3894 cdf_status);
3895 /* Pkt will be freed up by the callback */
3896 }
3897
3898} /* End lim_send_tpc_request_frame. */
3899
3900/**
3901 * \brief Send a TPC Report Action frame
3902 *
3903 *
3904 * \param pMac Pointer to the global MAC datastructure
3905 *
3906 * \param pTpcReqFrame Pointer to the received TPC Request
3907 *
3908 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3909 *
3910 *
3911 */
3912
3913tSirRetStatus
3914lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3915 tpSirMacTpcReqActionFrame pTpcReqFrame,
3916 tSirMacAddr peer, tpPESession psessionEntry)
3917{
3918 tDot11fTPCReport frm;
3919 uint8_t *pFrame;
3920 tpSirMacMgmtHdr pMacHdr;
3921 uint32_t nBytes, nPayload, nStatus;
3922 void *pPacket;
3923 CDF_STATUS cdf_status;
3924
3925 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3926
3927 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3928 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3929 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3930
3931 frm.TPCReport.tx_power = 0;
3932 frm.TPCReport.link_margin = 0;
3933 frm.TPCReport.present = 1;
3934
3935 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3936 if (DOT11F_FAILED(nStatus)) {
3937 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3938 "or a TPC Report (0x%08x)."), nStatus);
3939 /* We'll fall back on the worst case scenario: */
3940 nPayload = sizeof(tDot11fTPCReport);
3941 } else if (DOT11F_WARNED(nStatus)) {
3942 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3943 "the packed size for a TPC Report (0x"
3944 "%08x)."), nStatus);
3945 }
3946
3947 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3948
3949 cdf_status =
3950 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3951 (uint16_t) nBytes, (void **)&pFrame,
3952 (void **)&pPacket);
3953 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3954 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3955 " Report."), nBytes);
3956 return eSIR_FAILURE;
3957 }
3958 /* Paranoia: */
3959 cdf_mem_set(pFrame, nBytes, 0);
3960
3961 /* Next, we fill out the buffer descriptor: */
3962 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3963 SIR_MAC_MGMT_ACTION, peer);
3964
3965 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3966
3967 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3968
3969#ifdef WLAN_FEATURE_11W
3970 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3971#endif
3972
3973 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3974 sizeof(tSirMacMgmtHdr),
3975 nPayload, &nPayload);
3976 if (DOT11F_FAILED(nStatus)) {
3977 lim_log(pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."),
3978 nStatus);
3979 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3980 (void *)pFrame, (void *)pPacket);
3981 return eSIR_FAILURE; /* allocated! */
3982 } else if (DOT11F_WARNED(nStatus)) {
3983 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3984 "PC Report (0x%08x)."), nStatus);
3985 }
3986
3987 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3988 ((psessionEntry) ? psessionEntry->
3989 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3990 cdf_status =
3991 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3992 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3993 lim_tx_complete, pFrame, 0, 0);
3994 MTRACE(cdf_trace
3995 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3996 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3997 cdf_status));
3998 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3999 lim_log(pMac, LOGE,
4000 FL("Failed to send a TPC Report (%X)!"),
4001 cdf_status);
4002 /* Pkt will be freed up by the callback */
4003 return eSIR_FAILURE; /* just allocated... */
4004 }
4005
4006 return eSIR_SUCCESS;
4007
4008} /* End lim_send_tpc_report_frame. */
4009#endif /* ANI_SUPPORT_11H */
4010
4011/**
4012 * \brief Send a Channel Switch Announcement
4013 *
4014 *
4015 * \param pMac Pointer to the global MAC datastructure
4016 *
4017 * \param peer MAC address to which this frame will be sent
4018 *
4019 * \param nMode
4020 *
4021 * \param nNewChannel
4022 *
4023 * \param nCount
4024 *
4025 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4026 *
4027 *
4028 */
4029
4030tSirRetStatus
4031lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
4032 tSirMacAddr peer,
4033 uint8_t nMode,
4034 uint8_t nNewChannel,
4035 uint8_t nCount, tpPESession psessionEntry)
4036{
4037 tDot11fChannelSwitch frm;
4038 uint8_t *pFrame;
4039 tpSirMacMgmtHdr pMacHdr;
4040 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
4041 void *pPacket;
4042 CDF_STATUS cdf_status;
4043 uint8_t txFlag = 0;
4044
4045 uint8_t smeSessionId = 0;
4046
4047 if (psessionEntry == NULL) {
4048 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4049 return eSIR_FAILURE;
4050 }
4051 smeSessionId = psessionEntry->smeSessionId;
4052
4053 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4054
4055 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
4056 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
4057 frm.ChanSwitchAnn.switchMode = nMode;
4058 frm.ChanSwitchAnn.newChannel = nNewChannel;
4059 frm.ChanSwitchAnn.switchCount = nCount;
4060 frm.ChanSwitchAnn.present = 1;
4061
4062 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
4063 if (DOT11F_FAILED(nStatus)) {
4064 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4065 "or a Channel Switch (0x%08x)."),
4066 nStatus);
4067 /* We'll fall back on the worst case scenario: */
4068 nPayload = sizeof(tDot11fChannelSwitch);
4069 } else if (DOT11F_WARNED(nStatus)) {
4070 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4071 "the packed size for a Channel Switch (0x"
4072 "%08x)."), nStatus);
4073 }
4074
4075 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4076
4077 cdf_status =
4078 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4079 (void **)&pPacket);
4080 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4081 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
4082 " Report."), nBytes);
4083 return eSIR_FAILURE;
4084 }
4085 /* Paranoia: */
4086 cdf_mem_set(pFrame, nBytes, 0);
4087
4088 /* Next, we fill out the buffer descriptor: */
4089 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4090 SIR_MAC_MGMT_ACTION, peer,
4091 psessionEntry->selfMacAddr);
4092 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4093 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4094 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4095
4096#ifdef WLAN_FEATURE_11W
4097 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4098#endif
4099
4100 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
4101 sizeof(tSirMacMgmtHdr),
4102 nPayload, &nPayload);
4103 if (DOT11F_FAILED(nStatus)) {
4104 lim_log(pMac, LOGE,
4105 FL("Failed to pack a Channel Switch (0x%08x)."),
4106 nStatus);
4107 cds_packet_free((void *)pPacket);
4108 return eSIR_FAILURE; /* allocated! */
4109 } else if (DOT11F_WARNED(nStatus)) {
4110 lim_log(pMac, LOGW, FL("There were warnings while packing a C"
4111 "hannel Switch (0x%08x)."), nStatus);
4112 }
4113
4114 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4115 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4116 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4117 ) {
4118 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4119 }
4120
4121 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4122 psessionEntry->peSessionId, pMacHdr->fc.subType));
4123 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4124 TXRX_FRM_802_11_MGMT,
4125 ANI_TXDIR_TODS,
4126 7, lim_tx_complete, pFrame, txFlag,
4127 smeSessionId, 0);
4128 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4129 psessionEntry->peSessionId, cdf_status));
4130 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4131 lim_log(pMac, LOGE,
4132 FL("Failed to send a Channel Switch (%X)!"),
4133 cdf_status);
4134 /* Pkt will be freed up by the callback */
4135 return eSIR_FAILURE;
4136 }
4137
4138 return eSIR_SUCCESS;
4139
4140} /* End lim_send_channel_switch_mgmt_frame. */
4141
Abhishek Singh518323d2015-10-19 17:42:01 +05304142/**
4143 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
4144 * action frame over the air .
4145 * @mac_ctx: pointer to global mac structure
4146 * @peer: Destination mac.
4147 * @mode: channel switch mode
4148 * @new_op_class: new op class
4149 * @new_channel: new channel to switch
4150 * @count: channel switch count
4151 *
4152 * This function is called to send ECSA frame.
4153 *
4154 * Return: success if frame is sent else return failure
4155 */
4156
4157tSirRetStatus
4158lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
4159 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
4160 uint8_t new_channel, uint8_t count, tpPESession session_entry)
4161{
4162 tDot11fext_channel_switch_action_frame frm;
4163 uint8_t *frame;
4164 tpSirMacMgmtHdr mac_hdr;
4165 uint32_t num_bytes, n_payload, status;
4166 void *packet;
4167 CDF_STATUS cdf_status;
4168 uint8_t txFlag = 0;
4169 uint8_t sme_session_id = 0;
4170
4171 if (session_entry == NULL) {
4172 lim_log(mac_ctx, LOGE, FL("Session entry is NULL!!!"));
4173 return eSIR_FAILURE;
4174 }
4175
4176 sme_session_id = session_entry->smeSessionId;
4177
4178 cdf_mem_set(&frm, sizeof(frm), 0);
4179
4180 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
4181 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
4182
4183 frm.ext_chan_switch_ann_action.switch_mode = mode;
4184 frm.ext_chan_switch_ann_action.op_class = new_op_class;
4185 frm.ext_chan_switch_ann_action.new_channel = new_channel;
4186 frm.ext_chan_switch_ann_action.switch_count = count;
4187
4188
4189 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
4190 &frm, &n_payload);
4191 if (DOT11F_FAILED(status)) {
4192 lim_log(mac_ctx, LOGP,
4193 FL("Failed to get packed size for Channel Switch 0x%08x."),
4194 status);
4195 /* We'll fall back on the worst case scenario*/
4196 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
4197 } else if (DOT11F_WARNED(status)) {
4198 lim_log(mac_ctx, LOGW,
4199 FL("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)."),
4200 status);
4201 }
4202
4203 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
4204
4205 cdf_status = cds_packet_alloc((uint16_t)num_bytes,
4206 (void **) &frame, (void **) &packet);
4207
4208 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4209 lim_log(mac_ctx, LOGP,
4210 FL("Failed to allocate %d bytes for a Ext Channel Switch."),
4211 num_bytes);
4212 return eSIR_FAILURE;
4213 }
4214
4215 /* Paranoia*/
4216 cdf_mem_set(frame, num_bytes, 0);
4217
4218 /* Next, we fill out the buffer descriptor */
4219 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
4220 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
4221 mac_hdr = (tpSirMacMgmtHdr) frame;
4222 cdf_mem_copy((uint8_t *) mac_hdr->bssId,
4223 (uint8_t *) session_entry->bssId,
4224 sizeof(tSirMacAddr));
4225
4226 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
4227 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
4228 if (DOT11F_FAILED(status)) {
4229 lim_log(mac_ctx, LOGE,
4230 FL("Failed to pack a Channel Switch 0x%08x."),
4231 status);
4232 cds_packet_free((void *)packet);
4233 return eSIR_FAILURE;
4234 } else if (DOT11F_WARNED(status)) {
4235 lim_log(mac_ctx, LOGW,
4236 FL("There were warnings while packing a Channel Switch 0x%08x."),
4237 status);
4238 }
4239
4240 if ((SIR_BAND_5_GHZ ==
4241 lim_get_rf_band(session_entry->currentOperChannel)) ||
4242 (session_entry->pePersona == CDF_P2P_CLIENT_MODE) ||
4243 (session_entry->pePersona == CDF_P2P_GO_MODE)) {
4244 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4245 }
4246
4247 lim_log(mac_ctx, LOG1,
4248 FL("Send Ext channel Switch to :"MAC_ADDRESS_STR" with swcount %d, swmode %d , newchannel %d newops %d"),
4249 MAC_ADDR_ARRAY(mac_hdr->da),
4250 frm.ext_chan_switch_ann_action.switch_count,
4251 frm.ext_chan_switch_ann_action.switch_mode,
4252 frm.ext_chan_switch_ann_action.new_channel,
4253 frm.ext_chan_switch_ann_action.op_class);
4254
4255 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4256 session_entry->peSessionId, mac_hdr->fc.subType));
4257 cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
4258 TXRX_FRM_802_11_MGMT,
4259 ANI_TXDIR_TODS,
4260 7,
4261 lim_tx_complete, frame,
4262 txFlag, sme_session_id, 0);
4263 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4264 session_entry->peSessionId, cdf_status));
4265 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4266 lim_log(mac_ctx, LOGE,
4267 FL("Failed to send a Ext Channel Switch %X!"),
4268 cdf_status);
4269 /* Pkt will be freed up by the callback */
4270 return eSIR_FAILURE;
4271 }
4272 return eSIR_SUCCESS;
4273} /* End lim_send_extended_chan_switch_action_frame */
4274
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275tSirRetStatus
4276lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
4277 tSirMacAddr peer,
4278 uint8_t nMode, tpPESession psessionEntry)
4279{
4280 tDot11fOperatingMode frm;
4281 uint8_t *pFrame;
4282 tpSirMacMgmtHdr pMacHdr;
4283 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
4284 void *pPacket;
4285 CDF_STATUS cdf_status;
4286 uint8_t txFlag = 0;
4287
4288 uint8_t smeSessionId = 0;
4289
4290 if (psessionEntry == NULL) {
4291 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4292 return eSIR_FAILURE;
4293 }
4294 smeSessionId = psessionEntry->smeSessionId;
4295
4296 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4297
4298 frm.Category.category = SIR_MAC_ACTION_VHT;
4299 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
4300 frm.OperatingMode.chanWidth = nMode;
4301 frm.OperatingMode.rxNSS = 0;
4302 frm.OperatingMode.rxNSSType = 0;
4303
4304 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
4305 if (DOT11F_FAILED(nStatus)) {
4306 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4307 "or a Operating Mode (0x%08x)."),
4308 nStatus);
4309 /* We'll fall back on the worst case scenario: */
4310 nPayload = sizeof(tDot11fOperatingMode);
4311 } else if (DOT11F_WARNED(nStatus)) {
4312 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4313 "the packed size for a Operating Mode (0x"
4314 "%08x)."), nStatus);
4315 }
4316
4317 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4318
4319 cdf_status =
4320 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4321 (void **)&pPacket);
4322 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4323 lim_log(pMac, LOGP,
4324 FL("Failed to allocate %d bytes for a Operating Mode"
4325 " Report."), nBytes);
4326 return eSIR_FAILURE;
4327 }
4328 /* Paranoia: */
4329 cdf_mem_set(pFrame, nBytes, 0);
4330
4331 /* Next, we fill out the buffer descriptor: */
4332 if (psessionEntry->pePersona == CDF_SAP_MODE)
4333 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4334 SIR_MAC_MGMT_ACTION, peer,
4335 psessionEntry->selfMacAddr);
4336 else
4337 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4338 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
4339 psessionEntry->selfMacAddr);
4340 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4341 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4342 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4343 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
4344 sizeof(tSirMacMgmtHdr),
4345 nPayload, &nPayload);
4346 if (DOT11F_FAILED(nStatus)) {
4347 lim_log(pMac, LOGE,
4348 FL("Failed to pack a Operating Mode (0x%08x)."),
4349 nStatus);
4350 cds_packet_free((void *)pPacket);
4351 return eSIR_FAILURE; /* allocated! */
4352 } else if (DOT11F_WARNED(nStatus)) {
4353 lim_log(pMac, LOGW,
4354 FL("There were warnings while packing a Operating Mode"
4355 " (0x%08x)."), nStatus);
4356 }
4357 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4358 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4359 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4360 ) {
4361 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4362 }
4363
4364 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4365 psessionEntry->peSessionId, pMacHdr->fc.subType));
4366 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4367 TXRX_FRM_802_11_MGMT,
4368 ANI_TXDIR_TODS,
4369 7, lim_tx_complete, pFrame, txFlag,
4370 smeSessionId, 0);
4371 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4372 psessionEntry->peSessionId, cdf_status));
4373 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4374 lim_log(pMac, LOGE,
4375 FL("Failed to send a Channel Switch (%X)!"),
4376 cdf_status);
4377 /* Pkt will be freed up by the callback */
4378 return eSIR_FAILURE;
4379 }
4380
4381 return eSIR_SUCCESS;
4382}
4383
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004384#if defined WLAN_FEATURE_VOWIFI
4385
4386/**
4387 * \brief Send a Neighbor Report Request Action frame
4388 *
4389 *
4390 * \param pMac Pointer to the global MAC structure
4391 *
4392 * \param pNeighborReq Address of a tSirMacNeighborReportReq
4393 *
4394 * \param peer mac address of peer station.
4395 *
4396 * \param psessionEntry address of session entry.
4397 *
4398 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4399 *
4400 *
4401 */
4402
4403tSirRetStatus
4404lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
4405 tpSirMacNeighborReportReq pNeighborReq,
4406 tSirMacAddr peer, tpPESession psessionEntry)
4407{
4408 tSirRetStatus statusCode = eSIR_SUCCESS;
4409 tDot11fNeighborReportRequest frm;
4410 uint8_t *pFrame;
4411 tpSirMacMgmtHdr pMacHdr;
4412 uint32_t nBytes, nPayload, nStatus;
4413 void *pPacket;
4414 CDF_STATUS cdf_status;
4415 uint8_t txFlag = 0;
4416 uint8_t smeSessionId = 0;
4417
4418 if (psessionEntry == NULL) {
4419 lim_log(pMac, LOGE,
4420 FL
4421 ("(psession == NULL) in Request to send Neighbor Report request action frame"));
4422 return eSIR_FAILURE;
4423 }
4424 smeSessionId = psessionEntry->smeSessionId;
4425 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4426
4427 frm.Category.category = SIR_MAC_ACTION_RRM;
4428 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
4429 frm.DialogToken.token = pNeighborReq->dialogToken;
4430
4431 if (pNeighborReq->ssid_present) {
4432 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
4433 }
4434
4435 nStatus =
4436 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
4437 if (DOT11F_FAILED(nStatus)) {
4438 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4439 "or a Neighbor Report Request(0x%08x)."),
4440 nStatus);
4441 /* We'll fall back on the worst case scenario: */
4442 nPayload = sizeof(tDot11fNeighborReportRequest);
4443 } else if (DOT11F_WARNED(nStatus)) {
4444 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4445 "the packed size for a Neighbor Rep"
4446 "ort Request(0x%08x)."), nStatus);
4447 }
4448
4449 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4450
4451 cdf_status =
4452 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4453 (void **)&pPacket);
4454 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4455 lim_log(pMac, LOGP,
4456 FL("Failed to allocate %d bytes for a Neighbor "
4457 "Report Request."), nBytes);
4458 return eSIR_FAILURE;
4459 }
4460 /* Paranoia: */
4461 cdf_mem_set(pFrame, nBytes, 0);
4462
4463 /* Copy necessary info to BD */
4464 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4465 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4466
4467 /* Update A3 with the BSSID */
4468 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4469
4470 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4471
4472#ifdef WLAN_FEATURE_11W
4473 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4474#endif
4475
4476 /* Now, we're ready to "pack" the frames */
4477 nStatus = dot11f_pack_neighbor_report_request(pMac,
4478 &frm,
4479 pFrame +
4480 sizeof(tSirMacMgmtHdr),
4481 nPayload, &nPayload);
4482
4483 if (DOT11F_FAILED(nStatus)) {
4484 lim_log(pMac, LOGE,
4485 FL
4486 ("Failed to pack an Neighbor Report Request (0x%08x)."),
4487 nStatus);
4488
4489 /* FIXME - Need to convert to tSirRetStatus */
4490 statusCode = eSIR_FAILURE;
4491 goto returnAfterError;
4492 } else if (DOT11F_WARNED(nStatus)) {
4493 lim_log(pMac, LOGW,
4494 FL("There were warnings while packing Neighbor Report "
4495 "Request (0x%08x)."), nStatus);
4496 }
4497
4498 lim_log(pMac, LOGW, FL("Sending a Neighbor Report Request to "));
4499 lim_print_mac_addr(pMac, peer, LOGW);
4500
4501 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4502 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4503 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4504 ) {
4505 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4506 }
4507
4508 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4509 psessionEntry->peSessionId, pMacHdr->fc.subType));
4510 cdf_status = wma_tx_frame(pMac,
4511 pPacket,
4512 (uint16_t) nBytes,
4513 TXRX_FRM_802_11_MGMT,
4514 ANI_TXDIR_TODS,
4515 7, lim_tx_complete, pFrame, txFlag,
4516 smeSessionId, 0);
4517 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4518 psessionEntry->peSessionId, cdf_status));
4519 if (CDF_STATUS_SUCCESS != cdf_status) {
4520 PELOGE(lim_log
4521 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4522 cdf_status);
4523 )
4524 statusCode = eSIR_FAILURE;
4525 /* Pkt will be freed up by the callback */
4526 return statusCode;
4527 } else
4528 return eSIR_SUCCESS;
4529
4530returnAfterError:
4531 cds_packet_free((void *)pPacket);
4532
4533 return statusCode;
4534} /* End lim_send_neighbor_report_request_frame. */
4535
4536/**
4537 * \brief Send a Link Report Action frame
4538 *
4539 *
4540 * \param pMac Pointer to the global MAC structure
4541 *
4542 * \param pLinkReport Address of a tSirMacLinkReport
4543 *
4544 * \param peer mac address of peer station.
4545 *
4546 * \param psessionEntry address of session entry.
4547 *
4548 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4549 *
4550 *
4551 */
4552
4553tSirRetStatus
4554lim_send_link_report_action_frame(tpAniSirGlobal pMac,
4555 tpSirMacLinkReport pLinkReport,
4556 tSirMacAddr peer, tpPESession psessionEntry)
4557{
4558 tSirRetStatus statusCode = eSIR_SUCCESS;
4559 tDot11fLinkMeasurementReport frm;
4560 uint8_t *pFrame;
4561 tpSirMacMgmtHdr pMacHdr;
4562 uint32_t nBytes, nPayload, nStatus;
4563 void *pPacket;
4564 CDF_STATUS cdf_status;
4565 uint8_t txFlag = 0;
4566 uint8_t smeSessionId = 0;
4567
4568 if (psessionEntry == NULL) {
4569 lim_log(pMac, LOGE,
4570 FL
4571 ("(psession == NULL) in Request to send Link Report action frame"));
4572 return eSIR_FAILURE;
4573 }
4574
4575 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4576
4577 frm.Category.category = SIR_MAC_ACTION_RRM;
4578 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
4579 frm.DialogToken.token = pLinkReport->dialogToken;
4580
4581 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
4582 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
4583 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
4584 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
4585 /* such case this way than changing the frame parser. */
4586 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
4587 frm.TPCEleLen.TPCLen = 2;
4588 frm.TxPower.txPower = pLinkReport->txPower;
4589 frm.LinkMargin.linkMargin = 0;
4590
4591 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4592 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4593 frm.RCPI.rcpi = pLinkReport->rcpi;
4594 frm.RSNI.rsni = pLinkReport->rsni;
4595
4596 nStatus =
4597 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4598 if (DOT11F_FAILED(nStatus)) {
4599 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4600 "or a Link Report (0x%08x)."), nStatus);
4601 /* We'll fall back on the worst case scenario: */
4602 nPayload = sizeof(tDot11fLinkMeasurementReport);
4603 } else if (DOT11F_WARNED(nStatus)) {
4604 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4605 "the packed size for a Link Rep"
4606 "ort (0x%08x)."), nStatus);
4607 }
4608
4609 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4610
4611 cdf_status =
4612 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4613 (void **)&pPacket);
4614 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4615 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Link "
4616 "Report."), nBytes);
4617 return eSIR_FAILURE;
4618 }
4619 /* Paranoia: */
4620 cdf_mem_set(pFrame, nBytes, 0);
4621
4622 /* Copy necessary info to BD */
4623 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4624 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4625
4626 /* Update A3 with the BSSID */
4627 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4628
4629 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4630
4631#ifdef WLAN_FEATURE_11W
4632 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4633#endif
4634
4635 /* Now, we're ready to "pack" the frames */
4636 nStatus = dot11f_pack_link_measurement_report(pMac,
4637 &frm,
4638 pFrame +
4639 sizeof(tSirMacMgmtHdr),
4640 nPayload, &nPayload);
4641
4642 if (DOT11F_FAILED(nStatus)) {
4643 lim_log(pMac, LOGE,
4644 FL("Failed to pack an Link Report (0x%08x)."), nStatus);
4645
4646 /* FIXME - Need to convert to tSirRetStatus */
4647 statusCode = eSIR_FAILURE;
4648 goto returnAfterError;
4649 } else if (DOT11F_WARNED(nStatus)) {
4650 lim_log(pMac, LOGW,
4651 FL
4652 ("There were warnings while packing Link Report (0x%08x)."),
4653 nStatus);
4654 }
4655
4656 lim_log(pMac, LOGW, FL("Sending a Link Report to "));
4657 lim_print_mac_addr(pMac, peer, LOGW);
4658
4659 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4660 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4661 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
4662 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4663 }
4664
4665 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4666 psessionEntry->peSessionId, pMacHdr->fc.subType));
4667 cdf_status = wma_tx_frame(pMac,
4668 pPacket,
4669 (uint16_t) nBytes,
4670 TXRX_FRM_802_11_MGMT,
4671 ANI_TXDIR_TODS,
4672 7, lim_tx_complete, pFrame, txFlag,
4673 smeSessionId, 0);
4674 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4675 psessionEntry->peSessionId, cdf_status));
4676 if (CDF_STATUS_SUCCESS != cdf_status) {
4677 PELOGE(lim_log
4678 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4679 cdf_status);
4680 )
4681 statusCode = eSIR_FAILURE;
4682 /* Pkt will be freed up by the callback */
4683 return statusCode;
4684 } else
4685 return eSIR_SUCCESS;
4686
4687returnAfterError:
4688 cds_packet_free((void *)pPacket);
4689
4690 return statusCode;
4691} /* End lim_send_link_report_action_frame. */
4692
4693/**
4694 * \brief Send a Beacon Report Action frame
4695 *
4696 *
4697 * \param pMac Pointer to the global MAC structure
4698 *
4699 * \param dialog_token dialog token to be used in the action frame.
4700 *
4701 * \param num_report number of reports in pRRMReport.
4702 *
4703 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4704 *
4705 * \param peer mac address of peer station.
4706 *
4707 * \param psessionEntry address of session entry.
4708 *
4709 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4710 *
4711 *
4712 */
4713
4714tSirRetStatus
4715lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4716 uint8_t dialog_token,
4717 uint8_t num_report,
4718 tpSirMacRadioMeasureReport pRRMReport,
4719 tSirMacAddr peer,
4720 tpPESession psessionEntry)
4721{
4722 tSirRetStatus statusCode = eSIR_SUCCESS;
4723 uint8_t *pFrame;
4724 tpSirMacMgmtHdr pMacHdr;
4725 uint32_t nBytes, nPayload, nStatus;
4726 void *pPacket;
4727 CDF_STATUS cdf_status;
4728 uint8_t i;
4729 uint8_t txFlag = 0;
4730 uint8_t smeSessionId = 0;
4731
4732 tDot11fRadioMeasurementReport *frm =
4733 cdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
4734 if (!frm) {
4735 lim_log(pMac, LOGE,
4736 FL
4737 ("Not enough memory to allocate tDot11fRadioMeasurementReport"));
4738 return eSIR_MEM_ALLOC_FAILED;
4739 }
4740
4741 if (psessionEntry == NULL) {
4742 lim_log(pMac, LOGE,
4743 FL
4744 ("(psession == NULL) in Request to send Beacon Report action frame"));
4745 cdf_mem_free(frm);
4746 return eSIR_FAILURE;
4747 }
4748 cdf_mem_set((uint8_t *) frm, sizeof(*frm), 0);
4749
4750 frm->Category.category = SIR_MAC_ACTION_RRM;
4751 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4752 frm->DialogToken.token = dialog_token;
4753
4754 frm->num_MeasurementReport =
4755 (num_report >
4756 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4757 num_report;
4758
4759 for (i = 0; i < frm->num_MeasurementReport; i++) {
4760 frm->MeasurementReport[i].type = pRRMReport[i].type;
4761 frm->MeasurementReport[i].token = pRRMReport[i].token;
4762 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4763 switch (pRRMReport[i].type) {
4764 case SIR_MAC_RRM_BEACON_TYPE:
4765 populate_dot11f_beacon_report(pMac,
4766 &frm->MeasurementReport[i],
4767 &pRRMReport[i].report.
4768 beaconReport);
4769 frm->MeasurementReport[i].incapable =
4770 pRRMReport[i].incapable;
4771 frm->MeasurementReport[i].refused =
4772 pRRMReport[i].refused;
4773 frm->MeasurementReport[i].present = 1;
4774 break;
4775 default:
4776 frm->MeasurementReport[i].incapable =
4777 pRRMReport[i].incapable;
4778 frm->MeasurementReport[i].refused =
4779 pRRMReport[i].refused;
4780 frm->MeasurementReport[i].present = 1;
4781 break;
4782 }
4783 }
4784
4785 nStatus =
4786 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4787 if (DOT11F_FAILED(nStatus)) {
4788 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4789 "or a Radio Measure Report (0x%08x)."),
4790 nStatus);
4791 /* We'll fall back on the worst case scenario: */
4792 nPayload = sizeof(tDot11fLinkMeasurementReport);
4793 cdf_mem_free(frm);
4794 return eSIR_FAILURE;
4795 } else if (DOT11F_WARNED(nStatus)) {
4796 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4797 "the packed size for a Radio Measure Rep"
4798 "ort (0x%08x)."), nStatus);
4799 }
4800
4801 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4802
4803 cdf_status =
4804 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4805 (void **)&pPacket);
4806 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4807 lim_log(pMac, LOGP,
4808 FL("Failed to allocate %d bytes for a Radio Measure "
4809 "Report."), nBytes);
4810 cdf_mem_free(frm);
4811 return eSIR_FAILURE;
4812 }
4813 /* Paranoia: */
4814 cdf_mem_set(pFrame, nBytes, 0);
4815
4816 /* Copy necessary info to BD */
4817 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4818 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4819
4820 /* Update A3 with the BSSID */
4821 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4822
4823 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4824
4825#ifdef WLAN_FEATURE_11W
4826 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4827#endif
4828
4829 /* Now, we're ready to "pack" the frames */
4830 nStatus = dot11f_pack_radio_measurement_report(pMac,
4831 frm,
4832 pFrame +
4833 sizeof(tSirMacMgmtHdr),
4834 nPayload, &nPayload);
4835
4836 if (DOT11F_FAILED(nStatus)) {
4837 lim_log(pMac, LOGE,
4838 FL("Failed to pack an Radio Measure Report (0x%08x)."),
4839 nStatus);
4840
4841 /* FIXME - Need to convert to tSirRetStatus */
4842 statusCode = eSIR_FAILURE;
4843 goto returnAfterError;
4844 } else if (DOT11F_WARNED(nStatus)) {
4845 lim_log(pMac, LOGW,
4846 FL("There were warnings while packing Radio "
4847 "Measure Report (0x%08x)."), nStatus);
4848 }
4849
4850 lim_log(pMac, LOGW, FL("Sending a Radio Measure Report to "));
4851 lim_print_mac_addr(pMac, peer, LOGW);
4852
4853 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4854 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4855 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4856 ) {
4857 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4858 }
4859
4860 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4861 psessionEntry->peSessionId, pMacHdr->fc.subType));
4862 cdf_status = wma_tx_frame(pMac,
4863 pPacket,
4864 (uint16_t) nBytes,
4865 TXRX_FRM_802_11_MGMT,
4866 ANI_TXDIR_TODS,
4867 7, lim_tx_complete, pFrame, txFlag,
4868 smeSessionId, 0);
4869 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4870 psessionEntry->peSessionId, cdf_status));
4871 if (CDF_STATUS_SUCCESS != cdf_status) {
4872 PELOGE(lim_log
4873 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4874 cdf_status);
4875 )
4876 statusCode = eSIR_FAILURE;
4877 /* Pkt will be freed up by the callback */
4878 cdf_mem_free(frm);
4879 return statusCode;
4880 } else {
4881 cdf_mem_free(frm);
4882 return eSIR_SUCCESS;
4883 }
4884
4885returnAfterError:
4886 cdf_mem_free(frm);
4887 cds_packet_free((void *)pPacket);
4888 return statusCode;
4889}
4890
4891#endif
4892
4893#ifdef WLAN_FEATURE_11W
4894/**
4895 * \brief Send SA query request action frame to peer
4896 *
4897 * \sa lim_send_sa_query_request_frame
4898 *
4899 *
4900 * \param pMac The global tpAniSirGlobal object
4901 *
4902 * \param transId Transaction identifier
4903 *
4904 * \param peer The Mac address of the station to which this action frame is addressed
4905 *
4906 * \param psessionEntry The PE session entry
4907 *
4908 * \return eSIR_SUCCESS if setup completes successfully
4909 * eSIR_FAILURE is some problem is encountered
4910 */
4911
4912tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4913 tSirMacAddr peer,
4914 tpPESession psessionEntry)
4915{
4916
4917 tDot11fSaQueryReq frm; /* SA query request action frame */
4918 uint8_t *pFrame;
4919 tSirRetStatus nSirStatus;
4920 tpSirMacMgmtHdr pMacHdr;
4921 uint32_t nBytes, nPayload, nStatus;
4922 void *pPacket;
4923 CDF_STATUS cdf_status;
4924 uint8_t txFlag = 0;
4925 uint8_t smeSessionId = 0;
4926
4927 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4928 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4929 /* 11w action field is :
4930 action: 0 --> SA Query Request action frame
4931 action: 1 --> SA Query Response action frame */
4932 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4933 /* 11w SA Query Request transId */
4934 cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
4935
4936 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4937 if (DOT11F_FAILED(nStatus)) {
4938 lim_log(pMac, LOGP, FL("Failed to calculate the packed size "
4939 "for an SA Query Request (0x%08x)."),
4940 nStatus);
4941 /* We'll fall back on the worst case scenario: */
4942 nPayload = sizeof(tDot11fSaQueryReq);
4943 } else if (DOT11F_WARNED(nStatus)) {
4944 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4945 "the packed size for an SA Query Request"
4946 " (0x%08x)."), nStatus);
4947 }
4948
4949 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4950 cdf_status =
4951 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
4952 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4953 lim_log(pMac, LOGP,
4954 FL("Failed to allocate %d bytes for a SA Query Request "
4955 "action frame"), nBytes);
4956 return eSIR_FAILURE;
4957 }
4958 /* Paranoia: */
4959 cdf_mem_set(pFrame, nBytes, 0);
4960
4961 /* Copy necessary info to BD */
4962 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4963 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4964
4965 /* Update A3 with the BSSID */
4966 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4967
4968 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4969
4970 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4971 /* in the FC */
4972 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4973
4974 /* Pack 11w SA Query Request frame */
4975 nStatus = dot11f_pack_sa_query_req(pMac,
4976 &frm,
4977 pFrame + sizeof(tSirMacMgmtHdr),
4978 nPayload, &nPayload);
4979
4980 if (DOT11F_FAILED(nStatus)) {
4981 lim_log(pMac, LOGE,
4982 FL("Failed to pack an SA Query Request (0x%08x)."),
4983 nStatus);
4984 /* FIXME - Need to convert to tSirRetStatus */
4985 nSirStatus = eSIR_FAILURE;
4986 goto returnAfterError;
4987 } else if (DOT11F_WARNED(nStatus)) {
4988 lim_log(pMac, LOGW,
4989 FL
4990 ("There were warnings while packing SA Query Request (0x%08x)."),
4991 nStatus);
4992 }
4993
4994 lim_log(pMac, LOG1, FL("Sending an SA Query Request to "));
4995 lim_print_mac_addr(pMac, peer, LOG1);
4996 lim_log(pMac, LOG1, FL("Sending an SA Query Request from "));
4997 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOG1);
4998
4999 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
5000#ifdef WLAN_FEATURE_P2P
5001 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
5002 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
5003#endif
5004 ) {
5005 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
5006 }
5007 smeSessionId = psessionEntry->smeSessionId;
5008
5009 cdf_status = wma_tx_frame(pMac,
5010 pPacket,
5011 (uint16_t) nBytes,
5012 TXRX_FRM_802_11_MGMT,
5013 ANI_TXDIR_TODS,
5014 7, lim_tx_complete, pFrame, txFlag,
5015 smeSessionId, 0);
5016 if (CDF_STATUS_SUCCESS != cdf_status) {
5017 PELOGE(lim_log
5018 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
5019 cdf_status);
5020 )
5021 nSirStatus = eSIR_FAILURE;
5022 /* Pkt will be freed up by the callback */
5023 return nSirStatus;
5024 } else {
5025 return eSIR_SUCCESS;
5026 }
5027
5028returnAfterError:
5029 cds_packet_free((void *)pPacket);
5030 return nSirStatus;
5031} /* End lim_send_sa_query_request_frame */
5032
5033/**
5034 * \brief Send SA query response action frame to peer
5035 *
5036 * \sa lim_send_sa_query_response_frame
5037 *
5038 *
5039 * \param pMac The global tpAniSirGlobal object
5040 *
5041 * \param transId Transaction identifier received in SA query request action frame
5042 *
5043 * \param peer The Mac address of the AP to which this action frame is addressed
5044 *
5045 * \param psessionEntry The PE session entry
5046 *
5047 * \return eSIR_SUCCESS if setup completes successfully
5048 * eSIR_FAILURE is some problem is encountered
5049 */
5050
5051tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
5052 uint8_t *transId, tSirMacAddr peer,
5053 tpPESession psessionEntry)
5054{
5055
5056 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
5057 uint8_t *pFrame;
5058 tSirRetStatus nSirStatus;
5059 tpSirMacMgmtHdr pMacHdr;
5060 uint32_t nBytes, nPayload, nStatus;
5061 void *pPacket;
5062 CDF_STATUS cdf_status;
5063 uint8_t txFlag = 0;
5064 uint8_t smeSessionId = 0;
5065
5066 smeSessionId = psessionEntry->smeSessionId;
5067
5068 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
5069 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
5070 /*11w action field is :
5071 action: 0 --> SA query request action frame
5072 action: 1 --> SA query response action frame */
5073 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
5074 /*11w SA query response transId is same as
5075 SA query request transId */
5076 cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
5077
5078 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
5079 if (DOT11F_FAILED(nStatus)) {
5080 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
5081 "or a SA Query Response (0x%08x)."),
5082 nStatus);
5083 /* We'll fall back on the worst case scenario: */
5084 nPayload = sizeof(tDot11fSaQueryRsp);
5085 } else if (DOT11F_WARNED(nStatus)) {
5086 lim_log(pMac, LOGW, FL("There were warnings while calculating "
5087 "the packed size for an SA Query Response"
5088 " (0x%08x)."), nStatus);
5089 }
5090
5091 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
5092 cdf_status =
5093 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
5094 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
5095 lim_log(pMac, LOGP,
5096 FL("Failed to allocate %d bytes for a SA query response"
5097 " action frame"), nBytes);
5098 return eSIR_FAILURE;
5099 }
5100 /* Paranoia: */
5101 cdf_mem_set(pFrame, nBytes, 0);
5102
5103 /* Copy necessary info to BD */
5104 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
5105 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
5106
5107 /* Update A3 with the BSSID */
5108 pMacHdr = (tpSirMacMgmtHdr) pFrame;
5109
5110 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
5111
5112 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
5113 /* in the FC */
5114 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
5115
5116 /* Pack 11w SA query response frame */
5117 nStatus = dot11f_pack_sa_query_rsp(pMac,
5118 &frm,
5119 pFrame + sizeof(tSirMacMgmtHdr),
5120 nPayload, &nPayload);
5121
5122 if (DOT11F_FAILED(nStatus)) {
5123 lim_log(pMac, LOGE,
5124 FL("Failed to pack an SA Query Response (0x%08x)."),
5125 nStatus);
5126 /* FIXME - Need to convert to tSirRetStatus */
5127 nSirStatus = eSIR_FAILURE;
5128 goto returnAfterError;
5129 } else if (DOT11F_WARNED(nStatus)) {
5130 lim_log(pMac, LOGW,
5131 FL
5132 ("There were warnings while packing SA Query Response (0x%08x)."),
5133 nStatus);
5134 }
5135
5136 lim_log(pMac, LOG1, FL("Sending a SA Query Response to "));
5137 lim_print_mac_addr(pMac, peer, LOGW);
5138
5139 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
5140#ifdef WLAN_FEATURE_P2P
5141 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
5142 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
5143#endif
5144 ) {
5145 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
5146 }
5147
5148 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
5149 psessionEntry->peSessionId, pMacHdr->fc.subType));
5150 cdf_status = wma_tx_frame(pMac,
5151 pPacket,
5152 (uint16_t) nBytes,
5153 TXRX_FRM_802_11_MGMT,
5154 ANI_TXDIR_TODS,
5155 7, lim_tx_complete, pFrame, txFlag,
5156 smeSessionId, 0);
5157 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
5158 psessionEntry->peSessionId, cdf_status));
5159 if (CDF_STATUS_SUCCESS != cdf_status) {
5160 PELOGE(lim_log
5161 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
5162 cdf_status);
5163 )
5164 nSirStatus = eSIR_FAILURE;
5165 /* Pkt will be freed up by the callback */
5166 return nSirStatus;
5167 } else {
5168 return eSIR_SUCCESS;
5169 }
5170
5171returnAfterError:
5172 cds_packet_free((void *)pPacket);
5173 return nSirStatus;
5174} /* End lim_send_sa_query_response_frame */
5175#endif