blob: 353f4c373a30f1ed26e9a2fab8c9711764390ce5 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
3 *
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);
1205 populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
1206 pe_session);
1207 }
1208#ifdef WLAN_FEATURE_11AC
1209 if (sta->mlmStaContext.vhtCapability &&
1210 pe_session->vhtCapability) {
1211 lim_log(mac_ctx, LOG1,
1212 FL("Populate VHT IEs in Assoc Response"));
1213 populate_dot11f_vht_caps(mac_ctx, pe_session,
1214 &frm.VHTCaps);
1215 populate_dot11f_vht_operation(mac_ctx, pe_session,
1216 &frm.VHTOperation);
1217 is_vht = true;
1218 }
1219#endif
1220
1221 populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
1222 pe_session);
1223
1224#ifdef WLAN_FEATURE_11W
1225 if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
1226 if (wlan_cfg_get_int
1227 (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
1228 &max_retries) != eSIR_SUCCESS)
1229 lim_log(mac_ctx, LOGE,
1230 FL("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure"));
1231 else if (wlan_cfg_get_int
1232 (mac_ctx,
1233 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1234 &retry_int) != eSIR_SUCCESS)
1235 lim_log(mac_ctx, LOGE,
1236 FL("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure"));
1237 else
1238 populate_dot11f_timeout_interval(mac_ctx,
1239 &frm.TimeoutInterval,
1240 SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
1241 (max_retries -
1242 sta->pmfSaQueryRetryCount)
1243 * retry_int);
1244 }
1245#endif
1246 }
1247
1248 cdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
1249
1250 if (LIM_IS_AP_ROLE(pe_session) &&
1251 (pe_session->gLimProtectionControl !=
1252 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
1253 lim_decide_ap_protection(mac_ctx, peer_addr,
1254 &beacon_params, pe_session);
1255
1256 lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
1257 pe_session);
1258 lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
1259 pe_session);
1260
1261 /*
1262 * Populate Do11capabilities after updating session with
1263 * Assos req details
1264 */
1265 populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
1266
1267 beacon_params.bssIdx = pe_session->bssIdx;
1268
1269 /* Send message to HAL about beacon parameter change. */
1270 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1271 && beacon_params.paramChangeBitmap) {
1272 sch_set_fixed_beacon_fields(mac_ctx, pe_session);
1273 lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
1274 }
1275 /* Allocate a buffer for this frame: */
1276 status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
1277 if (DOT11F_FAILED(status)) {
1278 lim_log(mac_ctx, LOGE,
1279 FL("get Association Response size failure (0x%08x)."),
1280 status);
1281 return;
1282 } else if (DOT11F_WARNED(status)) {
1283 lim_log(mac_ctx, LOGW,
1284 FL("get Association Response size warning (0x%08x)."),
1285 status);
1286 }
1287
1288 bytes = sizeof(tSirMacMgmtHdr) + payload;
1289
1290 if (assoc_req != NULL) {
1291 addn_ie_len = (pe_session->addIeParams.assocRespDataLen != 0);
1292
1293 /* Nonzero length indicates Assoc rsp IE available */
1294 if (addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN
1295 && (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
1296 cdf_mem_copy(add_ie,
1297 pe_session->addIeParams.assocRespData_buff,
1298 pe_session->addIeParams.assocRespDataLen);
1299
1300 cdf_mem_set((uint8_t *) &extracted_ext_cap,
1301 sizeof(extracted_ext_cap), 0);
1302
1303 stripoff_len = addn_ie_len;
1304 sir_status =
1305 lim_strip_extcap_update_struct
1306 (mac_ctx, &add_ie[0], &stripoff_len,
1307 &extracted_ext_cap);
1308 if (eSIR_SUCCESS != sir_status) {
1309 lim_log(mac_ctx, LOG1,
1310 FL("strip off extcap IE failed"));
1311 } else {
1312 addn_ie_len = stripoff_len;
1313 extracted_flag = true;
1314 }
1315 bytes = bytes + addn_ie_len;
1316 }
1317 lim_log(mac_ctx, LOG1,
1318 FL("addn_ie_len = %d for Assoc Resp : %d"),
1319 addn_ie_len, assoc_req->addIEPresent);
1320 }
1321 cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
1322 (void **)&packet);
1323 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1324 lim_log(mac_ctx, LOGP, FL("cds_packet_alloc failed."));
1325 return;
1326 }
1327 /* Paranoia: */
1328 cdf_mem_set(frame, bytes, 0);
1329
1330 /* Next, we fill out the buffer descriptor: */
1331 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1332 (LIM_ASSOC == subtype) ?
1333 SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
1334 peer_addr,
1335 pe_session->selfMacAddr);
1336 mac_hdr = (tpSirMacMgmtHdr) frame;
1337
1338 sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
1339
1340 /* merge the ExtCap struct */
1341 if (extracted_flag)
1342 lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap);
1343 status = dot11f_pack_assoc_response(mac_ctx, &frm,
1344 frame + sizeof(tSirMacMgmtHdr),
1345 payload, &payload);
1346 if (DOT11F_FAILED(status)) {
1347 lim_log(mac_ctx, LOGE,
1348 FL("Association Response pack failure(0x%08x)."),
1349 status);
1350 cds_packet_free((void *)packet);
1351 return;
1352 } else if (DOT11F_WARNED(status)) {
1353 lim_log(mac_ctx, LOGW,
1354 FL("Association Response pack warning (0x%08x)."),
1355 status);
1356 }
1357
1358 if (subtype == LIM_ASSOC)
1359 lim_log(mac_ctx, LOG1,
1360 FL("*** Sending Assoc Resp status %d aid %d to "),
1361 status_code, aid);
1362 else
1363 lim_log(mac_ctx, LOG1,
1364 FL("*** Sending ReAssoc Resp status %d aid %d to "),
1365 status_code, aid);
1366
1367 lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
1368
1369 if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
1370 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
1371 &add_ie[0], addn_ie_len);
1372
1373 if ((SIR_BAND_5_GHZ ==
1374 lim_get_rf_band(pe_session->currentOperChannel)) ||
1375 (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
1376 (pe_session->pePersona == CDF_P2P_GO_MODE))
1377 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1378
1379 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
1380 pe_session->peSessionId, mac_hdr->fc.subType));
1381 /* Queue Association Response frame in high priority WQ */
1382 cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
1383 TXRX_FRM_802_11_MGMT,
1384 ANI_TXDIR_TODS,
1385 7, lim_tx_complete, frame, tx_flag,
1386 sme_session, 0);
1387 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
1388 pe_session->peSessionId, cdf_status));
1389
1390 /* Pkt will be freed up by the callback */
1391 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1392 lim_log(mac_ctx, LOGE,
1393 FL("*** Could not Send Re/AssocRsp, retCode=%X ***"),
1394 cdf_status);
1395
1396 /*
1397 * update the ANI peer station count.
1398 * FIXME_PROTECTION : take care of different type of station
1399 * counter inside this function.
1400 */
1401 lim_util_count_sta_add(mac_ctx, sta, pe_session);
1402
1403}
1404
1405void
1406lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
1407 tSirMacAddr peer,
1408 uint8_t wmmTspecPresent,
1409 tSirMacTSInfo *pTsinfo,
1410 tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
1411{
1412 uint8_t *pFrame;
1413 tpSirMacMgmtHdr pMacHdr;
1414 tDot11fDelTS DelTS;
1415 tDot11fWMMDelTS WMMDelTS;
1416 uint32_t nBytes, nPayload, nStatus;
1417 void *pPacket;
1418 CDF_STATUS cdf_status;
1419 uint8_t txFlag = 0;
1420 uint8_t smeSessionId = 0;
1421
1422 if (NULL == psessionEntry) {
1423 return;
1424 }
1425
1426 smeSessionId = psessionEntry->smeSessionId;
1427
1428 if (!wmmTspecPresent) {
1429 cdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
1430
1431 DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
1432 DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1433 populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
1434
1435 nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
1436 if (DOT11F_FAILED(nStatus)) {
1437 lim_log(pMac, LOGP,
1438 FL("Failed to calculate the packed si"
1439 "ze for a Del TS (0x%08x)."), nStatus);
1440 /* We'll fall back on the worst case scenario: */
1441 nPayload = sizeof(tDot11fDelTS);
1442 } else if (DOT11F_WARNED(nStatus)) {
1443 lim_log(pMac, LOGW,
1444 FL("There were warnings while calcula"
1445 "ting the packed size for a Del TS"
1446 " (0x%08x)."), nStatus);
1447 }
1448 } else {
1449 cdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
1450
1451 WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
1452 WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
1453 WMMDelTS.DialogToken.token = 0;
1454 WMMDelTS.StatusCode.statusCode = 0;
1455 populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
1456 nStatus =
1457 dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
1458 if (DOT11F_FAILED(nStatus)) {
1459 lim_log(pMac, LOGP,
1460 FL("Failed to calculate the packed si"
1461 "ze for a WMM Del TS (0x%08x)."), nStatus);
1462 /* We'll fall back on the worst case scenario: */
1463 nPayload = sizeof(tDot11fDelTS);
1464 } else if (DOT11F_WARNED(nStatus)) {
1465 lim_log(pMac, LOGW,
1466 FL("There were warnings while calcula"
1467 "ting the packed size for a WMM De"
1468 "l TS (0x%08x)."), nStatus);
1469 }
1470 }
1471
1472 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
1473
1474 cdf_status =
1475 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
1476 (void **)&pPacket);
1477 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1478 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
1479 "d TS Response."), nBytes);
1480 return;
1481 }
1482 /* Paranoia: */
1483 cdf_mem_set(pFrame, nBytes, 0);
1484
1485 /* Next, we fill out the buffer descriptor: */
1486 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1487 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
1488 pMacHdr = (tpSirMacMgmtHdr) pFrame;
1489
1490 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
1491
1492#ifdef WLAN_FEATURE_11W
1493 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
1494#endif
1495
1496 /* That done, pack the struct: */
1497 if (!wmmTspecPresent) {
1498 nStatus = dot11f_pack_del_ts(pMac, &DelTS,
1499 pFrame + sizeof(tSirMacMgmtHdr),
1500 nPayload, &nPayload);
1501 if (DOT11F_FAILED(nStatus)) {
1502 lim_log(pMac, LOGE,
1503 FL("Failed to pack a Del TS frame (0x%08x)."),
1504 nStatus);
1505 cds_packet_free((void *)pPacket);
1506 return; /* allocated! */
1507 } else if (DOT11F_WARNED(nStatus)) {
1508 lim_log(pMac, LOGW,
1509 FL("There were warnings while packing "
1510 "a Del TS frame (0x%08x)."), nStatus);
1511 }
1512 } else {
1513 nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
1514 pFrame + sizeof(tSirMacMgmtHdr),
1515 nPayload, &nPayload);
1516 if (DOT11F_FAILED(nStatus)) {
1517 lim_log(pMac, LOGE,
1518 FL
1519 ("Failed to pack a WMM Del TS frame (0x%08x)."),
1520 nStatus);
1521 cds_packet_free((void *)pPacket);
1522 return; /* allocated! */
1523 } else if (DOT11F_WARNED(nStatus)) {
1524 lim_log(pMac, LOGW,
1525 FL("There were warnings while packing "
1526 "a WMM Del TS frame (0x%08x)."), nStatus);
1527 }
1528 }
1529
1530 PELOG1(lim_log
1531 (pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes);
1532 lim_print_mac_addr(pMac, pMacHdr->da, LOG1);
1533 )
1534
1535 if ((SIR_BAND_5_GHZ ==
1536 lim_get_rf_band(psessionEntry->currentOperChannel))
1537 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE)
1538 || (psessionEntry->pePersona == CDF_P2P_GO_MODE)
1539 ) {
1540 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1541 }
1542
1543 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
1544 psessionEntry->peSessionId, pMacHdr->fc.subType));
1545 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
1546 TXRX_FRM_802_11_MGMT,
1547 ANI_TXDIR_TODS,
1548 7, lim_tx_complete, pFrame, txFlag,
1549 smeSessionId, 0);
1550 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
1551 psessionEntry->peSessionId, cdf_status));
1552 /* Pkt will be freed up by the callback */
1553 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1554 lim_log(pMac, LOGE, FL("Failed to send Del TS (%X)!"),
1555 cdf_status);
1556
1557} /* End lim_send_delts_req_action_frame. */
1558
1559/**
1560 * lim_send_assoc_req_mgmt_frame() - Send association request
1561 * @mac_ctx: Handle to MAC context
1562 * @mlm_assoc_req: Association request information
1563 * @pe_session: PE session information
1564 *
1565 * Builds and transmits association request frame to AP.
1566 *
1567 * Return: Void
1568 */
1569
1570void
1571lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
1572 tLimMlmAssocReq *mlm_assoc_req,
1573 tpPESession pe_session)
1574{
1575 tDot11fAssocRequest *frm;
1576 uint16_t caps;
1577 uint8_t *frame;
1578 tSirRetStatus sir_status;
1579 tLimMlmAssocCnf assoc_cnf;
1580 uint32_t bytes, payload, status;
1581 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1582 void *packet;
1583 CDF_STATUS cdf_status;
1584 uint16_t add_ie_len;
1585 uint8_t *add_ie;
1586 uint8_t *wps_ie = NULL;
1587#if defined WLAN_FEATURE_VOWIFI
1588 uint8_t power_caps = false;
1589#endif
1590 uint8_t tx_flag = 0;
1591 uint8_t sme_sessionid = 0;
1592 bool vht_enabled = false;
1593 tDot11fIEExtCap extr_ext_cap;
1594 bool extr_ext_flag = true;
1595 tpSirMacMgmtHdr mac_hdr;
1596
1597 if (NULL == pe_session) {
1598 lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
1599 return;
1600 }
1601
1602 sme_sessionid = pe_session->smeSessionId;
1603
1604 /* check this early to avoid unncessary operation */
1605 if (NULL == pe_session->pLimJoinReq) {
1606 lim_log(mac_ctx, LOGE, FL("pe_session->pLimJoinReq is NULL"));
1607 return;
1608 }
1609 add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
1610 add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
1611
1612 frm = cdf_mem_malloc(sizeof(tDot11fAssocRequest));
1613 if (NULL == frm) {
1614 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
1615 return;
1616 }
1617
1618 cdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
1619
1620 if (add_ie_len) {
1621 cdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
1622 0);
1623 sir_status = lim_strip_extcap_update_struct(mac_ctx,
1624 add_ie, &add_ie_len, &extr_ext_cap);
1625 if (eSIR_SUCCESS != sir_status) {
1626 extr_ext_flag = false;
1627 lim_log(mac_ctx, LOG1,
1628 FL("Unable to Stripoff ExtCap IE from Assoc Req"));
1629 } else {
1630 struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
1631 extr_ext_cap.bytes;
1632
1633 if (p_ext_cap->interworking_service)
1634 p_ext_cap->qos_map = 1;
1635 else {
1636 /*
1637 * No need to merge the EXT Cap from Supplicant
1638 * if interworkingService is not set, as currently
1639 * driver is only interested in interworkingService
1640 * capability from supplicant. if in future any other
1641 * EXT Cap info is required from supplicant
1642 * it needs to be handled here.
1643 */
1644 extr_ext_flag = false;
1645 }
1646 }
1647 } else {
1648 lim_log(mac_ctx, LOG1, FL("No additional IE for Assoc Req"));
1649 extr_ext_flag = false;
1650 }
1651
1652 caps = mlm_assoc_req->capabilityInfo;
1653#if defined(FEATURE_WLAN_WAPI)
1654 /*
1655 * According to WAPI standard:
1656 * 7.3.1.4 Capability Information field
1657 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
1658 * in transmitted Association or Reassociation management frames.
1659 * APs ignore the Privacy subfield within received Association and
1660 * Reassociation management frames.
1661 */
1662 if (pe_session->encryptType == eSIR_ED_WPI)
1663 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
1664#endif
1665 swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
1666
1667 frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
1668 populate_dot11f_ssid2(mac_ctx, &frm->SSID);
1669 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
1670 &frm->SuppRates, pe_session);
1671
1672 qos_enabled = (pe_session->limQosEnabled) &&
1673 SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
1674
1675 wme_enabled = (pe_session->limWmeEnabled) &&
1676 LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
1677
1678 /* We prefer .11e asociations: */
1679 if (qos_enabled)
1680 wme_enabled = false;
1681
1682 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
1683 LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
1684
1685 if (pe_session->lim11hEnable &&
1686 pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
1687#if defined WLAN_FEATURE_VOWIFI
1688 power_caps = true;
1689
1690 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1691 LIM_ASSOC, pe_session);
1692#endif
1693 populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
1694 LIM_ASSOC, pe_session);
1695
1696 }
1697#if defined WLAN_FEATURE_VOWIFI
1698 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1699 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
1700 if (power_caps == false) {
1701 power_caps = true;
1702 populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
1703 LIM_ASSOC, pe_session);
1704 }
1705 }
1706#endif
1707
1708 if (qos_enabled)
1709 populate_dot11f_qos_caps_station(mac_ctx, &frm->QOSCapsStation);
1710
1711 populate_dot11f_ext_supp_rates(mac_ctx,
1712 POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
1713 pe_session);
1714
1715#if defined WLAN_FEATURE_VOWIFI
1716 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
1717 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
1718 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1719 pe_session);
1720#endif
1721 /*
1722 * The join request *should* contain zero or one of the WPA and RSN
1723 * IEs. The payload send along with the request is a
1724 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1725 * typedef struct sSirRSNie
1726 * {
1727 * uint16_t length;
1728 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1729 * } tSirRSNie, *tpSirRSNie;
1730 * So, we should be able to make the following two calls harmlessly,
1731 * since they do nothing if they don't find the given IE in the
1732 * bytestream with which they're provided.
1733 * The net effect of this will be to faithfully transmit whatever
1734 * security IE is in the join request.
1735 * However, if we're associating for the purpose of WPS
1736 * enrollment, and we've been configured to indicate that by
1737 * eliding the WPA or RSN IE, we just skip this:
1738 */
1739 if (add_ie_len && add_ie)
1740 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1741
1742 if (NULL == wps_ie) {
1743 populate_dot11f_rsn_opaque(mac_ctx,
1744 &(pe_session->pLimJoinReq->rsnIE),
1745 &frm->RSNOpaque);
1746 populate_dot11f_wpa_opaque(mac_ctx,
1747 &(pe_session->pLimJoinReq->rsnIE),
1748 &frm->WPAOpaque);
1749#if defined(FEATURE_WLAN_WAPI)
1750 populate_dot11f_wapi_opaque(mac_ctx,
1751 &(pe_session->pLimJoinReq->rsnIE),
1752 &frm->WAPIOpaque);
1753#endif /* defined(FEATURE_WLAN_WAPI) */
1754 }
1755 /* include WME EDCA IE as well */
1756 if (wme_enabled) {
1757 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1758 pe_session, &frm->WMMInfoStation);
1759
1760 if (wsm_enabled)
1761 populate_dot11f_wmm_caps(&frm->WMMCaps);
1762 }
1763
1764 /*
1765 * Populate HT IEs, when operating in 11n and
1766 * when AP is also operating in 11n mode
1767 */
1768 if (pe_session->htCapability &&
1769 mac_ctx->lim.htCapabilityPresentInBeacon) {
1770 lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
1771 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
1772 }
1773#ifdef WLAN_FEATURE_11AC
1774 if (pe_session->vhtCapability &&
1775 pe_session->vhtCapabilityPresentInBeacon) {
1776 lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request"));
1777 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
1778 vht_enabled = true;
1779 }
1780 if (!vht_enabled &&
1781 pe_session->is_vendor_specific_vhtcaps) {
1782 lim_log(mac_ctx, LOG1,
1783 FL("Populate Vendor VHT IEs in Assoc Request"));
1784 frm->vendor2_ie.present = 1;
1785 frm->vendor2_ie.type =
1786 pe_session->vendor_specific_vht_ie_type;
1787 frm->vendor2_ie.sub_type =
1788 pe_session->vendor_specific_vht_ie_sub_type;
1789
1790 frm->vendor2_ie.VHTCaps.present = 1;
1791 populate_dot11f_vht_caps(mac_ctx, pe_session,
1792 &frm->vendor2_ie.VHTCaps);
1793 vht_enabled = true;
1794 }
1795
1796#endif
1797
1798 populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap, pe_session);
1799
1800#if defined WLAN_FEATURE_VOWIFI_11R
1801 if (pe_session->pLimJoinReq->is11Rconnection) {
1802#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
1803 tSirBssDescription *bssdescr;
1804
1805 bssdescr = &pe_session->pLimJoinReq->bssDescription;
1806 lim_log(mac_ctx, LOG1, FL("mdie = %02x %02x %02x"),
1807 (unsigned int) bssdescr->mdie[0],
1808 (unsigned int) bssdescr->mdie[1],
1809 (unsigned int) bssdescr->mdie[2]);
1810#endif
1811 populate_mdie(mac_ctx, &frm->MobilityDomain,
1812 pe_session->pLimJoinReq->bssDescription.mdie);
1813 } else {
1814 /* No 11r IEs dont send any MDIE */
1815 lim_log(mac_ctx, LOG1, FL("MDIE not present"));
1816 }
1817#endif
1818
1819#ifdef FEATURE_WLAN_ESE
1820 /*
1821 * ESE Version IE will be included in association request
1822 * when ESE is enabled on DUT through ini and it is also
1823 * advertised by the peer AP to which we are trying to
1824 * associate to.
1825 */
1826 if (pe_session->is_ese_version_ie_present &&
1827 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1828 populate_dot11f_ese_version(&frm->ESEVersion);
1829 /* For ESE Associations fill the ESE IEs */
1830 if (pe_session->isESEconnection &&
1831 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1832#ifndef FEATURE_DISABLE_RM
1833 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1834#endif
1835 }
1836#endif
1837
1838 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1839 if (DOT11F_FAILED(status)) {
1840 lim_log(mac_ctx, LOGP,
1841 FL("Association Request packet size failure(0x%08x)."),
1842 status);
1843 /* We'll fall back on the worst case scenario: */
1844 payload = sizeof(tDot11fAssocRequest);
1845 } else if (DOT11F_WARNED(status)) {
1846 lim_log(mac_ctx, LOGW,
1847 FL("Association request packet size warning (0x%08x)."),
1848 status);
1849 }
1850
1851 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1852
1853 cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
1854 (void **)&packet);
1855 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1856 lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes."),
1857 bytes);
1858
1859 pe_session->limMlmState = pe_session->limPrevMlmState;
1860 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
1861 pe_session->peSessionId,
1862 pe_session->limMlmState));
1863
1864 /* Update PE session id */
1865 assoc_cnf.sessionId = pe_session->peSessionId;
1866
1867 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1868
1869 cds_packet_free((void *)packet);
1870
1871 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1872 (uint32_t *) &assoc_cnf);
1873
1874 cdf_mem_free(frm);
1875 return;
1876 }
1877 /* Paranoia: */
1878 cdf_mem_set(frame, bytes, 0);
1879
1880 /* Next, we fill out the buffer descriptor: */
1881 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1882 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1883 pe_session->selfMacAddr);
1884 /* merge the ExtCap struct */
1885 if (extr_ext_flag)
1886 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap);
1887 /* That done, pack the Assoc Request: */
1888 status = dot11f_pack_assoc_request(mac_ctx, frm,
1889 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1890 if (DOT11F_FAILED(status)) {
1891 lim_log(mac_ctx, LOGE,
1892 FL("Assoc request pack failure (0x%08x)"), status);
1893 cds_packet_free((void *)packet);
1894 cdf_mem_free(frm);
1895 return;
1896 } else if (DOT11F_WARNED(status)) {
1897 lim_log(mac_ctx, LOGW,
1898 FL("Assoc request pack warning (0x%08x)"), status);
1899 }
1900
1901 lim_log(mac_ctx, LOG1,
1902 FL("*** Sending Association Request length %d to "), bytes);
1903 if (pe_session->assocReq != NULL) {
1904 cdf_mem_free(pe_session->assocReq);
1905 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001906 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001907 }
1908
1909 if (add_ie_len) {
1910 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
1911 add_ie, add_ie_len);
1912 payload += add_ie_len;
1913 }
1914
1915 pe_session->assocReq = cdf_mem_malloc(payload);
1916 if (NULL == pe_session->assocReq) {
1917 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
1918 } else {
1919 /*
1920 * Store the Assoc request. This is sent to csr/hdd in
1921 * join cnf response.
1922 */
1923 cdf_mem_copy(pe_session->assocReq,
1924 frame + sizeof(tSirMacMgmtHdr), payload);
1925 pe_session->assocReqLen = payload;
1926 }
1927
1928 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
1929 || (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
1930 || (pe_session->pePersona == CDF_P2P_GO_MODE)
1931 )
1932 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1933
1934 if (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
1935 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
1936
1937#ifdef FEATURE_WLAN_DIAG_SUPPORT
1938 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
1939 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
1940#endif
1941 mac_hdr = (tpSirMacMgmtHdr) frame;
1942 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
1943 pe_session->peSessionId, mac_hdr->fc.subType));
1944 cdf_status =
1945 wma_tx_frame(mac_ctx, packet,
1946 (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
1947 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
1948 lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
1949 MTRACE(cdf_trace
1950 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
1951 pe_session->peSessionId, cdf_status));
1952 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1953 lim_log(mac_ctx, LOGE,
1954 FL("Failed to send Association Request (%X)!"),
1955 cdf_status);
1956 /* Pkt will be freed up by the callback */
1957 cdf_mem_free(frm);
1958 return;
1959 }
1960 /* Free up buffer allocated for mlm_assoc_req */
1961 cdf_mem_free(mlm_assoc_req);
1962 mlm_assoc_req = NULL;
1963 cdf_mem_free(frm);
1964 return;
1965}
1966
1967#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
1968/**
1969 * lim_send_reassoc_req_with_ft_ies_mgmt_frame() - Send Reassoc Req with FTIEs.
1970 *
1971 * @mac_ctx: Handle to mac context
1972 * @mlm_reassoc_req: Original reassoc request
1973 * @pe_session: PE session information
1974 *
1975 * It builds a reassoc request with FT IEs and sends it to AP through WMA.
1976 * Then it creates assoc request and stores it for sending after join
1977 * confirmation.
1978 *
1979 * Return: void
1980 */
1981
1982void
1983lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal mac_ctx,
1984 tLimMlmReassocReq *mlm_reassoc_req,
1985 tpPESession pe_session)
1986{
1987 static tDot11fReAssocRequest frm;
1988 uint16_t caps;
1989 uint8_t *frame;
1990 uint32_t bytes, payload, status;
1991 uint8_t qos_enabled, wme_enabled, wsm_enabled;
1992 void *packet;
1993 CDF_STATUS cdf_status;
1994#if defined WLAN_FEATURE_VOWIFI
1995 uint8_t power_caps_populated = false;
1996#endif
1997 uint16_t ft_ies_length = 0;
1998 uint8_t *body;
1999 uint16_t add_ie_len;
2000 uint8_t *add_ie;
2001#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2002 uint8_t *wps_ie = NULL;
2003#endif
2004 uint8_t tx_flag = 0;
2005 uint8_t sme_sessionid = 0;
2006 bool vht_enabled = false;
2007 tpSirMacMgmtHdr mac_hdr;
2008 tftSMEContext *ft_sme_context;
2009
2010 if (NULL == pe_session)
2011 return;
2012
2013 sme_sessionid = pe_session->smeSessionId;
2014
2015 /* check this early to avoid unncessary operation */
2016 if (NULL == pe_session->pLimReAssocReq)
2017 return;
2018
2019 add_ie_len = pe_session->pLimReAssocReq->addIEAssoc.length;
2020 add_ie = pe_session->pLimReAssocReq->addIEAssoc.addIEdata;
2021 lim_log(mac_ctx, LOG1,
2022 FL("called in state (%d)."), pe_session->limMlmState);
2023
2024 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
2025
2026 caps = mlm_reassoc_req->capabilityInfo;
2027#if defined(FEATURE_WLAN_WAPI)
2028 /*
2029 * According to WAPI standard:
2030 * 7.3.1.4 Capability Information field
2031 * In WAPI, non-AP STAs within an ESS set the Privacy subfield
2032 * to 0 in transmitted Association or Reassociation management
2033 * frames. APs ignore the Privacy subfield within received
2034 * Association and Reassociation management frames.
2035 */
2036 if (pe_session->encryptType == eSIR_ED_WPI)
2037 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
2038#endif
2039 swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);
2040
2041 frm.ListenInterval.interval = mlm_reassoc_req->listenInterval;
2042
2043 /*
2044 * Get the old bssid of the older AP.
2045 * The previous ap bssid is stored in the FT Session
2046 * while creating the PE FT Session for reassociation.
2047 */
2048 cdf_mem_copy((uint8_t *)frm.CurrentAPAddress.mac,
2049 pe_session->prev_ap_bssid, sizeof(tSirMacAddr));
2050
2051 populate_dot11f_ssid2(mac_ctx, &frm.SSID);
2052 populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
2053 &frm.SuppRates, pe_session);
2054
2055 qos_enabled = (pe_session->limQosEnabled) &&
2056 SIR_MAC_GET_QOS(pe_session->limReassocBssCaps);
2057
2058 wme_enabled = (pe_session->limWmeEnabled) &&
2059 LIM_BSS_CAPS_GET(WME, pe_session->limReassocBssQosCaps);
2060
2061 wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
2062 LIM_BSS_CAPS_GET(WSM, pe_session->limReassocBssQosCaps);
2063
2064 if (pe_session->lim11hEnable &&
2065 pe_session->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
2066#if defined WLAN_FEATURE_VOWIFI
2067 power_caps_populated = true;
2068
2069 populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
2070 LIM_REASSOC, pe_session);
2071 populate_dot11f_supp_channels(mac_ctx, &frm.SuppChannels,
2072 LIM_REASSOC, pe_session);
2073#endif
2074 }
2075#if defined WLAN_FEATURE_VOWIFI
2076 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
2077 SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
2078 if (power_caps_populated == false) {
2079 power_caps_populated = true;
2080 populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
2081 LIM_REASSOC, pe_session);
2082 }
2083 }
2084#endif
2085
2086 if (qos_enabled)
2087 populate_dot11f_qos_caps_station(mac_ctx, &frm.QOSCapsStation);
2088
2089 populate_dot11f_ext_supp_rates(mac_ctx,
2090 POPULATE_DOT11F_RATES_OPERATIONAL, &frm.ExtSuppRates,
2091 pe_session);
2092
2093#if defined WLAN_FEATURE_VOWIFI
2094 if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
2095 SIR_MAC_GET_RRM(pe_session->limReassocBssCaps)) {
2096 populate_dot11f_rrm_ie(mac_ctx, &frm.RRMEnabledCap, pe_session);
2097 }
2098#endif
2099
2100 /*
2101 * Ideally this should be enabled for 11r also. But 11r does
2102 * not follow the usual norm of using the Opaque object
2103 * for rsnie and fties. Instead we just add the rsnie and fties
2104 * at the end of the pack routine for 11r.
2105 * This should ideally! be fixed.
2106 */
2107#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2108 /*
2109 * The join request *should* contain zero or one of the WPA and RSN
2110 * IEs. The payload send along with the request is a
2111 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
2112 *
2113 * typedef struct sSirRSNie
2114 * {
2115 * uint16_t length;
2116 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
2117 * } tSirRSNie, *tpSirRSNie;
2118 *
2119 * So, we should be able to make the following two calls harmlessly,
2120 * since they do nothing if they don't find the given IE in the
2121 * bytestream with which they're provided.
2122 *
2123 * The net effect of this will be to faithfully transmit whatever
2124 * security IE is in the join request.
2125
2126 * However, if we're associating for the purpose of WPS
2127 * enrollment, and we've been configured to indicate that by
2128 * eliding the WPA or RSN IE, we just skip this:
2129 */
2130 if (!pe_session->is11Rconnection) {
2131 if (add_ie_len && add_ie)
2132 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
2133 if (NULL == wps_ie) {
2134 populate_dot11f_rsn_opaque(mac_ctx,
2135 &(pe_session->pLimReAssocReq->rsnIE),
2136 &frm.RSNOpaque);
2137 populate_dot11f_wpa_opaque(mac_ctx,
2138 &(pe_session->pLimReAssocReq->rsnIE),
2139 &frm.WPAOpaque);
2140 }
2141#ifdef FEATURE_WLAN_ESE
2142 if (pe_session->pLimReAssocReq->cckmIE.length) {
2143 populate_dot11f_ese_cckm_opaque(mac_ctx,
2144 &(pe_session->pLimReAssocReq->cckmIE),
2145 &frm.ESECckmOpaque);
2146 }
2147#endif
2148 }
2149#ifdef FEATURE_WLAN_ESE
2150 /*
2151 * ESE Version IE will be included in re-association request
2152 * when ESE is enabled on DUT through ini and it is also
2153 * advertised by the peer AP to which we are trying to
2154 * associate to.
2155 */
2156 if (pe_session->is_ese_version_ie_present &&
2157 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
2158 populate_dot11f_ese_version(&frm.ESEVersion);
2159 /* For ESE Associations fill the ESE IEs */
2160 if (pe_session->isESEconnection &&
2161 pe_session->pLimReAssocReq->isESEFeatureIniEnabled) {
2162#ifndef FEATURE_DISABLE_RM
2163 populate_dot11f_ese_rad_mgmt_cap(&frm.ESERadMgmtCap);
2164#endif
2165 }
2166#endif /* FEATURE_WLAN_ESE */
2167#endif /* FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
2168
2169 /* include WME EDCA IE as well */
2170 if (wme_enabled) {
2171 populate_dot11f_wmm_info_station_per_session(mac_ctx,
2172 pe_session, &frm.WMMInfoStation);
2173 if (wsm_enabled)
2174 populate_dot11f_wmm_caps(&frm.WMMCaps);
2175#ifdef FEATURE_WLAN_ESE
2176 if (pe_session->isESEconnection) {
2177 uint32_t phymode;
2178 uint8_t rate;
2179
2180 populate_dot11f_re_assoc_tspec(mac_ctx, &frm,
2181 pe_session);
2182
2183 /*
2184 * Populate the TSRS IE if TSPEC is included in
2185 * the reassoc request
2186 */
2187 lim_get_phy_mode(mac_ctx, &phymode, pe_session);
2188 if (phymode == WNI_CFG_PHY_MODE_11G ||
2189 phymode == WNI_CFG_PHY_MODE_11A)
2190 rate = TSRS_11AG_RATE_6MBPS;
2191 else
2192 rate = TSRS_11B_RATE_5_5MBPS;
2193
2194 if (pe_session->pLimReAssocReq->eseTspecInfo.
2195 numTspecs) {
2196 tSirMacESETSRSIE tsrs_ie;
2197
2198 tsrs_ie.tsid = 0;
2199 tsrs_ie.rates[0] = rate;
2200 populate_dot11_tsrsie(mac_ctx, &tsrs_ie,
2201 &frm.ESETrafStrmRateSet,
2202 sizeof(uint8_t));
2203 }
2204 }
2205#endif
2206 }
2207
2208 ft_sme_context = &mac_ctx->roam.roamSession[sme_sessionid].ftSmeContext;
2209 if (pe_session->htCapability &&
2210 mac_ctx->lim.htCapabilityPresentInBeacon) {
2211 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm.HTCaps);
2212 }
2213#if defined WLAN_FEATURE_VOWIFI_11R
2214 if (pe_session->pLimReAssocReq->bssDescription.mdiePresent &&
2215 (ft_sme_context->addMDIE == true)
2216#if defined FEATURE_WLAN_ESE
2217 && !pe_session->isESEconnection
2218#endif
2219 ) {
2220 populate_mdie(mac_ctx, &frm.MobilityDomain,
2221 pe_session->pLimReAssocReq->bssDescription.mdie);
2222 }
2223#endif
2224
2225#ifdef WLAN_FEATURE_11AC
2226 if (pe_session->vhtCapability &&
2227 pe_session->vhtCapabilityPresentInBeacon) {
2228 lim_log(mac_ctx, LOG1,
2229 FL("Populate VHT IEs in Re-Assoc Request"));
2230 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm.VHTCaps);
2231 vht_enabled = true;
2232 populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm.ExtCap,
2233 pe_session);
2234 }
2235 if (!vht_enabled &&
2236 pe_session->is_vendor_specific_vhtcaps) {
2237 lim_log(mac_ctx, LOG1,
2238 FL("Populate Vendor VHT IEs in Re-Assoc Request"));
2239 frm.vendor2_ie.present = 1;
2240 frm.vendor2_ie.type =
2241 pe_session->vendor_specific_vht_ie_type;
2242 frm.vendor2_ie.sub_type =
2243 pe_session->vendor_specific_vht_ie_sub_type;
2244 frm.vendor2_ie.VHTCaps.present = 1;
2245 populate_dot11f_vht_caps(mac_ctx, pe_session,
2246 &frm.vendor2_ie.VHTCaps);
2247 vht_enabled = true;
2248 }
2249#endif
2250
2251 status = dot11f_get_packed_re_assoc_request_size(mac_ctx, &frm,
2252 &payload);
2253 if (DOT11F_FAILED(status)) {
2254 lim_log(mac_ctx, LOGP,
2255 FL("Failure in size calculation (0x%08x)."), status);
2256 /* We'll fall back on the worst case scenario: */
2257 payload = sizeof(tDot11fReAssocRequest);
2258 } else if (DOT11F_WARNED(status)) {
2259 lim_log(mac_ctx, LOGW,
2260 FL("Warnings in size calculation(0x%08x)."), status);
2261 }
2262
2263 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
2264
2265#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
2266 lim_log(mac_ctx, LOG1, FL("FT IE Reassoc Req (%d)."),
2267 ft_sme_context->reassoc_ft_ies_length);
2268#endif
2269
2270#if defined WLAN_FEATURE_VOWIFI_11R
2271 if (pe_session->is11Rconnection)
2272 ft_ies_length = ft_sme_context->reassoc_ft_ies_length;
2273#endif
2274
2275 cdf_status = cds_packet_alloc((uint16_t) bytes + ft_ies_length,
2276 (void **)&frame, (void **)&packet);
2277 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2278 pe_session->limMlmState = pe_session->limPrevMlmState;
2279 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
2280 pe_session->peSessionId,
2281 pe_session->limMlmState));
2282 lim_log(mac_ctx, LOGP, FL("Failed to alloc memory %d"), bytes);
2283 goto end;
2284 }
2285 /* Paranoia: */
2286 cdf_mem_set(frame, bytes + ft_ies_length, 0);
2287
2288#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2289 lim_print_mac_addr(mac_ctx, pe_session->limReAssocbssId, LOG1);
2290#endif
2291 /* Next, we fill out the buffer descriptor: */
2292 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2293 SIR_MAC_MGMT_REASSOC_REQ, pe_session->limReAssocbssId,
2294 pe_session->selfMacAddr);
2295 mac_hdr = (tpSirMacMgmtHdr) frame;
2296 /* That done, pack the ReAssoc Request: */
2297 status = dot11f_pack_re_assoc_request(mac_ctx, &frm, frame +
2298 sizeof(tSirMacMgmtHdr),
2299 payload, &payload);
2300 if (DOT11F_FAILED(status)) {
2301 lim_log(mac_ctx, LOGE, FL("Failure in pack (0x%08x)."), status);
2302 cds_packet_free((void *)packet);
2303 goto end;
2304 } else if (DOT11F_WARNED(status)) {
2305 lim_log(mac_ctx, LOGW, FL("Warnings in pack (0x%08x)."),
2306 status);
2307 }
2308
2309 lim_log(mac_ctx, LOG3,
2310 FL("*** Sending Re-Assoc Request length %d %d to "),
2311 bytes, payload);
2312
2313 if (pe_session->assocReq != NULL) {
2314 cdf_mem_free(pe_session->assocReq);
2315 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002316 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002317 }
2318
2319 if (add_ie_len) {
2320 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
2321 add_ie, add_ie_len);
2322 payload += add_ie_len;
2323 }
2324
2325 pe_session->assocReq = cdf_mem_malloc(payload);
2326 if (NULL == pe_session->assocReq) {
2327 lim_log(mac_ctx, LOGE, FL("Failed to alloc memory"));
2328 } else {
2329 /*
2330 * Store the Assoc request. This is sent to csr/hdd in
2331 * join cnf response.
2332 */
2333 cdf_mem_copy(pe_session->assocReq,
2334 frame + sizeof(tSirMacMgmtHdr), payload);
2335 pe_session->assocReqLen = payload;
2336 }
2337
2338 if (pe_session->is11Rconnection && ft_sme_context->reassoc_ft_ies) {
2339 int i = 0;
2340
2341 body = frame + bytes;
2342 for (i = 0; i < ft_ies_length; i++) {
2343 *body = ft_sme_context->reassoc_ft_ies[i];
2344 body++;
2345 }
2346 }
2347#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
2348 PELOGE(lim_log(mac_ctx, LOG1, FL("Re-assoc Req Frame is: "));
2349 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG1,
2350 (uint8_t *) frame, (bytes + ft_ies_length));
2351 )
2352#endif
2353 if ((SIR_BAND_5_GHZ ==
2354 lim_get_rf_band(pe_session->currentOperChannel)) ||
2355 (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
2356 (pe_session->pePersona == CDF_P2P_GO_MODE)) {
2357 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2358 }
2359
2360 if (NULL != pe_session->assocReq) {
2361 cdf_mem_free(pe_session->assocReq);
2362 pe_session->assocReq = NULL;
2363 }
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002364 if (ft_ies_length) {
2365 pe_session->assocReq = cdf_mem_malloc(ft_ies_length);
2366 if (NULL == pe_session->assocReq) {
2367 lim_log(mac_ctx,
2368 LOGE, FL("Failed to alloc memory for FT IEs"));
2369 pe_session->assocReqLen = 0;
2370 } else {
2371 /*
2372 * Store the FT IEs. This is sent to csr/hdd in
2373 * join cnf response.
2374 */
2375 cdf_mem_copy(pe_session->assocReq,
2376 ft_sme_context->reassoc_ft_ies, ft_ies_length);
2377 pe_session->assocReqLen = ft_ies_length;
2378 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002379 } else {
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002380 lim_log(mac_ctx, LOG1, FL("FT IEs not present"));
Naveen Rawat83102ef2015-11-03 10:42:34 -08002381 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002382 }
2383
2384#ifdef FEATURE_WLAN_DIAG_SUPPORT
2385 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_START_EVENT,
2386 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2387#endif
2388 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
2389 pe_session->peSessionId, mac_hdr->fc.subType));
2390 cdf_status = wma_tx_frame(mac_ctx, packet,
2391 (uint16_t) (bytes + ft_ies_length),
2392 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2393 lim_tx_complete, frame, tx_flag, sme_sessionid,
2394 0);
2395 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2396 pe_session->peSessionId, cdf_status));
2397 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2398 lim_log(mac_ctx, LOGE,
2399 FL("Failed to send Re-Assoc Request (%X)!"),
2400 cdf_status);
2401 }
2402
2403end:
2404 /* Free up buffer allocated for mlmAssocReq */
2405 cdf_mem_free(mlm_reassoc_req);
2406 pe_session->pLimMlmReassocReq = NULL;
2407
2408}
2409
2410void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
2411 tLimMlmReassocReq *pMlmReassocReq,
2412 tpPESession psessionEntry)
2413{
2414 tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
2415 tLimMlmReassocReq *pTmpMlmReassocReq = NULL;
2416 if (NULL == pTmpMlmReassocReq) {
2417 pTmpMlmReassocReq = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
2418 if (NULL == pTmpMlmReassocReq)
2419 goto end;
2420 cdf_mem_set(pTmpMlmReassocReq, sizeof(tLimMlmReassocReq), 0);
2421 cdf_mem_copy(pTmpMlmReassocReq, pMlmReassocReq,
2422 sizeof(tLimMlmReassocReq));
2423 }
2424 /* Prepare and send Reassociation request frame */
2425 /* start reassoc timer. */
2426 pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
2427 psessionEntry->peSessionId;
2428 /* Start reassociation failure timer */
2429 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE,
2430 psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
2431 if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
2432 != TX_SUCCESS) {
2433 /* Could not start reassoc failure timer. */
2434 /* Log error */
2435 lim_log(pMac, LOGP,
2436 FL("could not start Reassociation failure timer"));
2437 /* Return Reassoc confirm with */
2438 /* Resources Unavailable */
2439 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
2440 mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2441 goto end;
2442 }
2443
2444 lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac, pTmpMlmReassocReq,
2445 psessionEntry);
2446 return;
2447
2448end:
2449 /* Free up buffer allocated for reassocReq */
2450 if (pMlmReassocReq != NULL) {
2451 cdf_mem_free(pMlmReassocReq);
2452 pMlmReassocReq = NULL;
2453 }
2454 if (pTmpMlmReassocReq != NULL) {
2455 cdf_mem_free(pTmpMlmReassocReq);
2456 pTmpMlmReassocReq = NULL;
2457 }
2458 mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
2459 mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2460 /* Update PE sessio Id */
2461 mlmReassocCnf.sessionId = psessionEntry->peSessionId;
2462
2463 lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
2464 (uint32_t *) &mlmReassocCnf);
2465}
2466
2467#endif /* WLAN_FEATURE_VOWIFI_11R */
2468
2469void
2470lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal pMac,
2471 tLimMlmReassocReq *pMlmReassocReq,
2472 tpPESession psessionEntry)
2473{
2474 static tDot11fReAssocRequest frm;
2475 uint16_t caps;
2476 uint8_t *pFrame;
2477 uint32_t nBytes, nPayload, nStatus;
2478 uint8_t fQosEnabled, fWmeEnabled, fWsmEnabled;
2479 void *pPacket;
2480 CDF_STATUS cdf_status;
2481 uint16_t nAddIELen;
2482 uint8_t *pAddIE;
2483 uint8_t *wpsIe = NULL;
2484 uint8_t txFlag = 0;
2485#if defined WLAN_FEATURE_VOWIFI
2486 uint8_t PowerCapsPopulated = false;
2487#endif
2488 uint8_t smeSessionId = 0;
2489 bool isVHTEnabled = false;
2490 tpSirMacMgmtHdr pMacHdr;
2491
2492 if (NULL == psessionEntry) {
2493 return;
2494 }
2495
2496 smeSessionId = psessionEntry->smeSessionId;
2497
2498 /* check this early to avoid unncessary operation */
2499 if (NULL == psessionEntry->pLimReAssocReq) {
2500 return;
2501 }
2502 nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
2503 pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;
2504
2505 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
2506
2507 caps = pMlmReassocReq->capabilityInfo;
2508#if defined(FEATURE_WLAN_WAPI)
2509 /* CR: 262463 :
2510 According to WAPI standard:
2511 7.3.1.4 Capability Information field
2512 In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
2513 Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
2514 Reassociation management frames. */
2515 if (psessionEntry->encryptType == eSIR_ED_WPI)
2516 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
2517#endif
2518 swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);
2519
2520 frm.ListenInterval.interval = pMlmReassocReq->listenInterval;
2521
2522 cdf_mem_copy((uint8_t *) frm.CurrentAPAddress.mac,
2523 (uint8_t *) psessionEntry->bssId, 6);
2524
2525 populate_dot11f_ssid2(pMac, &frm.SSID);
2526 populate_dot11f_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2527 &frm.SuppRates, psessionEntry);
2528
2529 fQosEnabled = (psessionEntry->limQosEnabled) &&
2530 SIR_MAC_GET_QOS(psessionEntry->limReassocBssCaps);
2531
2532 fWmeEnabled = (psessionEntry->limWmeEnabled) &&
2533 LIM_BSS_CAPS_GET(WME, psessionEntry->limReassocBssQosCaps);
2534
2535 fWsmEnabled = (psessionEntry->limWsmEnabled) && fWmeEnabled &&
2536 LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);
2537
2538 if (psessionEntry->lim11hEnable &&
2539 psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
2540#if defined WLAN_FEATURE_VOWIFI
2541 PowerCapsPopulated = true;
2542 populate_dot11f_power_caps(pMac, &frm.PowerCaps, LIM_REASSOC,
2543 psessionEntry);
2544 populate_dot11f_supp_channels(pMac, &frm.SuppChannels, LIM_REASSOC,
2545 psessionEntry);
2546#endif
2547 }
2548#if defined WLAN_FEATURE_VOWIFI
2549 if (pMac->rrm.rrmPEContext.rrmEnable &&
2550 SIR_MAC_GET_RRM(psessionEntry->limCurrentBssCaps)) {
2551 if (PowerCapsPopulated == false) {
2552 PowerCapsPopulated = true;
2553 populate_dot11f_power_caps(pMac, &frm.PowerCaps,
2554 LIM_REASSOC, psessionEntry);
2555 }
2556 }
2557#endif
2558
2559 if (fQosEnabled)
2560 populate_dot11f_qos_caps_station(pMac, &frm.QOSCapsStation);
2561
2562 populate_dot11f_ext_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2563 &frm.ExtSuppRates, psessionEntry);
2564
2565#if defined WLAN_FEATURE_VOWIFI
2566 if (pMac->rrm.rrmPEContext.rrmEnable &&
2567 SIR_MAC_GET_RRM(psessionEntry->limReassocBssCaps)) {
2568 populate_dot11f_rrm_ie(pMac, &frm.RRMEnabledCap, psessionEntry);
2569 }
2570#endif
2571 /* The join request *should* contain zero or one of the WPA and RSN */
2572 /* IEs. The payload send along with the request is a */
2573 /* 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': */
2574
2575 /* typedef struct sSirRSNie */
2576 /* { */
2577 /* uint16_t length; */
2578 /* uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
2579 /* } tSirRSNie, *tpSirRSNie; */
2580
2581 /* So, we should be able to make the following two calls harmlessly, */
2582 /* since they do nothing if they don't find the given IE in the */
2583 /* bytestream with which they're provided. */
2584
2585 /* The net effect of this will be to faithfully transmit whatever */
2586 /* security IE is in the join request. */
2587
2588 /**However*, if we're associating for the purpose of WPS */
2589 /* enrollment, and we've been configured to indicate that by */
2590 /* eliding the WPA or RSN IE, we just skip this: */
2591 if (nAddIELen && pAddIE) {
2592 wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
2593 }
2594 if (NULL == wpsIe) {
2595 populate_dot11f_rsn_opaque(pMac,
2596 &(psessionEntry->pLimReAssocReq->rsnIE),
2597 &frm.RSNOpaque);
2598 populate_dot11f_wpa_opaque(pMac,
2599 &(psessionEntry->pLimReAssocReq->rsnIE),
2600 &frm.WPAOpaque);
2601#if defined(FEATURE_WLAN_WAPI)
2602 populate_dot11f_wapi_opaque(pMac,
2603 &(psessionEntry->pLimReAssocReq->
2604 rsnIE), &frm.WAPIOpaque);
2605#endif /* defined(FEATURE_WLAN_WAPI) */
2606 }
2607 /* include WME EDCA IE as well */
2608 if (fWmeEnabled) {
2609 populate_dot11f_wmm_info_station_per_session(pMac,
2610 psessionEntry,
2611 &frm.WMMInfoStation);
2612
2613 if (fWsmEnabled)
2614 populate_dot11f_wmm_caps(&frm.WMMCaps);
2615 }
2616
2617 if (psessionEntry->htCapability &&
2618 pMac->lim.htCapabilityPresentInBeacon) {
2619 populate_dot11f_ht_caps(pMac, psessionEntry, &frm.HTCaps);
2620 }
2621#ifdef WLAN_FEATURE_11AC
2622 if (psessionEntry->vhtCapability &&
2623 psessionEntry->vhtCapabilityPresentInBeacon) {
2624 lim_log(pMac, LOGW, FL("Populate VHT IEs in Re-Assoc Request"));
2625 populate_dot11f_vht_caps(pMac, psessionEntry, &frm.VHTCaps);
2626 isVHTEnabled = true;
2627 }
2628#endif
2629
2630 populate_dot11f_ext_cap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry);
2631
2632 nStatus = dot11f_get_packed_re_assoc_request_size(pMac, &frm, &nPayload);
2633 if (DOT11F_FAILED(nStatus)) {
2634 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
2635 "or a Re-Association Request (0x%08x)."),
2636 nStatus);
2637 /* We'll fall back on the worst case scenario: */
2638 nPayload = sizeof(tDot11fReAssocRequest);
2639 } else if (DOT11F_WARNED(nStatus)) {
2640 lim_log(pMac, LOGW, FL("There were warnings while calculating "
2641 "the packed size for a Re-Association Re "
2642 "quest(0x%08x)."), nStatus);
2643 }
2644
2645 nBytes = nPayload + sizeof(tSirMacMgmtHdr) + nAddIELen;
2646
2647 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
2648 (void **)&pPacket);
2649 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2650 psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
2651 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
2652 psessionEntry->peSessionId,
2653 psessionEntry->limMlmState));
2654 lim_log(pMac, LOGP,
2655 FL("Failed to allocate %d bytes for a Re-As"
2656 "sociation Request."), nBytes);
2657 goto end;
2658 }
2659 /* Paranoia: */
2660 cdf_mem_set(pFrame, nBytes, 0);
2661
2662 /* Next, we fill out the buffer descriptor: */
2663 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2664 SIR_MAC_MGMT_REASSOC_REQ, psessionEntry->limReAssocbssId,
2665 psessionEntry->selfMacAddr);
2666 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2667
2668 /* That done, pack the Probe Request: */
2669 nStatus = dot11f_pack_re_assoc_request(pMac, &frm, pFrame +
2670 sizeof(tSirMacMgmtHdr),
2671 nPayload, &nPayload);
2672 if (DOT11F_FAILED(nStatus)) {
2673 lim_log(pMac, LOGE, FL("Failed to pack a Re-Association Reque"
2674 "st (0x%08x)."), nStatus);
2675 cds_packet_free((void *)pPacket);
2676 goto end;
2677 } else if (DOT11F_WARNED(nStatus)) {
2678 lim_log(pMac, LOGW, FL("There were warnings while packing a R"
2679 "e-Association Request (0x%08x)."),
2680 nStatus);
2681 }
2682
2683 PELOG1(lim_log
2684 (pMac, LOG1,
2685 FL("*** Sending Re-Association Request length %d" "to "),
2686 nBytes);
2687 )
2688
2689 if (psessionEntry->assocReq != NULL) {
2690 cdf_mem_free(psessionEntry->assocReq);
2691 psessionEntry->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002692 psessionEntry->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693 }
2694
2695 if (nAddIELen) {
2696 cdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
2697 pAddIE, nAddIELen);
2698 nPayload += nAddIELen;
2699 }
2700
2701 psessionEntry->assocReq = cdf_mem_malloc(nPayload);
2702 if (NULL == psessionEntry->assocReq) {
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002703 lim_log(pMac, LOGE, FL("Unable to allocate mem for assoc req"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002704 } else {
2705 /* Store the Assoc request. This is sent to csr/hdd in join cnf response. */
2706 cdf_mem_copy(psessionEntry->assocReq,
2707 pFrame + sizeof(tSirMacMgmtHdr), nPayload);
2708 psessionEntry->assocReqLen = nPayload;
2709 }
2710
2711 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
2712 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
2713 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
2714 ) {
2715 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2716 }
2717
2718 if (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) {
2719 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
2720 }
2721
2722#ifdef FEATURE_WLAN_DIAG_SUPPORT
2723 lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT,
2724 psessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
2725#endif
2726 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
2727 psessionEntry->peSessionId, pMacHdr->fc.subType));
2728 cdf_status =
2729 wma_tx_frame(pMac, pPacket,
2730 (uint16_t) (sizeof(tSirMacMgmtHdr) + nPayload),
2731 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2732 lim_tx_complete, pFrame, txFlag, smeSessionId, 0);
2733 MTRACE(cdf_trace
2734 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2735 psessionEntry->peSessionId, cdf_status));
2736 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2737 lim_log(pMac, LOGE,
2738 FL("Failed to send Re-Association Request (%X)!"),
2739 cdf_status);
2740 /* Pkt will be freed up by the callback */
2741 }
2742
2743end:
2744 /* Free up buffer allocated for mlmAssocReq */
2745 cdf_mem_free(pMlmReassocReq);
2746 psessionEntry->pLimMlmReassocReq = NULL;
2747
2748} /* lim_send_reassoc_req_mgmt_frame */
2749
2750/**
2751 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2752 *
2753 * @mac_ctx: Pointer to Global MAC structure
2754 * @auth_frame: Pointer to Authentication frame structure
2755 * @peer_addr: MAC address of destination peer
2756 * @wep_bit: wep bit in frame control for Authentication frame3
2757 * @session: PE session information
2758 *
2759 * This function is called by lim_process_mlm_messages(). Authentication frame
2760 * is formatted and sent when this function is called.
2761 *
2762 * Return: void
2763 */
2764
2765void
2766lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2767 tpSirMacAuthFrameBody auth_frame,
2768 tSirMacAddr peer_addr,
2769 uint8_t wep_bit, tpPESession session)
2770{
2771 uint8_t *frame, *body;
2772 uint32_t frame_len = 0, body_len = 0;
2773 tpSirMacMgmtHdr mac_hdr;
2774 void *packet;
2775 CDF_STATUS cdf_status;
2776 uint8_t tx_flag = 0;
2777 uint8_t sme_sessionid = 0;
2778 uint16_t ft_ies_length = 0;
2779
2780 if (NULL == session) {
2781 lim_log(mac_ctx, LOGE, FL("Error: psession Entry is NULL"));
2782 return;
2783 }
2784
2785 sme_sessionid = session->smeSessionId;
2786
2787 lim_log(mac_ctx, LOG1,
2788 FL("Sending Auth seq# %d status %d (%d) to " MAC_ADDRESS_STR),
2789 auth_frame->authTransactionSeqNumber,
2790 auth_frame->authStatusCode,
2791 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
2792 MAC_ADDR_ARRAY(peer_addr));
2793
2794 switch (auth_frame->authTransactionSeqNumber) {
2795 case SIR_MAC_AUTH_FRAME_1:
2796 /*
2797 * Allocate buffer for Authenticaton frame of size
2798 * equal to management frame header length plus 2 bytes
2799 * each for auth algorithm number, transaction number
2800 * and status code.
2801 */
2802
2803 frame_len = sizeof(tSirMacMgmtHdr) +
2804 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2805 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2806
2807#if defined WLAN_FEATURE_VOWIFI_11R
2808 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2809 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2810 0 != session->ftPEContext.pFTPreAuthReq->
2811 ft_ies_length) {
2812 ft_ies_length = session->ftPEContext.
2813 pFTPreAuthReq->ft_ies_length;
2814 frame_len += ft_ies_length;
2815 lim_log(mac_ctx, LOG3,
2816 FL("Auth frame, FTIES length added=%d"),
2817 ft_ies_length);
2818 } else {
2819 lim_log(mac_ctx, LOG3,
2820 FL("Auth frame, Does not contain FTIES!!!"));
2821 frame_len += (2 + SIR_MDIE_SIZE);
2822 }
2823 }
2824#endif
2825 break;
2826
2827 case SIR_MAC_AUTH_FRAME_2:
2828 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2829 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2830 (auth_frame->authStatusCode !=
2831 eSIR_MAC_SUCCESS_STATUS))) {
2832 /*
2833 * Allocate buffer for Authenticaton frame of size
2834 * equal to management frame header length plus
2835 * 2 bytes each for auth algorithm number,
2836 * transaction number and status code.
2837 */
2838
2839 frame_len = sizeof(tSirMacMgmtHdr) +
2840 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2841 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2842 } else {
2843 /*
2844 * Shared Key algorithm with challenge text
2845 * to be sent.
2846 *
2847 * Allocate buffer for Authenticaton frame of size
2848 * equal to management frame header length plus
2849 * 2 bytes each for auth algorithm number,
2850 * transaction number, status code and 128 bytes
2851 * for challenge text.
2852 */
2853
2854 frame_len = sizeof(tSirMacMgmtHdr) +
2855 sizeof(tSirMacAuthFrame);
2856 body_len = sizeof(tSirMacAuthFrameBody);
2857 }
2858 break;
2859
2860 case SIR_MAC_AUTH_FRAME_3:
2861 if (wep_bit == LIM_WEP_IN_FC) {
2862 /*
2863 * Auth frame3 to be sent with encrypted framebody
2864 *
2865 * Allocate buffer for Authenticaton frame of size
2866 * equal to management frame header length plus 2 bytes
2867 * each for auth algorithm number, transaction number,
2868 * status code, 128 bytes for challenge text and
2869 * 4 bytes each for IV & ICV.
2870 */
2871
2872 frame_len = sizeof(tSirMacMgmtHdr) +
2873 LIM_ENCR_AUTH_BODY_LEN;
2874 body_len = LIM_ENCR_AUTH_BODY_LEN;
2875 } else {
2876
2877 /*
2878 * Auth frame3 to be sent without encrypted framebody
2879 *
2880 * Allocate buffer for Authenticaton frame of size equal
2881 * to management frame header length plus 2 bytes each
2882 * for auth algorithm number, transaction number and
2883 * status code.
2884 */
2885
2886 frame_len = sizeof(tSirMacMgmtHdr) +
2887 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2888 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2889 }
2890 break;
2891
2892 case SIR_MAC_AUTH_FRAME_4:
2893 /*
2894 * Allocate buffer for Authenticaton frame of size equal
2895 * to management frame header length plus 2 bytes each
2896 * for auth algorithm number, transaction number and
2897 * status code.
2898 */
2899
2900 frame_len = sizeof(tSirMacMgmtHdr) +
2901 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2902 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2903
2904 break;
2905 } /* switch (auth_frame->authTransactionSeqNumber) */
2906
2907 cdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
2908 (void **)&packet);
2909
2910 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2911 lim_log(mac_ctx, LOGP,
2912 FL("call to bufAlloc failed for AUTH frame"));
2913 return;
2914 }
2915
2916 cdf_mem_zero(frame, frame_len);
2917
2918 /* Prepare BD */
2919 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2920 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2921 mac_hdr = (tpSirMacMgmtHdr) frame;
2922 mac_hdr->fc.wep = wep_bit;
2923
2924 /* Prepare BSSId */
2925 if (LIM_IS_AP_ROLE(session) ||
2926 LIM_IS_BT_AMP_AP_ROLE(session))
2927 cdf_mem_copy((uint8_t *) mac_hdr->bssId,
2928 (uint8_t *) session->bssId,
2929 sizeof(tSirMacAddr));
2930
2931 /* Prepare Authentication frame body */
2932 body = frame + sizeof(tSirMacMgmtHdr);
2933
2934 if (wep_bit == LIM_WEP_IN_FC) {
2935 cdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
2936
2937 lim_log(mac_ctx, LOG1,
2938 FL("*** Sending Auth seq# 3 status %d (%d) to"
2939 MAC_ADDRESS_STR),
2940 auth_frame->authStatusCode,
2941 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
2942 MAC_ADDR_ARRAY(mac_hdr->da));
2943
2944 } else {
2945 *((uint16_t *) (body)) =
2946 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2947 body += sizeof(uint16_t);
2948 body_len -= sizeof(uint16_t);
2949
2950 *((uint16_t *) (body)) =
2951 sir_swap_u16if_needed(
2952 auth_frame->authTransactionSeqNumber);
2953 body += sizeof(uint16_t);
2954 body_len -= sizeof(uint16_t);
2955
2956 *((uint16_t *) (body)) =
2957 sir_swap_u16if_needed(auth_frame->authStatusCode);
2958 body += sizeof(uint16_t);
2959 body_len -= sizeof(uint16_t);
2960 if (body_len <= (sizeof(auth_frame->type) +
2961 sizeof(auth_frame->length) +
2962 sizeof(auth_frame->challengeText)))
2963 cdf_mem_copy(body, (uint8_t *) &auth_frame->type,
2964 body_len);
2965
2966#if defined WLAN_FEATURE_VOWIFI_11R
2967 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2968 (auth_frame->authTransactionSeqNumber ==
2969 SIR_MAC_AUTH_FRAME_1) &&
2970 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2971
2972 if (ft_ies_length > 0) {
2973 cdf_mem_copy(body,
2974 session->ftPEContext.
2975 pFTPreAuthReq->ft_ies,
2976 ft_ies_length);
2977#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
2978 lim_log(mac_ctx, LOG2,
2979 FL("Auth1 Frame FTIE is: "));
2980 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
2981 (uint8_t *) body,
2982 ft_ies_length);
2983#endif
2984 } else if (NULL != session->ftPEContext.
2985 pFTPreAuthReq->pbssDescription) {
2986 /* MDID attr is 54 */
2987 *body = SIR_MDIE_ELEMENT_ID;
2988 body++;
2989 *body = SIR_MDIE_SIZE;
2990 body++;
2991 cdf_mem_copy(body,
2992 &session->ftPEContext.pFTPreAuthReq->
2993 pbssDescription->mdie[0],
2994 SIR_MDIE_SIZE);
2995 }
2996 }
2997#endif
2998
2999 lim_log(mac_ctx, LOG1,
3000 FL("*** Sending Auth seq# %d status %d (%d) to "
3001 MAC_ADDRESS_STR),
3002 auth_frame->authTransactionSeqNumber,
3003 auth_frame->authStatusCode,
3004 (auth_frame->authStatusCode ==
3005 eSIR_MAC_SUCCESS_STATUS),
3006 MAC_ADDR_ARRAY(mac_hdr->da));
3007 }
3008 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2, frame, frame_len);
3009
3010 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
3011 || (session->pePersona == CDF_P2P_CLIENT_MODE)
3012 || (session->pePersona == CDF_P2P_GO_MODE)
3013#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
3014 || ((NULL != session->ftPEContext.pFTPreAuthReq) &&
3015 (SIR_BAND_5_GHZ ==
3016 lim_get_rf_band(session->ftPEContext.pFTPreAuthReq->
3017 preAuthchannelNum)))
3018#endif
3019 )
3020 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3021
3022
3023 if (session->pePersona == CDF_P2P_CLIENT_MODE)
3024 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
3025
3026
3027 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3028 session->peSessionId, mac_hdr->fc.subType));
3029 /* Queue Authentication frame in high priority WQ */
3030 cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
3031 TXRX_FRM_802_11_MGMT,
3032 ANI_TXDIR_TODS, 7, lim_tx_complete,
3033 frame, tx_flag, sme_sessionid, 0);
3034 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3035 session->peSessionId, cdf_status));
3036 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
3037 lim_log(mac_ctx, LOGE,
3038 FL("*** Could not send Auth frame, retCode=%X ***"),
3039 cdf_status);
3040
3041 return;
3042}
3043
3044CDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
3045{
3046 uint16_t aid;
3047 tpDphHashNode pStaDs;
3048 tLimMlmDeauthReq *pMlmDeauthReq;
3049 tLimMlmDeauthCnf mlmDeauthCnf;
3050 tpPESession psessionEntry;
3051
3052 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
3053 if (pMlmDeauthReq) {
3054 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
3055 lim_deactivate_and_change_timer(pMac,
3056 eLIM_DEAUTH_ACK_TIMER);
3057 }
3058
3059 psessionEntry = pe_find_session_by_session_id(pMac,
3060 pMlmDeauthReq->sessionId);
3061 if (psessionEntry == NULL) {
3062 PELOGE(lim_log(pMac, LOGE,
3063 FL
3064 ("session does not exist for given sessionId"));
3065 )
3066 mlmDeauthCnf.resultCode =
3067 eSIR_SME_INVALID_PARAMETERS;
3068 goto end;
3069 }
3070
3071 pStaDs =
3072 dph_lookup_hash_entry(pMac, pMlmDeauthReq->peerMacAddr, &aid,
3073 &psessionEntry->dph.dphHashTable);
3074 if (pStaDs == NULL) {
3075 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
3076 goto end;
3077 }
3078
3079 /* / Receive path cleanup with dummy packet */
3080 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
3081 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
3082 /* / Free up buffer allocated for mlmDeauthReq */
3083 cdf_mem_free(pMlmDeauthReq);
3084 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
3085 }
3086 return CDF_STATUS_SUCCESS;
3087end:
3088 cdf_mem_copy((uint8_t *) &mlmDeauthCnf.peerMacAddr,
3089 (uint8_t *) pMlmDeauthReq->peerMacAddr,
3090 sizeof(tSirMacAddr));
3091 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
3092 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
3093 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
3094
3095 /* Free up buffer allocated */
3096 /* for mlmDeauthReq */
3097 cdf_mem_free(pMlmDeauthReq);
3098
3099 lim_post_sme_message(pMac,
3100 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
3101 return CDF_STATUS_SUCCESS;
3102}
3103
3104/**
3105 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
3106 *
3107 * @mac_ctx: Handle to MAC context
3108 *
3109 * Sends disassoc confirmation to SME. Removes disassoc request stored
3110 * in lim.
3111 *
3112 * Return: CDF_STATUS_SUCCESS
3113 */
3114
3115CDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
3116{
3117 uint16_t aid;
3118 tpDphHashNode sta_ds;
3119 tLimMlmDisassocCnf disassoc_cnf;
3120 tpPESession pe_session;
3121 tLimMlmDisassocReq *disassoc_req;
3122
3123 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
3124 if (disassoc_req) {
3125 if (tx_timer_running(
3126 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
3127 lim_deactivate_and_change_timer(mac_ctx,
3128 eLIM_DISASSOC_ACK_TIMER);
3129
3130 pe_session = pe_find_session_by_session_id(
3131 mac_ctx, disassoc_req->sessionId);
3132 if (pe_session == NULL) {
3133 lim_log(mac_ctx, LOGE,
3134 FL("No session for given sessionId"));
3135 disassoc_cnf.resultCode =
3136 eSIR_SME_INVALID_PARAMETERS;
3137 goto end;
3138 }
3139
3140 sta_ds = dph_lookup_hash_entry(mac_ctx,
3141 disassoc_req->peerMacAddr, &aid,
3142 &pe_session->dph.dphHashTable);
3143 if (sta_ds == NULL) {
3144 lim_log(mac_ctx, LOGE, FL("StaDs Null"));
3145 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
3146 goto end;
3147 }
3148 /* Receive path cleanup with dummy packet */
3149 if (eSIR_SUCCESS !=
3150 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
3151 disassoc_cnf.resultCode =
3152 eSIR_SME_RESOURCES_UNAVAILABLE;
3153 lim_log(mac_ctx, LOGE, FL("cleanup_rx_path error"));
3154 goto end;
3155 }
3156#ifdef WLAN_FEATURE_VOWIFI_11R
3157 if (LIM_IS_STA_ROLE(pe_session) && (
3158#ifdef FEATURE_WLAN_ESE
3159 (pe_session->isESEconnection) ||
3160#endif
3161#ifdef FEATURE_WLAN_LFR
3162 (pe_session->isFastRoamIniFeatureEnabled) ||
3163#endif
3164 (pe_session->is11Rconnection)) &&
3165 (disassoc_req->reasonCode !=
3166 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
3167 lim_log(mac_ctx, LOGE,
3168 FL("FT Preauth Session (%p,%d) Clean up"),
3169 pe_session, pe_session->peSessionId);
3170
3171#if defined WLAN_FEATURE_VOWIFI_11R
3172 /* Delete FT session if there exists one */
3173 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
3174#endif
3175 } else {
3176 lim_log(mac_ctx, LOGE,
3177 FL("No FT Preauth Session Clean up in role %d"
3178#ifdef FEATURE_WLAN_ESE
3179 " isESE %d"
3180#endif
3181#ifdef FEATURE_WLAN_LFR
3182 " isLFR %d"
3183#endif
3184 " is11r %d reason %d"),
3185 GET_LIM_SYSTEM_ROLE(pe_session),
3186#ifdef FEATURE_WLAN_ESE
3187 pe_session->isESEconnection,
3188#endif
3189#ifdef FEATURE_WLAN_LFR
3190 pe_session->isFastRoamIniFeatureEnabled,
3191#endif
3192 pe_session->is11Rconnection,
3193 disassoc_req->reasonCode);
3194 }
3195#endif
3196 /* Free up buffer allocated for mlmDisassocReq */
3197 cdf_mem_free(disassoc_req);
3198 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
3199 return CDF_STATUS_SUCCESS;
3200 } else {
3201 return CDF_STATUS_SUCCESS;
3202 }
3203end:
3204 cdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
3205 (uint8_t *) disassoc_req->peerMacAddr,
3206 sizeof(tSirMacAddr));
3207 disassoc_cnf.aid = disassoc_req->aid;
3208 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
3209
3210 /* Update PE session ID */
3211 disassoc_cnf.sessionId = disassoc_req->sessionId;
3212
3213 if (disassoc_req != NULL) {
3214 /* / Free up buffer allocated for mlmDisassocReq */
3215 cdf_mem_free(disassoc_req);
3216 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
3217 }
3218
3219 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
3220 (uint32_t *) &disassoc_cnf);
3221 return CDF_STATUS_SUCCESS;
3222}
3223
3224CDF_STATUS lim_disassoc_tx_complete_cnf(tpAniSirGlobal pMac,
3225 uint32_t txCompleteSuccess)
3226{
3227 return lim_send_disassoc_cnf(pMac);
3228}
3229
3230CDF_STATUS lim_deauth_tx_complete_cnf(tpAniSirGlobal pMac,
3231 uint32_t txCompleteSuccess)
3232{
3233 return lim_send_deauth_cnf(pMac);
3234}
3235
3236/**
3237 * \brief This function is called to send Disassociate frame.
3238 *
3239 *
3240 * \param pMac Pointer to Global MAC structure
3241 *
3242 * \param nReason Indicates the reason that need to be sent in
3243 * Disassociation frame
3244 *
3245 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
3246 * sent
3247 *
3248 *
3249 */
3250
3251void
3252lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
3253 uint16_t nReason,
3254 tSirMacAddr peer,
3255 tpPESession psessionEntry, bool waitForAck)
3256{
3257 tDot11fDisassociation frm;
3258 uint8_t *pFrame;
3259 tpSirMacMgmtHdr pMacHdr;
3260 uint32_t nBytes, nPayload, nStatus;
3261 void *pPacket;
3262 CDF_STATUS cdf_status;
3263 uint8_t txFlag = 0;
3264 uint32_t val = 0;
3265 uint8_t smeSessionId = 0;
3266 if (NULL == psessionEntry) {
3267 return;
3268 }
3269
3270 /*
3271 * In case when cac timer is running for this SAP session then
3272 * avoid sending disassoc out. It is violation of dfs specification.
3273 */
3274 if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
3275 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
3276 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
3277 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
3278 FL
3279 ("CAC timer is running, drop disassoc from going out"));
3280 return;
3281 }
3282 smeSessionId = psessionEntry->smeSessionId;
3283
3284 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3285
3286 frm.Reason.code = nReason;
3287
3288 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
3289 if (DOT11F_FAILED(nStatus)) {
3290 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3291 "or a Disassociation (0x%08x)."),
3292 nStatus);
3293 /* We'll fall back on the worst case scenario: */
3294 nPayload = sizeof(tDot11fDisassociation);
3295 } else if (DOT11F_WARNED(nStatus)) {
3296 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3297 "the packed size for a Disassociation "
3298 "(0x%08x)."), nStatus);
3299 }
3300
3301 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3302
3303 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3304 (void **)&pPacket);
3305 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3306 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Dis"
3307 "association."), nBytes);
3308 return;
3309 }
3310 /* Paranoia: */
3311 cdf_mem_set(pFrame, nBytes, 0);
3312
3313 /* Next, we fill out the buffer descriptor: */
3314 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3315 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
3316 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3317
3318 /* Prepare the BSSID */
3319 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3320
3321#ifdef WLAN_FEATURE_11W
3322 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3323#endif
3324
3325 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
3326 sizeof(tSirMacMgmtHdr),
3327 nPayload, &nPayload);
3328 if (DOT11F_FAILED(nStatus)) {
3329 lim_log(pMac, LOGE,
3330 FL("Failed to pack a Disassociation (0x%08x)."),
3331 nStatus);
3332 cds_packet_free((void *)pPacket);
3333 return; /* allocated! */
3334 } else if (DOT11F_WARNED(nStatus)) {
3335 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
3336 "isassociation (0x%08x)."), nStatus);
3337 }
3338
3339 lim_log(pMac, LOG1,
3340 FL("***Sessionid %d Sending Disassociation frame with "
3341 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
3342 MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason,
3343 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
3344 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
3345
3346 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
3347 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3348 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
3349 ) {
3350 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3351 }
3352
3353 if ((psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3354 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
3355 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
3356 }
3357
3358 if (waitForAck) {
3359 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3360 psessionEntry->peSessionId,
3361 pMacHdr->fc.subType));
3362 /* Queue Disassociation frame in high priority WQ */
3363 /* get the duration from the request */
3364 cdf_status =
3365 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
3366 TXRX_FRM_802_11_MGMT,
3367 ANI_TXDIR_TODS, 7, lim_tx_complete,
3368 pFrame, lim_disassoc_tx_complete_cnf,
3369 txFlag, smeSessionId, false, 0);
3370 MTRACE(cdf_trace
3371 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3372 psessionEntry->peSessionId, cdf_status));
3373
3374 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
3375
3376 if (tx_timer_change
3377 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
3378 != TX_SUCCESS) {
3379 lim_log(pMac, LOGP,
3380 FL("Unable to change Disassoc ack Timer val"));
3381 return;
3382 } else if (TX_SUCCESS !=
3383 tx_timer_activate(&pMac->lim.limTimers.
3384 gLimDisassocAckTimer)) {
3385 lim_log(pMac, LOGP,
3386 FL("Unable to activate Disassoc ack Timer"));
3387 lim_deactivate_and_change_timer(pMac,
3388 eLIM_DISASSOC_ACK_TIMER);
3389 return;
3390 }
3391 } else {
3392 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3393 psessionEntry->peSessionId,
3394 pMacHdr->fc.subType));
3395 /* Queue Disassociation frame in high priority WQ */
3396 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3397 TXRX_FRM_802_11_MGMT,
3398 ANI_TXDIR_TODS,
3399 7,
3400 lim_tx_complete, pFrame, txFlag,
3401 smeSessionId, 0);
3402 MTRACE(cdf_trace
3403 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3404 psessionEntry->peSessionId, cdf_status));
3405 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3406 lim_log(pMac, LOGE,
3407 FL("Failed to send Disassociation (%X)!"),
3408 cdf_status);
3409 /* Pkt will be freed up by the callback */
3410 }
3411 }
3412} /* End lim_send_disassoc_mgmt_frame. */
3413
3414/**
3415 * \brief This function is called to send a Deauthenticate frame
3416 *
3417 *
3418 * \param pMac Pointer to global MAC structure
3419 *
3420 * \param nReason Indicates the reason that need to be sent in the
3421 * Deauthenticate frame
3422 *
3423 * \param peeer address of the STA to which the frame is to be sent
3424 *
3425 *
3426 */
3427
3428void
3429lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
3430 uint16_t nReason,
3431 tSirMacAddr peer,
3432 tpPESession psessionEntry, bool waitForAck)
3433{
3434 tDot11fDeAuth frm;
3435 uint8_t *pFrame;
3436 tpSirMacMgmtHdr pMacHdr;
3437 uint32_t nBytes, nPayload, nStatus;
3438 void *pPacket;
3439 CDF_STATUS cdf_status;
3440 uint8_t txFlag = 0;
3441 uint32_t val = 0;
3442#ifdef FEATURE_WLAN_TDLS
3443 uint16_t aid;
3444 tpDphHashNode pStaDs;
3445#endif
3446 uint8_t smeSessionId = 0;
3447
3448 if (NULL == psessionEntry) {
3449 return;
3450 }
3451
3452 /*
3453 * In case when cac timer is running for this SAP session then
3454 * avoid deauth frame out. It is violation of dfs specification.
3455 */
3456 if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
3457 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
3458 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
3459 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
3460 FL
3461 ("CAC timer is running, drop the deauth from going out"));
3462 return;
3463 }
3464 smeSessionId = psessionEntry->smeSessionId;
3465
3466 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3467
3468 frm.Reason.code = nReason;
3469
3470 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
3471 if (DOT11F_FAILED(nStatus)) {
3472 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3473 "or a De-Authentication (0x%08x)."),
3474 nStatus);
3475 /* We'll fall back on the worst case scenario: */
3476 nPayload = sizeof(tDot11fDeAuth);
3477 } else if (DOT11F_WARNED(nStatus)) {
3478 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3479 "the packed size for a De-Authentication "
3480 "(0x%08x)."), nStatus);
3481 }
3482
3483 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3484
3485 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3486 (void **)&pPacket);
3487 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3488 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
3489 "Authentication."), nBytes);
3490 return;
3491 }
3492 /* Paranoia: */
3493 cdf_mem_set(pFrame, nBytes, 0);
3494
3495 /* Next, we fill out the buffer descriptor: */
3496 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3497 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
3498 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3499
3500 /* Prepare the BSSID */
3501 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3502
3503#ifdef WLAN_FEATURE_11W
3504 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3505#endif
3506
3507 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
3508 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
3509 if (DOT11F_FAILED(nStatus)) {
3510 lim_log(pMac, LOGE,
3511 FL("Failed to pack a DeAuthentication (0x%08x)."),
3512 nStatus);
3513 cds_packet_free((void *)pPacket);
3514 return;
3515 } else if (DOT11F_WARNED(nStatus)) {
3516 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
3517 "e-Authentication (0x%08x)."), nStatus);
3518 }
3519 lim_log(pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with "
3520 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
3521 " ,From " MAC_ADDRESS_STR),
3522 psessionEntry->peSessionId, nReason, waitForAck,
3523 MAC_ADDR_ARRAY(pMacHdr->da),
3524 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
3525
3526 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
3527 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3528 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
3529 ) {
3530 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3531 }
3532
3533 if ((psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3534 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
3535 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
3536 }
3537#ifdef FEATURE_WLAN_TDLS
3538 pStaDs =
3539 dph_lookup_hash_entry(pMac, peer, &aid,
3540 &psessionEntry->dph.dphHashTable);
3541#endif
3542
3543 if (waitForAck) {
3544 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3545 psessionEntry->peSessionId,
3546 pMacHdr->fc.subType));
3547 /* Queue Disassociation frame in high priority WQ */
3548 cdf_status =
3549 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
3550 TXRX_FRM_802_11_MGMT,
3551 ANI_TXDIR_TODS, 7, lim_tx_complete,
3552 pFrame, lim_deauth_tx_complete_cnf,
3553 txFlag, smeSessionId, false, 0);
3554 MTRACE(cdf_trace
3555 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3556 psessionEntry->peSessionId, cdf_status));
3557 /* Pkt will be freed up by the callback lim_tx_complete */
3558 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3559 lim_log(pMac, LOGE,
3560 FL("Failed to send De-Authentication (%X)!"),
3561 cdf_status);
3562
3563 /* Call lim_process_deauth_ack_timeout which will send
3564 * DeauthCnf for this frame
3565 */
3566 lim_process_deauth_ack_timeout(pMac);
3567 return;
3568 }
3569
3570 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
3571
3572 if (tx_timer_change
3573 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
3574 != TX_SUCCESS) {
3575 lim_log(pMac, LOGP,
3576 FL("Unable to change Deauth ack Timer val"));
3577 return;
3578 } else if (TX_SUCCESS !=
3579 tx_timer_activate(&pMac->lim.limTimers.
3580 gLimDeauthAckTimer)) {
3581 lim_log(pMac, LOGP,
3582 FL("Unable to activate Deauth ack Timer"));
3583 lim_deactivate_and_change_timer(pMac,
3584 eLIM_DEAUTH_ACK_TIMER);
3585 return;
3586 }
3587 } else {
3588 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3589 psessionEntry->peSessionId,
3590 pMacHdr->fc.subType));
3591#ifdef FEATURE_WLAN_TDLS
3592 if ((NULL != pStaDs)
3593 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
3594 /* Queue Disassociation frame in high priority WQ */
3595 cdf_status =
3596 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3597 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
3598 7, lim_tx_complete, pFrame, txFlag,
3599 smeSessionId, 0);
3600 } else {
3601#endif
3602 /* Queue Disassociation frame in high priority WQ */
3603 cdf_status =
3604 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3605 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3606 7, lim_tx_complete, pFrame, txFlag,
3607 smeSessionId, 0);
3608#ifdef FEATURE_WLAN_TDLS
3609 }
3610#endif
3611 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3612 psessionEntry->peSessionId, cdf_status));
3613 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3614 lim_log(pMac, LOGE,
3615 FL("Failed to send De-Authentication (%X)!"),
3616 cdf_status);
3617 /* Pkt will be freed up by the callback */
3618 }
3619 }
3620
3621} /* End lim_send_deauth_mgmt_frame. */
3622
3623#ifdef ANI_SUPPORT_11H
3624/**
3625 * \brief Send a Measurement Report Action frame
3626 *
3627 *
3628 * \param pMac Pointer to the global MAC structure
3629 *
3630 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
3631 *
3632 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3633 *
3634 *
3635 */
3636
3637tSirRetStatus
3638lim_send_meas_report_frame(tpAniSirGlobal pMac,
3639 tpSirMacMeasReqActionFrame pMeasReqFrame,
3640 tSirMacAddr peer, tpPESession psessionEntry)
3641{
3642 tDot11fMeasurementReport frm;
3643 uint8_t *pFrame;
3644 tSirRetStatus nSirStatus;
3645 tpSirMacMgmtHdr pMacHdr;
3646 uint32_t nBytes, nPayload, nStatus;
3647 void *pPacket;
3648 CDF_STATUS cdf_status;
3649
3650 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3651
3652 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3653 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3654 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3655
3656 switch (pMeasReqFrame->measReqIE.measType) {
3657 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3658 nSirStatus =
3659 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3660 &frm.MeasurementReport);
3661 break;
3662 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3663 nSirStatus =
3664 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3665 &frm.MeasurementReport);
3666 break;
3667 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3668 nSirStatus =
3669 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3670 &frm.MeasurementReport);
3671 break;
3672 default:
3673 lim_log(pMac, LOGE, FL("Unknown measurement type %d in limSen"
3674 "dMeasReportFrame."),
3675 pMeasReqFrame->measReqIE.measType);
3676 return eSIR_FAILURE;
3677 }
3678
3679 if (eSIR_SUCCESS != nSirStatus)
3680 return eSIR_FAILURE;
3681
3682 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3683 if (DOT11F_FAILED(nStatus)) {
3684 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3685 "or a Measurement Report (0x%08x)."),
3686 nStatus);
3687 /* We'll fall back on the worst case scenario: */
3688 nPayload = sizeof(tDot11fMeasurementReport);
3689 } else if (DOT11F_WARNED(nStatus)) {
3690 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3691 "the packed size for a Measurement Rep"
3692 "ort (0x%08x)."), nStatus);
3693 }
3694
3695 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3696
3697 cdf_status =
3698 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3699 (uint16_t) nBytes, (void **)&pFrame,
3700 (void **)&pPacket);
3701 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3702 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
3703 "Authentication."), nBytes);
3704 return eSIR_FAILURE;
3705 }
3706 /* Paranoia: */
3707 cdf_mem_set(pFrame, nBytes, 0);
3708
3709 /* Next, we fill out the buffer descriptor: */
3710 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3711 SIR_MAC_MGMT_ACTION, peer);
3712 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3713
3714 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3715
3716#ifdef WLAN_FEATURE_11W
3717 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3718#endif
3719
3720 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3721 sizeof(tSirMacMgmtHdr),
3722 nPayload, &nPayload);
3723 if (DOT11F_FAILED(nStatus)) {
3724 lim_log(pMac, LOGE,
3725 FL("Failed to pack a Measurement Report (0x%08x)."),
3726 nStatus);
3727 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3728 (void *)pFrame, (void *)pPacket);
3729 return eSIR_FAILURE; /* allocated! */
3730 } else if (DOT11F_WARNED(nStatus)) {
3731 lim_log(pMac, LOGW, FL("There were warnings while packing a M"
3732 "easurement Report (0x%08x)."), nStatus);
3733 }
3734
3735 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3736 ((psessionEntry) ? psessionEntry->
3737 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3738 cdf_status =
3739 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3740 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3741 lim_tx_complete, pFrame, 0, 0);
3742 MTRACE(cdf_trace
3743 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3744 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3745 cdf_status));
3746 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3747 lim_log(pMac, LOGE,
3748 FL("Failed to send a Measurement Report (%X)!"),
3749 cdf_status);
3750 /* Pkt will be freed up by the callback */
3751 return eSIR_FAILURE; /* just allocated... */
3752 }
3753
3754 return eSIR_SUCCESS;
3755
3756} /* End lim_send_meas_report_frame. */
3757
3758/**
3759 * \brief Send a TPC Request Action frame
3760 *
3761 *
3762 * \param pMac Pointer to the global MAC datastructure
3763 *
3764 * \param peer MAC address to which the frame should be sent
3765 *
3766 *
3767 */
3768
3769void
3770lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3771 tSirMacAddr peer, tpPESession psessionEntry)
3772{
3773 tDot11fTPCRequest frm;
3774 uint8_t *pFrame;
3775 tpSirMacMgmtHdr pMacHdr;
3776 uint32_t nBytes, nPayload, nStatus;
3777 void *pPacket;
3778 CDF_STATUS cdf_status;
3779
3780 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3781
3782 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3783 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3784 frm.DialogToken.token = 1;
3785 frm.TPCRequest.present = 1;
3786
3787 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3788 if (DOT11F_FAILED(nStatus)) {
3789 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3790 "or a TPC Request (0x%08x)."), nStatus);
3791 /* We'll fall back on the worst case scenario: */
3792 nPayload = sizeof(tDot11fTPCRequest);
3793 } else if (DOT11F_WARNED(nStatus)) {
3794 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3795 "the packed size for a TPC Request (0x"
3796 "%08x)."), nStatus);
3797 }
3798
3799 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3800
3801 cdf_status =
3802 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3803 (uint16_t) nBytes, (void **)&pFrame,
3804 (void **)&pPacket);
3805 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3806 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3807 " Request."), nBytes);
3808 return;
3809 }
3810 /* Paranoia: */
3811 cdf_mem_set(pFrame, nBytes, 0);
3812
3813 /* Next, we fill out the buffer descriptor: */
3814 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3815 SIR_MAC_MGMT_ACTION, peer);
3816 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3817
3818 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3819
3820#ifdef WLAN_FEATURE_11W
3821 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3822#endif
3823
3824 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3825 sizeof(tSirMacMgmtHdr),
3826 nPayload, &nPayload);
3827 if (DOT11F_FAILED(nStatus)) {
3828 lim_log(pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."),
3829 nStatus);
3830 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3831 (void *)pFrame, (void *)pPacket);
3832 return; /* allocated! */
3833 } else if (DOT11F_WARNED(nStatus)) {
3834 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3835 "PC Request (0x%08x)."), nStatus);
3836 }
3837
3838 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3839 ((psessionEntry) ? psessionEntry->
3840 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3841 cdf_status =
3842 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3843 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3844 lim_tx_complete, pFrame, 0, 0);
3845 MTRACE(cdf_trace
3846 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3847 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3848 cdf_status));
3849 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3850 lim_log(pMac, LOGE,
3851 FL("Failed to send a TPC Request (%X)!"),
3852 cdf_status);
3853 /* Pkt will be freed up by the callback */
3854 }
3855
3856} /* End lim_send_tpc_request_frame. */
3857
3858/**
3859 * \brief Send a TPC Report Action frame
3860 *
3861 *
3862 * \param pMac Pointer to the global MAC datastructure
3863 *
3864 * \param pTpcReqFrame Pointer to the received TPC Request
3865 *
3866 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3867 *
3868 *
3869 */
3870
3871tSirRetStatus
3872lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3873 tpSirMacTpcReqActionFrame pTpcReqFrame,
3874 tSirMacAddr peer, tpPESession psessionEntry)
3875{
3876 tDot11fTPCReport frm;
3877 uint8_t *pFrame;
3878 tpSirMacMgmtHdr pMacHdr;
3879 uint32_t nBytes, nPayload, nStatus;
3880 void *pPacket;
3881 CDF_STATUS cdf_status;
3882
3883 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3884
3885 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3886 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3887 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3888
3889 frm.TPCReport.tx_power = 0;
3890 frm.TPCReport.link_margin = 0;
3891 frm.TPCReport.present = 1;
3892
3893 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3894 if (DOT11F_FAILED(nStatus)) {
3895 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3896 "or a TPC Report (0x%08x)."), nStatus);
3897 /* We'll fall back on the worst case scenario: */
3898 nPayload = sizeof(tDot11fTPCReport);
3899 } else if (DOT11F_WARNED(nStatus)) {
3900 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3901 "the packed size for a TPC Report (0x"
3902 "%08x)."), nStatus);
3903 }
3904
3905 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3906
3907 cdf_status =
3908 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3909 (uint16_t) nBytes, (void **)&pFrame,
3910 (void **)&pPacket);
3911 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3912 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3913 " Report."), nBytes);
3914 return eSIR_FAILURE;
3915 }
3916 /* Paranoia: */
3917 cdf_mem_set(pFrame, nBytes, 0);
3918
3919 /* Next, we fill out the buffer descriptor: */
3920 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3921 SIR_MAC_MGMT_ACTION, peer);
3922
3923 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3924
3925 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3926
3927#ifdef WLAN_FEATURE_11W
3928 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3929#endif
3930
3931 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3932 sizeof(tSirMacMgmtHdr),
3933 nPayload, &nPayload);
3934 if (DOT11F_FAILED(nStatus)) {
3935 lim_log(pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."),
3936 nStatus);
3937 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3938 (void *)pFrame, (void *)pPacket);
3939 return eSIR_FAILURE; /* allocated! */
3940 } else if (DOT11F_WARNED(nStatus)) {
3941 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3942 "PC Report (0x%08x)."), nStatus);
3943 }
3944
3945 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3946 ((psessionEntry) ? psessionEntry->
3947 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3948 cdf_status =
3949 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3950 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3951 lim_tx_complete, pFrame, 0, 0);
3952 MTRACE(cdf_trace
3953 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3954 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3955 cdf_status));
3956 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3957 lim_log(pMac, LOGE,
3958 FL("Failed to send a TPC Report (%X)!"),
3959 cdf_status);
3960 /* Pkt will be freed up by the callback */
3961 return eSIR_FAILURE; /* just allocated... */
3962 }
3963
3964 return eSIR_SUCCESS;
3965
3966} /* End lim_send_tpc_report_frame. */
3967#endif /* ANI_SUPPORT_11H */
3968
3969/**
3970 * \brief Send a Channel Switch Announcement
3971 *
3972 *
3973 * \param pMac Pointer to the global MAC datastructure
3974 *
3975 * \param peer MAC address to which this frame will be sent
3976 *
3977 * \param nMode
3978 *
3979 * \param nNewChannel
3980 *
3981 * \param nCount
3982 *
3983 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3984 *
3985 *
3986 */
3987
3988tSirRetStatus
3989lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
3990 tSirMacAddr peer,
3991 uint8_t nMode,
3992 uint8_t nNewChannel,
3993 uint8_t nCount, tpPESession psessionEntry)
3994{
3995 tDot11fChannelSwitch frm;
3996 uint8_t *pFrame;
3997 tpSirMacMgmtHdr pMacHdr;
3998 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
3999 void *pPacket;
4000 CDF_STATUS cdf_status;
4001 uint8_t txFlag = 0;
4002
4003 uint8_t smeSessionId = 0;
4004
4005 if (psessionEntry == NULL) {
4006 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4007 return eSIR_FAILURE;
4008 }
4009 smeSessionId = psessionEntry->smeSessionId;
4010
4011 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4012
4013 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
4014 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
4015 frm.ChanSwitchAnn.switchMode = nMode;
4016 frm.ChanSwitchAnn.newChannel = nNewChannel;
4017 frm.ChanSwitchAnn.switchCount = nCount;
4018 frm.ChanSwitchAnn.present = 1;
4019
4020 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
4021 if (DOT11F_FAILED(nStatus)) {
4022 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4023 "or a Channel Switch (0x%08x)."),
4024 nStatus);
4025 /* We'll fall back on the worst case scenario: */
4026 nPayload = sizeof(tDot11fChannelSwitch);
4027 } else if (DOT11F_WARNED(nStatus)) {
4028 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4029 "the packed size for a Channel Switch (0x"
4030 "%08x)."), nStatus);
4031 }
4032
4033 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4034
4035 cdf_status =
4036 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4037 (void **)&pPacket);
4038 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4039 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
4040 " Report."), nBytes);
4041 return eSIR_FAILURE;
4042 }
4043 /* Paranoia: */
4044 cdf_mem_set(pFrame, nBytes, 0);
4045
4046 /* Next, we fill out the buffer descriptor: */
4047 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4048 SIR_MAC_MGMT_ACTION, peer,
4049 psessionEntry->selfMacAddr);
4050 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4051 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4052 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4053
4054#ifdef WLAN_FEATURE_11W
4055 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4056#endif
4057
4058 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
4059 sizeof(tSirMacMgmtHdr),
4060 nPayload, &nPayload);
4061 if (DOT11F_FAILED(nStatus)) {
4062 lim_log(pMac, LOGE,
4063 FL("Failed to pack a Channel Switch (0x%08x)."),
4064 nStatus);
4065 cds_packet_free((void *)pPacket);
4066 return eSIR_FAILURE; /* allocated! */
4067 } else if (DOT11F_WARNED(nStatus)) {
4068 lim_log(pMac, LOGW, FL("There were warnings while packing a C"
4069 "hannel Switch (0x%08x)."), nStatus);
4070 }
4071
4072 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4073 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4074 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4075 ) {
4076 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4077 }
4078
4079 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4080 psessionEntry->peSessionId, pMacHdr->fc.subType));
4081 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4082 TXRX_FRM_802_11_MGMT,
4083 ANI_TXDIR_TODS,
4084 7, lim_tx_complete, pFrame, txFlag,
4085 smeSessionId, 0);
4086 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4087 psessionEntry->peSessionId, cdf_status));
4088 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4089 lim_log(pMac, LOGE,
4090 FL("Failed to send a Channel Switch (%X)!"),
4091 cdf_status);
4092 /* Pkt will be freed up by the callback */
4093 return eSIR_FAILURE;
4094 }
4095
4096 return eSIR_SUCCESS;
4097
4098} /* End lim_send_channel_switch_mgmt_frame. */
4099
4100#ifdef WLAN_FEATURE_11AC
4101tSirRetStatus
4102lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
4103 tSirMacAddr peer,
4104 uint8_t nMode, tpPESession psessionEntry)
4105{
4106 tDot11fOperatingMode frm;
4107 uint8_t *pFrame;
4108 tpSirMacMgmtHdr pMacHdr;
4109 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
4110 void *pPacket;
4111 CDF_STATUS cdf_status;
4112 uint8_t txFlag = 0;
4113
4114 uint8_t smeSessionId = 0;
4115
4116 if (psessionEntry == NULL) {
4117 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4118 return eSIR_FAILURE;
4119 }
4120 smeSessionId = psessionEntry->smeSessionId;
4121
4122 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4123
4124 frm.Category.category = SIR_MAC_ACTION_VHT;
4125 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
4126 frm.OperatingMode.chanWidth = nMode;
4127 frm.OperatingMode.rxNSS = 0;
4128 frm.OperatingMode.rxNSSType = 0;
4129
4130 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
4131 if (DOT11F_FAILED(nStatus)) {
4132 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4133 "or a Operating Mode (0x%08x)."),
4134 nStatus);
4135 /* We'll fall back on the worst case scenario: */
4136 nPayload = sizeof(tDot11fOperatingMode);
4137 } else if (DOT11F_WARNED(nStatus)) {
4138 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4139 "the packed size for a Operating Mode (0x"
4140 "%08x)."), nStatus);
4141 }
4142
4143 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4144
4145 cdf_status =
4146 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4147 (void **)&pPacket);
4148 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4149 lim_log(pMac, LOGP,
4150 FL("Failed to allocate %d bytes for a Operating Mode"
4151 " Report."), nBytes);
4152 return eSIR_FAILURE;
4153 }
4154 /* Paranoia: */
4155 cdf_mem_set(pFrame, nBytes, 0);
4156
4157 /* Next, we fill out the buffer descriptor: */
4158 if (psessionEntry->pePersona == CDF_SAP_MODE)
4159 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4160 SIR_MAC_MGMT_ACTION, peer,
4161 psessionEntry->selfMacAddr);
4162 else
4163 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4164 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
4165 psessionEntry->selfMacAddr);
4166 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4167 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4168 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4169 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
4170 sizeof(tSirMacMgmtHdr),
4171 nPayload, &nPayload);
4172 if (DOT11F_FAILED(nStatus)) {
4173 lim_log(pMac, LOGE,
4174 FL("Failed to pack a Operating Mode (0x%08x)."),
4175 nStatus);
4176 cds_packet_free((void *)pPacket);
4177 return eSIR_FAILURE; /* allocated! */
4178 } else if (DOT11F_WARNED(nStatus)) {
4179 lim_log(pMac, LOGW,
4180 FL("There were warnings while packing a Operating Mode"
4181 " (0x%08x)."), nStatus);
4182 }
4183 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4184 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4185 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4186 ) {
4187 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4188 }
4189
4190 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4191 psessionEntry->peSessionId, pMacHdr->fc.subType));
4192 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4193 TXRX_FRM_802_11_MGMT,
4194 ANI_TXDIR_TODS,
4195 7, lim_tx_complete, pFrame, txFlag,
4196 smeSessionId, 0);
4197 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4198 psessionEntry->peSessionId, cdf_status));
4199 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4200 lim_log(pMac, LOGE,
4201 FL("Failed to send a Channel Switch (%X)!"),
4202 cdf_status);
4203 /* Pkt will be freed up by the callback */
4204 return eSIR_FAILURE;
4205 }
4206
4207 return eSIR_SUCCESS;
4208}
4209
4210/**
4211 * \brief Send a VHT Channel Switch Announcement
4212 *
4213 *
4214 * \param pMac Pointer to the global MAC datastructure
4215 *
4216 * \param peer MAC address to which this frame will be sent
4217 *
4218 * \param nChanWidth
4219 *
4220 * \param nNewChannel
4221 *
4222 *
4223 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4224 *
4225 *
4226 */
4227
4228tSirRetStatus
4229lim_send_vht_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
4230 tSirMacAddr peer,
4231 uint8_t nChanWidth,
4232 uint8_t nNewChannel,
4233 uint8_t ncbMode, tpPESession psessionEntry)
4234{
4235 tDot11fChannelSwitch frm;
4236 uint8_t *pFrame;
4237 tpSirMacMgmtHdr pMacHdr;
4238 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
4239 void *pPacket;
4240 CDF_STATUS cdf_status;
4241 uint8_t txFlag = 0;
4242
4243 uint8_t smeSessionId = 0;
4244
4245 if (psessionEntry == NULL) {
4246 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4247 return eSIR_FAILURE;
4248 }
4249 smeSessionId = psessionEntry->smeSessionId;
4250
4251 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4252
4253 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
4254 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
4255 frm.ChanSwitchAnn.switchMode = 1;
4256 frm.ChanSwitchAnn.newChannel = nNewChannel;
4257 frm.ChanSwitchAnn.switchCount = 1;
4258 frm.sec_chan_offset_ele.secondaryChannelOffset =
4259 lim_get_htcb_state(ncbMode);
4260 frm.sec_chan_offset_ele.present = 1;
4261 frm.WiderBWChanSwitchAnn.newChanWidth = nChanWidth;
4262 frm.WiderBWChanSwitchAnn.newCenterChanFreq0 =
4263 lim_get_center_channel(pMac, nNewChannel, ncbMode, nChanWidth);
4264 frm.WiderBWChanSwitchAnn.newCenterChanFreq1 = 0;
4265 frm.ChanSwitchAnn.present = 1;
4266 frm.WiderBWChanSwitchAnn.present = 1;
4267
4268 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
4269 if (DOT11F_FAILED(nStatus)) {
4270 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4271 "or a Channel Switch (0x%08x)."),
4272 nStatus);
4273 /* We'll fall back on the worst case scenario: */
4274 nPayload = sizeof(tDot11fChannelSwitch);
4275 } else if (DOT11F_WARNED(nStatus)) {
4276 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4277 "the packed size for a Channel Switch (0x"
4278 "%08x)."), nStatus);
4279 }
4280
4281 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4282
4283 cdf_status =
4284 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4285 (void **)&pPacket);
4286 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4287 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
4288 " Report."), nBytes);
4289 return eSIR_FAILURE;
4290 }
4291 /* Paranoia: */
4292 cdf_mem_set(pFrame, nBytes, 0);
4293
4294 /* Next, we fill out the buffer descriptor: */
4295 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4296 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4297 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4298 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4299 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4300 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
4301 sizeof(tSirMacMgmtHdr),
4302 nPayload, &nPayload);
4303 if (DOT11F_FAILED(nStatus)) {
4304 lim_log(pMac, LOGE,
4305 FL("Failed to pack a Channel Switch (0x%08x)."),
4306 nStatus);
4307 cds_packet_free((void *)pPacket);
4308 return eSIR_FAILURE; /* allocated! */
4309 } else if (DOT11F_WARNED(nStatus)) {
4310 lim_log(pMac, LOGW, FL("There were warnings while packing a C"
4311 "hannel Switch (0x%08x)."), nStatus);
4312 }
4313
4314 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4315 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4316 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4317 ) {
4318 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4319 }
4320
4321 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4322 psessionEntry->peSessionId, pMacHdr->fc.subType));
4323 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4324 TXRX_FRM_802_11_MGMT,
4325 ANI_TXDIR_TODS,
4326 7, lim_tx_complete, pFrame, txFlag,
4327 smeSessionId, 0);
4328 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4329 psessionEntry->peSessionId, cdf_status));
4330 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4331 lim_log(pMac, LOGE,
4332 FL("Failed to send a Channel Switch (%X)!"),
4333 cdf_status);
4334 /* Pkt will be freed up by the callback */
4335 return eSIR_FAILURE;
4336 }
4337
4338 return eSIR_SUCCESS;
4339
4340} /* End lim_send_vht_channel_switch_mgmt_frame. */
4341
4342#endif
4343
4344#if defined WLAN_FEATURE_VOWIFI
4345
4346/**
4347 * \brief Send a Neighbor Report Request Action frame
4348 *
4349 *
4350 * \param pMac Pointer to the global MAC structure
4351 *
4352 * \param pNeighborReq Address of a tSirMacNeighborReportReq
4353 *
4354 * \param peer mac address of peer station.
4355 *
4356 * \param psessionEntry address of session entry.
4357 *
4358 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4359 *
4360 *
4361 */
4362
4363tSirRetStatus
4364lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
4365 tpSirMacNeighborReportReq pNeighborReq,
4366 tSirMacAddr peer, tpPESession psessionEntry)
4367{
4368 tSirRetStatus statusCode = eSIR_SUCCESS;
4369 tDot11fNeighborReportRequest frm;
4370 uint8_t *pFrame;
4371 tpSirMacMgmtHdr pMacHdr;
4372 uint32_t nBytes, nPayload, nStatus;
4373 void *pPacket;
4374 CDF_STATUS cdf_status;
4375 uint8_t txFlag = 0;
4376 uint8_t smeSessionId = 0;
4377
4378 if (psessionEntry == NULL) {
4379 lim_log(pMac, LOGE,
4380 FL
4381 ("(psession == NULL) in Request to send Neighbor Report request action frame"));
4382 return eSIR_FAILURE;
4383 }
4384 smeSessionId = psessionEntry->smeSessionId;
4385 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4386
4387 frm.Category.category = SIR_MAC_ACTION_RRM;
4388 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
4389 frm.DialogToken.token = pNeighborReq->dialogToken;
4390
4391 if (pNeighborReq->ssid_present) {
4392 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
4393 }
4394
4395 nStatus =
4396 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
4397 if (DOT11F_FAILED(nStatus)) {
4398 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4399 "or a Neighbor Report Request(0x%08x)."),
4400 nStatus);
4401 /* We'll fall back on the worst case scenario: */
4402 nPayload = sizeof(tDot11fNeighborReportRequest);
4403 } else if (DOT11F_WARNED(nStatus)) {
4404 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4405 "the packed size for a Neighbor Rep"
4406 "ort Request(0x%08x)."), nStatus);
4407 }
4408
4409 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4410
4411 cdf_status =
4412 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4413 (void **)&pPacket);
4414 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4415 lim_log(pMac, LOGP,
4416 FL("Failed to allocate %d bytes for a Neighbor "
4417 "Report Request."), nBytes);
4418 return eSIR_FAILURE;
4419 }
4420 /* Paranoia: */
4421 cdf_mem_set(pFrame, nBytes, 0);
4422
4423 /* Copy necessary info to BD */
4424 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4425 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4426
4427 /* Update A3 with the BSSID */
4428 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4429
4430 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4431
4432#ifdef WLAN_FEATURE_11W
4433 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4434#endif
4435
4436 /* Now, we're ready to "pack" the frames */
4437 nStatus = dot11f_pack_neighbor_report_request(pMac,
4438 &frm,
4439 pFrame +
4440 sizeof(tSirMacMgmtHdr),
4441 nPayload, &nPayload);
4442
4443 if (DOT11F_FAILED(nStatus)) {
4444 lim_log(pMac, LOGE,
4445 FL
4446 ("Failed to pack an Neighbor Report Request (0x%08x)."),
4447 nStatus);
4448
4449 /* FIXME - Need to convert to tSirRetStatus */
4450 statusCode = eSIR_FAILURE;
4451 goto returnAfterError;
4452 } else if (DOT11F_WARNED(nStatus)) {
4453 lim_log(pMac, LOGW,
4454 FL("There were warnings while packing Neighbor Report "
4455 "Request (0x%08x)."), nStatus);
4456 }
4457
4458 lim_log(pMac, LOGW, FL("Sending a Neighbor Report Request to "));
4459 lim_print_mac_addr(pMac, peer, LOGW);
4460
4461 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4462 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4463 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4464 ) {
4465 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4466 }
4467
4468 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4469 psessionEntry->peSessionId, pMacHdr->fc.subType));
4470 cdf_status = wma_tx_frame(pMac,
4471 pPacket,
4472 (uint16_t) nBytes,
4473 TXRX_FRM_802_11_MGMT,
4474 ANI_TXDIR_TODS,
4475 7, lim_tx_complete, pFrame, txFlag,
4476 smeSessionId, 0);
4477 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4478 psessionEntry->peSessionId, cdf_status));
4479 if (CDF_STATUS_SUCCESS != cdf_status) {
4480 PELOGE(lim_log
4481 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4482 cdf_status);
4483 )
4484 statusCode = eSIR_FAILURE;
4485 /* Pkt will be freed up by the callback */
4486 return statusCode;
4487 } else
4488 return eSIR_SUCCESS;
4489
4490returnAfterError:
4491 cds_packet_free((void *)pPacket);
4492
4493 return statusCode;
4494} /* End lim_send_neighbor_report_request_frame. */
4495
4496/**
4497 * \brief Send a Link Report Action frame
4498 *
4499 *
4500 * \param pMac Pointer to the global MAC structure
4501 *
4502 * \param pLinkReport Address of a tSirMacLinkReport
4503 *
4504 * \param peer mac address of peer station.
4505 *
4506 * \param psessionEntry address of session entry.
4507 *
4508 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4509 *
4510 *
4511 */
4512
4513tSirRetStatus
4514lim_send_link_report_action_frame(tpAniSirGlobal pMac,
4515 tpSirMacLinkReport pLinkReport,
4516 tSirMacAddr peer, tpPESession psessionEntry)
4517{
4518 tSirRetStatus statusCode = eSIR_SUCCESS;
4519 tDot11fLinkMeasurementReport frm;
4520 uint8_t *pFrame;
4521 tpSirMacMgmtHdr pMacHdr;
4522 uint32_t nBytes, nPayload, nStatus;
4523 void *pPacket;
4524 CDF_STATUS cdf_status;
4525 uint8_t txFlag = 0;
4526 uint8_t smeSessionId = 0;
4527
4528 if (psessionEntry == NULL) {
4529 lim_log(pMac, LOGE,
4530 FL
4531 ("(psession == NULL) in Request to send Link Report action frame"));
4532 return eSIR_FAILURE;
4533 }
4534
4535 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4536
4537 frm.Category.category = SIR_MAC_ACTION_RRM;
4538 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
4539 frm.DialogToken.token = pLinkReport->dialogToken;
4540
4541 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
4542 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
4543 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
4544 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
4545 /* such case this way than changing the frame parser. */
4546 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
4547 frm.TPCEleLen.TPCLen = 2;
4548 frm.TxPower.txPower = pLinkReport->txPower;
4549 frm.LinkMargin.linkMargin = 0;
4550
4551 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4552 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4553 frm.RCPI.rcpi = pLinkReport->rcpi;
4554 frm.RSNI.rsni = pLinkReport->rsni;
4555
4556 nStatus =
4557 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4558 if (DOT11F_FAILED(nStatus)) {
4559 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4560 "or a Link Report (0x%08x)."), nStatus);
4561 /* We'll fall back on the worst case scenario: */
4562 nPayload = sizeof(tDot11fLinkMeasurementReport);
4563 } else if (DOT11F_WARNED(nStatus)) {
4564 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4565 "the packed size for a Link Rep"
4566 "ort (0x%08x)."), nStatus);
4567 }
4568
4569 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4570
4571 cdf_status =
4572 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4573 (void **)&pPacket);
4574 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4575 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Link "
4576 "Report."), nBytes);
4577 return eSIR_FAILURE;
4578 }
4579 /* Paranoia: */
4580 cdf_mem_set(pFrame, nBytes, 0);
4581
4582 /* Copy necessary info to BD */
4583 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4584 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4585
4586 /* Update A3 with the BSSID */
4587 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4588
4589 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4590
4591#ifdef WLAN_FEATURE_11W
4592 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4593#endif
4594
4595 /* Now, we're ready to "pack" the frames */
4596 nStatus = dot11f_pack_link_measurement_report(pMac,
4597 &frm,
4598 pFrame +
4599 sizeof(tSirMacMgmtHdr),
4600 nPayload, &nPayload);
4601
4602 if (DOT11F_FAILED(nStatus)) {
4603 lim_log(pMac, LOGE,
4604 FL("Failed to pack an Link Report (0x%08x)."), nStatus);
4605
4606 /* FIXME - Need to convert to tSirRetStatus */
4607 statusCode = eSIR_FAILURE;
4608 goto returnAfterError;
4609 } else if (DOT11F_WARNED(nStatus)) {
4610 lim_log(pMac, LOGW,
4611 FL
4612 ("There were warnings while packing Link Report (0x%08x)."),
4613 nStatus);
4614 }
4615
4616 lim_log(pMac, LOGW, FL("Sending a Link Report to "));
4617 lim_print_mac_addr(pMac, peer, LOGW);
4618
4619 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4620 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4621 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
4622 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4623 }
4624
4625 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4626 psessionEntry->peSessionId, pMacHdr->fc.subType));
4627 cdf_status = wma_tx_frame(pMac,
4628 pPacket,
4629 (uint16_t) nBytes,
4630 TXRX_FRM_802_11_MGMT,
4631 ANI_TXDIR_TODS,
4632 7, lim_tx_complete, pFrame, txFlag,
4633 smeSessionId, 0);
4634 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4635 psessionEntry->peSessionId, cdf_status));
4636 if (CDF_STATUS_SUCCESS != cdf_status) {
4637 PELOGE(lim_log
4638 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4639 cdf_status);
4640 )
4641 statusCode = eSIR_FAILURE;
4642 /* Pkt will be freed up by the callback */
4643 return statusCode;
4644 } else
4645 return eSIR_SUCCESS;
4646
4647returnAfterError:
4648 cds_packet_free((void *)pPacket);
4649
4650 return statusCode;
4651} /* End lim_send_link_report_action_frame. */
4652
4653/**
4654 * \brief Send a Beacon Report Action frame
4655 *
4656 *
4657 * \param pMac Pointer to the global MAC structure
4658 *
4659 * \param dialog_token dialog token to be used in the action frame.
4660 *
4661 * \param num_report number of reports in pRRMReport.
4662 *
4663 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4664 *
4665 * \param peer mac address of peer station.
4666 *
4667 * \param psessionEntry address of session entry.
4668 *
4669 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4670 *
4671 *
4672 */
4673
4674tSirRetStatus
4675lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4676 uint8_t dialog_token,
4677 uint8_t num_report,
4678 tpSirMacRadioMeasureReport pRRMReport,
4679 tSirMacAddr peer,
4680 tpPESession psessionEntry)
4681{
4682 tSirRetStatus statusCode = eSIR_SUCCESS;
4683 uint8_t *pFrame;
4684 tpSirMacMgmtHdr pMacHdr;
4685 uint32_t nBytes, nPayload, nStatus;
4686 void *pPacket;
4687 CDF_STATUS cdf_status;
4688 uint8_t i;
4689 uint8_t txFlag = 0;
4690 uint8_t smeSessionId = 0;
4691
4692 tDot11fRadioMeasurementReport *frm =
4693 cdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
4694 if (!frm) {
4695 lim_log(pMac, LOGE,
4696 FL
4697 ("Not enough memory to allocate tDot11fRadioMeasurementReport"));
4698 return eSIR_MEM_ALLOC_FAILED;
4699 }
4700
4701 if (psessionEntry == NULL) {
4702 lim_log(pMac, LOGE,
4703 FL
4704 ("(psession == NULL) in Request to send Beacon Report action frame"));
4705 cdf_mem_free(frm);
4706 return eSIR_FAILURE;
4707 }
4708 cdf_mem_set((uint8_t *) frm, sizeof(*frm), 0);
4709
4710 frm->Category.category = SIR_MAC_ACTION_RRM;
4711 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4712 frm->DialogToken.token = dialog_token;
4713
4714 frm->num_MeasurementReport =
4715 (num_report >
4716 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4717 num_report;
4718
4719 for (i = 0; i < frm->num_MeasurementReport; i++) {
4720 frm->MeasurementReport[i].type = pRRMReport[i].type;
4721 frm->MeasurementReport[i].token = pRRMReport[i].token;
4722 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4723 switch (pRRMReport[i].type) {
4724 case SIR_MAC_RRM_BEACON_TYPE:
4725 populate_dot11f_beacon_report(pMac,
4726 &frm->MeasurementReport[i],
4727 &pRRMReport[i].report.
4728 beaconReport);
4729 frm->MeasurementReport[i].incapable =
4730 pRRMReport[i].incapable;
4731 frm->MeasurementReport[i].refused =
4732 pRRMReport[i].refused;
4733 frm->MeasurementReport[i].present = 1;
4734 break;
4735 default:
4736 frm->MeasurementReport[i].incapable =
4737 pRRMReport[i].incapable;
4738 frm->MeasurementReport[i].refused =
4739 pRRMReport[i].refused;
4740 frm->MeasurementReport[i].present = 1;
4741 break;
4742 }
4743 }
4744
4745 nStatus =
4746 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4747 if (DOT11F_FAILED(nStatus)) {
4748 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4749 "or a Radio Measure Report (0x%08x)."),
4750 nStatus);
4751 /* We'll fall back on the worst case scenario: */
4752 nPayload = sizeof(tDot11fLinkMeasurementReport);
4753 cdf_mem_free(frm);
4754 return eSIR_FAILURE;
4755 } else if (DOT11F_WARNED(nStatus)) {
4756 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4757 "the packed size for a Radio Measure Rep"
4758 "ort (0x%08x)."), nStatus);
4759 }
4760
4761 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4762
4763 cdf_status =
4764 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4765 (void **)&pPacket);
4766 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4767 lim_log(pMac, LOGP,
4768 FL("Failed to allocate %d bytes for a Radio Measure "
4769 "Report."), nBytes);
4770 cdf_mem_free(frm);
4771 return eSIR_FAILURE;
4772 }
4773 /* Paranoia: */
4774 cdf_mem_set(pFrame, nBytes, 0);
4775
4776 /* Copy necessary info to BD */
4777 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4778 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4779
4780 /* Update A3 with the BSSID */
4781 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4782
4783 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4784
4785#ifdef WLAN_FEATURE_11W
4786 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4787#endif
4788
4789 /* Now, we're ready to "pack" the frames */
4790 nStatus = dot11f_pack_radio_measurement_report(pMac,
4791 frm,
4792 pFrame +
4793 sizeof(tSirMacMgmtHdr),
4794 nPayload, &nPayload);
4795
4796 if (DOT11F_FAILED(nStatus)) {
4797 lim_log(pMac, LOGE,
4798 FL("Failed to pack an Radio Measure Report (0x%08x)."),
4799 nStatus);
4800
4801 /* FIXME - Need to convert to tSirRetStatus */
4802 statusCode = eSIR_FAILURE;
4803 goto returnAfterError;
4804 } else if (DOT11F_WARNED(nStatus)) {
4805 lim_log(pMac, LOGW,
4806 FL("There were warnings while packing Radio "
4807 "Measure Report (0x%08x)."), nStatus);
4808 }
4809
4810 lim_log(pMac, LOGW, FL("Sending a Radio Measure Report to "));
4811 lim_print_mac_addr(pMac, peer, LOGW);
4812
4813 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4814 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4815 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4816 ) {
4817 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4818 }
4819
4820 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4821 psessionEntry->peSessionId, pMacHdr->fc.subType));
4822 cdf_status = wma_tx_frame(pMac,
4823 pPacket,
4824 (uint16_t) nBytes,
4825 TXRX_FRM_802_11_MGMT,
4826 ANI_TXDIR_TODS,
4827 7, lim_tx_complete, pFrame, txFlag,
4828 smeSessionId, 0);
4829 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4830 psessionEntry->peSessionId, cdf_status));
4831 if (CDF_STATUS_SUCCESS != cdf_status) {
4832 PELOGE(lim_log
4833 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4834 cdf_status);
4835 )
4836 statusCode = eSIR_FAILURE;
4837 /* Pkt will be freed up by the callback */
4838 cdf_mem_free(frm);
4839 return statusCode;
4840 } else {
4841 cdf_mem_free(frm);
4842 return eSIR_SUCCESS;
4843 }
4844
4845returnAfterError:
4846 cdf_mem_free(frm);
4847 cds_packet_free((void *)pPacket);
4848 return statusCode;
4849}
4850
4851#endif
4852
4853#ifdef WLAN_FEATURE_11W
4854/**
4855 * \brief Send SA query request action frame to peer
4856 *
4857 * \sa lim_send_sa_query_request_frame
4858 *
4859 *
4860 * \param pMac The global tpAniSirGlobal object
4861 *
4862 * \param transId Transaction identifier
4863 *
4864 * \param peer The Mac address of the station to which this action frame is addressed
4865 *
4866 * \param psessionEntry The PE session entry
4867 *
4868 * \return eSIR_SUCCESS if setup completes successfully
4869 * eSIR_FAILURE is some problem is encountered
4870 */
4871
4872tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
4873 tSirMacAddr peer,
4874 tpPESession psessionEntry)
4875{
4876
4877 tDot11fSaQueryReq frm; /* SA query request action frame */
4878 uint8_t *pFrame;
4879 tSirRetStatus nSirStatus;
4880 tpSirMacMgmtHdr pMacHdr;
4881 uint32_t nBytes, nPayload, nStatus;
4882 void *pPacket;
4883 CDF_STATUS cdf_status;
4884 uint8_t txFlag = 0;
4885 uint8_t smeSessionId = 0;
4886
4887 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4888 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
4889 /* 11w action field is :
4890 action: 0 --> SA Query Request action frame
4891 action: 1 --> SA Query Response action frame */
4892 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
4893 /* 11w SA Query Request transId */
4894 cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
4895
4896 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
4897 if (DOT11F_FAILED(nStatus)) {
4898 lim_log(pMac, LOGP, FL("Failed to calculate the packed size "
4899 "for an SA Query Request (0x%08x)."),
4900 nStatus);
4901 /* We'll fall back on the worst case scenario: */
4902 nPayload = sizeof(tDot11fSaQueryReq);
4903 } else if (DOT11F_WARNED(nStatus)) {
4904 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4905 "the packed size for an SA Query Request"
4906 " (0x%08x)."), nStatus);
4907 }
4908
4909 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4910 cdf_status =
4911 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
4912 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4913 lim_log(pMac, LOGP,
4914 FL("Failed to allocate %d bytes for a SA Query Request "
4915 "action frame"), nBytes);
4916 return eSIR_FAILURE;
4917 }
4918 /* Paranoia: */
4919 cdf_mem_set(pFrame, nBytes, 0);
4920
4921 /* Copy necessary info to BD */
4922 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4923 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4924
4925 /* Update A3 with the BSSID */
4926 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4927
4928 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4929
4930 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
4931 /* in the FC */
4932 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4933
4934 /* Pack 11w SA Query Request frame */
4935 nStatus = dot11f_pack_sa_query_req(pMac,
4936 &frm,
4937 pFrame + sizeof(tSirMacMgmtHdr),
4938 nPayload, &nPayload);
4939
4940 if (DOT11F_FAILED(nStatus)) {
4941 lim_log(pMac, LOGE,
4942 FL("Failed to pack an SA Query Request (0x%08x)."),
4943 nStatus);
4944 /* FIXME - Need to convert to tSirRetStatus */
4945 nSirStatus = eSIR_FAILURE;
4946 goto returnAfterError;
4947 } else if (DOT11F_WARNED(nStatus)) {
4948 lim_log(pMac, LOGW,
4949 FL
4950 ("There were warnings while packing SA Query Request (0x%08x)."),
4951 nStatus);
4952 }
4953
4954 lim_log(pMac, LOG1, FL("Sending an SA Query Request to "));
4955 lim_print_mac_addr(pMac, peer, LOG1);
4956 lim_log(pMac, LOG1, FL("Sending an SA Query Request from "));
4957 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOG1);
4958
4959 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4960#ifdef WLAN_FEATURE_P2P
4961 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4962 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4963#endif
4964 ) {
4965 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4966 }
4967 smeSessionId = psessionEntry->smeSessionId;
4968
4969 cdf_status = wma_tx_frame(pMac,
4970 pPacket,
4971 (uint16_t) nBytes,
4972 TXRX_FRM_802_11_MGMT,
4973 ANI_TXDIR_TODS,
4974 7, lim_tx_complete, pFrame, txFlag,
4975 smeSessionId, 0);
4976 if (CDF_STATUS_SUCCESS != cdf_status) {
4977 PELOGE(lim_log
4978 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4979 cdf_status);
4980 )
4981 nSirStatus = eSIR_FAILURE;
4982 /* Pkt will be freed up by the callback */
4983 return nSirStatus;
4984 } else {
4985 return eSIR_SUCCESS;
4986 }
4987
4988returnAfterError:
4989 cds_packet_free((void *)pPacket);
4990 return nSirStatus;
4991} /* End lim_send_sa_query_request_frame */
4992
4993/**
4994 * \brief Send SA query response action frame to peer
4995 *
4996 * \sa lim_send_sa_query_response_frame
4997 *
4998 *
4999 * \param pMac The global tpAniSirGlobal object
5000 *
5001 * \param transId Transaction identifier received in SA query request action frame
5002 *
5003 * \param peer The Mac address of the AP to which this action frame is addressed
5004 *
5005 * \param psessionEntry The PE session entry
5006 *
5007 * \return eSIR_SUCCESS if setup completes successfully
5008 * eSIR_FAILURE is some problem is encountered
5009 */
5010
5011tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
5012 uint8_t *transId, tSirMacAddr peer,
5013 tpPESession psessionEntry)
5014{
5015
5016 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
5017 uint8_t *pFrame;
5018 tSirRetStatus nSirStatus;
5019 tpSirMacMgmtHdr pMacHdr;
5020 uint32_t nBytes, nPayload, nStatus;
5021 void *pPacket;
5022 CDF_STATUS cdf_status;
5023 uint8_t txFlag = 0;
5024 uint8_t smeSessionId = 0;
5025
5026 smeSessionId = psessionEntry->smeSessionId;
5027
5028 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
5029 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
5030 /*11w action field is :
5031 action: 0 --> SA query request action frame
5032 action: 1 --> SA query response action frame */
5033 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
5034 /*11w SA query response transId is same as
5035 SA query request transId */
5036 cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
5037
5038 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
5039 if (DOT11F_FAILED(nStatus)) {
5040 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
5041 "or a SA Query Response (0x%08x)."),
5042 nStatus);
5043 /* We'll fall back on the worst case scenario: */
5044 nPayload = sizeof(tDot11fSaQueryRsp);
5045 } else if (DOT11F_WARNED(nStatus)) {
5046 lim_log(pMac, LOGW, FL("There were warnings while calculating "
5047 "the packed size for an SA Query Response"
5048 " (0x%08x)."), nStatus);
5049 }
5050
5051 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
5052 cdf_status =
5053 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
5054 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
5055 lim_log(pMac, LOGP,
5056 FL("Failed to allocate %d bytes for a SA query response"
5057 " action frame"), nBytes);
5058 return eSIR_FAILURE;
5059 }
5060 /* Paranoia: */
5061 cdf_mem_set(pFrame, nBytes, 0);
5062
5063 /* Copy necessary info to BD */
5064 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
5065 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
5066
5067 /* Update A3 with the BSSID */
5068 pMacHdr = (tpSirMacMgmtHdr) pFrame;
5069
5070 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
5071
5072 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
5073 /* in the FC */
5074 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
5075
5076 /* Pack 11w SA query response frame */
5077 nStatus = dot11f_pack_sa_query_rsp(pMac,
5078 &frm,
5079 pFrame + sizeof(tSirMacMgmtHdr),
5080 nPayload, &nPayload);
5081
5082 if (DOT11F_FAILED(nStatus)) {
5083 lim_log(pMac, LOGE,
5084 FL("Failed to pack an SA Query Response (0x%08x)."),
5085 nStatus);
5086 /* FIXME - Need to convert to tSirRetStatus */
5087 nSirStatus = eSIR_FAILURE;
5088 goto returnAfterError;
5089 } else if (DOT11F_WARNED(nStatus)) {
5090 lim_log(pMac, LOGW,
5091 FL
5092 ("There were warnings while packing SA Query Response (0x%08x)."),
5093 nStatus);
5094 }
5095
5096 lim_log(pMac, LOG1, FL("Sending a SA Query Response to "));
5097 lim_print_mac_addr(pMac, peer, LOGW);
5098
5099 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
5100#ifdef WLAN_FEATURE_P2P
5101 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
5102 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
5103#endif
5104 ) {
5105 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
5106 }
5107
5108 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
5109 psessionEntry->peSessionId, pMacHdr->fc.subType));
5110 cdf_status = wma_tx_frame(pMac,
5111 pPacket,
5112 (uint16_t) nBytes,
5113 TXRX_FRM_802_11_MGMT,
5114 ANI_TXDIR_TODS,
5115 7, lim_tx_complete, pFrame, txFlag,
5116 smeSessionId, 0);
5117 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
5118 psessionEntry->peSessionId, cdf_status));
5119 if (CDF_STATUS_SUCCESS != cdf_status) {
5120 PELOGE(lim_log
5121 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
5122 cdf_status);
5123 )
5124 nSirStatus = eSIR_FAILURE;
5125 /* Pkt will be freed up by the callback */
5126 return nSirStatus;
5127 } else {
5128 return eSIR_SUCCESS;
5129 }
5130
5131returnAfterError:
5132 cds_packet_free((void *)pPacket);
5133 return nSirStatus;
5134} /* End lim_send_sa_query_response_frame */
5135#endif