blob: 62f452b6e97afeefff2274286cebde5b1faef0ee [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
Krishna Kumaar Natarajand26e9e72015-11-03 11:49:03 -08001716 if (mac_ctx->rrm.rrmPEContext.rrmEnable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
1718 pe_session);
1719#endif
1720 /*
1721 * The join request *should* contain zero or one of the WPA and RSN
1722 * IEs. The payload send along with the request is a
1723 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
1724 * typedef struct sSirRSNie
1725 * {
1726 * uint16_t length;
1727 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
1728 * } tSirRSNie, *tpSirRSNie;
1729 * So, we should be able to make the following two calls harmlessly,
1730 * since they do nothing if they don't find the given IE in the
1731 * bytestream with which they're provided.
1732 * The net effect of this will be to faithfully transmit whatever
1733 * security IE is in the join request.
1734 * However, if we're associating for the purpose of WPS
1735 * enrollment, and we've been configured to indicate that by
1736 * eliding the WPA or RSN IE, we just skip this:
1737 */
1738 if (add_ie_len && add_ie)
1739 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
1740
1741 if (NULL == wps_ie) {
1742 populate_dot11f_rsn_opaque(mac_ctx,
1743 &(pe_session->pLimJoinReq->rsnIE),
1744 &frm->RSNOpaque);
1745 populate_dot11f_wpa_opaque(mac_ctx,
1746 &(pe_session->pLimJoinReq->rsnIE),
1747 &frm->WPAOpaque);
1748#if defined(FEATURE_WLAN_WAPI)
1749 populate_dot11f_wapi_opaque(mac_ctx,
1750 &(pe_session->pLimJoinReq->rsnIE),
1751 &frm->WAPIOpaque);
1752#endif /* defined(FEATURE_WLAN_WAPI) */
1753 }
1754 /* include WME EDCA IE as well */
1755 if (wme_enabled) {
1756 populate_dot11f_wmm_info_station_per_session(mac_ctx,
1757 pe_session, &frm->WMMInfoStation);
1758
1759 if (wsm_enabled)
1760 populate_dot11f_wmm_caps(&frm->WMMCaps);
1761 }
1762
1763 /*
1764 * Populate HT IEs, when operating in 11n and
1765 * when AP is also operating in 11n mode
1766 */
1767 if (pe_session->htCapability &&
1768 mac_ctx->lim.htCapabilityPresentInBeacon) {
1769 lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
1770 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
1771 }
1772#ifdef WLAN_FEATURE_11AC
1773 if (pe_session->vhtCapability &&
1774 pe_session->vhtCapabilityPresentInBeacon) {
1775 lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request"));
1776 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
1777 vht_enabled = true;
1778 }
1779 if (!vht_enabled &&
1780 pe_session->is_vendor_specific_vhtcaps) {
1781 lim_log(mac_ctx, LOG1,
1782 FL("Populate Vendor VHT IEs in Assoc Request"));
1783 frm->vendor2_ie.present = 1;
1784 frm->vendor2_ie.type =
1785 pe_session->vendor_specific_vht_ie_type;
1786 frm->vendor2_ie.sub_type =
1787 pe_session->vendor_specific_vht_ie_sub_type;
1788
1789 frm->vendor2_ie.VHTCaps.present = 1;
1790 populate_dot11f_vht_caps(mac_ctx, pe_session,
1791 &frm->vendor2_ie.VHTCaps);
1792 vht_enabled = true;
1793 }
1794
1795#endif
1796
1797 populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap, pe_session);
1798
1799#if defined WLAN_FEATURE_VOWIFI_11R
1800 if (pe_session->pLimJoinReq->is11Rconnection) {
1801#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
1802 tSirBssDescription *bssdescr;
1803
1804 bssdescr = &pe_session->pLimJoinReq->bssDescription;
1805 lim_log(mac_ctx, LOG1, FL("mdie = %02x %02x %02x"),
1806 (unsigned int) bssdescr->mdie[0],
1807 (unsigned int) bssdescr->mdie[1],
1808 (unsigned int) bssdescr->mdie[2]);
1809#endif
1810 populate_mdie(mac_ctx, &frm->MobilityDomain,
1811 pe_session->pLimJoinReq->bssDescription.mdie);
1812 } else {
1813 /* No 11r IEs dont send any MDIE */
1814 lim_log(mac_ctx, LOG1, FL("MDIE not present"));
1815 }
1816#endif
1817
1818#ifdef FEATURE_WLAN_ESE
1819 /*
1820 * ESE Version IE will be included in association request
1821 * when ESE is enabled on DUT through ini and it is also
1822 * advertised by the peer AP to which we are trying to
1823 * associate to.
1824 */
1825 if (pe_session->is_ese_version_ie_present &&
1826 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
1827 populate_dot11f_ese_version(&frm->ESEVersion);
1828 /* For ESE Associations fill the ESE IEs */
1829 if (pe_session->isESEconnection &&
1830 pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
1831#ifndef FEATURE_DISABLE_RM
1832 populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
1833#endif
1834 }
1835#endif
1836
1837 status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
1838 if (DOT11F_FAILED(status)) {
1839 lim_log(mac_ctx, LOGP,
1840 FL("Association Request packet size failure(0x%08x)."),
1841 status);
1842 /* We'll fall back on the worst case scenario: */
1843 payload = sizeof(tDot11fAssocRequest);
1844 } else if (DOT11F_WARNED(status)) {
1845 lim_log(mac_ctx, LOGW,
1846 FL("Association request packet size warning (0x%08x)."),
1847 status);
1848 }
1849
1850 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
1851
1852 cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
1853 (void **)&packet);
1854 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1855 lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes."),
1856 bytes);
1857
1858 pe_session->limMlmState = pe_session->limPrevMlmState;
1859 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
1860 pe_session->peSessionId,
1861 pe_session->limMlmState));
1862
1863 /* Update PE session id */
1864 assoc_cnf.sessionId = pe_session->peSessionId;
1865
1866 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
1867
1868 cds_packet_free((void *)packet);
1869
1870 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1871 (uint32_t *) &assoc_cnf);
1872
1873 cdf_mem_free(frm);
1874 return;
1875 }
1876 /* Paranoia: */
1877 cdf_mem_set(frame, bytes, 0);
1878
1879 /* Next, we fill out the buffer descriptor: */
1880 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
1881 SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
1882 pe_session->selfMacAddr);
1883 /* merge the ExtCap struct */
1884 if (extr_ext_flag)
1885 lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap);
1886 /* That done, pack the Assoc Request: */
1887 status = dot11f_pack_assoc_request(mac_ctx, frm,
1888 frame + sizeof(tSirMacMgmtHdr), payload, &payload);
1889 if (DOT11F_FAILED(status)) {
1890 lim_log(mac_ctx, LOGE,
1891 FL("Assoc request pack failure (0x%08x)"), status);
1892 cds_packet_free((void *)packet);
1893 cdf_mem_free(frm);
1894 return;
1895 } else if (DOT11F_WARNED(status)) {
1896 lim_log(mac_ctx, LOGW,
1897 FL("Assoc request pack warning (0x%08x)"), status);
1898 }
1899
1900 lim_log(mac_ctx, LOG1,
1901 FL("*** Sending Association Request length %d to "), bytes);
1902 if (pe_session->assocReq != NULL) {
1903 cdf_mem_free(pe_session->assocReq);
1904 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08001905 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001906 }
1907
1908 if (add_ie_len) {
1909 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
1910 add_ie, add_ie_len);
1911 payload += add_ie_len;
1912 }
1913
1914 pe_session->assocReq = cdf_mem_malloc(payload);
1915 if (NULL == pe_session->assocReq) {
1916 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
1917 } else {
1918 /*
1919 * Store the Assoc request. This is sent to csr/hdd in
1920 * join cnf response.
1921 */
1922 cdf_mem_copy(pe_session->assocReq,
1923 frame + sizeof(tSirMacMgmtHdr), payload);
1924 pe_session->assocReqLen = payload;
1925 }
1926
1927 if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
1928 || (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
1929 || (pe_session->pePersona == CDF_P2P_GO_MODE)
1930 )
1931 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
1932
Sushant Kaushik46556062015-12-02 16:57:47 +05301933 if (pe_session->pePersona == CDF_P2P_CLIENT_MODE ||
1934 pe_session->pePersona == CDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935 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
Krishna Kumaar Natarajand26e9e72015-11-03 11:49:03 -08002094 if (mac_ctx->rrm.rrmPEContext.rrmEnable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095 populate_dot11f_rrm_ie(mac_ctx, &frm.RRMEnabledCap, pe_session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002096#endif
2097
2098 /*
2099 * Ideally this should be enabled for 11r also. But 11r does
2100 * not follow the usual norm of using the Opaque object
2101 * for rsnie and fties. Instead we just add the rsnie and fties
2102 * at the end of the pack routine for 11r.
2103 * This should ideally! be fixed.
2104 */
2105#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2106 /*
2107 * The join request *should* contain zero or one of the WPA and RSN
2108 * IEs. The payload send along with the request is a
2109 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
2110 *
2111 * typedef struct sSirRSNie
2112 * {
2113 * uint16_t length;
2114 * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
2115 * } tSirRSNie, *tpSirRSNie;
2116 *
2117 * So, we should be able to make the following two calls harmlessly,
2118 * since they do nothing if they don't find the given IE in the
2119 * bytestream with which they're provided.
2120 *
2121 * The net effect of this will be to faithfully transmit whatever
2122 * security IE is in the join request.
2123
2124 * However, if we're associating for the purpose of WPS
2125 * enrollment, and we've been configured to indicate that by
2126 * eliding the WPA or RSN IE, we just skip this:
2127 */
2128 if (!pe_session->is11Rconnection) {
2129 if (add_ie_len && add_ie)
2130 wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
2131 if (NULL == wps_ie) {
2132 populate_dot11f_rsn_opaque(mac_ctx,
2133 &(pe_session->pLimReAssocReq->rsnIE),
2134 &frm.RSNOpaque);
2135 populate_dot11f_wpa_opaque(mac_ctx,
2136 &(pe_session->pLimReAssocReq->rsnIE),
2137 &frm.WPAOpaque);
2138 }
2139#ifdef FEATURE_WLAN_ESE
2140 if (pe_session->pLimReAssocReq->cckmIE.length) {
2141 populate_dot11f_ese_cckm_opaque(mac_ctx,
2142 &(pe_session->pLimReAssocReq->cckmIE),
2143 &frm.ESECckmOpaque);
2144 }
2145#endif
2146 }
2147#ifdef FEATURE_WLAN_ESE
2148 /*
2149 * ESE Version IE will be included in re-association request
2150 * when ESE is enabled on DUT through ini and it is also
2151 * advertised by the peer AP to which we are trying to
2152 * associate to.
2153 */
2154 if (pe_session->is_ese_version_ie_present &&
2155 mac_ctx->roam.configParam.isEseIniFeatureEnabled)
2156 populate_dot11f_ese_version(&frm.ESEVersion);
2157 /* For ESE Associations fill the ESE IEs */
2158 if (pe_session->isESEconnection &&
2159 pe_session->pLimReAssocReq->isESEFeatureIniEnabled) {
2160#ifndef FEATURE_DISABLE_RM
2161 populate_dot11f_ese_rad_mgmt_cap(&frm.ESERadMgmtCap);
2162#endif
2163 }
2164#endif /* FEATURE_WLAN_ESE */
2165#endif /* FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
2166
2167 /* include WME EDCA IE as well */
2168 if (wme_enabled) {
2169 populate_dot11f_wmm_info_station_per_session(mac_ctx,
2170 pe_session, &frm.WMMInfoStation);
2171 if (wsm_enabled)
2172 populate_dot11f_wmm_caps(&frm.WMMCaps);
2173#ifdef FEATURE_WLAN_ESE
2174 if (pe_session->isESEconnection) {
2175 uint32_t phymode;
2176 uint8_t rate;
2177
2178 populate_dot11f_re_assoc_tspec(mac_ctx, &frm,
2179 pe_session);
2180
2181 /*
2182 * Populate the TSRS IE if TSPEC is included in
2183 * the reassoc request
2184 */
2185 lim_get_phy_mode(mac_ctx, &phymode, pe_session);
2186 if (phymode == WNI_CFG_PHY_MODE_11G ||
2187 phymode == WNI_CFG_PHY_MODE_11A)
2188 rate = TSRS_11AG_RATE_6MBPS;
2189 else
2190 rate = TSRS_11B_RATE_5_5MBPS;
2191
2192 if (pe_session->pLimReAssocReq->eseTspecInfo.
2193 numTspecs) {
2194 tSirMacESETSRSIE tsrs_ie;
2195
2196 tsrs_ie.tsid = 0;
2197 tsrs_ie.rates[0] = rate;
2198 populate_dot11_tsrsie(mac_ctx, &tsrs_ie,
2199 &frm.ESETrafStrmRateSet,
2200 sizeof(uint8_t));
2201 }
2202 }
2203#endif
2204 }
2205
2206 ft_sme_context = &mac_ctx->roam.roamSession[sme_sessionid].ftSmeContext;
2207 if (pe_session->htCapability &&
2208 mac_ctx->lim.htCapabilityPresentInBeacon) {
2209 populate_dot11f_ht_caps(mac_ctx, pe_session, &frm.HTCaps);
2210 }
2211#if defined WLAN_FEATURE_VOWIFI_11R
2212 if (pe_session->pLimReAssocReq->bssDescription.mdiePresent &&
2213 (ft_sme_context->addMDIE == true)
2214#if defined FEATURE_WLAN_ESE
2215 && !pe_session->isESEconnection
2216#endif
2217 ) {
2218 populate_mdie(mac_ctx, &frm.MobilityDomain,
2219 pe_session->pLimReAssocReq->bssDescription.mdie);
2220 }
2221#endif
2222
2223#ifdef WLAN_FEATURE_11AC
2224 if (pe_session->vhtCapability &&
2225 pe_session->vhtCapabilityPresentInBeacon) {
2226 lim_log(mac_ctx, LOG1,
2227 FL("Populate VHT IEs in Re-Assoc Request"));
2228 populate_dot11f_vht_caps(mac_ctx, pe_session, &frm.VHTCaps);
2229 vht_enabled = true;
2230 populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm.ExtCap,
2231 pe_session);
2232 }
2233 if (!vht_enabled &&
2234 pe_session->is_vendor_specific_vhtcaps) {
2235 lim_log(mac_ctx, LOG1,
2236 FL("Populate Vendor VHT IEs in Re-Assoc Request"));
2237 frm.vendor2_ie.present = 1;
2238 frm.vendor2_ie.type =
2239 pe_session->vendor_specific_vht_ie_type;
2240 frm.vendor2_ie.sub_type =
2241 pe_session->vendor_specific_vht_ie_sub_type;
2242 frm.vendor2_ie.VHTCaps.present = 1;
2243 populate_dot11f_vht_caps(mac_ctx, pe_session,
2244 &frm.vendor2_ie.VHTCaps);
2245 vht_enabled = true;
2246 }
2247#endif
2248
2249 status = dot11f_get_packed_re_assoc_request_size(mac_ctx, &frm,
2250 &payload);
2251 if (DOT11F_FAILED(status)) {
2252 lim_log(mac_ctx, LOGP,
2253 FL("Failure in size calculation (0x%08x)."), status);
2254 /* We'll fall back on the worst case scenario: */
2255 payload = sizeof(tDot11fReAssocRequest);
2256 } else if (DOT11F_WARNED(status)) {
2257 lim_log(mac_ctx, LOGW,
2258 FL("Warnings in size calculation(0x%08x)."), status);
2259 }
2260
2261 bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
2262
2263#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
2264 lim_log(mac_ctx, LOG1, FL("FT IE Reassoc Req (%d)."),
2265 ft_sme_context->reassoc_ft_ies_length);
2266#endif
2267
2268#if defined WLAN_FEATURE_VOWIFI_11R
2269 if (pe_session->is11Rconnection)
2270 ft_ies_length = ft_sme_context->reassoc_ft_ies_length;
2271#endif
2272
2273 cdf_status = cds_packet_alloc((uint16_t) bytes + ft_ies_length,
2274 (void **)&frame, (void **)&packet);
2275 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2276 pe_session->limMlmState = pe_session->limPrevMlmState;
2277 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
2278 pe_session->peSessionId,
2279 pe_session->limMlmState));
2280 lim_log(mac_ctx, LOGP, FL("Failed to alloc memory %d"), bytes);
2281 goto end;
2282 }
2283 /* Paranoia: */
2284 cdf_mem_set(frame, bytes + ft_ies_length, 0);
2285
2286#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
2287 lim_print_mac_addr(mac_ctx, pe_session->limReAssocbssId, LOG1);
2288#endif
2289 /* Next, we fill out the buffer descriptor: */
2290 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2291 SIR_MAC_MGMT_REASSOC_REQ, pe_session->limReAssocbssId,
2292 pe_session->selfMacAddr);
2293 mac_hdr = (tpSirMacMgmtHdr) frame;
2294 /* That done, pack the ReAssoc Request: */
2295 status = dot11f_pack_re_assoc_request(mac_ctx, &frm, frame +
2296 sizeof(tSirMacMgmtHdr),
2297 payload, &payload);
2298 if (DOT11F_FAILED(status)) {
2299 lim_log(mac_ctx, LOGE, FL("Failure in pack (0x%08x)."), status);
2300 cds_packet_free((void *)packet);
2301 goto end;
2302 } else if (DOT11F_WARNED(status)) {
2303 lim_log(mac_ctx, LOGW, FL("Warnings in pack (0x%08x)."),
2304 status);
2305 }
2306
2307 lim_log(mac_ctx, LOG3,
2308 FL("*** Sending Re-Assoc Request length %d %d to "),
2309 bytes, payload);
2310
2311 if (pe_session->assocReq != NULL) {
2312 cdf_mem_free(pe_session->assocReq);
2313 pe_session->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002314 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002315 }
2316
2317 if (add_ie_len) {
2318 cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
2319 add_ie, add_ie_len);
2320 payload += add_ie_len;
2321 }
2322
2323 pe_session->assocReq = cdf_mem_malloc(payload);
2324 if (NULL == pe_session->assocReq) {
2325 lim_log(mac_ctx, LOGE, FL("Failed to alloc memory"));
2326 } else {
2327 /*
2328 * Store the Assoc request. This is sent to csr/hdd in
2329 * join cnf response.
2330 */
2331 cdf_mem_copy(pe_session->assocReq,
2332 frame + sizeof(tSirMacMgmtHdr), payload);
2333 pe_session->assocReqLen = payload;
2334 }
2335
2336 if (pe_session->is11Rconnection && ft_sme_context->reassoc_ft_ies) {
2337 int i = 0;
2338
2339 body = frame + bytes;
2340 for (i = 0; i < ft_ies_length; i++) {
2341 *body = ft_sme_context->reassoc_ft_ies[i];
2342 body++;
2343 }
2344 }
2345#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
2346 PELOGE(lim_log(mac_ctx, LOG1, FL("Re-assoc Req Frame is: "));
2347 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG1,
2348 (uint8_t *) frame, (bytes + ft_ies_length));
2349 )
2350#endif
2351 if ((SIR_BAND_5_GHZ ==
2352 lim_get_rf_band(pe_session->currentOperChannel)) ||
2353 (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
2354 (pe_session->pePersona == CDF_P2P_GO_MODE)) {
2355 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2356 }
2357
2358 if (NULL != pe_session->assocReq) {
2359 cdf_mem_free(pe_session->assocReq);
2360 pe_session->assocReq = NULL;
Sreelakshmi Konamki3b8ba612015-12-02 18:13:22 +05302361 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002362 }
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002363 if (ft_ies_length) {
2364 pe_session->assocReq = cdf_mem_malloc(ft_ies_length);
2365 if (NULL == pe_session->assocReq) {
2366 lim_log(mac_ctx,
2367 LOGE, FL("Failed to alloc memory for FT IEs"));
2368 pe_session->assocReqLen = 0;
2369 } else {
2370 /*
2371 * Store the FT IEs. This is sent to csr/hdd in
2372 * join cnf response.
2373 */
2374 cdf_mem_copy(pe_session->assocReq,
2375 ft_sme_context->reassoc_ft_ies, ft_ies_length);
2376 pe_session->assocReqLen = ft_ies_length;
2377 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002378 } else {
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002379 lim_log(mac_ctx, LOG1, FL("FT IEs not present"));
Naveen Rawat83102ef2015-11-03 10:42:34 -08002380 pe_session->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381 }
2382
2383#ifdef FEATURE_WLAN_DIAG_SUPPORT
2384 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_START_EVENT,
2385 pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
2386#endif
2387 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
2388 pe_session->peSessionId, mac_hdr->fc.subType));
2389 cdf_status = wma_tx_frame(mac_ctx, packet,
2390 (uint16_t) (bytes + ft_ies_length),
2391 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2392 lim_tx_complete, frame, tx_flag, sme_sessionid,
2393 0);
2394 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2395 pe_session->peSessionId, cdf_status));
2396 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2397 lim_log(mac_ctx, LOGE,
2398 FL("Failed to send Re-Assoc Request (%X)!"),
2399 cdf_status);
2400 }
2401
2402end:
2403 /* Free up buffer allocated for mlmAssocReq */
2404 cdf_mem_free(mlm_reassoc_req);
2405 pe_session->pLimMlmReassocReq = NULL;
2406
2407}
2408
2409void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
2410 tLimMlmReassocReq *pMlmReassocReq,
2411 tpPESession psessionEntry)
2412{
2413 tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
2414 tLimMlmReassocReq *pTmpMlmReassocReq = NULL;
2415 if (NULL == pTmpMlmReassocReq) {
2416 pTmpMlmReassocReq = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
2417 if (NULL == pTmpMlmReassocReq)
2418 goto end;
2419 cdf_mem_set(pTmpMlmReassocReq, sizeof(tLimMlmReassocReq), 0);
2420 cdf_mem_copy(pTmpMlmReassocReq, pMlmReassocReq,
2421 sizeof(tLimMlmReassocReq));
2422 }
2423 /* Prepare and send Reassociation request frame */
2424 /* start reassoc timer. */
2425 pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
2426 psessionEntry->peSessionId;
2427 /* Start reassociation failure timer */
2428 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE,
2429 psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
2430 if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
2431 != TX_SUCCESS) {
2432 /* Could not start reassoc failure timer. */
2433 /* Log error */
2434 lim_log(pMac, LOGP,
2435 FL("could not start Reassociation failure timer"));
2436 /* Return Reassoc confirm with */
2437 /* Resources Unavailable */
2438 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
2439 mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2440 goto end;
2441 }
2442
2443 lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac, pTmpMlmReassocReq,
2444 psessionEntry);
2445 return;
2446
2447end:
2448 /* Free up buffer allocated for reassocReq */
2449 if (pMlmReassocReq != NULL) {
2450 cdf_mem_free(pMlmReassocReq);
2451 pMlmReassocReq = NULL;
2452 }
2453 if (pTmpMlmReassocReq != NULL) {
2454 cdf_mem_free(pTmpMlmReassocReq);
2455 pTmpMlmReassocReq = NULL;
2456 }
2457 mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
2458 mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2459 /* Update PE sessio Id */
2460 mlmReassocCnf.sessionId = psessionEntry->peSessionId;
2461
2462 lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
2463 (uint32_t *) &mlmReassocCnf);
2464}
2465
2466#endif /* WLAN_FEATURE_VOWIFI_11R */
2467
2468void
2469lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal pMac,
2470 tLimMlmReassocReq *pMlmReassocReq,
2471 tpPESession psessionEntry)
2472{
2473 static tDot11fReAssocRequest frm;
2474 uint16_t caps;
2475 uint8_t *pFrame;
2476 uint32_t nBytes, nPayload, nStatus;
2477 uint8_t fQosEnabled, fWmeEnabled, fWsmEnabled;
2478 void *pPacket;
2479 CDF_STATUS cdf_status;
2480 uint16_t nAddIELen;
2481 uint8_t *pAddIE;
2482 uint8_t *wpsIe = NULL;
2483 uint8_t txFlag = 0;
2484#if defined WLAN_FEATURE_VOWIFI
2485 uint8_t PowerCapsPopulated = false;
2486#endif
2487 uint8_t smeSessionId = 0;
2488 bool isVHTEnabled = false;
2489 tpSirMacMgmtHdr pMacHdr;
2490
2491 if (NULL == psessionEntry) {
2492 return;
2493 }
2494
2495 smeSessionId = psessionEntry->smeSessionId;
2496
2497 /* check this early to avoid unncessary operation */
2498 if (NULL == psessionEntry->pLimReAssocReq) {
2499 return;
2500 }
2501 nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
2502 pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;
2503
2504 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
2505
2506 caps = pMlmReassocReq->capabilityInfo;
2507#if defined(FEATURE_WLAN_WAPI)
2508 /* CR: 262463 :
2509 According to WAPI standard:
2510 7.3.1.4 Capability Information field
2511 In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
2512 Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
2513 Reassociation management frames. */
2514 if (psessionEntry->encryptType == eSIR_ED_WPI)
2515 ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
2516#endif
2517 swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);
2518
2519 frm.ListenInterval.interval = pMlmReassocReq->listenInterval;
2520
2521 cdf_mem_copy((uint8_t *) frm.CurrentAPAddress.mac,
2522 (uint8_t *) psessionEntry->bssId, 6);
2523
2524 populate_dot11f_ssid2(pMac, &frm.SSID);
2525 populate_dot11f_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2526 &frm.SuppRates, psessionEntry);
2527
2528 fQosEnabled = (psessionEntry->limQosEnabled) &&
2529 SIR_MAC_GET_QOS(psessionEntry->limReassocBssCaps);
2530
2531 fWmeEnabled = (psessionEntry->limWmeEnabled) &&
2532 LIM_BSS_CAPS_GET(WME, psessionEntry->limReassocBssQosCaps);
2533
2534 fWsmEnabled = (psessionEntry->limWsmEnabled) && fWmeEnabled &&
2535 LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);
2536
2537 if (psessionEntry->lim11hEnable &&
2538 psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
2539#if defined WLAN_FEATURE_VOWIFI
2540 PowerCapsPopulated = true;
2541 populate_dot11f_power_caps(pMac, &frm.PowerCaps, LIM_REASSOC,
2542 psessionEntry);
2543 populate_dot11f_supp_channels(pMac, &frm.SuppChannels, LIM_REASSOC,
2544 psessionEntry);
2545#endif
2546 }
2547#if defined WLAN_FEATURE_VOWIFI
2548 if (pMac->rrm.rrmPEContext.rrmEnable &&
2549 SIR_MAC_GET_RRM(psessionEntry->limCurrentBssCaps)) {
2550 if (PowerCapsPopulated == false) {
2551 PowerCapsPopulated = true;
2552 populate_dot11f_power_caps(pMac, &frm.PowerCaps,
2553 LIM_REASSOC, psessionEntry);
2554 }
2555 }
2556#endif
2557
2558 if (fQosEnabled)
2559 populate_dot11f_qos_caps_station(pMac, &frm.QOSCapsStation);
2560
2561 populate_dot11f_ext_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2562 &frm.ExtSuppRates, psessionEntry);
2563
2564#if defined WLAN_FEATURE_VOWIFI
Krishna Kumaar Natarajand26e9e72015-11-03 11:49:03 -08002565 if (pMac->rrm.rrmPEContext.rrmEnable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002566 populate_dot11f_rrm_ie(pMac, &frm.RRMEnabledCap, psessionEntry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002567#endif
2568 /* The join request *should* contain zero or one of the WPA and RSN */
2569 /* IEs. The payload send along with the request is a */
2570 /* 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': */
2571
2572 /* typedef struct sSirRSNie */
2573 /* { */
2574 /* uint16_t length; */
2575 /* uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
2576 /* } tSirRSNie, *tpSirRSNie; */
2577
2578 /* So, we should be able to make the following two calls harmlessly, */
2579 /* since they do nothing if they don't find the given IE in the */
2580 /* bytestream with which they're provided. */
2581
2582 /* The net effect of this will be to faithfully transmit whatever */
2583 /* security IE is in the join request. */
2584
2585 /**However*, if we're associating for the purpose of WPS */
2586 /* enrollment, and we've been configured to indicate that by */
2587 /* eliding the WPA or RSN IE, we just skip this: */
2588 if (nAddIELen && pAddIE) {
2589 wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
2590 }
2591 if (NULL == wpsIe) {
2592 populate_dot11f_rsn_opaque(pMac,
2593 &(psessionEntry->pLimReAssocReq->rsnIE),
2594 &frm.RSNOpaque);
2595 populate_dot11f_wpa_opaque(pMac,
2596 &(psessionEntry->pLimReAssocReq->rsnIE),
2597 &frm.WPAOpaque);
2598#if defined(FEATURE_WLAN_WAPI)
2599 populate_dot11f_wapi_opaque(pMac,
2600 &(psessionEntry->pLimReAssocReq->
2601 rsnIE), &frm.WAPIOpaque);
2602#endif /* defined(FEATURE_WLAN_WAPI) */
2603 }
2604 /* include WME EDCA IE as well */
2605 if (fWmeEnabled) {
2606 populate_dot11f_wmm_info_station_per_session(pMac,
2607 psessionEntry,
2608 &frm.WMMInfoStation);
2609
2610 if (fWsmEnabled)
2611 populate_dot11f_wmm_caps(&frm.WMMCaps);
2612 }
2613
2614 if (psessionEntry->htCapability &&
2615 pMac->lim.htCapabilityPresentInBeacon) {
2616 populate_dot11f_ht_caps(pMac, psessionEntry, &frm.HTCaps);
2617 }
2618#ifdef WLAN_FEATURE_11AC
2619 if (psessionEntry->vhtCapability &&
2620 psessionEntry->vhtCapabilityPresentInBeacon) {
2621 lim_log(pMac, LOGW, FL("Populate VHT IEs in Re-Assoc Request"));
2622 populate_dot11f_vht_caps(pMac, psessionEntry, &frm.VHTCaps);
2623 isVHTEnabled = true;
2624 }
2625#endif
2626
2627 populate_dot11f_ext_cap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry);
2628
2629 nStatus = dot11f_get_packed_re_assoc_request_size(pMac, &frm, &nPayload);
2630 if (DOT11F_FAILED(nStatus)) {
2631 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
2632 "or a Re-Association Request (0x%08x)."),
2633 nStatus);
2634 /* We'll fall back on the worst case scenario: */
2635 nPayload = sizeof(tDot11fReAssocRequest);
2636 } else if (DOT11F_WARNED(nStatus)) {
2637 lim_log(pMac, LOGW, FL("There were warnings while calculating "
2638 "the packed size for a Re-Association Re "
2639 "quest(0x%08x)."), nStatus);
2640 }
2641
2642 nBytes = nPayload + sizeof(tSirMacMgmtHdr) + nAddIELen;
2643
2644 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
2645 (void **)&pPacket);
2646 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2647 psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
2648 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
2649 psessionEntry->peSessionId,
2650 psessionEntry->limMlmState));
2651 lim_log(pMac, LOGP,
2652 FL("Failed to allocate %d bytes for a Re-As"
2653 "sociation Request."), nBytes);
2654 goto end;
2655 }
2656 /* Paranoia: */
2657 cdf_mem_set(pFrame, nBytes, 0);
2658
2659 /* Next, we fill out the buffer descriptor: */
2660 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
2661 SIR_MAC_MGMT_REASSOC_REQ, psessionEntry->limReAssocbssId,
2662 psessionEntry->selfMacAddr);
2663 pMacHdr = (tpSirMacMgmtHdr) pFrame;
2664
2665 /* That done, pack the Probe Request: */
2666 nStatus = dot11f_pack_re_assoc_request(pMac, &frm, pFrame +
2667 sizeof(tSirMacMgmtHdr),
2668 nPayload, &nPayload);
2669 if (DOT11F_FAILED(nStatus)) {
2670 lim_log(pMac, LOGE, FL("Failed to pack a Re-Association Reque"
2671 "st (0x%08x)."), nStatus);
2672 cds_packet_free((void *)pPacket);
2673 goto end;
2674 } else if (DOT11F_WARNED(nStatus)) {
2675 lim_log(pMac, LOGW, FL("There were warnings while packing a R"
2676 "e-Association Request (0x%08x)."),
2677 nStatus);
2678 }
2679
2680 PELOG1(lim_log
2681 (pMac, LOG1,
2682 FL("*** Sending Re-Association Request length %d" "to "),
2683 nBytes);
2684 )
2685
2686 if (psessionEntry->assocReq != NULL) {
2687 cdf_mem_free(psessionEntry->assocReq);
2688 psessionEntry->assocReq = NULL;
Naveen Rawat83102ef2015-11-03 10:42:34 -08002689 psessionEntry->assocReqLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690 }
2691
2692 if (nAddIELen) {
2693 cdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
2694 pAddIE, nAddIELen);
2695 nPayload += nAddIELen;
2696 }
2697
2698 psessionEntry->assocReq = cdf_mem_malloc(nPayload);
2699 if (NULL == psessionEntry->assocReq) {
Varun Reddy Yeturu61ce89c2015-11-01 07:57:39 -08002700 lim_log(pMac, LOGE, FL("Unable to allocate mem for assoc req"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701 } else {
2702 /* Store the Assoc request. This is sent to csr/hdd in join cnf response. */
2703 cdf_mem_copy(psessionEntry->assocReq,
2704 pFrame + sizeof(tSirMacMgmtHdr), nPayload);
2705 psessionEntry->assocReqLen = nPayload;
2706 }
2707
2708 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
2709 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
2710 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
2711 ) {
2712 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
2713 }
2714
Sushant Kaushik46556062015-12-02 16:57:47 +05302715 if (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE ||
2716 psessionEntry->pePersona == CDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002717 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002718
2719#ifdef FEATURE_WLAN_DIAG_SUPPORT
2720 lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT,
2721 psessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
2722#endif
2723 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
2724 psessionEntry->peSessionId, pMacHdr->fc.subType));
2725 cdf_status =
2726 wma_tx_frame(pMac, pPacket,
2727 (uint16_t) (sizeof(tSirMacMgmtHdr) + nPayload),
2728 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
2729 lim_tx_complete, pFrame, txFlag, smeSessionId, 0);
2730 MTRACE(cdf_trace
2731 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
2732 psessionEntry->peSessionId, cdf_status));
2733 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2734 lim_log(pMac, LOGE,
2735 FL("Failed to send Re-Association Request (%X)!"),
2736 cdf_status);
2737 /* Pkt will be freed up by the callback */
2738 }
2739
2740end:
2741 /* Free up buffer allocated for mlmAssocReq */
2742 cdf_mem_free(pMlmReassocReq);
2743 psessionEntry->pLimMlmReassocReq = NULL;
2744
2745} /* lim_send_reassoc_req_mgmt_frame */
2746
2747/**
2748 * lim_send_auth_mgmt_frame() - Send an Authentication frame
2749 *
2750 * @mac_ctx: Pointer to Global MAC structure
2751 * @auth_frame: Pointer to Authentication frame structure
2752 * @peer_addr: MAC address of destination peer
2753 * @wep_bit: wep bit in frame control for Authentication frame3
2754 * @session: PE session information
2755 *
2756 * This function is called by lim_process_mlm_messages(). Authentication frame
2757 * is formatted and sent when this function is called.
2758 *
2759 * Return: void
2760 */
2761
2762void
2763lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
2764 tpSirMacAuthFrameBody auth_frame,
2765 tSirMacAddr peer_addr,
2766 uint8_t wep_bit, tpPESession session)
2767{
2768 uint8_t *frame, *body;
2769 uint32_t frame_len = 0, body_len = 0;
2770 tpSirMacMgmtHdr mac_hdr;
2771 void *packet;
2772 CDF_STATUS cdf_status;
2773 uint8_t tx_flag = 0;
2774 uint8_t sme_sessionid = 0;
2775 uint16_t ft_ies_length = 0;
2776
2777 if (NULL == session) {
2778 lim_log(mac_ctx, LOGE, FL("Error: psession Entry is NULL"));
2779 return;
2780 }
2781
2782 sme_sessionid = session->smeSessionId;
2783
2784 lim_log(mac_ctx, LOG1,
2785 FL("Sending Auth seq# %d status %d (%d) to " MAC_ADDRESS_STR),
2786 auth_frame->authTransactionSeqNumber,
2787 auth_frame->authStatusCode,
2788 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
2789 MAC_ADDR_ARRAY(peer_addr));
2790
2791 switch (auth_frame->authTransactionSeqNumber) {
2792 case SIR_MAC_AUTH_FRAME_1:
2793 /*
2794 * Allocate buffer for Authenticaton frame of size
2795 * equal to management frame header length plus 2 bytes
2796 * each for auth algorithm number, transaction number
2797 * and status code.
2798 */
2799
2800 frame_len = sizeof(tSirMacMgmtHdr) +
2801 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2802 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2803
2804#if defined WLAN_FEATURE_VOWIFI_11R
2805 if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
2806 if (NULL != session->ftPEContext.pFTPreAuthReq &&
2807 0 != session->ftPEContext.pFTPreAuthReq->
2808 ft_ies_length) {
2809 ft_ies_length = session->ftPEContext.
2810 pFTPreAuthReq->ft_ies_length;
2811 frame_len += ft_ies_length;
2812 lim_log(mac_ctx, LOG3,
2813 FL("Auth frame, FTIES length added=%d"),
2814 ft_ies_length);
2815 } else {
2816 lim_log(mac_ctx, LOG3,
2817 FL("Auth frame, Does not contain FTIES!!!"));
2818 frame_len += (2 + SIR_MDIE_SIZE);
2819 }
2820 }
2821#endif
2822 break;
2823
2824 case SIR_MAC_AUTH_FRAME_2:
2825 if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
2826 ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
2827 (auth_frame->authStatusCode !=
2828 eSIR_MAC_SUCCESS_STATUS))) {
2829 /*
2830 * Allocate buffer for Authenticaton frame of size
2831 * equal to management frame header length plus
2832 * 2 bytes each for auth algorithm number,
2833 * transaction number and status code.
2834 */
2835
2836 frame_len = sizeof(tSirMacMgmtHdr) +
2837 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2838 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2839 } else {
2840 /*
2841 * Shared Key algorithm with challenge text
2842 * to be sent.
2843 *
2844 * Allocate buffer for Authenticaton frame of size
2845 * equal to management frame header length plus
2846 * 2 bytes each for auth algorithm number,
2847 * transaction number, status code and 128 bytes
2848 * for challenge text.
2849 */
2850
2851 frame_len = sizeof(tSirMacMgmtHdr) +
2852 sizeof(tSirMacAuthFrame);
2853 body_len = sizeof(tSirMacAuthFrameBody);
2854 }
2855 break;
2856
2857 case SIR_MAC_AUTH_FRAME_3:
2858 if (wep_bit == LIM_WEP_IN_FC) {
2859 /*
2860 * Auth frame3 to be sent with encrypted framebody
2861 *
2862 * Allocate buffer for Authenticaton frame of size
2863 * equal to management frame header length plus 2 bytes
2864 * each for auth algorithm number, transaction number,
2865 * status code, 128 bytes for challenge text and
2866 * 4 bytes each for IV & ICV.
2867 */
2868
2869 frame_len = sizeof(tSirMacMgmtHdr) +
2870 LIM_ENCR_AUTH_BODY_LEN;
2871 body_len = LIM_ENCR_AUTH_BODY_LEN;
2872 } else {
2873
2874 /*
2875 * Auth frame3 to be sent without encrypted framebody
2876 *
2877 * Allocate buffer for Authenticaton frame of size equal
2878 * to management frame header length plus 2 bytes each
2879 * for auth algorithm number, transaction number and
2880 * status code.
2881 */
2882
2883 frame_len = sizeof(tSirMacMgmtHdr) +
2884 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2885 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2886 }
2887 break;
2888
2889 case SIR_MAC_AUTH_FRAME_4:
2890 /*
2891 * Allocate buffer for Authenticaton frame of size equal
2892 * to management frame header length plus 2 bytes each
2893 * for auth algorithm number, transaction number and
2894 * status code.
2895 */
2896
2897 frame_len = sizeof(tSirMacMgmtHdr) +
2898 SIR_MAC_AUTH_CHALLENGE_OFFSET;
2899 body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
2900
2901 break;
2902 } /* switch (auth_frame->authTransactionSeqNumber) */
2903
2904 cdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
2905 (void **)&packet);
2906
2907 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
2908 lim_log(mac_ctx, LOGP,
2909 FL("call to bufAlloc failed for AUTH frame"));
2910 return;
2911 }
2912
2913 cdf_mem_zero(frame, frame_len);
2914
2915 /* Prepare BD */
2916 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
2917 SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
2918 mac_hdr = (tpSirMacMgmtHdr) frame;
2919 mac_hdr->fc.wep = wep_bit;
2920
2921 /* Prepare BSSId */
2922 if (LIM_IS_AP_ROLE(session) ||
2923 LIM_IS_BT_AMP_AP_ROLE(session))
2924 cdf_mem_copy((uint8_t *) mac_hdr->bssId,
2925 (uint8_t *) session->bssId,
2926 sizeof(tSirMacAddr));
2927
2928 /* Prepare Authentication frame body */
2929 body = frame + sizeof(tSirMacMgmtHdr);
2930
2931 if (wep_bit == LIM_WEP_IN_FC) {
2932 cdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
2933
2934 lim_log(mac_ctx, LOG1,
2935 FL("*** Sending Auth seq# 3 status %d (%d) to"
2936 MAC_ADDRESS_STR),
2937 auth_frame->authStatusCode,
2938 (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
2939 MAC_ADDR_ARRAY(mac_hdr->da));
2940
2941 } else {
2942 *((uint16_t *) (body)) =
2943 sir_swap_u16if_needed(auth_frame->authAlgoNumber);
2944 body += sizeof(uint16_t);
2945 body_len -= sizeof(uint16_t);
2946
2947 *((uint16_t *) (body)) =
2948 sir_swap_u16if_needed(
2949 auth_frame->authTransactionSeqNumber);
2950 body += sizeof(uint16_t);
2951 body_len -= sizeof(uint16_t);
2952
2953 *((uint16_t *) (body)) =
2954 sir_swap_u16if_needed(auth_frame->authStatusCode);
2955 body += sizeof(uint16_t);
2956 body_len -= sizeof(uint16_t);
2957 if (body_len <= (sizeof(auth_frame->type) +
2958 sizeof(auth_frame->length) +
2959 sizeof(auth_frame->challengeText)))
2960 cdf_mem_copy(body, (uint8_t *) &auth_frame->type,
2961 body_len);
2962
2963#if defined WLAN_FEATURE_VOWIFI_11R
2964 if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
2965 (auth_frame->authTransactionSeqNumber ==
2966 SIR_MAC_AUTH_FRAME_1) &&
2967 (session->ftPEContext.pFTPreAuthReq != NULL)) {
2968
2969 if (ft_ies_length > 0) {
2970 cdf_mem_copy(body,
2971 session->ftPEContext.
2972 pFTPreAuthReq->ft_ies,
2973 ft_ies_length);
2974#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
2975 lim_log(mac_ctx, LOG2,
2976 FL("Auth1 Frame FTIE is: "));
2977 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
2978 (uint8_t *) body,
2979 ft_ies_length);
2980#endif
2981 } else if (NULL != session->ftPEContext.
2982 pFTPreAuthReq->pbssDescription) {
2983 /* MDID attr is 54 */
2984 *body = SIR_MDIE_ELEMENT_ID;
2985 body++;
2986 *body = SIR_MDIE_SIZE;
2987 body++;
2988 cdf_mem_copy(body,
2989 &session->ftPEContext.pFTPreAuthReq->
2990 pbssDescription->mdie[0],
2991 SIR_MDIE_SIZE);
2992 }
2993 }
2994#endif
2995
2996 lim_log(mac_ctx, LOG1,
2997 FL("*** Sending Auth seq# %d status %d (%d) to "
2998 MAC_ADDRESS_STR),
2999 auth_frame->authTransactionSeqNumber,
3000 auth_frame->authStatusCode,
3001 (auth_frame->authStatusCode ==
3002 eSIR_MAC_SUCCESS_STATUS),
3003 MAC_ADDR_ARRAY(mac_hdr->da));
3004 }
3005 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2, frame, frame_len);
3006
3007 if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
3008 || (session->pePersona == CDF_P2P_CLIENT_MODE)
3009 || (session->pePersona == CDF_P2P_GO_MODE)
3010#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
3011 || ((NULL != session->ftPEContext.pFTPreAuthReq) &&
3012 (SIR_BAND_5_GHZ ==
3013 lim_get_rf_band(session->ftPEContext.pFTPreAuthReq->
3014 preAuthchannelNum)))
3015#endif
3016 )
3017 tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3018
3019
Sushant Kaushik46556062015-12-02 16:57:47 +05303020 if (session->pePersona == CDF_P2P_CLIENT_MODE ||
3021 session->pePersona == CDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003022 tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
3023
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003024 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3025 session->peSessionId, mac_hdr->fc.subType));
3026 /* Queue Authentication frame in high priority WQ */
3027 cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
3028 TXRX_FRM_802_11_MGMT,
3029 ANI_TXDIR_TODS, 7, lim_tx_complete,
3030 frame, tx_flag, sme_sessionid, 0);
3031 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3032 session->peSessionId, cdf_status));
3033 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
3034 lim_log(mac_ctx, LOGE,
3035 FL("*** Could not send Auth frame, retCode=%X ***"),
3036 cdf_status);
3037
3038 return;
3039}
3040
3041CDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
3042{
3043 uint16_t aid;
3044 tpDphHashNode pStaDs;
3045 tLimMlmDeauthReq *pMlmDeauthReq;
3046 tLimMlmDeauthCnf mlmDeauthCnf;
3047 tpPESession psessionEntry;
3048
3049 pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
3050 if (pMlmDeauthReq) {
3051 if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
3052 lim_deactivate_and_change_timer(pMac,
3053 eLIM_DEAUTH_ACK_TIMER);
3054 }
3055
3056 psessionEntry = pe_find_session_by_session_id(pMac,
3057 pMlmDeauthReq->sessionId);
3058 if (psessionEntry == NULL) {
3059 PELOGE(lim_log(pMac, LOGE,
3060 FL
3061 ("session does not exist for given sessionId"));
3062 )
3063 mlmDeauthCnf.resultCode =
3064 eSIR_SME_INVALID_PARAMETERS;
3065 goto end;
3066 }
3067
3068 pStaDs =
3069 dph_lookup_hash_entry(pMac, pMlmDeauthReq->peerMacAddr, &aid,
3070 &psessionEntry->dph.dphHashTable);
3071 if (pStaDs == NULL) {
3072 mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
3073 goto end;
3074 }
3075
3076 /* / Receive path cleanup with dummy packet */
3077 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
3078 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
Abhishek Singhe0680852015-12-16 14:28:48 +05303079#ifdef WLAN_FEATURE_VOWIFI_11R
3080 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
3081 (
3082#ifdef FEATURE_WLAN_ESE
3083 (psessionEntry->isESEconnection) ||
3084#endif
3085#ifdef FEATURE_WLAN_LFR
3086 (psessionEntry->isFastRoamIniFeatureEnabled) ||
3087#endif
3088 (psessionEntry->is11Rconnection))) {
3089 PELOGE(lim_log(pMac, LOGE,
3090 FL("FT Preauth Session (%p,%d) Cleanup Deauth reason %d Trigger = %d"),
3091 psessionEntry, psessionEntry->peSessionId,
3092 pMlmDeauthReq->reasonCode,
3093 pMlmDeauthReq->deauthTrigger););
3094 lim_ft_cleanup(pMac, psessionEntry);
3095 } else {
3096 PELOGE(lim_log(pMac, LOGE,
3097 FL("No FT Preauth Session Cleanup in role %d"
3098#ifdef FEATURE_WLAN_ESE
3099 " isESE %d"
3100#endif
3101#ifdef FEATURE_WLAN_LFR
3102 " isLFR %d"
3103#endif
3104 " is11r %d, Deauth reason %d Trigger = %d"),
3105 psessionEntry->limSystemRole,
3106#ifdef FEATURE_WLAN_ESE
3107 psessionEntry->isESEconnection,
3108#endif
3109#ifdef FEATURE_WLAN_LFR
3110 psessionEntry->isFastRoamIniFeatureEnabled,
3111#endif
3112 psessionEntry->is11Rconnection,
3113 pMlmDeauthReq->reasonCode,
3114 pMlmDeauthReq->deauthTrigger););
3115 }
3116#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003117 /* / Free up buffer allocated for mlmDeauthReq */
3118 cdf_mem_free(pMlmDeauthReq);
3119 pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
3120 }
3121 return CDF_STATUS_SUCCESS;
3122end:
3123 cdf_mem_copy((uint8_t *) &mlmDeauthCnf.peerMacAddr,
3124 (uint8_t *) pMlmDeauthReq->peerMacAddr,
3125 sizeof(tSirMacAddr));
3126 mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
3127 mlmDeauthCnf.aid = pMlmDeauthReq->aid;
3128 mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
3129
3130 /* Free up buffer allocated */
3131 /* for mlmDeauthReq */
3132 cdf_mem_free(pMlmDeauthReq);
3133
3134 lim_post_sme_message(pMac,
3135 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
3136 return CDF_STATUS_SUCCESS;
3137}
3138
3139/**
3140 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
3141 *
3142 * @mac_ctx: Handle to MAC context
3143 *
3144 * Sends disassoc confirmation to SME. Removes disassoc request stored
3145 * in lim.
3146 *
3147 * Return: CDF_STATUS_SUCCESS
3148 */
3149
3150CDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
3151{
3152 uint16_t aid;
3153 tpDphHashNode sta_ds;
3154 tLimMlmDisassocCnf disassoc_cnf;
3155 tpPESession pe_session;
3156 tLimMlmDisassocReq *disassoc_req;
3157
3158 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
3159 if (disassoc_req) {
3160 if (tx_timer_running(
3161 &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
3162 lim_deactivate_and_change_timer(mac_ctx,
3163 eLIM_DISASSOC_ACK_TIMER);
3164
3165 pe_session = pe_find_session_by_session_id(
3166 mac_ctx, disassoc_req->sessionId);
3167 if (pe_session == NULL) {
3168 lim_log(mac_ctx, LOGE,
3169 FL("No session for given sessionId"));
3170 disassoc_cnf.resultCode =
3171 eSIR_SME_INVALID_PARAMETERS;
3172 goto end;
3173 }
3174
3175 sta_ds = dph_lookup_hash_entry(mac_ctx,
3176 disassoc_req->peerMacAddr, &aid,
3177 &pe_session->dph.dphHashTable);
3178 if (sta_ds == NULL) {
3179 lim_log(mac_ctx, LOGE, FL("StaDs Null"));
3180 disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
3181 goto end;
3182 }
3183 /* Receive path cleanup with dummy packet */
3184 if (eSIR_SUCCESS !=
3185 lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
3186 disassoc_cnf.resultCode =
3187 eSIR_SME_RESOURCES_UNAVAILABLE;
3188 lim_log(mac_ctx, LOGE, FL("cleanup_rx_path error"));
3189 goto end;
3190 }
3191#ifdef WLAN_FEATURE_VOWIFI_11R
3192 if (LIM_IS_STA_ROLE(pe_session) && (
3193#ifdef FEATURE_WLAN_ESE
3194 (pe_session->isESEconnection) ||
3195#endif
3196#ifdef FEATURE_WLAN_LFR
3197 (pe_session->isFastRoamIniFeatureEnabled) ||
3198#endif
3199 (pe_session->is11Rconnection)) &&
3200 (disassoc_req->reasonCode !=
3201 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
Srinivas Girigowdaf2599dd2015-11-16 18:20:46 -08003202 lim_log(mac_ctx, LOG1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003203 FL("FT Preauth Session (%p,%d) Clean up"),
3204 pe_session, pe_session->peSessionId);
3205
3206#if defined WLAN_FEATURE_VOWIFI_11R
3207 /* Delete FT session if there exists one */
3208 lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
3209#endif
3210 } else {
3211 lim_log(mac_ctx, LOGE,
3212 FL("No FT Preauth Session Clean up in role %d"
3213#ifdef FEATURE_WLAN_ESE
3214 " isESE %d"
3215#endif
3216#ifdef FEATURE_WLAN_LFR
3217 " isLFR %d"
3218#endif
3219 " is11r %d reason %d"),
3220 GET_LIM_SYSTEM_ROLE(pe_session),
3221#ifdef FEATURE_WLAN_ESE
3222 pe_session->isESEconnection,
3223#endif
3224#ifdef FEATURE_WLAN_LFR
3225 pe_session->isFastRoamIniFeatureEnabled,
3226#endif
3227 pe_session->is11Rconnection,
3228 disassoc_req->reasonCode);
3229 }
3230#endif
3231 /* Free up buffer allocated for mlmDisassocReq */
3232 cdf_mem_free(disassoc_req);
3233 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
3234 return CDF_STATUS_SUCCESS;
3235 } else {
3236 return CDF_STATUS_SUCCESS;
3237 }
3238end:
3239 cdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
3240 (uint8_t *) disassoc_req->peerMacAddr,
3241 sizeof(tSirMacAddr));
3242 disassoc_cnf.aid = disassoc_req->aid;
3243 disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
3244
3245 /* Update PE session ID */
3246 disassoc_cnf.sessionId = disassoc_req->sessionId;
3247
3248 if (disassoc_req != NULL) {
3249 /* / Free up buffer allocated for mlmDisassocReq */
3250 cdf_mem_free(disassoc_req);
3251 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
3252 }
3253
3254 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
3255 (uint32_t *) &disassoc_cnf);
3256 return CDF_STATUS_SUCCESS;
3257}
3258
3259CDF_STATUS lim_disassoc_tx_complete_cnf(tpAniSirGlobal pMac,
3260 uint32_t txCompleteSuccess)
3261{
3262 return lim_send_disassoc_cnf(pMac);
3263}
3264
3265CDF_STATUS lim_deauth_tx_complete_cnf(tpAniSirGlobal pMac,
3266 uint32_t txCompleteSuccess)
3267{
3268 return lim_send_deauth_cnf(pMac);
3269}
3270
3271/**
3272 * \brief This function is called to send Disassociate frame.
3273 *
3274 *
3275 * \param pMac Pointer to Global MAC structure
3276 *
3277 * \param nReason Indicates the reason that need to be sent in
3278 * Disassociation frame
3279 *
3280 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
3281 * sent
3282 *
3283 *
3284 */
3285
3286void
3287lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
3288 uint16_t nReason,
3289 tSirMacAddr peer,
3290 tpPESession psessionEntry, bool waitForAck)
3291{
3292 tDot11fDisassociation frm;
3293 uint8_t *pFrame;
3294 tpSirMacMgmtHdr pMacHdr;
3295 uint32_t nBytes, nPayload, nStatus;
3296 void *pPacket;
3297 CDF_STATUS cdf_status;
3298 uint8_t txFlag = 0;
3299 uint32_t val = 0;
3300 uint8_t smeSessionId = 0;
3301 if (NULL == psessionEntry) {
3302 return;
3303 }
3304
3305 /*
3306 * In case when cac timer is running for this SAP session then
3307 * avoid sending disassoc out. It is violation of dfs specification.
3308 */
3309 if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
3310 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
3311 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
3312 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
3313 FL
3314 ("CAC timer is running, drop disassoc from going out"));
3315 return;
3316 }
3317 smeSessionId = psessionEntry->smeSessionId;
3318
3319 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3320
3321 frm.Reason.code = nReason;
3322
3323 nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
3324 if (DOT11F_FAILED(nStatus)) {
3325 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3326 "or a Disassociation (0x%08x)."),
3327 nStatus);
3328 /* We'll fall back on the worst case scenario: */
3329 nPayload = sizeof(tDot11fDisassociation);
3330 } else if (DOT11F_WARNED(nStatus)) {
3331 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3332 "the packed size for a Disassociation "
3333 "(0x%08x)."), nStatus);
3334 }
3335
3336 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3337
3338 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3339 (void **)&pPacket);
3340 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3341 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Dis"
3342 "association."), nBytes);
3343 return;
3344 }
3345 /* Paranoia: */
3346 cdf_mem_set(pFrame, nBytes, 0);
3347
3348 /* Next, we fill out the buffer descriptor: */
3349 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3350 SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
3351 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3352
3353 /* Prepare the BSSID */
3354 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3355
3356#ifdef WLAN_FEATURE_11W
3357 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3358#endif
3359
3360 nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
3361 sizeof(tSirMacMgmtHdr),
3362 nPayload, &nPayload);
3363 if (DOT11F_FAILED(nStatus)) {
3364 lim_log(pMac, LOGE,
3365 FL("Failed to pack a Disassociation (0x%08x)."),
3366 nStatus);
3367 cds_packet_free((void *)pPacket);
3368 return; /* allocated! */
3369 } else if (DOT11F_WARNED(nStatus)) {
3370 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
3371 "isassociation (0x%08x)."), nStatus);
3372 }
3373
3374 lim_log(pMac, LOG1,
3375 FL("***Sessionid %d Sending Disassociation frame with "
3376 "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
3377 MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason,
3378 waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
3379 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
3380
3381 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
3382 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3383 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
3384 ) {
3385 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3386 }
3387
Sushant Kaushik46556062015-12-02 16:57:47 +05303388 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003389
3390 if (waitForAck) {
3391 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3392 psessionEntry->peSessionId,
3393 pMacHdr->fc.subType));
3394 /* Queue Disassociation frame in high priority WQ */
3395 /* get the duration from the request */
3396 cdf_status =
3397 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
3398 TXRX_FRM_802_11_MGMT,
3399 ANI_TXDIR_TODS, 7, lim_tx_complete,
3400 pFrame, lim_disassoc_tx_complete_cnf,
3401 txFlag, smeSessionId, false, 0);
3402 MTRACE(cdf_trace
3403 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3404 psessionEntry->peSessionId, cdf_status));
3405
3406 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
3407
3408 if (tx_timer_change
3409 (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
3410 != TX_SUCCESS) {
3411 lim_log(pMac, LOGP,
3412 FL("Unable to change Disassoc ack Timer val"));
3413 return;
3414 } else if (TX_SUCCESS !=
3415 tx_timer_activate(&pMac->lim.limTimers.
3416 gLimDisassocAckTimer)) {
3417 lim_log(pMac, LOGP,
3418 FL("Unable to activate Disassoc ack Timer"));
3419 lim_deactivate_and_change_timer(pMac,
3420 eLIM_DISASSOC_ACK_TIMER);
3421 return;
3422 }
3423 } else {
3424 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3425 psessionEntry->peSessionId,
3426 pMacHdr->fc.subType));
3427 /* Queue Disassociation frame in high priority WQ */
3428 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3429 TXRX_FRM_802_11_MGMT,
3430 ANI_TXDIR_TODS,
3431 7,
3432 lim_tx_complete, pFrame, txFlag,
3433 smeSessionId, 0);
3434 MTRACE(cdf_trace
3435 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3436 psessionEntry->peSessionId, cdf_status));
3437 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3438 lim_log(pMac, LOGE,
3439 FL("Failed to send Disassociation (%X)!"),
3440 cdf_status);
3441 /* Pkt will be freed up by the callback */
3442 }
3443 }
3444} /* End lim_send_disassoc_mgmt_frame. */
3445
3446/**
3447 * \brief This function is called to send a Deauthenticate frame
3448 *
3449 *
3450 * \param pMac Pointer to global MAC structure
3451 *
3452 * \param nReason Indicates the reason that need to be sent in the
3453 * Deauthenticate frame
3454 *
3455 * \param peeer address of the STA to which the frame is to be sent
3456 *
3457 *
3458 */
3459
3460void
3461lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
3462 uint16_t nReason,
3463 tSirMacAddr peer,
3464 tpPESession psessionEntry, bool waitForAck)
3465{
3466 tDot11fDeAuth frm;
3467 uint8_t *pFrame;
3468 tpSirMacMgmtHdr pMacHdr;
3469 uint32_t nBytes, nPayload, nStatus;
3470 void *pPacket;
3471 CDF_STATUS cdf_status;
3472 uint8_t txFlag = 0;
3473 uint32_t val = 0;
3474#ifdef FEATURE_WLAN_TDLS
3475 uint16_t aid;
3476 tpDphHashNode pStaDs;
3477#endif
3478 uint8_t smeSessionId = 0;
3479
3480 if (NULL == psessionEntry) {
3481 return;
3482 }
3483
3484 /*
3485 * In case when cac timer is running for this SAP session then
3486 * avoid deauth frame out. It is violation of dfs specification.
3487 */
3488 if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
3489 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
3490 (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
3491 CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
3492 FL
3493 ("CAC timer is running, drop the deauth from going out"));
3494 return;
3495 }
3496 smeSessionId = psessionEntry->smeSessionId;
3497
3498 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3499
3500 frm.Reason.code = nReason;
3501
3502 nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
3503 if (DOT11F_FAILED(nStatus)) {
3504 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3505 "or a De-Authentication (0x%08x)."),
3506 nStatus);
3507 /* We'll fall back on the worst case scenario: */
3508 nPayload = sizeof(tDot11fDeAuth);
3509 } else if (DOT11F_WARNED(nStatus)) {
3510 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3511 "the packed size for a De-Authentication "
3512 "(0x%08x)."), nStatus);
3513 }
3514
3515 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3516
3517 cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
3518 (void **)&pPacket);
3519 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3520 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
3521 "Authentication."), nBytes);
3522 return;
3523 }
3524 /* Paranoia: */
3525 cdf_mem_set(pFrame, nBytes, 0);
3526
3527 /* Next, we fill out the buffer descriptor: */
3528 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3529 SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
3530 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3531
3532 /* Prepare the BSSID */
3533 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
3534
3535#ifdef WLAN_FEATURE_11W
3536 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3537#endif
3538
3539 nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
3540 sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
3541 if (DOT11F_FAILED(nStatus)) {
3542 lim_log(pMac, LOGE,
3543 FL("Failed to pack a DeAuthentication (0x%08x)."),
3544 nStatus);
3545 cds_packet_free((void *)pPacket);
3546 return;
3547 } else if (DOT11F_WARNED(nStatus)) {
3548 lim_log(pMac, LOGW, FL("There were warnings while packing a D"
3549 "e-Authentication (0x%08x)."), nStatus);
3550 }
3551 lim_log(pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with "
3552 "reason %u and waitForAck %d to " MAC_ADDRESS_STR
3553 " ,From " MAC_ADDRESS_STR),
3554 psessionEntry->peSessionId, nReason, waitForAck,
3555 MAC_ADDR_ARRAY(pMacHdr->da),
3556 MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
3557
3558 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
3559 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
3560 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
3561 ) {
3562 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
3563 }
3564
Sushant Kaushik46556062015-12-02 16:57:47 +05303565 txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003566#ifdef FEATURE_WLAN_TDLS
3567 pStaDs =
3568 dph_lookup_hash_entry(pMac, peer, &aid,
3569 &psessionEntry->dph.dphHashTable);
3570#endif
3571
3572 if (waitForAck) {
3573 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3574 psessionEntry->peSessionId,
3575 pMacHdr->fc.subType));
3576 /* Queue Disassociation frame in high priority WQ */
3577 cdf_status =
3578 wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
3579 TXRX_FRM_802_11_MGMT,
3580 ANI_TXDIR_TODS, 7, lim_tx_complete,
3581 pFrame, lim_deauth_tx_complete_cnf,
3582 txFlag, smeSessionId, false, 0);
3583 MTRACE(cdf_trace
3584 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3585 psessionEntry->peSessionId, cdf_status));
3586 /* Pkt will be freed up by the callback lim_tx_complete */
3587 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3588 lim_log(pMac, LOGE,
3589 FL("Failed to send De-Authentication (%X)!"),
3590 cdf_status);
3591
3592 /* Call lim_process_deauth_ack_timeout which will send
3593 * DeauthCnf for this frame
3594 */
3595 lim_process_deauth_ack_timeout(pMac);
3596 return;
3597 }
3598
3599 val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
3600
3601 if (tx_timer_change
3602 (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
3603 != TX_SUCCESS) {
3604 lim_log(pMac, LOGP,
3605 FL("Unable to change Deauth ack Timer val"));
3606 return;
3607 } else if (TX_SUCCESS !=
3608 tx_timer_activate(&pMac->lim.limTimers.
3609 gLimDeauthAckTimer)) {
3610 lim_log(pMac, LOGP,
3611 FL("Unable to activate Deauth ack Timer"));
3612 lim_deactivate_and_change_timer(pMac,
3613 eLIM_DEAUTH_ACK_TIMER);
3614 return;
3615 }
3616 } else {
3617 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3618 psessionEntry->peSessionId,
3619 pMacHdr->fc.subType));
3620#ifdef FEATURE_WLAN_TDLS
3621 if ((NULL != pStaDs)
3622 && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
3623 /* Queue Disassociation frame in high priority WQ */
3624 cdf_status =
3625 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3626 TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
3627 7, lim_tx_complete, pFrame, txFlag,
3628 smeSessionId, 0);
3629 } else {
3630#endif
3631 /* Queue Disassociation frame in high priority WQ */
3632 cdf_status =
3633 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3634 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
3635 7, lim_tx_complete, pFrame, txFlag,
3636 smeSessionId, 0);
3637#ifdef FEATURE_WLAN_TDLS
3638 }
3639#endif
3640 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3641 psessionEntry->peSessionId, cdf_status));
3642 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3643 lim_log(pMac, LOGE,
3644 FL("Failed to send De-Authentication (%X)!"),
3645 cdf_status);
3646 /* Pkt will be freed up by the callback */
3647 }
3648 }
3649
3650} /* End lim_send_deauth_mgmt_frame. */
3651
3652#ifdef ANI_SUPPORT_11H
3653/**
3654 * \brief Send a Measurement Report Action frame
3655 *
3656 *
3657 * \param pMac Pointer to the global MAC structure
3658 *
3659 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
3660 *
3661 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3662 *
3663 *
3664 */
3665
3666tSirRetStatus
3667lim_send_meas_report_frame(tpAniSirGlobal pMac,
3668 tpSirMacMeasReqActionFrame pMeasReqFrame,
3669 tSirMacAddr peer, tpPESession psessionEntry)
3670{
3671 tDot11fMeasurementReport frm;
3672 uint8_t *pFrame;
3673 tSirRetStatus nSirStatus;
3674 tpSirMacMgmtHdr pMacHdr;
3675 uint32_t nBytes, nPayload, nStatus;
3676 void *pPacket;
3677 CDF_STATUS cdf_status;
3678
3679 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3680
3681 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3682 frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
3683 frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
3684
3685 switch (pMeasReqFrame->measReqIE.measType) {
3686 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
3687 nSirStatus =
3688 populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
3689 &frm.MeasurementReport);
3690 break;
3691 case SIR_MAC_CCA_MEASUREMENT_TYPE:
3692 nSirStatus =
3693 populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
3694 &frm.MeasurementReport);
3695 break;
3696 case SIR_MAC_RPI_MEASUREMENT_TYPE:
3697 nSirStatus =
3698 populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
3699 &frm.MeasurementReport);
3700 break;
3701 default:
3702 lim_log(pMac, LOGE, FL("Unknown measurement type %d in limSen"
3703 "dMeasReportFrame."),
3704 pMeasReqFrame->measReqIE.measType);
3705 return eSIR_FAILURE;
3706 }
3707
3708 if (eSIR_SUCCESS != nSirStatus)
3709 return eSIR_FAILURE;
3710
3711 nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
3712 if (DOT11F_FAILED(nStatus)) {
3713 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3714 "or a Measurement Report (0x%08x)."),
3715 nStatus);
3716 /* We'll fall back on the worst case scenario: */
3717 nPayload = sizeof(tDot11fMeasurementReport);
3718 } else if (DOT11F_WARNED(nStatus)) {
3719 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3720 "the packed size for a Measurement Rep"
3721 "ort (0x%08x)."), nStatus);
3722 }
3723
3724 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3725
3726 cdf_status =
3727 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3728 (uint16_t) nBytes, (void **)&pFrame,
3729 (void **)&pPacket);
3730 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3731 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
3732 "Authentication."), nBytes);
3733 return eSIR_FAILURE;
3734 }
3735 /* Paranoia: */
3736 cdf_mem_set(pFrame, nBytes, 0);
3737
3738 /* Next, we fill out the buffer descriptor: */
3739 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3740 SIR_MAC_MGMT_ACTION, peer);
3741 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3742
3743 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3744
3745#ifdef WLAN_FEATURE_11W
3746 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3747#endif
3748
3749 nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
3750 sizeof(tSirMacMgmtHdr),
3751 nPayload, &nPayload);
3752 if (DOT11F_FAILED(nStatus)) {
3753 lim_log(pMac, LOGE,
3754 FL("Failed to pack a Measurement Report (0x%08x)."),
3755 nStatus);
3756 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3757 (void *)pFrame, (void *)pPacket);
3758 return eSIR_FAILURE; /* allocated! */
3759 } else if (DOT11F_WARNED(nStatus)) {
3760 lim_log(pMac, LOGW, FL("There were warnings while packing a M"
3761 "easurement Report (0x%08x)."), nStatus);
3762 }
3763
3764 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3765 ((psessionEntry) ? psessionEntry->
3766 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3767 cdf_status =
3768 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3769 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3770 lim_tx_complete, pFrame, 0, 0);
3771 MTRACE(cdf_trace
3772 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3773 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3774 cdf_status));
3775 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3776 lim_log(pMac, LOGE,
3777 FL("Failed to send a Measurement Report (%X)!"),
3778 cdf_status);
3779 /* Pkt will be freed up by the callback */
3780 return eSIR_FAILURE; /* just allocated... */
3781 }
3782
3783 return eSIR_SUCCESS;
3784
3785} /* End lim_send_meas_report_frame. */
3786
3787/**
3788 * \brief Send a TPC Request Action frame
3789 *
3790 *
3791 * \param pMac Pointer to the global MAC datastructure
3792 *
3793 * \param peer MAC address to which the frame should be sent
3794 *
3795 *
3796 */
3797
3798void
3799lim_send_tpc_request_frame(tpAniSirGlobal pMac,
3800 tSirMacAddr peer, tpPESession psessionEntry)
3801{
3802 tDot11fTPCRequest frm;
3803 uint8_t *pFrame;
3804 tpSirMacMgmtHdr pMacHdr;
3805 uint32_t nBytes, nPayload, nStatus;
3806 void *pPacket;
3807 CDF_STATUS cdf_status;
3808
3809 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3810
3811 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3812 frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
3813 frm.DialogToken.token = 1;
3814 frm.TPCRequest.present = 1;
3815
3816 nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
3817 if (DOT11F_FAILED(nStatus)) {
3818 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3819 "or a TPC Request (0x%08x)."), nStatus);
3820 /* We'll fall back on the worst case scenario: */
3821 nPayload = sizeof(tDot11fTPCRequest);
3822 } else if (DOT11F_WARNED(nStatus)) {
3823 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3824 "the packed size for a TPC Request (0x"
3825 "%08x)."), nStatus);
3826 }
3827
3828 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3829
3830 cdf_status =
3831 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3832 (uint16_t) nBytes, (void **)&pFrame,
3833 (void **)&pPacket);
3834 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3835 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3836 " Request."), nBytes);
3837 return;
3838 }
3839 /* Paranoia: */
3840 cdf_mem_set(pFrame, nBytes, 0);
3841
3842 /* Next, we fill out the buffer descriptor: */
3843 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3844 SIR_MAC_MGMT_ACTION, peer);
3845 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3846
3847 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3848
3849#ifdef WLAN_FEATURE_11W
3850 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3851#endif
3852
3853 nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
3854 sizeof(tSirMacMgmtHdr),
3855 nPayload, &nPayload);
3856 if (DOT11F_FAILED(nStatus)) {
3857 lim_log(pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."),
3858 nStatus);
3859 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3860 (void *)pFrame, (void *)pPacket);
3861 return; /* allocated! */
3862 } else if (DOT11F_WARNED(nStatus)) {
3863 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3864 "PC Request (0x%08x)."), nStatus);
3865 }
3866
3867 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3868 ((psessionEntry) ? psessionEntry->
3869 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3870 cdf_status =
3871 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3872 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3873 lim_tx_complete, pFrame, 0, 0);
3874 MTRACE(cdf_trace
3875 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3876 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3877 cdf_status));
3878 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3879 lim_log(pMac, LOGE,
3880 FL("Failed to send a TPC Request (%X)!"),
3881 cdf_status);
3882 /* Pkt will be freed up by the callback */
3883 }
3884
3885} /* End lim_send_tpc_request_frame. */
3886
3887/**
3888 * \brief Send a TPC Report Action frame
3889 *
3890 *
3891 * \param pMac Pointer to the global MAC datastructure
3892 *
3893 * \param pTpcReqFrame Pointer to the received TPC Request
3894 *
3895 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
3896 *
3897 *
3898 */
3899
3900tSirRetStatus
3901lim_send_tpc_report_frame(tpAniSirGlobal pMac,
3902 tpSirMacTpcReqActionFrame pTpcReqFrame,
3903 tSirMacAddr peer, tpPESession psessionEntry)
3904{
3905 tDot11fTPCReport frm;
3906 uint8_t *pFrame;
3907 tpSirMacMgmtHdr pMacHdr;
3908 uint32_t nBytes, nPayload, nStatus;
3909 void *pPacket;
3910 CDF_STATUS cdf_status;
3911
3912 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
3913
3914 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
3915 frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
3916 frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
3917
3918 frm.TPCReport.tx_power = 0;
3919 frm.TPCReport.link_margin = 0;
3920 frm.TPCReport.present = 1;
3921
3922 nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
3923 if (DOT11F_FAILED(nStatus)) {
3924 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
3925 "or a TPC Report (0x%08x)."), nStatus);
3926 /* We'll fall back on the worst case scenario: */
3927 nPayload = sizeof(tDot11fTPCReport);
3928 } else if (DOT11F_WARNED(nStatus)) {
3929 lim_log(pMac, LOGW, FL("There were warnings while calculating "
3930 "the packed size for a TPC Report (0x"
3931 "%08x)."), nStatus);
3932 }
3933
3934 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
3935
3936 cdf_status =
3937 cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3938 (uint16_t) nBytes, (void **)&pFrame,
3939 (void **)&pPacket);
3940 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3941 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
3942 " Report."), nBytes);
3943 return eSIR_FAILURE;
3944 }
3945 /* Paranoia: */
3946 cdf_mem_set(pFrame, nBytes, 0);
3947
3948 /* Next, we fill out the buffer descriptor: */
3949 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
3950 SIR_MAC_MGMT_ACTION, peer);
3951
3952 pMacHdr = (tpSirMacMgmtHdr) pFrame;
3953
3954 cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
3955
3956#ifdef WLAN_FEATURE_11W
3957 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
3958#endif
3959
3960 nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
3961 sizeof(tSirMacMgmtHdr),
3962 nPayload, &nPayload);
3963 if (DOT11F_FAILED(nStatus)) {
3964 lim_log(pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."),
3965 nStatus);
3966 cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
3967 (void *)pFrame, (void *)pPacket);
3968 return eSIR_FAILURE; /* allocated! */
3969 } else if (DOT11F_WARNED(nStatus)) {
3970 lim_log(pMac, LOGW, FL("There were warnings while packing a T"
3971 "PC Report (0x%08x)."), nStatus);
3972 }
3973
3974 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
3975 ((psessionEntry) ? psessionEntry->
3976 peSessionId : NO_SESSION), pMacHdr->fc.subType));
3977 cdf_status =
3978 wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
3979 TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
3980 lim_tx_complete, pFrame, 0, 0);
3981 MTRACE(cdf_trace
3982 (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
3983 ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
3984 cdf_status));
3985 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3986 lim_log(pMac, LOGE,
3987 FL("Failed to send a TPC Report (%X)!"),
3988 cdf_status);
3989 /* Pkt will be freed up by the callback */
3990 return eSIR_FAILURE; /* just allocated... */
3991 }
3992
3993 return eSIR_SUCCESS;
3994
3995} /* End lim_send_tpc_report_frame. */
3996#endif /* ANI_SUPPORT_11H */
3997
3998/**
3999 * \brief Send a Channel Switch Announcement
4000 *
4001 *
4002 * \param pMac Pointer to the global MAC datastructure
4003 *
4004 * \param peer MAC address to which this frame will be sent
4005 *
4006 * \param nMode
4007 *
4008 * \param nNewChannel
4009 *
4010 * \param nCount
4011 *
4012 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4013 *
4014 *
4015 */
4016
4017tSirRetStatus
4018lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
4019 tSirMacAddr peer,
4020 uint8_t nMode,
4021 uint8_t nNewChannel,
4022 uint8_t nCount, tpPESession psessionEntry)
4023{
4024 tDot11fChannelSwitch frm;
4025 uint8_t *pFrame;
4026 tpSirMacMgmtHdr pMacHdr;
4027 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
4028 void *pPacket;
4029 CDF_STATUS cdf_status;
4030 uint8_t txFlag = 0;
4031
4032 uint8_t smeSessionId = 0;
4033
4034 if (psessionEntry == NULL) {
4035 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4036 return eSIR_FAILURE;
4037 }
4038 smeSessionId = psessionEntry->smeSessionId;
4039
4040 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4041
4042 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
4043 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
4044 frm.ChanSwitchAnn.switchMode = nMode;
4045 frm.ChanSwitchAnn.newChannel = nNewChannel;
4046 frm.ChanSwitchAnn.switchCount = nCount;
4047 frm.ChanSwitchAnn.present = 1;
4048
4049 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
4050 if (DOT11F_FAILED(nStatus)) {
4051 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4052 "or a Channel Switch (0x%08x)."),
4053 nStatus);
4054 /* We'll fall back on the worst case scenario: */
4055 nPayload = sizeof(tDot11fChannelSwitch);
4056 } else if (DOT11F_WARNED(nStatus)) {
4057 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4058 "the packed size for a Channel Switch (0x"
4059 "%08x)."), nStatus);
4060 }
4061
4062 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4063
4064 cdf_status =
4065 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4066 (void **)&pPacket);
4067 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4068 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
4069 " Report."), nBytes);
4070 return eSIR_FAILURE;
4071 }
4072 /* Paranoia: */
4073 cdf_mem_set(pFrame, nBytes, 0);
4074
4075 /* Next, we fill out the buffer descriptor: */
4076 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4077 SIR_MAC_MGMT_ACTION, peer,
4078 psessionEntry->selfMacAddr);
4079 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4080 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4081 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4082
4083#ifdef WLAN_FEATURE_11W
4084 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4085#endif
4086
4087 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
4088 sizeof(tSirMacMgmtHdr),
4089 nPayload, &nPayload);
4090 if (DOT11F_FAILED(nStatus)) {
4091 lim_log(pMac, LOGE,
4092 FL("Failed to pack a Channel Switch (0x%08x)."),
4093 nStatus);
4094 cds_packet_free((void *)pPacket);
4095 return eSIR_FAILURE; /* allocated! */
4096 } else if (DOT11F_WARNED(nStatus)) {
4097 lim_log(pMac, LOGW, FL("There were warnings while packing a C"
4098 "hannel Switch (0x%08x)."), nStatus);
4099 }
4100
4101 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4102 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4103 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4104 ) {
4105 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4106 }
4107
4108 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4109 psessionEntry->peSessionId, pMacHdr->fc.subType));
4110 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4111 TXRX_FRM_802_11_MGMT,
4112 ANI_TXDIR_TODS,
4113 7, lim_tx_complete, pFrame, txFlag,
4114 smeSessionId, 0);
4115 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4116 psessionEntry->peSessionId, cdf_status));
4117 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4118 lim_log(pMac, LOGE,
4119 FL("Failed to send a Channel Switch (%X)!"),
4120 cdf_status);
4121 /* Pkt will be freed up by the callback */
4122 return eSIR_FAILURE;
4123 }
4124
4125 return eSIR_SUCCESS;
4126
4127} /* End lim_send_channel_switch_mgmt_frame. */
4128
Abhishek Singh518323d2015-10-19 17:42:01 +05304129/**
4130 * lim_send_extended_chan_switch_action_frame()- function to send ECSA
4131 * action frame over the air .
4132 * @mac_ctx: pointer to global mac structure
4133 * @peer: Destination mac.
4134 * @mode: channel switch mode
4135 * @new_op_class: new op class
4136 * @new_channel: new channel to switch
4137 * @count: channel switch count
4138 *
4139 * This function is called to send ECSA frame.
4140 *
4141 * Return: success if frame is sent else return failure
4142 */
4143
4144tSirRetStatus
4145lim_send_extended_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
4146 tSirMacAddr peer, uint8_t mode, uint8_t new_op_class,
4147 uint8_t new_channel, uint8_t count, tpPESession session_entry)
4148{
4149 tDot11fext_channel_switch_action_frame frm;
4150 uint8_t *frame;
4151 tpSirMacMgmtHdr mac_hdr;
4152 uint32_t num_bytes, n_payload, status;
4153 void *packet;
4154 CDF_STATUS cdf_status;
4155 uint8_t txFlag = 0;
4156 uint8_t sme_session_id = 0;
4157
4158 if (session_entry == NULL) {
4159 lim_log(mac_ctx, LOGE, FL("Session entry is NULL!!!"));
4160 return eSIR_FAILURE;
4161 }
4162
4163 sme_session_id = session_entry->smeSessionId;
4164
4165 cdf_mem_set(&frm, sizeof(frm), 0);
4166
4167 frm.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
4168 frm.Action.action = SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID;
4169
4170 frm.ext_chan_switch_ann_action.switch_mode = mode;
4171 frm.ext_chan_switch_ann_action.op_class = new_op_class;
4172 frm.ext_chan_switch_ann_action.new_channel = new_channel;
4173 frm.ext_chan_switch_ann_action.switch_count = count;
4174
4175
4176 status = dot11f_get_packed_ext_channel_switch_action_frame_size(mac_ctx,
4177 &frm, &n_payload);
4178 if (DOT11F_FAILED(status)) {
4179 lim_log(mac_ctx, LOGP,
4180 FL("Failed to get packed size for Channel Switch 0x%08x."),
4181 status);
4182 /* We'll fall back on the worst case scenario*/
4183 n_payload = sizeof(tDot11fext_channel_switch_action_frame);
4184 } else if (DOT11F_WARNED(status)) {
4185 lim_log(mac_ctx, LOGW,
4186 FL("There were warnings while calculating the packed size for a Ext Channel Switch (0x%08x)."),
4187 status);
4188 }
4189
4190 num_bytes = n_payload + sizeof(tSirMacMgmtHdr);
4191
4192 cdf_status = cds_packet_alloc((uint16_t)num_bytes,
4193 (void **) &frame, (void **) &packet);
4194
4195 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4196 lim_log(mac_ctx, LOGP,
4197 FL("Failed to allocate %d bytes for a Ext Channel Switch."),
4198 num_bytes);
4199 return eSIR_FAILURE;
4200 }
4201
4202 /* Paranoia*/
4203 cdf_mem_set(frame, num_bytes, 0);
4204
4205 /* Next, we fill out the buffer descriptor */
4206 lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
4207 SIR_MAC_MGMT_ACTION, peer, session_entry->selfMacAddr);
4208 mac_hdr = (tpSirMacMgmtHdr) frame;
4209 cdf_mem_copy((uint8_t *) mac_hdr->bssId,
4210 (uint8_t *) session_entry->bssId,
4211 sizeof(tSirMacAddr));
4212
4213 status = dot11f_pack_ext_channel_switch_action_frame(mac_ctx, &frm,
4214 frame + sizeof(tSirMacMgmtHdr), n_payload, &n_payload);
4215 if (DOT11F_FAILED(status)) {
4216 lim_log(mac_ctx, LOGE,
4217 FL("Failed to pack a Channel Switch 0x%08x."),
4218 status);
4219 cds_packet_free((void *)packet);
4220 return eSIR_FAILURE;
4221 } else if (DOT11F_WARNED(status)) {
4222 lim_log(mac_ctx, LOGW,
4223 FL("There were warnings while packing a Channel Switch 0x%08x."),
4224 status);
4225 }
4226
4227 if ((SIR_BAND_5_GHZ ==
4228 lim_get_rf_band(session_entry->currentOperChannel)) ||
4229 (session_entry->pePersona == CDF_P2P_CLIENT_MODE) ||
4230 (session_entry->pePersona == CDF_P2P_GO_MODE)) {
4231 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4232 }
4233
4234 lim_log(mac_ctx, LOG1,
4235 FL("Send Ext channel Switch to :"MAC_ADDRESS_STR" with swcount %d, swmode %d , newchannel %d newops %d"),
4236 MAC_ADDR_ARRAY(mac_hdr->da),
4237 frm.ext_chan_switch_ann_action.switch_count,
4238 frm.ext_chan_switch_ann_action.switch_mode,
4239 frm.ext_chan_switch_ann_action.new_channel,
4240 frm.ext_chan_switch_ann_action.op_class);
4241
4242 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4243 session_entry->peSessionId, mac_hdr->fc.subType));
4244 cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) num_bytes,
4245 TXRX_FRM_802_11_MGMT,
4246 ANI_TXDIR_TODS,
4247 7,
4248 lim_tx_complete, frame,
4249 txFlag, sme_session_id, 0);
4250 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4251 session_entry->peSessionId, cdf_status));
4252 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4253 lim_log(mac_ctx, LOGE,
4254 FL("Failed to send a Ext Channel Switch %X!"),
4255 cdf_status);
4256 /* Pkt will be freed up by the callback */
4257 return eSIR_FAILURE;
4258 }
4259 return eSIR_SUCCESS;
4260} /* End lim_send_extended_chan_switch_action_frame */
4261
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004262#ifdef WLAN_FEATURE_11AC
4263tSirRetStatus
4264lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
4265 tSirMacAddr peer,
4266 uint8_t nMode, tpPESession psessionEntry)
4267{
4268 tDot11fOperatingMode frm;
4269 uint8_t *pFrame;
4270 tpSirMacMgmtHdr pMacHdr;
4271 uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
4272 void *pPacket;
4273 CDF_STATUS cdf_status;
4274 uint8_t txFlag = 0;
4275
4276 uint8_t smeSessionId = 0;
4277
4278 if (psessionEntry == NULL) {
4279 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4280 return eSIR_FAILURE;
4281 }
4282 smeSessionId = psessionEntry->smeSessionId;
4283
4284 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4285
4286 frm.Category.category = SIR_MAC_ACTION_VHT;
4287 frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
4288 frm.OperatingMode.chanWidth = nMode;
4289 frm.OperatingMode.rxNSS = 0;
4290 frm.OperatingMode.rxNSSType = 0;
4291
4292 nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
4293 if (DOT11F_FAILED(nStatus)) {
4294 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4295 "or a Operating Mode (0x%08x)."),
4296 nStatus);
4297 /* We'll fall back on the worst case scenario: */
4298 nPayload = sizeof(tDot11fOperatingMode);
4299 } else if (DOT11F_WARNED(nStatus)) {
4300 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4301 "the packed size for a Operating Mode (0x"
4302 "%08x)."), nStatus);
4303 }
4304
4305 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4306
4307 cdf_status =
4308 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4309 (void **)&pPacket);
4310 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4311 lim_log(pMac, LOGP,
4312 FL("Failed to allocate %d bytes for a Operating Mode"
4313 " Report."), nBytes);
4314 return eSIR_FAILURE;
4315 }
4316 /* Paranoia: */
4317 cdf_mem_set(pFrame, nBytes, 0);
4318
4319 /* Next, we fill out the buffer descriptor: */
4320 if (psessionEntry->pePersona == CDF_SAP_MODE)
4321 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4322 SIR_MAC_MGMT_ACTION, peer,
4323 psessionEntry->selfMacAddr);
4324 else
4325 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4326 SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
4327 psessionEntry->selfMacAddr);
4328 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4329 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4330 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4331 nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
4332 sizeof(tSirMacMgmtHdr),
4333 nPayload, &nPayload);
4334 if (DOT11F_FAILED(nStatus)) {
4335 lim_log(pMac, LOGE,
4336 FL("Failed to pack a Operating Mode (0x%08x)."),
4337 nStatus);
4338 cds_packet_free((void *)pPacket);
4339 return eSIR_FAILURE; /* allocated! */
4340 } else if (DOT11F_WARNED(nStatus)) {
4341 lim_log(pMac, LOGW,
4342 FL("There were warnings while packing a Operating Mode"
4343 " (0x%08x)."), nStatus);
4344 }
4345 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4346 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4347 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4348 ) {
4349 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4350 }
4351
4352 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4353 psessionEntry->peSessionId, pMacHdr->fc.subType));
4354 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4355 TXRX_FRM_802_11_MGMT,
4356 ANI_TXDIR_TODS,
4357 7, lim_tx_complete, pFrame, txFlag,
4358 smeSessionId, 0);
4359 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4360 psessionEntry->peSessionId, cdf_status));
4361 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4362 lim_log(pMac, LOGE,
4363 FL("Failed to send a Channel Switch (%X)!"),
4364 cdf_status);
4365 /* Pkt will be freed up by the callback */
4366 return eSIR_FAILURE;
4367 }
4368
4369 return eSIR_SUCCESS;
4370}
4371
4372/**
4373 * \brief Send a VHT Channel Switch Announcement
4374 *
4375 *
4376 * \param pMac Pointer to the global MAC datastructure
4377 *
4378 * \param peer MAC address to which this frame will be sent
4379 *
4380 * \param nChanWidth
4381 *
4382 * \param nNewChannel
4383 *
4384 *
4385 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4386 *
4387 *
4388 */
4389
4390tSirRetStatus
4391lim_send_vht_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
4392 tSirMacAddr peer,
4393 uint8_t nChanWidth,
4394 uint8_t nNewChannel,
4395 uint8_t ncbMode, tpPESession psessionEntry)
4396{
4397 tDot11fChannelSwitch frm;
4398 uint8_t *pFrame;
4399 tpSirMacMgmtHdr pMacHdr;
4400 uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
4401 void *pPacket;
4402 CDF_STATUS cdf_status;
4403 uint8_t txFlag = 0;
4404
4405 uint8_t smeSessionId = 0;
4406
4407 if (psessionEntry == NULL) {
4408 PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
4409 return eSIR_FAILURE;
4410 }
4411 smeSessionId = psessionEntry->smeSessionId;
4412
4413 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4414
4415 frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
4416 frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
4417 frm.ChanSwitchAnn.switchMode = 1;
4418 frm.ChanSwitchAnn.newChannel = nNewChannel;
4419 frm.ChanSwitchAnn.switchCount = 1;
4420 frm.sec_chan_offset_ele.secondaryChannelOffset =
4421 lim_get_htcb_state(ncbMode);
4422 frm.sec_chan_offset_ele.present = 1;
4423 frm.WiderBWChanSwitchAnn.newChanWidth = nChanWidth;
4424 frm.WiderBWChanSwitchAnn.newCenterChanFreq0 =
4425 lim_get_center_channel(pMac, nNewChannel, ncbMode, nChanWidth);
4426 frm.WiderBWChanSwitchAnn.newCenterChanFreq1 = 0;
4427 frm.ChanSwitchAnn.present = 1;
4428 frm.WiderBWChanSwitchAnn.present = 1;
4429
4430 nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
4431 if (DOT11F_FAILED(nStatus)) {
4432 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4433 "or a Channel Switch (0x%08x)."),
4434 nStatus);
4435 /* We'll fall back on the worst case scenario: */
4436 nPayload = sizeof(tDot11fChannelSwitch);
4437 } else if (DOT11F_WARNED(nStatus)) {
4438 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4439 "the packed size for a Channel Switch (0x"
4440 "%08x)."), nStatus);
4441 }
4442
4443 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4444
4445 cdf_status =
4446 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4447 (void **)&pPacket);
4448 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4449 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
4450 " Report."), nBytes);
4451 return eSIR_FAILURE;
4452 }
4453 /* Paranoia: */
4454 cdf_mem_set(pFrame, nBytes, 0);
4455
4456 /* Next, we fill out the buffer descriptor: */
4457 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4458 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4459 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4460 cdf_mem_copy((uint8_t *) pMacHdr->bssId,
4461 (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
4462 nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
4463 sizeof(tSirMacMgmtHdr),
4464 nPayload, &nPayload);
4465 if (DOT11F_FAILED(nStatus)) {
4466 lim_log(pMac, LOGE,
4467 FL("Failed to pack a Channel Switch (0x%08x)."),
4468 nStatus);
4469 cds_packet_free((void *)pPacket);
4470 return eSIR_FAILURE; /* allocated! */
4471 } else if (DOT11F_WARNED(nStatus)) {
4472 lim_log(pMac, LOGW, FL("There were warnings while packing a C"
4473 "hannel Switch (0x%08x)."), nStatus);
4474 }
4475
4476 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4477 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4478 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4479 ) {
4480 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4481 }
4482
4483 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4484 psessionEntry->peSessionId, pMacHdr->fc.subType));
4485 cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
4486 TXRX_FRM_802_11_MGMT,
4487 ANI_TXDIR_TODS,
4488 7, lim_tx_complete, pFrame, txFlag,
4489 smeSessionId, 0);
4490 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4491 psessionEntry->peSessionId, cdf_status));
4492 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4493 lim_log(pMac, LOGE,
4494 FL("Failed to send a Channel Switch (%X)!"),
4495 cdf_status);
4496 /* Pkt will be freed up by the callback */
4497 return eSIR_FAILURE;
4498 }
4499
4500 return eSIR_SUCCESS;
4501
4502} /* End lim_send_vht_channel_switch_mgmt_frame. */
4503
4504#endif
4505
4506#if defined WLAN_FEATURE_VOWIFI
4507
4508/**
4509 * \brief Send a Neighbor Report Request Action frame
4510 *
4511 *
4512 * \param pMac Pointer to the global MAC structure
4513 *
4514 * \param pNeighborReq Address of a tSirMacNeighborReportReq
4515 *
4516 * \param peer mac address of peer station.
4517 *
4518 * \param psessionEntry address of session entry.
4519 *
4520 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4521 *
4522 *
4523 */
4524
4525tSirRetStatus
4526lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
4527 tpSirMacNeighborReportReq pNeighborReq,
4528 tSirMacAddr peer, tpPESession psessionEntry)
4529{
4530 tSirRetStatus statusCode = eSIR_SUCCESS;
4531 tDot11fNeighborReportRequest frm;
4532 uint8_t *pFrame;
4533 tpSirMacMgmtHdr pMacHdr;
4534 uint32_t nBytes, nPayload, nStatus;
4535 void *pPacket;
4536 CDF_STATUS cdf_status;
4537 uint8_t txFlag = 0;
4538 uint8_t smeSessionId = 0;
4539
4540 if (psessionEntry == NULL) {
4541 lim_log(pMac, LOGE,
4542 FL
4543 ("(psession == NULL) in Request to send Neighbor Report request action frame"));
4544 return eSIR_FAILURE;
4545 }
4546 smeSessionId = psessionEntry->smeSessionId;
4547 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4548
4549 frm.Category.category = SIR_MAC_ACTION_RRM;
4550 frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
4551 frm.DialogToken.token = pNeighborReq->dialogToken;
4552
4553 if (pNeighborReq->ssid_present) {
4554 populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
4555 }
4556
4557 nStatus =
4558 dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
4559 if (DOT11F_FAILED(nStatus)) {
4560 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4561 "or a Neighbor Report Request(0x%08x)."),
4562 nStatus);
4563 /* We'll fall back on the worst case scenario: */
4564 nPayload = sizeof(tDot11fNeighborReportRequest);
4565 } else if (DOT11F_WARNED(nStatus)) {
4566 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4567 "the packed size for a Neighbor Rep"
4568 "ort Request(0x%08x)."), nStatus);
4569 }
4570
4571 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4572
4573 cdf_status =
4574 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4575 (void **)&pPacket);
4576 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4577 lim_log(pMac, LOGP,
4578 FL("Failed to allocate %d bytes for a Neighbor "
4579 "Report Request."), nBytes);
4580 return eSIR_FAILURE;
4581 }
4582 /* Paranoia: */
4583 cdf_mem_set(pFrame, nBytes, 0);
4584
4585 /* Copy necessary info to BD */
4586 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4587 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4588
4589 /* Update A3 with the BSSID */
4590 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4591
4592 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4593
4594#ifdef WLAN_FEATURE_11W
4595 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4596#endif
4597
4598 /* Now, we're ready to "pack" the frames */
4599 nStatus = dot11f_pack_neighbor_report_request(pMac,
4600 &frm,
4601 pFrame +
4602 sizeof(tSirMacMgmtHdr),
4603 nPayload, &nPayload);
4604
4605 if (DOT11F_FAILED(nStatus)) {
4606 lim_log(pMac, LOGE,
4607 FL
4608 ("Failed to pack an Neighbor Report Request (0x%08x)."),
4609 nStatus);
4610
4611 /* FIXME - Need to convert to tSirRetStatus */
4612 statusCode = eSIR_FAILURE;
4613 goto returnAfterError;
4614 } else if (DOT11F_WARNED(nStatus)) {
4615 lim_log(pMac, LOGW,
4616 FL("There were warnings while packing Neighbor Report "
4617 "Request (0x%08x)."), nStatus);
4618 }
4619
4620 lim_log(pMac, LOGW, FL("Sending a Neighbor Report Request to "));
4621 lim_print_mac_addr(pMac, peer, LOGW);
4622
4623 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4624 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4625 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4626 ) {
4627 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4628 }
4629
4630 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4631 psessionEntry->peSessionId, pMacHdr->fc.subType));
4632 cdf_status = wma_tx_frame(pMac,
4633 pPacket,
4634 (uint16_t) nBytes,
4635 TXRX_FRM_802_11_MGMT,
4636 ANI_TXDIR_TODS,
4637 7, lim_tx_complete, pFrame, txFlag,
4638 smeSessionId, 0);
4639 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4640 psessionEntry->peSessionId, cdf_status));
4641 if (CDF_STATUS_SUCCESS != cdf_status) {
4642 PELOGE(lim_log
4643 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4644 cdf_status);
4645 )
4646 statusCode = eSIR_FAILURE;
4647 /* Pkt will be freed up by the callback */
4648 return statusCode;
4649 } else
4650 return eSIR_SUCCESS;
4651
4652returnAfterError:
4653 cds_packet_free((void *)pPacket);
4654
4655 return statusCode;
4656} /* End lim_send_neighbor_report_request_frame. */
4657
4658/**
4659 * \brief Send a Link Report Action frame
4660 *
4661 *
4662 * \param pMac Pointer to the global MAC structure
4663 *
4664 * \param pLinkReport Address of a tSirMacLinkReport
4665 *
4666 * \param peer mac address of peer station.
4667 *
4668 * \param psessionEntry address of session entry.
4669 *
4670 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4671 *
4672 *
4673 */
4674
4675tSirRetStatus
4676lim_send_link_report_action_frame(tpAniSirGlobal pMac,
4677 tpSirMacLinkReport pLinkReport,
4678 tSirMacAddr peer, tpPESession psessionEntry)
4679{
4680 tSirRetStatus statusCode = eSIR_SUCCESS;
4681 tDot11fLinkMeasurementReport frm;
4682 uint8_t *pFrame;
4683 tpSirMacMgmtHdr pMacHdr;
4684 uint32_t nBytes, nPayload, nStatus;
4685 void *pPacket;
4686 CDF_STATUS cdf_status;
4687 uint8_t txFlag = 0;
4688 uint8_t smeSessionId = 0;
4689
4690 if (psessionEntry == NULL) {
4691 lim_log(pMac, LOGE,
4692 FL
4693 ("(psession == NULL) in Request to send Link Report action frame"));
4694 return eSIR_FAILURE;
4695 }
4696
4697 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
4698
4699 frm.Category.category = SIR_MAC_ACTION_RRM;
4700 frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
4701 frm.DialogToken.token = pLinkReport->dialogToken;
4702
4703 /* IEEE Std. 802.11 7.3.2.18. for the report element. */
4704 /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
4705 /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
4706 /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
4707 /* such case this way than changing the frame parser. */
4708 frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
4709 frm.TPCEleLen.TPCLen = 2;
4710 frm.TxPower.txPower = pLinkReport->txPower;
4711 frm.LinkMargin.linkMargin = 0;
4712
4713 frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
4714 frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
4715 frm.RCPI.rcpi = pLinkReport->rcpi;
4716 frm.RSNI.rsni = pLinkReport->rsni;
4717
4718 nStatus =
4719 dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
4720 if (DOT11F_FAILED(nStatus)) {
4721 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4722 "or a Link Report (0x%08x)."), nStatus);
4723 /* We'll fall back on the worst case scenario: */
4724 nPayload = sizeof(tDot11fLinkMeasurementReport);
4725 } else if (DOT11F_WARNED(nStatus)) {
4726 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4727 "the packed size for a Link Rep"
4728 "ort (0x%08x)."), nStatus);
4729 }
4730
4731 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4732
4733 cdf_status =
4734 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4735 (void **)&pPacket);
4736 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4737 lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Link "
4738 "Report."), nBytes);
4739 return eSIR_FAILURE;
4740 }
4741 /* Paranoia: */
4742 cdf_mem_set(pFrame, nBytes, 0);
4743
4744 /* Copy necessary info to BD */
4745 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4746 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4747
4748 /* Update A3 with the BSSID */
4749 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4750
4751 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4752
4753#ifdef WLAN_FEATURE_11W
4754 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4755#endif
4756
4757 /* Now, we're ready to "pack" the frames */
4758 nStatus = dot11f_pack_link_measurement_report(pMac,
4759 &frm,
4760 pFrame +
4761 sizeof(tSirMacMgmtHdr),
4762 nPayload, &nPayload);
4763
4764 if (DOT11F_FAILED(nStatus)) {
4765 lim_log(pMac, LOGE,
4766 FL("Failed to pack an Link Report (0x%08x)."), nStatus);
4767
4768 /* FIXME - Need to convert to tSirRetStatus */
4769 statusCode = eSIR_FAILURE;
4770 goto returnAfterError;
4771 } else if (DOT11F_WARNED(nStatus)) {
4772 lim_log(pMac, LOGW,
4773 FL
4774 ("There were warnings while packing Link Report (0x%08x)."),
4775 nStatus);
4776 }
4777
4778 lim_log(pMac, LOGW, FL("Sending a Link Report to "));
4779 lim_print_mac_addr(pMac, peer, LOGW);
4780
4781 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4782 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4783 (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
4784 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4785 }
4786
4787 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4788 psessionEntry->peSessionId, pMacHdr->fc.subType));
4789 cdf_status = wma_tx_frame(pMac,
4790 pPacket,
4791 (uint16_t) nBytes,
4792 TXRX_FRM_802_11_MGMT,
4793 ANI_TXDIR_TODS,
4794 7, lim_tx_complete, pFrame, txFlag,
4795 smeSessionId, 0);
4796 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4797 psessionEntry->peSessionId, cdf_status));
4798 if (CDF_STATUS_SUCCESS != cdf_status) {
4799 PELOGE(lim_log
4800 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4801 cdf_status);
4802 )
4803 statusCode = eSIR_FAILURE;
4804 /* Pkt will be freed up by the callback */
4805 return statusCode;
4806 } else
4807 return eSIR_SUCCESS;
4808
4809returnAfterError:
4810 cds_packet_free((void *)pPacket);
4811
4812 return statusCode;
4813} /* End lim_send_link_report_action_frame. */
4814
4815/**
4816 * \brief Send a Beacon Report Action frame
4817 *
4818 *
4819 * \param pMac Pointer to the global MAC structure
4820 *
4821 * \param dialog_token dialog token to be used in the action frame.
4822 *
4823 * \param num_report number of reports in pRRMReport.
4824 *
4825 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
4826 *
4827 * \param peer mac address of peer station.
4828 *
4829 * \param psessionEntry address of session entry.
4830 *
4831 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
4832 *
4833 *
4834 */
4835
4836tSirRetStatus
4837lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
4838 uint8_t dialog_token,
4839 uint8_t num_report,
4840 tpSirMacRadioMeasureReport pRRMReport,
4841 tSirMacAddr peer,
4842 tpPESession psessionEntry)
4843{
4844 tSirRetStatus statusCode = eSIR_SUCCESS;
4845 uint8_t *pFrame;
4846 tpSirMacMgmtHdr pMacHdr;
4847 uint32_t nBytes, nPayload, nStatus;
4848 void *pPacket;
4849 CDF_STATUS cdf_status;
4850 uint8_t i;
4851 uint8_t txFlag = 0;
4852 uint8_t smeSessionId = 0;
4853
4854 tDot11fRadioMeasurementReport *frm =
4855 cdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
4856 if (!frm) {
4857 lim_log(pMac, LOGE,
4858 FL
4859 ("Not enough memory to allocate tDot11fRadioMeasurementReport"));
4860 return eSIR_MEM_ALLOC_FAILED;
4861 }
4862
4863 if (psessionEntry == NULL) {
4864 lim_log(pMac, LOGE,
4865 FL
4866 ("(psession == NULL) in Request to send Beacon Report action frame"));
4867 cdf_mem_free(frm);
4868 return eSIR_FAILURE;
4869 }
4870 cdf_mem_set((uint8_t *) frm, sizeof(*frm), 0);
4871
4872 frm->Category.category = SIR_MAC_ACTION_RRM;
4873 frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
4874 frm->DialogToken.token = dialog_token;
4875
4876 frm->num_MeasurementReport =
4877 (num_report >
4878 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
4879 num_report;
4880
4881 for (i = 0; i < frm->num_MeasurementReport; i++) {
4882 frm->MeasurementReport[i].type = pRRMReport[i].type;
4883 frm->MeasurementReport[i].token = pRRMReport[i].token;
4884 frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
4885 switch (pRRMReport[i].type) {
4886 case SIR_MAC_RRM_BEACON_TYPE:
4887 populate_dot11f_beacon_report(pMac,
4888 &frm->MeasurementReport[i],
4889 &pRRMReport[i].report.
4890 beaconReport);
4891 frm->MeasurementReport[i].incapable =
4892 pRRMReport[i].incapable;
4893 frm->MeasurementReport[i].refused =
4894 pRRMReport[i].refused;
4895 frm->MeasurementReport[i].present = 1;
4896 break;
4897 default:
4898 frm->MeasurementReport[i].incapable =
4899 pRRMReport[i].incapable;
4900 frm->MeasurementReport[i].refused =
4901 pRRMReport[i].refused;
4902 frm->MeasurementReport[i].present = 1;
4903 break;
4904 }
4905 }
4906
4907 nStatus =
4908 dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
4909 if (DOT11F_FAILED(nStatus)) {
4910 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
4911 "or a Radio Measure Report (0x%08x)."),
4912 nStatus);
4913 /* We'll fall back on the worst case scenario: */
4914 nPayload = sizeof(tDot11fLinkMeasurementReport);
4915 cdf_mem_free(frm);
4916 return eSIR_FAILURE;
4917 } else if (DOT11F_WARNED(nStatus)) {
4918 lim_log(pMac, LOGW, FL("There were warnings while calculating "
4919 "the packed size for a Radio Measure Rep"
4920 "ort (0x%08x)."), nStatus);
4921 }
4922
4923 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
4924
4925 cdf_status =
4926 cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
4927 (void **)&pPacket);
4928 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
4929 lim_log(pMac, LOGP,
4930 FL("Failed to allocate %d bytes for a Radio Measure "
4931 "Report."), nBytes);
4932 cdf_mem_free(frm);
4933 return eSIR_FAILURE;
4934 }
4935 /* Paranoia: */
4936 cdf_mem_set(pFrame, nBytes, 0);
4937
4938 /* Copy necessary info to BD */
4939 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
4940 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
4941
4942 /* Update A3 with the BSSID */
4943 pMacHdr = (tpSirMacMgmtHdr) pFrame;
4944
4945 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
4946
4947#ifdef WLAN_FEATURE_11W
4948 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
4949#endif
4950
4951 /* Now, we're ready to "pack" the frames */
4952 nStatus = dot11f_pack_radio_measurement_report(pMac,
4953 frm,
4954 pFrame +
4955 sizeof(tSirMacMgmtHdr),
4956 nPayload, &nPayload);
4957
4958 if (DOT11F_FAILED(nStatus)) {
4959 lim_log(pMac, LOGE,
4960 FL("Failed to pack an Radio Measure Report (0x%08x)."),
4961 nStatus);
4962
4963 /* FIXME - Need to convert to tSirRetStatus */
4964 statusCode = eSIR_FAILURE;
4965 goto returnAfterError;
4966 } else if (DOT11F_WARNED(nStatus)) {
4967 lim_log(pMac, LOGW,
4968 FL("There were warnings while packing Radio "
4969 "Measure Report (0x%08x)."), nStatus);
4970 }
4971
4972 lim_log(pMac, LOGW, FL("Sending a Radio Measure Report to "));
4973 lim_print_mac_addr(pMac, peer, LOGW);
4974
4975 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
4976 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
4977 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
4978 ) {
4979 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
4980 }
4981
4982 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
4983 psessionEntry->peSessionId, pMacHdr->fc.subType));
4984 cdf_status = wma_tx_frame(pMac,
4985 pPacket,
4986 (uint16_t) nBytes,
4987 TXRX_FRM_802_11_MGMT,
4988 ANI_TXDIR_TODS,
4989 7, lim_tx_complete, pFrame, txFlag,
4990 smeSessionId, 0);
4991 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
4992 psessionEntry->peSessionId, cdf_status));
4993 if (CDF_STATUS_SUCCESS != cdf_status) {
4994 PELOGE(lim_log
4995 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
4996 cdf_status);
4997 )
4998 statusCode = eSIR_FAILURE;
4999 /* Pkt will be freed up by the callback */
5000 cdf_mem_free(frm);
5001 return statusCode;
5002 } else {
5003 cdf_mem_free(frm);
5004 return eSIR_SUCCESS;
5005 }
5006
5007returnAfterError:
5008 cdf_mem_free(frm);
5009 cds_packet_free((void *)pPacket);
5010 return statusCode;
5011}
5012
5013#endif
5014
5015#ifdef WLAN_FEATURE_11W
5016/**
5017 * \brief Send SA query request action frame to peer
5018 *
5019 * \sa lim_send_sa_query_request_frame
5020 *
5021 *
5022 * \param pMac The global tpAniSirGlobal object
5023 *
5024 * \param transId Transaction identifier
5025 *
5026 * \param peer The Mac address of the station to which this action frame is addressed
5027 *
5028 * \param psessionEntry The PE session entry
5029 *
5030 * \return eSIR_SUCCESS if setup completes successfully
5031 * eSIR_FAILURE is some problem is encountered
5032 */
5033
5034tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
5035 tSirMacAddr peer,
5036 tpPESession psessionEntry)
5037{
5038
5039 tDot11fSaQueryReq frm; /* SA query request action frame */
5040 uint8_t *pFrame;
5041 tSirRetStatus nSirStatus;
5042 tpSirMacMgmtHdr pMacHdr;
5043 uint32_t nBytes, nPayload, nStatus;
5044 void *pPacket;
5045 CDF_STATUS cdf_status;
5046 uint8_t txFlag = 0;
5047 uint8_t smeSessionId = 0;
5048
5049 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
5050 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
5051 /* 11w action field is :
5052 action: 0 --> SA Query Request action frame
5053 action: 1 --> SA Query Response action frame */
5054 frm.Action.action = SIR_MAC_SA_QUERY_REQ;
5055 /* 11w SA Query Request transId */
5056 cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
5057
5058 nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
5059 if (DOT11F_FAILED(nStatus)) {
5060 lim_log(pMac, LOGP, FL("Failed to calculate the packed size "
5061 "for an SA Query Request (0x%08x)."),
5062 nStatus);
5063 /* We'll fall back on the worst case scenario: */
5064 nPayload = sizeof(tDot11fSaQueryReq);
5065 } else if (DOT11F_WARNED(nStatus)) {
5066 lim_log(pMac, LOGW, FL("There were warnings while calculating "
5067 "the packed size for an SA Query Request"
5068 " (0x%08x)."), nStatus);
5069 }
5070
5071 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
5072 cdf_status =
5073 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
5074 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
5075 lim_log(pMac, LOGP,
5076 FL("Failed to allocate %d bytes for a SA Query Request "
5077 "action frame"), nBytes);
5078 return eSIR_FAILURE;
5079 }
5080 /* Paranoia: */
5081 cdf_mem_set(pFrame, nBytes, 0);
5082
5083 /* Copy necessary info to BD */
5084 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
5085 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
5086
5087 /* Update A3 with the BSSID */
5088 pMacHdr = (tpSirMacMgmtHdr) pFrame;
5089
5090 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
5091
5092 /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
5093 /* in the FC */
5094 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
5095
5096 /* Pack 11w SA Query Request frame */
5097 nStatus = dot11f_pack_sa_query_req(pMac,
5098 &frm,
5099 pFrame + sizeof(tSirMacMgmtHdr),
5100 nPayload, &nPayload);
5101
5102 if (DOT11F_FAILED(nStatus)) {
5103 lim_log(pMac, LOGE,
5104 FL("Failed to pack an SA Query Request (0x%08x)."),
5105 nStatus);
5106 /* FIXME - Need to convert to tSirRetStatus */
5107 nSirStatus = eSIR_FAILURE;
5108 goto returnAfterError;
5109 } else if (DOT11F_WARNED(nStatus)) {
5110 lim_log(pMac, LOGW,
5111 FL
5112 ("There were warnings while packing SA Query Request (0x%08x)."),
5113 nStatus);
5114 }
5115
5116 lim_log(pMac, LOG1, FL("Sending an SA Query Request to "));
5117 lim_print_mac_addr(pMac, peer, LOG1);
5118 lim_log(pMac, LOG1, FL("Sending an SA Query Request from "));
5119 lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOG1);
5120
5121 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
5122#ifdef WLAN_FEATURE_P2P
5123 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
5124 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
5125#endif
5126 ) {
5127 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
5128 }
5129 smeSessionId = psessionEntry->smeSessionId;
5130
5131 cdf_status = wma_tx_frame(pMac,
5132 pPacket,
5133 (uint16_t) nBytes,
5134 TXRX_FRM_802_11_MGMT,
5135 ANI_TXDIR_TODS,
5136 7, lim_tx_complete, pFrame, txFlag,
5137 smeSessionId, 0);
5138 if (CDF_STATUS_SUCCESS != cdf_status) {
5139 PELOGE(lim_log
5140 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
5141 cdf_status);
5142 )
5143 nSirStatus = eSIR_FAILURE;
5144 /* Pkt will be freed up by the callback */
5145 return nSirStatus;
5146 } else {
5147 return eSIR_SUCCESS;
5148 }
5149
5150returnAfterError:
5151 cds_packet_free((void *)pPacket);
5152 return nSirStatus;
5153} /* End lim_send_sa_query_request_frame */
5154
5155/**
5156 * \brief Send SA query response action frame to peer
5157 *
5158 * \sa lim_send_sa_query_response_frame
5159 *
5160 *
5161 * \param pMac The global tpAniSirGlobal object
5162 *
5163 * \param transId Transaction identifier received in SA query request action frame
5164 *
5165 * \param peer The Mac address of the AP to which this action frame is addressed
5166 *
5167 * \param psessionEntry The PE session entry
5168 *
5169 * \return eSIR_SUCCESS if setup completes successfully
5170 * eSIR_FAILURE is some problem is encountered
5171 */
5172
5173tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
5174 uint8_t *transId, tSirMacAddr peer,
5175 tpPESession psessionEntry)
5176{
5177
5178 tDot11fSaQueryRsp frm; /* SA query reponse action frame */
5179 uint8_t *pFrame;
5180 tSirRetStatus nSirStatus;
5181 tpSirMacMgmtHdr pMacHdr;
5182 uint32_t nBytes, nPayload, nStatus;
5183 void *pPacket;
5184 CDF_STATUS cdf_status;
5185 uint8_t txFlag = 0;
5186 uint8_t smeSessionId = 0;
5187
5188 smeSessionId = psessionEntry->smeSessionId;
5189
5190 cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
5191 frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
5192 /*11w action field is :
5193 action: 0 --> SA query request action frame
5194 action: 1 --> SA query response action frame */
5195 frm.Action.action = SIR_MAC_SA_QUERY_RSP;
5196 /*11w SA query response transId is same as
5197 SA query request transId */
5198 cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
5199
5200 nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
5201 if (DOT11F_FAILED(nStatus)) {
5202 lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
5203 "or a SA Query Response (0x%08x)."),
5204 nStatus);
5205 /* We'll fall back on the worst case scenario: */
5206 nPayload = sizeof(tDot11fSaQueryRsp);
5207 } else if (DOT11F_WARNED(nStatus)) {
5208 lim_log(pMac, LOGW, FL("There were warnings while calculating "
5209 "the packed size for an SA Query Response"
5210 " (0x%08x)."), nStatus);
5211 }
5212
5213 nBytes = nPayload + sizeof(tSirMacMgmtHdr);
5214 cdf_status =
5215 cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
5216 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
5217 lim_log(pMac, LOGP,
5218 FL("Failed to allocate %d bytes for a SA query response"
5219 " action frame"), nBytes);
5220 return eSIR_FAILURE;
5221 }
5222 /* Paranoia: */
5223 cdf_mem_set(pFrame, nBytes, 0);
5224
5225 /* Copy necessary info to BD */
5226 lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
5227 SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
5228
5229 /* Update A3 with the BSSID */
5230 pMacHdr = (tpSirMacMgmtHdr) pFrame;
5231
5232 sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
5233
5234 /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
5235 /* in the FC */
5236 lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
5237
5238 /* Pack 11w SA query response frame */
5239 nStatus = dot11f_pack_sa_query_rsp(pMac,
5240 &frm,
5241 pFrame + sizeof(tSirMacMgmtHdr),
5242 nPayload, &nPayload);
5243
5244 if (DOT11F_FAILED(nStatus)) {
5245 lim_log(pMac, LOGE,
5246 FL("Failed to pack an SA Query Response (0x%08x)."),
5247 nStatus);
5248 /* FIXME - Need to convert to tSirRetStatus */
5249 nSirStatus = eSIR_FAILURE;
5250 goto returnAfterError;
5251 } else if (DOT11F_WARNED(nStatus)) {
5252 lim_log(pMac, LOGW,
5253 FL
5254 ("There were warnings while packing SA Query Response (0x%08x)."),
5255 nStatus);
5256 }
5257
5258 lim_log(pMac, LOG1, FL("Sending a SA Query Response to "));
5259 lim_print_mac_addr(pMac, peer, LOGW);
5260
5261 if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
5262#ifdef WLAN_FEATURE_P2P
5263 || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
5264 (psessionEntry->pePersona == CDF_P2P_GO_MODE)
5265#endif
5266 ) {
5267 txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
5268 }
5269
5270 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
5271 psessionEntry->peSessionId, pMacHdr->fc.subType));
5272 cdf_status = wma_tx_frame(pMac,
5273 pPacket,
5274 (uint16_t) nBytes,
5275 TXRX_FRM_802_11_MGMT,
5276 ANI_TXDIR_TODS,
5277 7, lim_tx_complete, pFrame, txFlag,
5278 smeSessionId, 0);
5279 MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
5280 psessionEntry->peSessionId, cdf_status));
5281 if (CDF_STATUS_SUCCESS != cdf_status) {
5282 PELOGE(lim_log
5283 (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
5284 cdf_status);
5285 )
5286 nSirStatus = eSIR_FAILURE;
5287 /* Pkt will be freed up by the callback */
5288 return nSirStatus;
5289 } else {
5290 return eSIR_SUCCESS;
5291 }
5292
5293returnAfterError:
5294 cds_packet_free((void *)pPacket);
5295 return nSirStatus;
5296} /* End lim_send_sa_query_response_frame */
5297#endif