blob: b7d0a4a1aa78a8362418d9befff341b02f169c85 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Anurag Chouhan6d760662016-02-20 16:05:43 +05302 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*
Naveen Rawatada5fac2016-01-28 16:24:32 -080029 * This file lim_process_assoc_req_frame.c contains the code
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080030 * for processing Re/Association Request Frame.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080031 */
32#include "cds_api.h"
33#include "ani_global.h"
34#include "wni_cfg.h"
35#include "sir_api.h"
36#include "cfg_api.h"
37
38#include "sch_api.h"
39#include "utils_api.h"
40#include "lim_types.h"
41#include "lim_utils.h"
42#include "lim_assoc_utils.h"
43#include "lim_security_utils.h"
44#include "lim_ser_des_utils.h"
45#include "lim_sta_hash_api.h"
46#include "lim_admit_control.h"
47#include "cds_packet.h"
48#include "lim_session_utils.h"
49
Anurag Chouhan6d760662016-02-20 16:05:43 +053050#include "qdf_types.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051#include "cds_utils.h"
52
53/**
54 * lim_convert_supported_channels - Parses channel support IE
Krunal Soni99752a12016-04-12 17:44:45 -070055 * @mac_ctx: A pointer to Global MAC structure
56 * @assoc_ind: A pointer to SME ASSOC/REASSOC IND
57 * @assoc_req: A pointer to ASSOC/REASSOC Request frame
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058 *
59 * This function is called by lim_process_assoc_req_frame() to
60 * parse the channel support IE in the Assoc/Reassoc Request
61 * frame, and send relevant information in the SME_ASSOC_IND
62 *
Krunal Soni99752a12016-04-12 17:44:45 -070063 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080064 */
Krunal Soni99752a12016-04-12 17:44:45 -070065static void lim_convert_supported_channels(tpAniSirGlobal mac_ctx,
66 tpLimMlmAssocInd assoc_ind,
67 tSirAssocReq *assoc_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068{
69 uint16_t i, j, index = 0;
Naveen Rawatada5fac2016-01-28 16:24:32 -080070 uint8_t first_ch_no;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080071 uint8_t chn_count;
Naveen Rawatada5fac2016-01-28 16:24:32 -080072 uint8_t next_ch_no;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073 uint8_t channel_offset = 0;
74
75 if (assoc_req->supportedChannels.length >=
76 SIR_MAX_SUPPORTED_CHANNEL_LIST) {
77 lim_log(mac_ctx, LOG1,
78 FL("Number of supported channels:%d is more than MAX"),
79 assoc_req->supportedChannels.length);
80 assoc_ind->supportedChannels.numChnl = 0;
81 return;
82 }
83
84 for (i = 0; i < (assoc_req->supportedChannels.length); i++) {
85 /* Get First Channel Number */
Naveen Rawatada5fac2016-01-28 16:24:32 -080086 first_ch_no = assoc_req->supportedChannels.supportedChannels[i];
87 assoc_ind->supportedChannels.channelList[index] = first_ch_no;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088 i++;
89 index++;
90
91 /* Get Number of Channels in a Subband */
Naveen Rawatada5fac2016-01-28 16:24:32 -080092 chn_count = assoc_req->supportedChannels.supportedChannels[i];
93 lim_log(mac_ctx, LOG2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080094 FL("Rcv assoc_req: chnl=%d, numOfChnl=%d "),
Naveen Rawatada5fac2016-01-28 16:24:32 -080095 first_ch_no, chn_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096 if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
Naveen Rawatada5fac2016-01-28 16:24:32 -080097 lim_log(mac_ctx, LOGW,
98 FL("Ch count > max supported =%d "),
99 chn_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800100 assoc_ind->supportedChannels.numChnl = 0;
101 return;
102 }
103 if (chn_count <= 1)
104 continue;
Naveen Rawatada5fac2016-01-28 16:24:32 -0800105 next_ch_no = first_ch_no;
106 if (SIR_BAND_5_GHZ == lim_get_rf_band(first_ch_no))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107 channel_offset = SIR_11A_FREQUENCY_OFFSET;
Naveen Rawatada5fac2016-01-28 16:24:32 -0800108 else if (SIR_BAND_2_4_GHZ == lim_get_rf_band(first_ch_no))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800109 channel_offset = SIR_11B_FREQUENCY_OFFSET;
110 else
111 continue;
112
113 for (j = 1; j < chn_count; j++) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800114 next_ch_no += channel_offset;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800115 assoc_ind->supportedChannels.channelList[index]
Naveen Rawatada5fac2016-01-28 16:24:32 -0800116 = next_ch_no;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800117 index++;
118 if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800119 lim_log(mac_ctx, LOGW,
120 FL("Ch count > supported =%d "),
121 chn_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800122 assoc_ind->supportedChannels.numChnl = 0;
123 return;
124 }
125 }
126 }
127
128 assoc_ind->supportedChannels.numChnl = (uint8_t) index;
Naveen Rawatada5fac2016-01-28 16:24:32 -0800129 lim_log(mac_ctx, LOG2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800130 FL("Send AssocInd to WSM: minPwr %d, maxPwr %d, numChnl %d"),
131 assoc_ind->powerCap.minTxPower,
132 assoc_ind->powerCap.maxTxPower,
Naveen Rawatada5fac2016-01-28 16:24:32 -0800133 assoc_ind->supportedChannels.numChnl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800134}
135
Naveen Rawatada5fac2016-01-28 16:24:32 -0800136/**
137 * lim_check_sta_in_pe_entries() - checks if sta exists in any dph tables.
Krunal Soni99752a12016-04-12 17:44:45 -0700138 * @mac_ctx: Pointer to Global MAC structure
139 * @hdr: A pointer to the MAC header
Poddar, Siddarth7ca1e082016-08-09 19:06:48 +0530140 * @sessionid - session id for which session is initiated
Naveen Rawatada5fac2016-01-28 16:24:32 -0800141 *
142 * This function is called by lim_process_assoc_req_frame() to check if STA
143 * entry already exists in any of the PE entries of the AP. If it exists, deauth
144 * will be sent on that session and the STA deletion will happen. After this,
145 * the ASSOC request will be processed
146 *
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -0700147 * Return: True if duplicate entry found; FALSE otherwise.
Naveen Rawatada5fac2016-01-28 16:24:32 -0800148 */
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -0700149static bool lim_check_sta_in_pe_entries(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
Poddar, Siddarth7ca1e082016-08-09 19:06:48 +0530150 uint16_t sessionid)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800151{
152 uint8_t i;
Naveen Rawatada5fac2016-01-28 16:24:32 -0800153 uint16_t assoc_id = 0;
154 tpDphHashNode sta_ds = NULL;
155 tpPESession session = NULL;
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -0700156 bool dup_entry = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800157
Naveen Rawatada5fac2016-01-28 16:24:32 -0800158 for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
159 if ((&mac_ctx->lim.gpSession[i] != NULL) &&
160 (mac_ctx->lim.gpSession[i].valid) &&
161 (mac_ctx->lim.gpSession[i].pePersona == QDF_SAP_MODE)) {
162 session = &mac_ctx->lim.gpSession[i];
163 sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa,
164 &assoc_id, &session->dph.dphHashTable);
165 if (sta_ds
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800166#ifdef WLAN_FEATURE_11W
Poddar, Siddarth7ca1e082016-08-09 19:06:48 +0530167 && (!sta_ds->rmfEnabled ||
168 (sessionid != session->peSessionId))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800169#endif
170 ) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800171 lim_log(mac_ctx, LOGE,
Sandeep Puligilla2eeaf6a2016-07-22 20:02:02 -0700172 FL("Sending Disassoc and Deleting existing STA entry: "
Naveen Rawatada5fac2016-01-28 16:24:32 -0800173 MAC_ADDRESS_STR),
174 MAC_ADDR_ARRAY(session->selfMacAddr));
Sandeep Puligilla2eeaf6a2016-07-22 20:02:02 -0700175 lim_send_disassoc_mgmt_frame(mac_ctx,
Naveen Rawatada5fac2016-01-28 16:24:32 -0800176 eSIR_MAC_UNSPEC_FAILURE_REASON,
177 (uint8_t *) hdr->sa, session, false);
Sandeep Puligilla2eeaf6a2016-07-22 20:02:02 -0700178 /*
179 * Cleanup Rx path posts eWNI_SME_DISASSOC_RSP
180 * msg to SME after delete sta which will update
181 * the userspace with disconnect
182 */
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -0700183 sta_ds->mlmStaContext.cleanupTrigger =
184 eLIM_DUPLICATE_ENTRY;
185 sta_ds->mlmStaContext.disassocReason =
186 eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
187 lim_send_sme_disassoc_ind(mac_ctx, sta_ds,
188 session);
189 dup_entry = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800190 break;
191 }
192 }
193 }
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -0700194 return dup_entry;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800195}
196
Naveen Rawatada5fac2016-01-28 16:24:32 -0800197/**
Krunal Soni99752a12016-04-12 17:44:45 -0700198 * lim_chk_sa_da() - checks source addr to destination addr of assoc req frame
199 * @mac_ctx: pointer to Global MAC structure
200 * @hdr: pointer to the MAC head
201 * @session: pointer to pe session entry
202 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
Naveen Rawatada5fac2016-01-28 16:24:32 -0800203 *
Krunal Soni99752a12016-04-12 17:44:45 -0700204 * Checks source addr to destination addr of assoc req frame
Naveen Rawatada5fac2016-01-28 16:24:32 -0800205 *
Ankit Guptaa5076012016-09-14 11:32:19 -0700206 * Return: true if source and destination address are different
Naveen Rawatada5fac2016-01-28 16:24:32 -0800207 */
Krunal Soni99752a12016-04-12 17:44:45 -0700208static bool lim_chk_sa_da(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
209 tpPESession session, uint8_t sub_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800210{
Ankit Guptaa5076012016-09-14 11:32:19 -0700211 if (qdf_mem_cmp((uint8_t *) hdr->sa,
Krunal Soni99752a12016-04-12 17:44:45 -0700212 (uint8_t *) hdr->da,
Ankit Guptaa5076012016-09-14 11:32:19 -0700213 (uint8_t) (sizeof(tSirMacAddr))))
Krunal Soni99752a12016-04-12 17:44:45 -0700214 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800215
Krunal Soni99752a12016-04-12 17:44:45 -0700216 lim_log(mac_ctx, LOGE, FL("Assoc Req rejected: wlan.sa = wlan.da"));
217 lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
218 1, hdr->sa, sub_type, 0, session);
219 return false;
220}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800221
Krunal Soni99752a12016-04-12 17:44:45 -0700222/**
223 * lim_chk_tkip() - checks TKIP counter measure is active
224 * @mac_ctx: pointer to Global MAC structure
225 * @hdr: pointer to the MAC head
226 * @session: pointer to pe session entry
227 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
228 *
229 * Checks TKIP counter measure is active
230 *
231 * Return: true of no error, false otherwise
232 */
233static bool lim_chk_tkip(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
234 tpPESession session, uint8_t sub_type)
235{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800236 /*
Krunal Soni99752a12016-04-12 17:44:45 -0700237 * If TKIP counter measures active send Assoc Rsp frame to station
238 * with eSIR_MAC_MIC_FAILURE_REASON
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239 */
Krunal Soni99752a12016-04-12 17:44:45 -0700240 if (!(session->bTkipCntrMeasActive && LIM_IS_AP_ROLE(session)))
241 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242
Krunal Soni99752a12016-04-12 17:44:45 -0700243 lim_log(mac_ctx, LOGE,
244 FL("Assoc Req rejected: TKIP counter measure is active"));
245 lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_MIC_FAILURE_REASON, 1,
246 hdr->sa, sub_type, 0, session);
247 return false;
248}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800249
Krunal Soni99752a12016-04-12 17:44:45 -0700250/**
251 * lim_chk_assoc_req_parse_error() - checks for error in frame parsing
252 * @mac_ctx: pointer to Global MAC structure
253 * @hdr: pointer to the MAC head
254 * @session: pointer to pe session entry
255 * @assoc_req: pointer to ASSOC/REASSOC Request frame
256 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
257 * @frm_body: frame body
258 * @frame_len: frame len
259 *
260 * Checks for error in frame parsing
261 *
262 * Return: true of no error, false otherwise
263 */
264static bool lim_chk_assoc_req_parse_error(tpAniSirGlobal mac_ctx,
265 tpSirMacMgmtHdr hdr,
266 tpPESession session,
267 tpSirAssocReq assoc_req,
268 uint8_t sub_type, uint8_t *frm_body,
Krishna Kumaar Natarajandb582ec2016-03-08 17:37:04 -0800269 uint32_t frame_len)
Krunal Soni99752a12016-04-12 17:44:45 -0700270{
271 tSirRetStatus status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272
Naveen Rawatada5fac2016-01-28 16:24:32 -0800273 if (sub_type == LIM_ASSOC)
Krunal Soni99752a12016-04-12 17:44:45 -0700274 status = sir_convert_assoc_req_frame2_struct(mac_ctx, frm_body,
275 frame_len, assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 else
Krunal Soni99752a12016-04-12 17:44:45 -0700277 status = sir_convert_reassoc_req_frame2_struct(mac_ctx,
278 frm_body, frame_len, assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800279
Krunal Soni99752a12016-04-12 17:44:45 -0700280 if (status == eSIR_SUCCESS)
281 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800282
Krunal Soni99752a12016-04-12 17:44:45 -0700283 lim_log(mac_ctx, LOGW,
284 FL("Assoc Req rejected: frame parsing error. source addr:"
285 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(hdr->sa));
286 lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
287 1, hdr->sa, sub_type, 0, session);
288 return false;
289}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290
Krunal Soni99752a12016-04-12 17:44:45 -0700291/**
292 * lim_chk_capab() - checks for capab match
293 * @mac_ctx: pointer to Global MAC structure
294 * @hdr: pointer to the MAC head
295 * @session: pointer to pe session entry
296 * @assoc_req: pointer to ASSOC/REASSOC Request frame
297 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
298 * @local_cap: local capabilities of SAP
299 *
300 * Checks for capab match
301 *
302 * Return: true of no error, false otherwise
303 */
304static bool lim_chk_capab(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
305 tpPESession session, tpSirAssocReq assoc_req,
306 uint8_t sub_type, tSirMacCapabilityInfo *local_cap)
307{
308 uint16_t temp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309
Naveen Rawatada5fac2016-01-28 16:24:32 -0800310 if (cfg_get_capability_info(mac_ctx, &temp, session) != eSIR_SUCCESS) {
311 lim_log(mac_ctx, LOGP, FL("could not retrieve Capabilities"));
Krunal Soni99752a12016-04-12 17:44:45 -0700312 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800313 }
Krunal Soni99752a12016-04-12 17:44:45 -0700314
315 lim_copy_u16((uint8_t *) local_cap, temp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800316
Naveen Rawatada5fac2016-01-28 16:24:32 -0800317 if (lim_compare_capabilities(mac_ctx, assoc_req,
Krunal Soni99752a12016-04-12 17:44:45 -0700318 local_cap, session) == false) {
319 lim_log(mac_ctx, LOGW,
320 FL("Rcvd %s Req with unsupported capab from"
321 MAC_ADDRESS_STR),
Naveen Rawatada5fac2016-01-28 16:24:32 -0800322 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
323 MAC_ADDR_ARRAY(hdr->sa));
Krunal Soni99752a12016-04-12 17:44:45 -0700324 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800325 * Capabilities of requesting STA does not match with
326 * local capabilities. Respond with 'unsupported capabilities'
327 * status code.
328 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800329 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700330 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
331 1, hdr->sa, sub_type, 0, session);
332 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333 }
Krunal Soni99752a12016-04-12 17:44:45 -0700334 return true;
335}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336
Krunal Soni99752a12016-04-12 17:44:45 -0700337/**
338 * lim_chk_ssid() - checks for SSID match
339 * @mac_ctx: pointer to Global MAC structure
340 * @hdr: pointer to the MAC head
341 * @session: pointer to pe session entry
342 * @assoc_req: pointer to ASSOC/REASSOC Request frame
343 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
344 *
345 * Checks for SSID match
346 *
347 * Return: true of no error, false otherwise
348 */
349static bool lim_chk_ssid(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
350 tpPESession session, tpSirAssocReq assoc_req,
351 uint8_t sub_type)
352{
353 if (lim_cmp_ssid(&assoc_req->ssId, session) != true)
354 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800355
Krunal Soni99752a12016-04-12 17:44:45 -0700356 lim_log(mac_ctx, LOGE,
357 FL("%s Req with ssid wrong(Rcvd: %.*s self: %.*s) from "
358 MAC_ADDRESS_STR),
359 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
360 assoc_req->ssId.length, assoc_req->ssId.ssId,
361 session->ssId.length, session->ssId.ssId,
362 MAC_ADDR_ARRAY(hdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800363
Krunal Soni99752a12016-04-12 17:44:45 -0700364 /*
365 * Received Re/Association Request with either Broadcast SSID OR with
366 * SSID that does not match with local one. Respond with unspecified
367 * status code.
368 */
369 lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
370 1, hdr->sa, sub_type, 0, session);
371 return false;
372}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800373
Krunal Soni99752a12016-04-12 17:44:45 -0700374/**
375 * lim_chk_rates() - checks for supported rates
376 * @mac_ctx: pointer to Global MAC structure
377 * @hdr: pointer to the MAC head
378 * @session: pointer to pe session entry
379 * @assoc_req: pointer to ASSOC/REASSOC Request frame
380 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
381 *
382 * Checks for supported rates
383 *
384 * Return: true of no error, false otherwise
385 */
386static bool lim_chk_rates(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
387 tpPESession session, tpSirAssocReq assoc_req,
388 uint8_t sub_type)
389{
390 uint8_t i = 0, j = 0;
391 tSirMacRateSet basic_rates;
392 /*
393 * Verify if the requested rates are available in supported rate
394 * set or Extended rate set. Some APs are adding basic rates in
395 * Extended rateset IE
396 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800397 basic_rates.numRates = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398
Krunal Soni99752a12016-04-12 17:44:45 -0700399 for (i = 0; i < assoc_req->supportedRates.numRates
400 && (i < SIR_MAC_RATESET_EID_MAX); i++) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800401 basic_rates.rate[i] = assoc_req->supportedRates.rate[i];
402 basic_rates.numRates++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403 }
404
Krunal Soni99752a12016-04-12 17:44:45 -0700405 for (j = 0; (j < assoc_req->extendedRates.numRates)
406 && (i < SIR_MAC_RATESET_EID_MAX); i++, j++) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800407 basic_rates.rate[i] = assoc_req->extendedRates.rate[j];
408 basic_rates.numRates++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800409 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800410
Krunal Soni99752a12016-04-12 17:44:45 -0700411 if (lim_check_rx_basic_rates(mac_ctx, basic_rates, session) == true)
412 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413
Krunal Soni99752a12016-04-12 17:44:45 -0700414 lim_log(mac_ctx, LOGW,
415 FL("Assoc Req rejected: unsupported rates, soruce addr: %s"
416 MAC_ADDRESS_STR),
417 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
418 MAC_ADDR_ARRAY(hdr->sa));
419 /*
420 * Requesting STA does not support ALL BSS basic rates. Respond with
421 * 'basic rates not supported' status code.
422 */
423 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
424 eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, 1,
425 hdr->sa, sub_type, 0, session);
426 return false;
427}
428
429/**
430 * lim_chk_11g_only() - checks for non 11g STA
431 * @mac_ctx: pointer to Global MAC structure
432 * @hdr: pointer to the MAC head
433 * @session: pointer to pe session entry
434 * @assoc_req: pointer to ASSOC/REASSOC Request frame
435 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
436 *
437 * Checks for non 11g STA
438 *
439 * Return: true of no error, false otherwise
440 */
441static bool lim_chk_11g_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
442 tpPESession session, tpSirAssocReq assoc_req,
443 uint8_t sub_type)
444{
Naveen Rawatada5fac2016-01-28 16:24:32 -0800445 if (LIM_IS_AP_ROLE(session) &&
446 (session->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) &&
447 (assoc_req->HTCaps.present)) {
448 lim_log(mac_ctx, LOGE,
Krunal Soni99752a12016-04-12 17:44:45 -0700449 FL("SOFTAP was in 11G only mode, rejecting legacy STA: "
450 MAC_ADDRESS_STR),
451 MAC_ADDR_ARRAY(hdr->sa));
Naveen Rawatada5fac2016-01-28 16:24:32 -0800452 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700453 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
454 1, hdr->sa, sub_type, 0, session);
455 return false;
456 }
457 return true;
458}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459
Krunal Soni99752a12016-04-12 17:44:45 -0700460/**
461 * lim_chk_11n_only() - checks for non 11n STA
462 * @mac_ctx: pointer to Global MAC structure
463 * @hdr: pointer to the MAC head
464 * @session: pointer to pe session entry
465 * @assoc_req: pointer to ASSOC/REASSOC Request frame
466 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
467 *
468 * Checks for non 11n STA
469 *
470 * Return: true of no error, false otherwise
471 */
472static bool lim_chk_11n_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
473 tpPESession session, tpSirAssocReq assoc_req,
474 uint8_t sub_type)
475{
Naveen Rawatada5fac2016-01-28 16:24:32 -0800476 if (LIM_IS_AP_ROLE(session) &&
477 (session->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) &&
478 (!assoc_req->HTCaps.present)) {
479 lim_log(mac_ctx, LOGE,
Krunal Soni99752a12016-04-12 17:44:45 -0700480 FL("SOFTAP was in 11N only mode, rejecting legacy STA: "
481 MAC_ADDRESS_STR),
482 MAC_ADDR_ARRAY(hdr->sa));
Naveen Rawatada5fac2016-01-28 16:24:32 -0800483 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700484 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
485 1, hdr->sa, sub_type, 0, session);
486 return false;
487 }
488 return true;
489}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800490
Krunal Soni99752a12016-04-12 17:44:45 -0700491/**
492 * lim_chk_11ac_only() - checks for non 11ac STA
493 * @mac_ctx: pointer to Global MAC structure
494 * @hdr: pointer to the MAC head
495 * @session: pointer to pe session entry
496 * @assoc_req: pointer to ASSOC/REASSOC Request frame
497 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
498 *
499 * Checks for non 11ac STA
500 *
501 * Return: true of no error, false otherwise
502 */
503static bool lim_chk_11ac_only(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
504 tpPESession session, tpSirAssocReq assoc_req,
505 uint8_t sub_type)
506{
Kapil Gupta4b2efbb2016-10-03 13:07:20 +0530507 tDot11fIEVHTCaps *vht_caps;
508
509 if (assoc_req->VHTCaps.present)
510 vht_caps = &assoc_req->VHTCaps;
511 else if (assoc_req->vendor_vht_ie.VHTCaps.present &&
512 session->vendor_vht_sap)
513 vht_caps = &assoc_req->vendor_vht_ie.VHTCaps;
514 else
515 vht_caps = NULL;
516
Naveen Rawatada5fac2016-01-28 16:24:32 -0800517 if (LIM_IS_AP_ROLE(session) &&
Krunal Soni99752a12016-04-12 17:44:45 -0700518 (session->dot11mode == WNI_CFG_DOT11_MODE_11AC_ONLY) &&
wadesong3e727f62016-11-07 17:51:57 +0800519 ((vht_caps == NULL) || ((vht_caps != NULL) && (!vht_caps->present)))) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800520 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700521 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
522 1, hdr->sa, sub_type, 0, session);
523 lim_log(mac_ctx, LOGE,
524 FL("SOFTAP was in 11AC only mode, reject"));
525 return false;
526 }
527 return true;
528}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800529
Krunal Soni99752a12016-04-12 17:44:45 -0700530/**
531 * lim_process_for_spectrum_mgmt() - process assoc req for spectrum mgmt
532 * @mac_ctx: pointer to Global MAC structure
533 * @hdr: pointer to the MAC head
534 * @session: pointer to pe session entry
535 * @assoc_req: pointer to ASSOC/REASSOC Request frame
536 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
537 * @local_cap: local capabilities of SAP
538 *
539 * Checks for SSID match
540 *
541 * process assoc req for spectrum mgmt
542 */
543static void
544lim_process_for_spectrum_mgmt(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
545 tpPESession session, tpSirAssocReq assoc_req,
546 uint8_t sub_type, tSirMacCapabilityInfo local_cap)
547{
Naveen Rawatada5fac2016-01-28 16:24:32 -0800548 if (local_cap.spectrumMgt) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800549 tSirRetStatus status = eSIR_SUCCESS;
Krunal Soni99752a12016-04-12 17:44:45 -0700550 /*
551 * If station is 11h capable, then it SHOULD send all mandatory
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800552 * IEs in assoc request frame. Let us verify that
553 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800554 if (assoc_req->capabilityInfo.spectrumMgt) {
Krunal Soni99752a12016-04-12 17:44:45 -0700555 if (!((assoc_req->powerCapabilityPresent)
Naveen Rawatada5fac2016-01-28 16:24:32 -0800556 && (assoc_req->supportedChannelsPresent))) {
Krunal Soni99752a12016-04-12 17:44:45 -0700557 /*
558 * One or more required information elements are
559 * missing, log the peers error
560 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800561 if (!assoc_req->powerCapabilityPresent) {
562 lim_log(mac_ctx, LOG1,
Krunal Soni99752a12016-04-12 17:44:45 -0700563 FL("LIM Info: Missing Power capability IE in %s Req from "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564 MAC_ADDRESS_STR),
Krunal Soni99752a12016-04-12 17:44:45 -0700565 (LIM_ASSOC == sub_type) ?
566 "Assoc" : "ReAssoc",
Naveen Rawatada5fac2016-01-28 16:24:32 -0800567 MAC_ADDR_ARRAY(hdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800568 }
Naveen Rawatada5fac2016-01-28 16:24:32 -0800569 if (!assoc_req->supportedChannelsPresent) {
570 lim_log(mac_ctx, LOGW,
Krunal Soni99752a12016-04-12 17:44:45 -0700571 FL("LIM Info: Missing Supported channel IE in %s Req from "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572 MAC_ADDRESS_STR),
Krunal Soni99752a12016-04-12 17:44:45 -0700573 (LIM_ASSOC == sub_type) ?
574 "Assoc" : "ReAssoc",
Naveen Rawatada5fac2016-01-28 16:24:32 -0800575 MAC_ADDR_ARRAY(hdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576 }
577 } else {
578 /* Assoc request has mandatory fields */
579 status =
Krunal Soni99752a12016-04-12 17:44:45 -0700580 lim_is_dot11h_power_capabilities_in_range(
581 mac_ctx, assoc_req, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800582 if (eSIR_SUCCESS != status) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800583 lim_log(mac_ctx, LOGW,
Krunal Soni99752a12016-04-12 17:44:45 -0700584 FL("LIM Info: MinTxPower(STA) > MaxTxPower(AP) in %s Req from "
585 MAC_ADDRESS_STR),
586 (LIM_ASSOC == sub_type) ?
587 "Assoc" : "ReAssoc",
Naveen Rawatada5fac2016-01-28 16:24:32 -0800588 MAC_ADDR_ARRAY(hdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 }
Krunal Soni99752a12016-04-12 17:44:45 -0700590 status = lim_is_dot11h_supported_channels_valid(
591 mac_ctx, assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 if (eSIR_SUCCESS != status) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800593 lim_log(mac_ctx, LOGW,
Krunal Soni99752a12016-04-12 17:44:45 -0700594 FL("LIM Info: wrong supported channels (STA) in %s Req from "
595 MAC_ADDRESS_STR),
596 (LIM_ASSOC == sub_type) ?
597 "Assoc" : "ReAssoc",
Naveen Rawatada5fac2016-01-28 16:24:32 -0800598 MAC_ADDR_ARRAY(hdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599 }
600 /* IEs are valid, use them if needed */
601 }
602 } /* if(assoc.capabilityInfo.spectrumMgt) */
603 else {
Krunal Soni99752a12016-04-12 17:44:45 -0700604 /*
605 * As per the capabiities, the spectrum management is
606 * not enabled on the station. The AP may allow the
607 * associations to happen even if spectrum management
608 * is not allowed, if the transmit power of station is
609 * below the regulatory maximum
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800610 */
611
Krunal Soni99752a12016-04-12 17:44:45 -0700612 /*
613 * TODO: presently, this is not handled. In the current
614 * implemetation, the AP would allow the station to
615 * associate even if it doesn't support spectrum
616 * management.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617 */
618 }
619 } /* end of spectrum management related processing */
Krunal Soni99752a12016-04-12 17:44:45 -0700620}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621
Krunal Soni99752a12016-04-12 17:44:45 -0700622/**
623 * lim_chk_mcs() - checks for supported MCS
624 * @mac_ctx: pointer to Global MAC structure
625 * @hdr: pointer to the MAC head
626 * @session: pointer to pe session entry
627 * @assoc_req: pointer to ASSOC/REASSOC Request frame
628 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
629 *
630 * Checks for supported MCS
631 *
632 * Return: true of no error, false otherwise
633 */
634static bool lim_chk_mcs(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
635 tpPESession session, tpSirAssocReq assoc_req,
636 uint8_t sub_type)
637{
638 if ((assoc_req->HTCaps.present) && (lim_check_mcs_set(mac_ctx,
639 assoc_req->HTCaps.supportedMCSSet) == false)) {
640 lim_log(mac_ctx, LOGW,
641 FL("rcvd %s req with unsupported MCS Rate Set from "
642 MAC_ADDRESS_STR),
Naveen Rawatada5fac2016-01-28 16:24:32 -0800643 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
644 MAC_ADDR_ARRAY(hdr->sa));
Krunal Soni99752a12016-04-12 17:44:45 -0700645 /*
646 * Requesting STA does not support ALL BSS MCS basic Rate set
647 * rates. Spec does not define any status code for this
648 * scenario.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800650 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700651 eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
652 1, hdr->sa, sub_type, 0, session);
653 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800654 }
Krunal Soni99752a12016-04-12 17:44:45 -0700655 return true;
656}
657
658/**
659 * lim_chk_is_11b_sta_supported() - checks if STA is 11b
660 * @mac_ctx: pointer to Global MAC structure
661 * @hdr: pointer to the MAC head
662 * @session: pointer to pe session entry
663 * @assoc_req: pointer to ASSOC/REASSOC Request frame
664 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
665 * @phy_mode: phy mode
666 *
667 * Checks if STA is 11b
668 *
669 * Return: true of no error, false otherwise
670 */
671static bool lim_chk_is_11b_sta_supported(tpAniSirGlobal mac_ctx,
672 tpSirMacMgmtHdr hdr,
673 tpPESession session,
674 tpSirAssocReq assoc_req,
675 uint8_t sub_type, uint32_t phy_mode)
676{
677 uint32_t cfg_11g_only;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678
Naveen Rawatada5fac2016-01-28 16:24:32 -0800679 if (phy_mode == WNI_CFG_PHY_MODE_11G) {
Krunal Soni99752a12016-04-12 17:44:45 -0700680 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11G_ONLY_POLICY,
681 &cfg_11g_only) != eSIR_SUCCESS) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800682 lim_log(mac_ctx, LOGP,
Krunal Soni99752a12016-04-12 17:44:45 -0700683 FL("couldn't get 11g-only flag"));
684 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 }
686
Krunal Soni99752a12016-04-12 17:44:45 -0700687 if (!assoc_req->extendedRatesPresent && cfg_11g_only) {
688 /*
689 * Received Re/Association Request from 11b STA when 11g
690 * only policy option is set. Reject with unspecified
691 * status code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800693 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700694 eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
695 1, hdr->sa, sub_type, 0, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800696
Krunal Soni99752a12016-04-12 17:44:45 -0700697 lim_log(mac_ctx, LOGW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800698 FL("Rejecting Re/Assoc req from 11b STA: "));
Naveen Rawatada5fac2016-01-28 16:24:32 -0800699 lim_print_mac_addr(mac_ctx, hdr->sa, LOGW);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800700
701#ifdef WLAN_DEBUG
Naveen Rawatada5fac2016-01-28 16:24:32 -0800702 mac_ctx->lim.gLim11bStaAssocRejectCount++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800703#endif
Krunal Soni99752a12016-04-12 17:44:45 -0700704 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800705 }
706 }
Krunal Soni99752a12016-04-12 17:44:45 -0700707 return true;
708}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709
Krunal Soni99752a12016-04-12 17:44:45 -0700710/**
711 * lim_print_ht_cap() - prints HT caps
712 * @mac_ctx: pointer to Global MAC structure
713 * @session: pointer to pe session entry
714 * @assoc_req: pointer to ASSOC/REASSOC Request frame
715 *
716 * Prints HT caps
717 *
718 * Return: void
719 */
720static void lim_print_ht_cap(tpAniSirGlobal mac_ctx, tpPESession session,
721 tpSirAssocReq assoc_req)
722{
723 if (!session->htCapability)
724 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800725
Krunal Soni99752a12016-04-12 17:44:45 -0700726 /* There are; are they turned on in the STA? */
727 if (assoc_req->HTCaps.present) {
728 /* The station *does* support 802.11n HT capability... */
729 lim_log(mac_ctx, LOG1,
730 FL("AdvCodingCap:%d ChaWidthSet:%d PowerSave:%d greenField:%d shortGI20:%d shortGI40:%d txSTBC:%d rxSTBC:%d delayBA:%d maxAMSDUsize:%d DSSS/CCK:%d PSMP:%d stbcCntl:%d lsigTXProt:%d"),
731 assoc_req->HTCaps.advCodingCap,
732 assoc_req->HTCaps.supportedChannelWidthSet,
733 assoc_req->HTCaps.mimoPowerSave,
734 assoc_req->HTCaps.greenField,
735 assoc_req->HTCaps.shortGI20MHz,
736 assoc_req->HTCaps.shortGI40MHz,
737 assoc_req->HTCaps.txSTBC,
738 assoc_req->HTCaps.rxSTBC,
739 assoc_req->HTCaps.delayedBA,
740 assoc_req->HTCaps.maximalAMSDUsize,
741 assoc_req->HTCaps.dsssCckMode40MHz,
742 assoc_req->HTCaps.psmp,
743 assoc_req->HTCaps.stbcControlFrame,
744 assoc_req->HTCaps.lsigTXOPProtection);
745 /*
746 * Make sure the STA's caps are compatible with our own:
747 * 11.15.2 Support of DSSS/CCK in 40 MHz the AP shall refuse
748 * association requests from an HT STA that has the DSSS/CCK
749 * Mode in 40 MHz subfield set to 1;
750 */
751 }
752}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753
Krunal Soni99752a12016-04-12 17:44:45 -0700754/**
755 * lim_chk_n_process_wpa_rsn_ie() - wpa ie related checks
756 * @mac_ctx: pointer to Global MAC structure
757 * @hdr: pointer to the MAC head
758 * @session: pointer to pe session entry
759 * @assoc_req: pointer to ASSOC/REASSOC Request frame
760 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
761 * @pmf_connection: flag indicating pmf connection
762 *
763 * wpa ie related checks
764 *
765 * Return: true of no error, false otherwise
766 */
767static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx,
768 tpSirMacMgmtHdr hdr,
769 tpPESession session,
770 tpSirAssocReq assoc_req,
771 uint8_t sub_type, bool *pmf_connection)
772{
773 uint8_t *wps_ie = NULL;
774 tDot11fIEWPA dot11f_ie_wpa;
775 tDot11fIERSN dot11f_ie_rsn;
776 tSirRetStatus status = eSIR_SUCCESS;
777 /*
778 * Clear the buffers so that frame parser knows that there isn't a
779 * previously decoded IE in these buffers
780 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800781 qdf_mem_set((uint8_t *) &dot11f_ie_rsn, sizeof(dot11f_ie_rsn), 0);
782 qdf_mem_set((uint8_t *) &dot11f_ie_wpa, sizeof(dot11f_ie_wpa), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800783
784 /* if additional IE is present, check if it has WscIE */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800785 if (assoc_req->addIEPresent && assoc_req->addIE.length)
Krunal Soni99752a12016-04-12 17:44:45 -0700786 wps_ie = limGetWscIEPtr(mac_ctx, assoc_req->addIE.addIEdata,
787 assoc_req->addIE.length);
788 else
789 lim_log(mac_ctx, LOG1,
790 FL("Assoc req addIEPresent = %d addIE length = %d"),
Naveen Rawatada5fac2016-01-28 16:24:32 -0800791 assoc_req->addIEPresent, assoc_req->addIE.length);
Krunal Soni99752a12016-04-12 17:44:45 -0700792
Naveen Rawatada5fac2016-01-28 16:24:32 -0800793 /* when wps_ie is present, RSN/WPA IE is ignored */
794 if (wps_ie == NULL) {
Krunal Soni99752a12016-04-12 17:44:45 -0700795 /* check whether as RSN IE is present */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800796 if (LIM_IS_AP_ROLE(session) &&
797 session->pLimStartBssReq->privacy &&
798 session->pLimStartBssReq->rsnIE.length) {
Krunal Soni99752a12016-04-12 17:44:45 -0700799 lim_log(mac_ctx, LOGE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 FL("RSN enabled auth, Re/Assoc req from STA: "
Krunal Soni99752a12016-04-12 17:44:45 -0700801 MAC_ADDRESS_STR),
802 MAC_ADDR_ARRAY(hdr->sa));
Naveen Rawatada5fac2016-01-28 16:24:32 -0800803 if (assoc_req->rsnPresent) {
804 if (assoc_req->rsn.length) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805 /* Unpack the RSN IE */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800806 dot11f_unpack_ie_rsn(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700807 &assoc_req->rsn.info[0],
808 assoc_req->rsn.length,
809 &dot11f_ie_rsn);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800810
Krunal Soni99752a12016-04-12 17:44:45 -0700811 /* Check RSN version is supported */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800812 if (SIR_MAC_OUI_VERSION_1 ==
Krunal Soni99752a12016-04-12 17:44:45 -0700813 dot11f_ie_rsn.version) {
814 /*
815 * check the groupwise and
816 * pairwise cipher suites
817 */
818 status =
819 lim_check_rx_rsn_ie_match(
820 mac_ctx, dot11f_ie_rsn,
821 session,
822 assoc_req->HTCaps.present,
823 pmf_connection);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530824 if (eSIR_SUCCESS != status) {
Krunal Soni99752a12016-04-12 17:44:45 -0700825 lim_log(mac_ctx, LOGW,
826 FL("Re/Assoc rejected from: " MAC_ADDRESS_STR),
827 MAC_ADDR_ARRAY(
828 hdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800829
Krunal Soni99752a12016-04-12 17:44:45 -0700830 /*
831 * some IE is not
832 * properly sent
833 * received Association
834 * req frame with RSN IE
835 * but length is 0
836 */
837 lim_send_assoc_rsp_mgmt_frame(
838 mac_ctx,
839 status, 1,
840 hdr->sa,
841 sub_type, 0,
842 session);
843 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800844 }
845 } else {
Krunal Soni99752a12016-04-12 17:44:45 -0700846 lim_log(mac_ctx, LOGW,
847 FL("Re/Assoc rejected from: " MAC_ADDRESS_STR),
848 MAC_ADDR_ARRAY(
849 hdr->sa));
850 /*
851 * rcvd Assoc req frame with RSN
852 * IE version wrong
853 */
854 lim_send_assoc_rsp_mgmt_frame(
855 mac_ctx,
856 eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
857 1, hdr->sa, sub_type, 0,
858 session);
859 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800860 }
861 } else {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800862 lim_log(mac_ctx, LOGW,
Krunal Soni99752a12016-04-12 17:44:45 -0700863 FL("Re/Assoc rejected from: "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864 MAC_ADDRESS_STR),
Naveen Rawatada5fac2016-01-28 16:24:32 -0800865 MAC_ADDR_ARRAY(hdr->sa));
Krunal Soni99752a12016-04-12 17:44:45 -0700866 /*
867 * rcvd Assoc req frame with RSN IE but
868 * length is 0
869 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800870 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700871 eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
872 1, hdr->sa, sub_type, 0,
873 session);
874 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875 }
Naveen Rawatada5fac2016-01-28 16:24:32 -0800876 } /* end - if(assoc_req->rsnPresent) */
877 if ((!assoc_req->rsnPresent) && assoc_req->wpaPresent) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878 /* Unpack the WPA IE */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800879 if (assoc_req->wpa.length) {
Krunal Soni99752a12016-04-12 17:44:45 -0700880 /* OUI is not taken care */
881 dot11f_unpack_ie_wpa(mac_ctx,
882 &assoc_req->wpa.info[4],
883 assoc_req->wpa.length,
884 &dot11f_ie_wpa);
885 /*
886 * check the groupwise and pairwise
887 * cipher suites
888 */
889 status = lim_check_rx_wpa_ie_match(
890 mac_ctx, dot11f_ie_wpa,
891 session,
892 assoc_req->HTCaps.present);
Anurag Chouhan6d760662016-02-20 16:05:43 +0530893 if (eSIR_SUCCESS != status) {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800894 lim_log(mac_ctx, LOGW,
Krunal Soni99752a12016-04-12 17:44:45 -0700895 FL("Re/Assoc rejected from: "
896 MAC_ADDRESS_STR),
897 MAC_ADDR_ARRAY(
898 hdr->sa));
899 /*
900 * rcvd Assoc req frame with WPA
901 * IE but mismatch
902 */
903 lim_send_assoc_rsp_mgmt_frame(
904 mac_ctx, status, 1,
905 hdr->sa, sub_type, 0,
906 session);
907 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800908 }
909 } else {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800910 lim_log(mac_ctx, LOGW,
Krunal Soni99752a12016-04-12 17:44:45 -0700911 FL("Re/Assoc rejected from: "
912 MAC_ADDRESS_STR),
Naveen Rawatada5fac2016-01-28 16:24:32 -0800913 MAC_ADDR_ARRAY(hdr->sa));
Krunal Soni99752a12016-04-12 17:44:45 -0700914 /*
915 * rcvd Assoc req frame with invalid WPA
916 * IE
917 */
Naveen Rawatada5fac2016-01-28 16:24:32 -0800918 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -0700919 eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
920 1, hdr->sa, sub_type, 0,
921 session);
922 return false;
Naveen Rawatada5fac2016-01-28 16:24:32 -0800923 } /* end - if(assoc_req->wpa.length) */
924 } /* end - if(assoc_req->wpaPresent) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 }
Krunal Soni99752a12016-04-12 17:44:45 -0700926 /*
927 * end of if(session->pLimStartBssReq->privacy
928 * && session->pLimStartBssReq->rsnIE->length)
929 */
930 } /* end of if( ! assoc_req->wscInfo.present ) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800931 else {
Naveen Rawatada5fac2016-01-28 16:24:32 -0800932 lim_log(mac_ctx, LOG1, FL("Assoc req WSE IE is present"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800933 }
Krunal Soni99752a12016-04-12 17:44:45 -0700934 return true;
935}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800936
Krunal Soni99752a12016-04-12 17:44:45 -0700937/**
938 * lim_process_assoc_req_no_sta_ctx() - process assoc req for no sta ctx present
939 * @mac_ctx: pointer to Global MAC structure
940 * @hdr: pointer to the MAC head
941 * @session: pointer to pe session entry
942 * @assoc_req: pointer to ASSOC/REASSOC Request frame
943 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
944 * @sta_pre_auth_ctx: sta pre auth context
945 * @sta_ds: station dph entry
946 * @auth_type: indicates security type
947 *
948 * Process assoc req for no sta ctx present
949 *
950 * Return: true of no error, false otherwise
951 */
952static bool lim_process_assoc_req_no_sta_ctx(tpAniSirGlobal mac_ctx,
953 tpSirMacMgmtHdr hdr, tpPESession session,
954 tpSirAssocReq assoc_req, uint8_t sub_type,
955 struct tLimPreAuthNode *sta_pre_auth_ctx,
956 tpDphHashNode sta_ds, tAniAuthType *auth_type)
957{
958 /* Requesting STA is not currently associated */
959 if (pe_get_current_stas_count(mac_ctx) ==
960 mac_ctx->lim.gLimAssocStaLimit) {
961 /*
962 * Maximum number of STAs that AP can handle reached.
963 * Send Association response to peer MAC entity
964 */
965 lim_log(mac_ctx, LOGE, FL("Max Sta count reached : %d"),
966 mac_ctx->lim.maxStation);
967 lim_reject_association(mac_ctx, hdr->sa, sub_type, false,
968 (tAniAuthType) 0, 0, false,
969 (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
970 session);
971 return false;
972 }
973 /* Check if STA is pre-authenticated. */
974 if ((sta_pre_auth_ctx == NULL) || (sta_pre_auth_ctx &&
975 (sta_pre_auth_ctx->mlmState != eLIM_MLM_AUTHENTICATED_STATE))) {
976 /*
977 * STA is not pre-authenticated yet requesting Re/Association
978 * before Authentication. OR STA is in the process of getting
979 * authenticated and sent Re/Association request. Send
980 * Deauthentication frame with 'prior authentication required'
981 * reason code.
982 */
983 lim_send_deauth_mgmt_frame(mac_ctx,
984 eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON,
985 hdr->sa, session, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800986
Krunal Soni99752a12016-04-12 17:44:45 -0700987 lim_log(mac_ctx, LOGW,
988 FL("rcvd %s req, sessionid: %d, without pre-auth ctx"
989 MAC_ADDRESS_STR),
990 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
991 session->peSessionId, MAC_ADDR_ARRAY(hdr->sa));
992 return false;
993 }
994 /* Delete 'pre-auth' context of STA */
995 *auth_type = sta_pre_auth_ctx->authType;
996 lim_delete_pre_auth_node(mac_ctx, hdr->sa);
997 /* All is well. Assign AID (after else part) */
998 return true;
999}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001000
Krunal Soni99752a12016-04-12 17:44:45 -07001001/**
1002 * lim_process_assoc_req_sta_ctx() - process assoc req for sta context present
1003 * @mac_ctx: pointer to Global MAC structure
1004 * @hdr: pointer to the MAC head
1005 * @session: pointer to pe session entry
1006 * @assoc_req: pointer to ASSOC/REASSOC Request frame
1007 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
1008 * @sta_pre_auth_ctx: sta pre auth context
1009 * @sta_ds: station dph entry
1010 * @peer_idx: peer index
1011 * @auth_type: indicates security type
1012 * @update_ctx: indicates if STA context already exist
1013 *
1014 * Process assoc req for sta context present
1015 *
1016 * Return: true of no error, false otherwise
1017 */
1018static bool lim_process_assoc_req_sta_ctx(tpAniSirGlobal mac_ctx,
1019 tpSirMacMgmtHdr hdr, tpPESession session,
1020 tpSirAssocReq assoc_req, uint8_t sub_type,
1021 struct tLimPreAuthNode *sta_pre_auth_ctx,
1022 tpDphHashNode sta_ds, uint16_t peer_idx,
1023 tAniAuthType *auth_type, uint8_t *update_ctx)
1024{
1025 /* STA context does exist for this STA */
1026 if (sta_ds->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
1027 /*
1028 * Requesting STA is in some 'transient' state? Ignore the
1029 * Re/Assoc Req frame by incrementing debug counter & logging
1030 * error.
1031 */
1032 if (sub_type == LIM_ASSOC) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001033#ifdef WLAN_DEBUG
Krunal Soni99752a12016-04-12 17:44:45 -07001034 mac_ctx->lim.gLimNumAssocReqDropInvldState++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001035#endif
Krunal Soni99752a12016-04-12 17:44:45 -07001036 lim_log(mac_ctx, LOG1,
1037 FL("received Assoc req in state %X from "),
1038 sta_ds->mlmStaContext.mlmState);
1039 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001040#ifdef WLAN_DEBUG
Krunal Soni99752a12016-04-12 17:44:45 -07001041 mac_ctx->lim.gLimNumReassocReqDropInvldState++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042#endif
Krunal Soni99752a12016-04-12 17:44:45 -07001043 lim_log(mac_ctx, LOG1,
1044 FL("received ReAssoc req in state %X from "),
1045 sta_ds->mlmStaContext.mlmState);
1046 }
1047 lim_print_mac_addr(mac_ctx, hdr->sa, LOG1);
1048 lim_print_mlm_state(mac_ctx, LOG1,
1049 (tLimMlmStates) sta_ds->mlmStaContext.mlmState);
1050 return false;
1051 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052
Krunal Soni99752a12016-04-12 17:44:45 -07001053 /* STA sent assoc req frame while already in 'associated' state */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054
1055#ifdef WLAN_FEATURE_11W
Krunal Soni99752a12016-04-12 17:44:45 -07001056 lim_log(mac_ctx, LOG1,
1057 FL("Re/Assoc request from station that is already associated"));
1058 lim_log(mac_ctx, LOG1, FL("PMF enabled %d, SA Query state %d"),
1059 sta_ds->rmfEnabled, sta_ds->pmfSaQueryState);
1060 if (sta_ds->rmfEnabled) {
1061 switch (sta_ds->pmfSaQueryState) {
1062 /*
1063 * start SA Query procedure, respond to Association Request with
1064 * try again later
1065 */
1066 case DPH_SA_QUERY_NOT_IN_PROGRESS:
1067 /*
1068 * We should reset the retry counter before we start
1069 * the SA query procedure, otherwise in next set of SA
1070 * query procedure we will end up using the stale value.
1071 */
1072 sta_ds->pmfSaQueryRetryCount = 0;
1073 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
1074 eSIR_MAC_TRY_AGAIN_LATER, 1, hdr->sa,
1075 sub_type, sta_ds, session);
1076 lim_send_sa_query_request_frame(mac_ctx,
1077 (uint8_t *) &(sta_ds->pmfSaQueryCurrentTransId),
1078 hdr->sa, session);
1079 sta_ds->pmfSaQueryStartTransId =
1080 sta_ds->pmfSaQueryCurrentTransId;
1081 sta_ds->pmfSaQueryCurrentTransId++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001082
Krunal Soni99752a12016-04-12 17:44:45 -07001083 /* start timer for SA Query retry */
1084 if (tx_timer_activate(&sta_ds->pmfSaQueryTimer)
1085 != TX_SUCCESS) {
1086 lim_log(mac_ctx, LOGE,
1087 FL("PMF SA Query timer start failed!"));
1088 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089 }
Krunal Soni99752a12016-04-12 17:44:45 -07001090 sta_ds->pmfSaQueryState = DPH_SA_QUERY_IN_PROGRESS;
1091 return false;
1092 /*
1093 * SA Query procedure still going, respond to Association
1094 * Request with try again later
1095 */
1096 case DPH_SA_QUERY_IN_PROGRESS:
1097 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
1098 eSIR_MAC_TRY_AGAIN_LATER, 1,
1099 hdr->sa, sub_type, 0, session);
1100 return false;
1101
1102 /*
1103 * SA Query procedure timed out, accept Association
1104 * Request normally
1105 */
1106 case DPH_SA_QUERY_TIMED_OUT:
1107 sta_ds->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
1108 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001109 }
Krunal Soni99752a12016-04-12 17:44:45 -07001110 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001111#endif
1112
Krunal Soni99752a12016-04-12 17:44:45 -07001113 /* no change in the capability so drop the frame */
1114 if ((sub_type == LIM_ASSOC) &&
Ankit Guptaa5076012016-09-14 11:32:19 -07001115 (!qdf_mem_cmp(&sta_ds->mlmStaContext.capabilityInfo,
Krunal Soni99752a12016-04-12 17:44:45 -07001116 &assoc_req->capabilityInfo,
1117 sizeof(tSirMacCapabilityInfo)))) {
1118 lim_log(mac_ctx, LOGE,
1119 FL(" Received Assoc req in state %X STAid=%d"),
1120 sta_ds->mlmStaContext.mlmState, peer_idx);
1121 return false;
1122 } else {
1123 /*
1124 * STA sent Re/association Request frame while already in
1125 * 'associated' state. Update STA capabilities and send
1126 * Association response frame with same AID
1127 */
1128 lim_log(mac_ctx, LOG1,
1129 FL("Rcvd Assoc req from STA already connected"));
1130 sta_ds->mlmStaContext.capabilityInfo =
1131 assoc_req->capabilityInfo;
1132 if (sta_pre_auth_ctx && (sta_pre_auth_ctx->mlmState ==
1133 eLIM_MLM_AUTHENTICATED_STATE)) {
1134 /* STA has triggered pre-auth again */
1135 *auth_type = sta_pre_auth_ctx->authType;
1136 lim_delete_pre_auth_node(mac_ctx, hdr->sa);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001137 } else {
Krunal Soni99752a12016-04-12 17:44:45 -07001138 *auth_type = sta_ds->mlmStaContext.authType;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001139 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001140
Krunal Soni99752a12016-04-12 17:44:45 -07001141 *update_ctx = true;
1142 if (dph_init_sta_state(mac_ctx, hdr->sa, peer_idx, true,
1143 &session->dph.dphHashTable) == NULL) {
1144 lim_log(mac_ctx, LOGE,
1145 FL("could not Init STAid=%d"), peer_idx);
1146 return false;
1147 }
1148 }
1149 return true;
1150}
1151
1152/**
1153 * lim_chk_wmm() - wmm related checks
1154 * @mac_ctx: pointer to Global MAC structure
1155 * @hdr: pointer to the MAC head
1156 * @session: pointer to pe session entry
1157 * @assoc_req: pointer to ASSOC/REASSOC Request frame
1158 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
1159 * @qos_mode: qos mode
1160 *
1161 * wmm related checks
1162 *
1163 * Return: true of no error, false otherwise
1164 */
1165static bool lim_chk_wmm(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
1166 tpPESession session, tpSirAssocReq assoc_req,
1167 uint8_t sub_type, tHalBitVal qos_mode)
1168{
1169 tHalBitVal wme_mode;
Naveen Rawatada5fac2016-01-28 16:24:32 -08001170 limGetWmeMode(session, &wme_mode);
1171 if ((qos_mode == eHAL_SET) || (wme_mode == eHAL_SET)) {
Krunal Soni99752a12016-04-12 17:44:45 -07001172 /*
1173 * for a qsta, check if the requested Traffic spec is admissible
1174 * for a non-qsta check if the sta can be admitted
1175 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001176 if (assoc_req->addtsPresent) {
Krunal Soni99752a12016-04-12 17:44:45 -07001177 uint8_t tspecIdx = 0;
Naveen Rawatada5fac2016-01-28 16:24:32 -08001178 if (lim_admit_control_add_ts(mac_ctx, hdr->sa,
Krunal Soni99752a12016-04-12 17:44:45 -07001179 &(assoc_req->addtsReq),
1180 &(assoc_req->qosCapability),
1181 0, false, NULL, &tspecIdx, session) !=
1182 eSIR_SUCCESS) {
1183 lim_log(mac_ctx, LOGW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001184 FL("AdmitControl: TSPEC rejected"));
Naveen Rawatada5fac2016-01-28 16:24:32 -08001185 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -07001186 eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
1187 1, hdr->sa, sub_type, 0, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188#ifdef WLAN_DEBUG
Naveen Rawatada5fac2016-01-28 16:24:32 -08001189 mac_ctx->lim.gLimNumAssocReqDropACRejectTS++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001190#endif
Krunal Soni99752a12016-04-12 17:44:45 -07001191 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192 }
Naveen Rawatada5fac2016-01-28 16:24:32 -08001193 } else if (lim_admit_control_add_sta(mac_ctx, hdr->sa, false)
Krunal Soni99752a12016-04-12 17:44:45 -07001194 != eSIR_SUCCESS) {
1195 lim_log(mac_ctx, LOGW,
1196 FL("AdmitControl: Sta rejected"));
Naveen Rawatada5fac2016-01-28 16:24:32 -08001197 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
Krunal Soni99752a12016-04-12 17:44:45 -07001198 eSIR_MAC_QAP_NO_BANDWIDTH_REASON, 1,
1199 hdr->sa, sub_type, 0, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001200#ifdef WLAN_DEBUG
Naveen Rawatada5fac2016-01-28 16:24:32 -08001201 mac_ctx->lim.gLimNumAssocReqDropACRejectSta++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202#endif
Krunal Soni99752a12016-04-12 17:44:45 -07001203 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204 }
1205 /* else all ok */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001206 lim_log(mac_ctx, LOG1, FL("AdmitControl: Sta OK!"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001207 }
Krunal Soni99752a12016-04-12 17:44:45 -07001208 return true;
1209}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210
Krunal Soni99752a12016-04-12 17:44:45 -07001211/**
1212 * lim_update_sta_ds() - updates ds dph entry
1213 * @mac_ctx: pointer to Global MAC structure
1214 * @hdr: pointer to the MAC head
1215 * @session: pointer to pe session entry
1216 * @assoc_req: pointer to ASSOC/REASSOC Request frame
1217 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
1218 * @sta_ds: station dph entry
1219 * @tmp_assoc_req: pointer to tmp ASSOC/REASSOC Request frame
1220 * @auth_type: indicates security type
1221 * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above
1222 * @peer_idx: peer index
1223 * @qos_mode: qos mode
1224 * @pmf_connection: flag indicating pmf connection
1225 *
1226 * Updates ds dph entry
1227 *
1228 * Return: true of no error, false otherwise
1229 */
1230static bool lim_update_sta_ds(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr,
1231 tpPESession session, tpSirAssocReq assoc_req,
1232 uint8_t sub_type, tpDphHashNode sta_ds,
1233 tpSirAssocReq tmp_assoc_req,
1234 tAniAuthType auth_type,
1235 bool *assoc_req_copied, uint16_t peer_idx,
1236 tHalBitVal qos_mode, bool pmf_connection)
1237{
Krunal Soni99752a12016-04-12 17:44:45 -07001238 tHalBitVal wme_mode, wsm_mode;
1239 uint8_t *ht_cap_ie = NULL;
1240#ifdef WLAN_FEATURE_11W
1241 tPmfSaQueryTimerId timer_id;
1242 uint32_t retry_interval;
1243#endif
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301244 tDot11fIEVHTCaps *vht_caps;
1245
1246 if (assoc_req->VHTCaps.present)
1247 vht_caps = &assoc_req->VHTCaps;
1248 else if (assoc_req->vendor_vht_ie.VHTCaps.present &&
1249 session->vendor_vht_sap)
1250 vht_caps = &assoc_req->vendor_vht_ie.VHTCaps;
1251 else
1252 vht_caps = NULL;
1253
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001254 /*
Krunal Soni99752a12016-04-12 17:44:45 -07001255 * check here if the parsedAssocReq already pointing to the assoc_req
1256 * and free it before assigning this new assoc_req
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001258 if (session->parsedAssocReq != NULL) {
1259 tmp_assoc_req = session->parsedAssocReq[sta_ds->assocId];
1260 if (tmp_assoc_req != NULL) {
1261 if (tmp_assoc_req->assocReqFrame) {
1262 qdf_mem_free(tmp_assoc_req->assocReqFrame);
1263 tmp_assoc_req->assocReqFrame = NULL;
1264 tmp_assoc_req->assocReqFrameLength = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001265 }
Naveen Rawatada5fac2016-01-28 16:24:32 -08001266 qdf_mem_free(tmp_assoc_req);
1267 tmp_assoc_req = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 }
1269
Naveen Rawatada5fac2016-01-28 16:24:32 -08001270 session->parsedAssocReq[sta_ds->assocId] = assoc_req;
Krunal Soni99752a12016-04-12 17:44:45 -07001271 *assoc_req_copied = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 }
1273
Naveen Rawatada5fac2016-01-28 16:24:32 -08001274 sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present;
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301275 if ((vht_caps != NULL) && vht_caps->present)
1276 sta_ds->mlmStaContext.vhtCapability = vht_caps->present;
1277 else
1278 sta_ds->mlmStaContext.vhtCapability = false;
Naveen Rawatada5fac2016-01-28 16:24:32 -08001279 sta_ds->qos.addtsPresent =
1280 (assoc_req->addtsPresent == 0) ? false : true;
1281 sta_ds->qos.addts = assoc_req->addtsReq;
1282 sta_ds->qos.capability = assoc_req->qosCapability;
1283 sta_ds->versionPresent = 0;
Krunal Soni99752a12016-04-12 17:44:45 -07001284 /*
1285 * short slot and short preamble should be updated before doing
1286 * limaddsta
1287 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001288 sta_ds->shortPreambleEnabled =
1289 (uint8_t) assoc_req->capabilityInfo.shortPreamble;
1290 sta_ds->shortSlotTimeEnabled =
1291 (uint8_t) assoc_req->capabilityInfo.shortSlotTime;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292
Naveen Rawatada5fac2016-01-28 16:24:32 -08001293 sta_ds->valid = 0;
1294 sta_ds->mlmStaContext.authType = auth_type;
1295 sta_ds->staType = STA_ENTRY_PEER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296
Krunal Soni99752a12016-04-12 17:44:45 -07001297 /*
1298 * TODO: If listen interval is more than certain limit, reject the
1299 * association. Need to check customer requirements and then implement.
1300 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001301 sta_ds->mlmStaContext.listenInterval = assoc_req->listenInterval;
1302 sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001303
Krunal Soni99752a12016-04-12 17:44:45 -07001304 /*
1305 * The following count will be used to knock-off the station if it
1306 * doesn't come back to receive the buffered data. The AP will wait
1307 * for numTimSent number of beacons after sending TIM information for
1308 * the station, before assuming that the station is no more associated
1309 * and disassociates it
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310 */
1311
Krunal Soni99752a12016-04-12 17:44:45 -07001312 /* timWaitCount used by PMM for monitoring the STA's in PS for LINK */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001313 sta_ds->timWaitCount =
1314 (uint8_t) GET_TIM_WAIT_COUNT(assoc_req->listenInterval);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001315
Krunal Soni99752a12016-04-12 17:44:45 -07001316 /* Init the Current successful MPDU's tranfered to this STA count = 0 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001317 sta_ds->curTxMpduCnt = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001318
Naveen Rawatada5fac2016-01-28 16:24:32 -08001319 if (IS_DOT11_MODE_HT(session->dot11mode) &&
1320 assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) {
1321 sta_ds->htGreenfield = (uint8_t) assoc_req->HTCaps.greenField;
1322 sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity;
1323 sta_ds->htDsssCckRate40MHzSupport =
1324 (uint8_t) assoc_req->HTCaps.dsssCckMode40MHz;
1325 sta_ds->htLsigTXOPProtection =
1326 (uint8_t) assoc_req->HTCaps.lsigTXOPProtection;
1327 sta_ds->htMaxAmsduLength =
1328 (uint8_t) assoc_req->HTCaps.maximalAMSDUsize;
1329 sta_ds->htMaxRxAMpduFactor = assoc_req->HTCaps.maxRxAMPDUFactor;
1330 sta_ds->htMIMOPSState = assoc_req->HTCaps.mimoPowerSave;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001331
Krunal Soni99752a12016-04-12 17:44:45 -07001332 /* assoc_req will be copied to session->parsedAssocReq later */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001333 ht_cap_ie = ((uint8_t *) &assoc_req->HTCaps) + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334
Sandeep Puligilla607f34a2016-05-25 14:37:47 -07001335 if (session->htConfig.ht_sgi20) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001336 sta_ds->htShortGI20Mhz =
Krunal Soni99752a12016-04-12 17:44:45 -07001337 (uint8_t)assoc_req->HTCaps.shortGI20MHz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001338 } else {
1339 /* Unset htShortGI20Mhz in ht_caps*/
1340 *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI20MHZ_S);
Naveen Rawatada5fac2016-01-28 16:24:32 -08001341 sta_ds->htShortGI20Mhz = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 }
1343
Sandeep Puligilla607f34a2016-05-25 14:37:47 -07001344 if (session->htConfig.ht_sgi40) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001345 sta_ds->htShortGI40Mhz =
1346 (uint8_t)assoc_req->HTCaps.shortGI40MHz;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001347 } else {
1348 /* Unset htShortGI40Mhz in ht_caps */
1349 *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI40MHZ_S);
Naveen Rawatada5fac2016-01-28 16:24:32 -08001350 sta_ds->htShortGI40Mhz = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351 }
1352
Naveen Rawatada5fac2016-01-28 16:24:32 -08001353 sta_ds->htSupportedChannelWidthSet =
1354 (uint8_t) assoc_req->HTCaps.supportedChannelWidthSet;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355 /*
1356 * peer just follows AP; so when we are softAP/GO,
1357 * we just store our session entry's secondary channel offset
1358 * here in peer INFRA STA. However, if peer's 40MHz channel
1359 * width support is disabled then secondary channel will be zero
1360 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001361 sta_ds->htSecondaryChannelOffset =
Krunal Soni99752a12016-04-12 17:44:45 -07001362 (sta_ds->htSupportedChannelWidthSet) ?
1363 session->htSecondaryChannelOffset : 0;
Naveen Rawatada5fac2016-01-28 16:24:32 -08001364 if (assoc_req->operMode.present) {
1365 sta_ds->vhtSupportedChannelWidthSet =
1366 (uint8_t) ((assoc_req->operMode.chanWidth ==
Krunal Soni99752a12016-04-12 17:44:45 -07001367 eHT_CHANNEL_WIDTH_80MHZ) ?
1368 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ :
1369 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
Naveen Rawatada5fac2016-01-28 16:24:32 -08001370 sta_ds->htSupportedChannelWidthSet =
Krunal Soni99752a12016-04-12 17:44:45 -07001371 (uint8_t) (assoc_req->operMode.chanWidth ?
1372 eHT_CHANNEL_WIDTH_40MHZ :
1373 eHT_CHANNEL_WIDTH_20MHZ);
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301374 } else if ((vht_caps != NULL) && vht_caps->present) {
Krunal Soni99752a12016-04-12 17:44:45 -07001375 /*
1376 * Check if STA has enabled it's channel bonding mode.
1377 * If channel bonding mode is enabled, we decide based
1378 * on SAP's current configuration. else, we set it to
1379 * VHT20. */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001380 sta_ds->vhtSupportedChannelWidthSet =
Krunal Soni99752a12016-04-12 17:44:45 -07001381 (uint8_t) ((sta_ds->htSupportedChannelWidthSet
1382 == eHT_CHANNEL_WIDTH_20MHZ) ?
1383 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
1384 session->ch_width - 1);
Naveen Rawatada5fac2016-01-28 16:24:32 -08001385 sta_ds->htMaxRxAMpduFactor =
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301386 vht_caps->maxAMPDULenExp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387 }
1388 /* Lesser among the AP and STA bandwidth of operation. */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001389 sta_ds->htSupportedChannelWidthSet =
1390 (sta_ds->htSupportedChannelWidthSet <
Krunal Soni99752a12016-04-12 17:44:45 -07001391 session->htSupportedChannelWidthSet) ?
1392 sta_ds->htSupportedChannelWidthSet :
1393 session->htSupportedChannelWidthSet;
Naveen Rawatada5fac2016-01-28 16:24:32 -08001394 sta_ds->baPolicyFlag = 0xFF;
1395 sta_ds->htLdpcCapable =
1396 (uint8_t) assoc_req->HTCaps.advCodingCap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001397 }
1398
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301399 if ((vht_caps != NULL) && vht_caps->present &&
1400 assoc_req->wmeInfoPresent) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001401 sta_ds->vhtLdpcCapable =
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301402 (uint8_t) vht_caps->ldpcCodingCap;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001403 }
1404
Naveen Rawatada5fac2016-01-28 16:24:32 -08001405 if (!assoc_req->wmeInfoPresent) {
1406 sta_ds->mlmStaContext.htCapability = 0;
1407 sta_ds->mlmStaContext.vhtCapability = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001408 }
Naveen Rawatada5fac2016-01-28 16:24:32 -08001409 if (sta_ds->mlmStaContext.vhtCapability) {
Krunal Soni53993f72016-07-08 18:20:03 -07001410 if (session->vht_config.su_beam_formee &&
Naveen Rawatada5fac2016-01-28 16:24:32 -08001411 assoc_req->VHTCaps.suBeamFormerCap)
1412 sta_ds->vhtBeamFormerCapable = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413 else
Naveen Rawatada5fac2016-01-28 16:24:32 -08001414 sta_ds->vhtBeamFormerCapable = 0;
Krunal Soni53993f72016-07-08 18:20:03 -07001415 if (session->vht_config.su_beam_former &&
Naveen Rawatada5fac2016-01-28 16:24:32 -08001416 assoc_req->VHTCaps.suBeamformeeCap)
1417 sta_ds->vht_su_bfee_capable = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001418 else
Naveen Rawatada5fac2016-01-28 16:24:32 -08001419 sta_ds->vht_su_bfee_capable = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001420 }
Krunal Soni99752a12016-04-12 17:44:45 -07001421 if (lim_populate_matching_rate_set(mac_ctx, sta_ds,
1422 &(assoc_req->supportedRates),
1423 &(assoc_req->extendedRates),
1424 assoc_req->HTCaps.supportedMCSSet,
Kapil Gupta4b2efbb2016-10-03 13:07:20 +05301425 session, vht_caps) != eSIR_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001426 /* Could not update hash table entry at DPH with rateset */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001427 lim_log(mac_ctx, LOGE,
Krunal Soni99752a12016-04-12 17:44:45 -07001428 FL("Couldn't update hash entry for aid=%d, MacAddr: "
1429 MAC_ADDRESS_STR),
1430 peer_idx, MAC_ADDR_ARRAY(hdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431
1432 /* Release AID */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001433 lim_release_peer_idx(mac_ctx, peer_idx, session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001434
Naveen Rawatada5fac2016-01-28 16:24:32 -08001435 lim_reject_association(mac_ctx, hdr->sa,
Krunal Soni99752a12016-04-12 17:44:45 -07001436 sub_type, true, auth_type, peer_idx, true,
1437 (tSirResultCodes)eSIR_MAC_UNSPEC_FAILURE_STATUS,
1438 session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001439
Naveen Rawatada5fac2016-01-28 16:24:32 -08001440 if (session->parsedAssocReq)
Krunal Soni99752a12016-04-12 17:44:45 -07001441 assoc_req = session->parsedAssocReq[sta_ds->assocId];
1442 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443 }
Naveen Rawatada5fac2016-01-28 16:24:32 -08001444 if (assoc_req->operMode.present) {
1445 sta_ds->vhtSupportedRxNss = assoc_req->operMode.rxNSS + 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 } else {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001447 sta_ds->vhtSupportedRxNss =
1448 ((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
Krunal Soni99752a12016-04-12 17:44:45 -07001449 == MCSMAPMASK2x2) ? 1 : 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001450 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451
Krunal Soni99752a12016-04-12 17:44:45 -07001452 /* Add STA context at MAC HW (BMU, RHP & TFP) */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001453 sta_ds->qosMode = false;
1454 sta_ds->lleEnabled = false;
1455 if (assoc_req->capabilityInfo.qos && (qos_mode == eHAL_SET)) {
1456 sta_ds->lleEnabled = true;
1457 sta_ds->qosMode = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001458 }
1459
Naveen Rawatada5fac2016-01-28 16:24:32 -08001460 sta_ds->wmeEnabled = false;
1461 sta_ds->wsmEnabled = false;
1462 limGetWmeMode(session, &wme_mode);
1463 if ((!sta_ds->lleEnabled) && assoc_req->wmeInfoPresent
1464 && (wme_mode == eHAL_SET)) {
1465 sta_ds->wmeEnabled = true;
1466 sta_ds->qosMode = true;
1467 limGetWsmMode(session, &wsm_mode);
Krunal Soni99752a12016-04-12 17:44:45 -07001468 /*
1469 * WMM_APSD - WMM_SA related processing should be separate;
1470 * WMM_SA and WMM_APSD can coexist
1471 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001472 if (assoc_req->WMMInfoStation.present) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001473 /* check whether AP supports or not */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001474 if (LIM_IS_AP_ROLE(session) &&
Krunal Soni99752a12016-04-12 17:44:45 -07001475 (session->apUapsdEnable == 0) &&
1476 (assoc_req->WMMInfoStation.acbe_uapsd ||
1477 assoc_req->WMMInfoStation.acbk_uapsd ||
1478 assoc_req->WMMInfoStation.acvo_uapsd ||
1479 assoc_req->WMMInfoStation.acvi_uapsd)) {
1480 /*
1481 * Rcvd Re/Assoc Req from STA when UPASD is
1482 * not supported.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001483 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001484 lim_log(mac_ctx, LOGE,
Krunal Soni99752a12016-04-12 17:44:45 -07001485 FL("UAPSD not supported, reply accordingly"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001486 /* update UAPSD and send it to LIM to add STA */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001487 sta_ds->qos.capability.qosInfo.acbe_uapsd = 0;
1488 sta_ds->qos.capability.qosInfo.acbk_uapsd = 0;
1489 sta_ds->qos.capability.qosInfo.acvo_uapsd = 0;
1490 sta_ds->qos.capability.qosInfo.acvi_uapsd = 0;
1491 sta_ds->qos.capability.qosInfo.maxSpLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001492 } else {
1493 /* update UAPSD and send it to LIM to add STA */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001494 sta_ds->qos.capability.qosInfo.acbe_uapsd =
1495 assoc_req->WMMInfoStation.acbe_uapsd;
1496 sta_ds->qos.capability.qosInfo.acbk_uapsd =
1497 assoc_req->WMMInfoStation.acbk_uapsd;
1498 sta_ds->qos.capability.qosInfo.acvo_uapsd =
1499 assoc_req->WMMInfoStation.acvo_uapsd;
1500 sta_ds->qos.capability.qosInfo.acvi_uapsd =
1501 assoc_req->WMMInfoStation.acvi_uapsd;
1502 sta_ds->qos.capability.qosInfo.maxSpLen =
1503 assoc_req->WMMInfoStation.max_sp_length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504 }
1505 }
Naveen Rawatada5fac2016-01-28 16:24:32 -08001506 if (assoc_req->wsmCapablePresent && (wsm_mode == eHAL_SET))
1507 sta_ds->wsmEnabled = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001508 }
1509 /* Re/Assoc Response frame to requesting STA */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001510 sta_ds->mlmStaContext.subType = sub_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001511
1512#ifdef WLAN_FEATURE_11W
Naveen Rawatada5fac2016-01-28 16:24:32 -08001513 sta_ds->rmfEnabled = (pmf_connection) ? 1 : 0;
1514 sta_ds->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
1515 timer_id.fields.sessionId = session->peSessionId;
1516 timer_id.fields.peerIdx = peer_idx;
1517 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
Krunal Soni99752a12016-04-12 17:44:45 -07001518 &retry_interval) != eSIR_SUCCESS) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001519 lim_log(mac_ctx, LOGE,
Krunal Soni99752a12016-04-12 17:44:45 -07001520 FL("Couldn't get PMF SA Query retry interval value"));
1521 lim_reject_association(mac_ctx, hdr->sa, sub_type, true,
1522 auth_type, peer_idx, false,
1523 (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
1524 session);
1525 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526 }
Naveen Rawatada5fac2016-01-28 16:24:32 -08001527 if (WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN > retry_interval) {
1528 retry_interval = WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529 }
Krunal Soni99752a12016-04-12 17:44:45 -07001530 if (tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer,
1531 "PMF SA Query timer", lim_pmf_sa_query_timer_handler,
1532 timer_id.value,
1533 SYS_MS_TO_TICKS((retry_interval * 1024) / 1000),
1534 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
1535 lim_log(mac_ctx, LOGE,
1536 FL("could not create PMF SA Query timer"));
1537 lim_reject_association(mac_ctx, hdr->sa, sub_type,
1538 true, auth_type, peer_idx, false,
1539 (tSirResultCodes)eSIR_MAC_UNSPEC_FAILURE_STATUS,
1540 session);
1541 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542 }
1543#endif
1544
Naveen Rawatada5fac2016-01-28 16:24:32 -08001545 if (assoc_req->ExtCap.present) {
1546 lim_set_stads_rtt_cap(sta_ds,
1547 (struct s_ext_cap *) assoc_req->ExtCap.bytes, mac_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548 } else {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001549 sta_ds->timingMeasCap = 0;
1550 PELOG1(lim_log(mac_ctx, LOG1, FL("ExtCap not present"));)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 }
Krunal Soni99752a12016-04-12 17:44:45 -07001552 return true;
1553}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554
Krunal Soni99752a12016-04-12 17:44:45 -07001555/**
1556 * lim_update_sta_ctx() - add/del sta depending on connection state machine
1557 * @mac_ctx: pointer to Global MAC structure
1558 * @session: pointer to pe session entry
1559 * @assoc_req: pointer to ASSOC/REASSOC Request frame
1560 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
1561 * @sta_ds: station dph entry
1562 * @update_ctx: indicates if STA context already exist
1563 *
1564 * Checks for SSID match
1565 *
1566 * Return: true of no error, false otherwise
1567 */
1568static bool lim_update_sta_ctx(tpAniSirGlobal mac_ctx, tpPESession session,
1569 tpSirAssocReq assoc_req, uint8_t sub_type,
1570 tpDphHashNode sta_ds, uint8_t update_ctx)
1571{
1572 tLimMlmStates mlm_prev_state;
1573 /*
1574 * BTAMP: If STA context already exist (ie. update_ctx = 1) for this STA
1575 * then we should delete the old one, and add the new STA. This is taken
1576 * care of in the lim_del_sta() routine.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001577 *
Krunal Soni99752a12016-04-12 17:44:45 -07001578 * Prior to BTAMP, we were setting this flag so that when PE receives
1579 * SME_ASSOC_CNF, and if this flag is set, then PE shall delete the old
1580 * station and then add. But now in BTAMP, we're directly adding station
1581 * before waiting for SME_ASSOC_CNF, so we can do this now.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001582 */
Krunal Soni99752a12016-04-12 17:44:45 -07001583 if (!(update_ctx)) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001584 sta_ds->mlmStaContext.updateContext = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585
Krunal Soni99752a12016-04-12 17:44:45 -07001586 /*
1587 * BTAMP: Add STA context at HW - issue WMA_ADD_STA_REQ to HAL
1588 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001589 if (lim_add_sta(mac_ctx, sta_ds, false, session) !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001590 eSIR_SUCCESS) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001591 lim_log(mac_ctx, LOGE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592 FL("could not Add STA with assocId=%d"),
Naveen Rawatada5fac2016-01-28 16:24:32 -08001593 sta_ds->assocId);
1594 lim_reject_association(mac_ctx, sta_ds->staAddr,
Krunal Soni99752a12016-04-12 17:44:45 -07001595 sta_ds->mlmStaContext.subType, true,
1596 sta_ds->mlmStaContext.authType,
1597 sta_ds->assocId, true,
1598 (tSirResultCodes)eSIR_MAC_UNSPEC_FAILURE_STATUS,
1599 session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001600
Naveen Rawatada5fac2016-01-28 16:24:32 -08001601 if (session->parsedAssocReq)
Krunal Soni99752a12016-04-12 17:44:45 -07001602 assoc_req =
1603 session->parsedAssocReq[sta_ds->assocId];
1604 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001605 }
1606 } else {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001607 sta_ds->mlmStaContext.updateContext = 1;
Naveen Rawatada5fac2016-01-28 16:24:32 -08001608 mlm_prev_state = sta_ds->mlmStaContext.mlmState;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609
Krunal Soni99752a12016-04-12 17:44:45 -07001610 /*
1611 * As per the HAL/FW needs the reassoc req need not be calling
1612 * lim_del_sta
1613 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001614 if (sub_type != LIM_REASSOC) {
Krunal Soni99752a12016-04-12 17:44:45 -07001615 /*
1616 * we need to set the mlmState here in order
1617 * differentiate in lim_del_sta.
1618 */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001619 sta_ds->mlmStaContext.mlmState =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
Krunal Soni99752a12016-04-12 17:44:45 -07001621 if (lim_del_sta(mac_ctx, sta_ds, true, session)
1622 != eSIR_SUCCESS) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001623 lim_log(mac_ctx, LOGE,
Krunal Soni99752a12016-04-12 17:44:45 -07001624 FL("Couldn't DEL STA, assocId=%d staId %d"),
Naveen Rawatada5fac2016-01-28 16:24:32 -08001625 sta_ds->assocId, sta_ds->staIndex);
1626 lim_reject_association(mac_ctx, sta_ds->staAddr,
Krunal Soni99752a12016-04-12 17:44:45 -07001627 sta_ds->mlmStaContext.subType, true,
1628 sta_ds->mlmStaContext.authType,
1629 sta_ds->assocId, true,
1630 (tSirResultCodes)
1631 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1632 session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633
1634 /* Restoring the state back. */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001635 sta_ds->mlmStaContext.mlmState = mlm_prev_state;
1636 if (session->parsedAssocReq)
Krunal Soni99752a12016-04-12 17:44:45 -07001637 assoc_req = session->parsedAssocReq[
1638 sta_ds->assocId];
1639 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640 }
1641 } else {
Krunal Soni99752a12016-04-12 17:44:45 -07001642 /*
1643 * mlmState is changed in lim_add_sta context use the
1644 * same AID, already allocated
1645 */
1646 if (lim_add_sta(mac_ctx, sta_ds, false, session)
1647 != eSIR_SUCCESS) {
Naveen Rawatada5fac2016-01-28 16:24:32 -08001648 lim_log(mac_ctx, LOGE,
Krunal Soni99752a12016-04-12 17:44:45 -07001649 FL("UPASD not supported, REASSOC Failed"));
Naveen Rawatada5fac2016-01-28 16:24:32 -08001650 lim_reject_association(mac_ctx, sta_ds->staAddr,
Krunal Soni99752a12016-04-12 17:44:45 -07001651 sta_ds->mlmStaContext.subType, true,
1652 sta_ds->mlmStaContext.authType,
1653 sta_ds->assocId, true,
1654 (tSirResultCodes)
1655 eSIR_MAC_WME_REFUSED_STATUS,
1656 session);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657
1658 /* Restoring the state back. */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001659 sta_ds->mlmStaContext.mlmState = mlm_prev_state;
1660 if (session->parsedAssocReq)
Krunal Soni99752a12016-04-12 17:44:45 -07001661 assoc_req = session->parsedAssocReq[
Naveen Rawatada5fac2016-01-28 16:24:32 -08001662 sta_ds->assocId];
Krunal Soni99752a12016-04-12 17:44:45 -07001663 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001666 }
Krunal Soni99752a12016-04-12 17:44:45 -07001667 return true;
1668}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669
Krunal Soni99752a12016-04-12 17:44:45 -07001670/**
1671 * lim_process_assoc_cleanup() - frees up resources used in function
1672 * lim_process_assoc_req_frame()
1673 * @mac_ctx: pointer to Global MAC structure
1674 * @session: pointer to pe session entry
1675 * @assoc_req: pointer to ASSOC/REASSOC Request frame
1676 * @sta_ds: station dph entry
1677 * @tmp_assoc_req: pointer to tmp ASSOC/REASSOC Request frame
1678 * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above
1679 *
1680 * Frees up resources used in function lim_process_assoc_req_frame
1681 *
1682 * Return: void
1683 */
1684static void lim_process_assoc_cleanup(tpAniSirGlobal mac_ctx,
1685 tpPESession session,
1686 tpSirAssocReq assoc_req,
1687 tpDphHashNode sta_ds,
1688 tpSirAssocReq tmp_assoc_req,
1689 bool *assoc_req_copied)
1690{
Naveen Rawatada5fac2016-01-28 16:24:32 -08001691 if (assoc_req != NULL) {
1692 if (assoc_req->assocReqFrame) {
1693 qdf_mem_free(assoc_req->assocReqFrame);
1694 assoc_req->assocReqFrame = NULL;
1695 assoc_req->assocReqFrameLength = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001696 }
1697
Naveen Rawatada5fac2016-01-28 16:24:32 -08001698 qdf_mem_free(assoc_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699 /* to avoid double free */
Krunal Soni99752a12016-04-12 17:44:45 -07001700 if (*assoc_req_copied && session->parsedAssocReq)
Naveen Rawatada5fac2016-01-28 16:24:32 -08001701 session->parsedAssocReq[sta_ds->assocId] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001702 }
1703
1704 /* If it is not duplicate Assoc request then only make to Null */
Naveen Rawatada5fac2016-01-28 16:24:32 -08001705 if ((sta_ds != NULL) &&
1706 (sta_ds->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) {
1707 if (session->parsedAssocReq != NULL) {
1708 tmp_assoc_req =
1709 session->parsedAssocReq[sta_ds->assocId];
1710 if (tmp_assoc_req != NULL) {
1711 if (tmp_assoc_req->assocReqFrame) {
Krunal Soni99752a12016-04-12 17:44:45 -07001712 qdf_mem_free(
1713 tmp_assoc_req->assocReqFrame);
Naveen Rawatada5fac2016-01-28 16:24:32 -08001714 tmp_assoc_req->assocReqFrame = NULL;
1715 tmp_assoc_req->assocReqFrameLength = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001716 }
Naveen Rawatada5fac2016-01-28 16:24:32 -08001717 qdf_mem_free(tmp_assoc_req);
Krunal Soni99752a12016-04-12 17:44:45 -07001718 session->parsedAssocReq[sta_ds->assocId] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 }
1720 }
1721 }
Krunal Soni99752a12016-04-12 17:44:45 -07001722}
1723
1724/**
1725 * lim_process_assoc_req_frame() - Process RE/ASSOC Request frame.
1726 * @mac_ctx: Pointer to Global MAC structure
1727 * @rx_pkt_info: A pointer to Buffer descriptor + associated PDUs
1728 * @sub_type: Indicates whether it is Association Request(=0) or Reassociation
1729 * Request(=1) frame
1730 * @session: pe session entry
1731 *
1732 * This function is called to process RE/ASSOC Request frame.
1733 *
1734 * @Return: void
1735 */
1736void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
1737 uint8_t sub_type, tpPESession session)
1738{
1739 bool pmf_connection = false, assoc_req_copied = false;
1740 uint8_t update_ctx, *frm_body;
1741 uint16_t peer_idx, assoc_id = 0;
Krishna Kumaar Natarajandb582ec2016-03-08 17:37:04 -08001742 uint32_t frame_len;
Krunal Soni99752a12016-04-12 17:44:45 -07001743 uint32_t phy_mode;
1744 tHalBitVal qos_mode;
1745 tpSirMacMgmtHdr hdr;
1746 struct tLimPreAuthNode *sta_pre_auth_ctx;
1747 tAniAuthType auth_type;
1748 tSirMacCapabilityInfo local_cap;
1749 tpDphHashNode sta_ds = NULL;
1750 tpSirAssocReq assoc_req, tmp_assoc_req;
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -07001751 bool dup_entry = false;
Krunal Soni99752a12016-04-12 17:44:45 -07001752
1753 lim_get_phy_mode(mac_ctx, &phy_mode, session);
1754
1755 limGetQosMode(session, &qos_mode);
1756
1757 hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1758 frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
1759
1760 lim_log(mac_ctx, LOG1,
1761 FL("Rcvd %s Req Frame, sessionid: %d systemrole %d MlmState %d from: "
1762 MAC_ADDRESS_STR),
1763 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
1764 session->peSessionId, GET_LIM_SYSTEM_ROLE(session),
1765 session->limMlmState, MAC_ADDR_ARRAY(hdr->sa));
1766
Rajeev Kumarbe5d7fd2016-04-15 14:35:12 -07001767 if (LIM_IS_STA_ROLE(session)) {
Krunal Soni99752a12016-04-12 17:44:45 -07001768 lim_log(mac_ctx, LOGE,
1769 FL("Rcvd unexpected ASSOC REQ, sessionid: %d sys sub_type=%d for role=%d from: "
1770 MAC_ADDRESS_STR),
1771 session->peSessionId, sub_type,
1772 GET_LIM_SYSTEM_ROLE(session),
1773 MAC_ADDR_ARRAY(hdr->sa));
1774 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG3,
1775 WMA_GET_RX_MPDU_DATA(rx_pkt_info), frame_len);
1776 return;
1777 }
Liangwei Dong9028d752016-10-17 02:00:17 -04001778 if (session->limMlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) {
1779 lim_log(mac_ctx, LOGE, FL("drop ASSOC REQ on sessionid: %d "
1780 "role=%d from: "MAC_ADDRESS_STR" in limMlmState %d"),
1781 session->peSessionId,
1782 GET_LIM_SYSTEM_ROLE(session),
1783 MAC_ADDR_ARRAY(hdr->sa),
1784 eLIM_MLM_WT_DEL_BSS_RSP_STATE);
1785 return;
1786 }
Krunal Soni99752a12016-04-12 17:44:45 -07001787
1788 /*
1789 * If a STA is already present in DPH and it is initiating a Assoc
1790 * re-transmit, do not process it. This can happen when first Assoc Req
1791 * frame is received but ACK lost at STA side. The ACK for this dropped
1792 * Assoc Req frame should be sent by HW. Host simply does not process it
1793 * once the entry for the STA is already present in DPH.
1794 */
1795 sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa, &assoc_id,
1796 &session->dph.dphHashTable);
1797 if (NULL != sta_ds) {
1798 if (hdr->fc.retry > 0) {
1799 lim_log(mac_ctx, LOGE,
1800 FL("STA is initiating Assoc Req after ACK lost. Do not process sessionid: %d sys sub_type=%d for role=%d from: "
1801 MAC_ADDRESS_STR), session->peSessionId,
1802 sub_type, GET_LIM_SYSTEM_ROLE(session),
1803 MAC_ADDR_ARRAY(hdr->sa));
1804 } else if (!sta_ds->rmfEnabled) {
1805 /*
1806 * Do this only for non PMF case.
1807 * STA might have missed the assoc response, so it is
1808 * sending assoc request frame again.
1809 */
1810 lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_SUCCESS,
1811 sta_ds->assocId, sta_ds->staAddr,
1812 sta_ds->mlmStaContext.subType,
1813 sta_ds, session);
1814 lim_log(mac_ctx, LOGE,
1815 FL("DUT already received an assoc request frame and STA is sending another assoc req.So, do not Process sessionid: %d sys sub_type=%d for role=%d from: "
1816 MAC_ADDRESS_STR),
1817 session->peSessionId, sub_type,
1818 session->limSystemRole,
1819 MAC_ADDR_ARRAY(hdr->sa));
1820 }
1821 return;
1822 }
1823
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -07001824 dup_entry = lim_check_sta_in_pe_entries(mac_ctx, hdr,
1825 session->peSessionId);
Krunal Soni99752a12016-04-12 17:44:45 -07001826
1827 /* Get pointer to Re/Association Request frame body */
1828 frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
1829
1830 if (lim_is_group_addr(hdr->sa)) {
1831 /*
1832 * Rcvd Re/Assoc Req frame from BC/MC address Log error and
1833 * ignore it
1834 */
1835 lim_log(mac_ctx, LOGE,
1836 FL("Rcvd %s Req, sessionid: %d from a BC/MC address"
1837 MAC_ADDRESS_STR),
1838 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
1839 session->peSessionId, MAC_ADDR_ARRAY(hdr->sa));
1840 return;
1841 }
1842
1843 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
1844 (uint8_t *) frm_body, frame_len);
1845
1846 if (false == lim_chk_sa_da(mac_ctx, hdr, session, sub_type))
1847 return;
1848
1849 if (false == lim_chk_tkip(mac_ctx, hdr, session, sub_type))
1850 return;
1851
Kondabattini, Ganeshe4f18e02016-09-13 13:01:22 +05301852 /* check for the presence of vendor IE */
1853 if ((session->access_policy_vendor_ie) &&
1854 (session->access_policy ==
1855 LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT)) {
1856 if (!cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
1857 &session->access_policy_vendor_ie[2],
1858 3, frm_body + LIM_ASSOC_REQ_IE_OFFSET, frame_len)) {
1859 lim_log(mac_ctx, LOGE,
1860 FL("Vendor ie not present and access policy is %x, Rejected association"),
1861 session->access_policy);
1862 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
1863 eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, hdr->sa,
1864 sub_type, 0, session);
1865 return;
1866 }
1867 }
Krunal Soni99752a12016-04-12 17:44:45 -07001868 /* Allocate memory for the Assoc Request frame */
1869 assoc_req = qdf_mem_malloc(sizeof(*assoc_req));
1870 if (NULL == assoc_req) {
1871 lim_log(mac_ctx, LOGP,
1872 FL("Allocate Memory failed in assoc_req"));
1873 return;
1874 }
Krunal Soni99752a12016-04-12 17:44:45 -07001875
1876 /* Parse Assoc Request frame */
1877 if (false == lim_chk_assoc_req_parse_error(mac_ctx, hdr, session,
1878 assoc_req, sub_type, frm_body, frame_len))
1879 goto error;
1880
1881 assoc_req->assocReqFrame = qdf_mem_malloc(frame_len);
1882 if (NULL == assoc_req->assocReqFrame) {
1883 lim_log(mac_ctx, LOGE,
1884 FL("Memory alloc failed for the assoc req, len=%d"),
1885 frame_len);
1886 goto error;
1887 }
1888
1889 qdf_mem_copy((uint8_t *) assoc_req->assocReqFrame,
1890 (uint8_t *) frm_body, frame_len);
1891 assoc_req->assocReqFrameLength = frame_len;
1892
1893 if (false == lim_chk_capab(mac_ctx, hdr, session, assoc_req,
1894 sub_type, &local_cap))
1895 goto error;
1896
1897 update_ctx = false;
1898
1899 if (false == lim_chk_ssid(mac_ctx, hdr, session, assoc_req, sub_type))
1900 goto error;
1901
1902 if (false == lim_chk_rates(mac_ctx, hdr, session, assoc_req, sub_type))
1903 goto error;
1904
1905 if (false == lim_chk_11g_only(mac_ctx, hdr, session, assoc_req,
1906 sub_type))
1907 goto error;
1908
1909 if (false == lim_chk_11n_only(mac_ctx, hdr, session, assoc_req,
1910 sub_type))
1911 goto error;
1912
1913 if (false == lim_chk_11ac_only(mac_ctx, hdr, session, assoc_req,
1914 sub_type))
1915 goto error;
1916
1917 /* Spectrum Management (11h) specific checks */
1918 lim_process_for_spectrum_mgmt(mac_ctx, hdr, session,
1919 assoc_req, sub_type, local_cap);
1920
1921 if (false == lim_chk_mcs(mac_ctx, hdr, session, assoc_req, sub_type))
1922 goto error;
1923
1924 if (false == lim_chk_is_11b_sta_supported(mac_ctx, hdr, session,
1925 assoc_req, sub_type, phy_mode))
1926 goto error;
1927
1928 /*
1929 * Check for 802.11n HT caps compatibility; are HT Capabilities
1930 * turned on in lim?
1931 */
1932 lim_print_ht_cap(mac_ctx, session, assoc_req);
1933
1934 if (false == lim_chk_n_process_wpa_rsn_ie(mac_ctx, hdr, session,
1935 assoc_req, sub_type, &pmf_connection))
1936 goto error;
1937
1938 /* Extract 'associated' context for STA, if any. */
1939 sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa, &peer_idx,
1940 &session->dph.dphHashTable);
1941
1942 /* Extract pre-auth context for the STA, if any. */
1943 sta_pre_auth_ctx = lim_search_pre_auth_list(mac_ctx, hdr->sa);
1944
1945 if (sta_ds == NULL) {
1946 if (false == lim_process_assoc_req_no_sta_ctx(mac_ctx, hdr,
1947 session, assoc_req, sub_type, sta_pre_auth_ctx,
1948 sta_ds, &auth_type))
1949 goto error;
1950 } else {
1951 if (false == lim_process_assoc_req_sta_ctx(mac_ctx, hdr,
1952 session, assoc_req, sub_type, sta_pre_auth_ctx,
1953 sta_ds, peer_idx, &auth_type, &update_ctx))
1954 goto error;
1955 goto sendIndToSme;
1956 }
1957
1958 /* check if sta is allowed per QoS AC rules */
1959 if (false == lim_chk_wmm(mac_ctx, hdr, session,
1960 assoc_req, sub_type, qos_mode))
1961 goto error;
1962
1963 /* STA is Associated ! */
1964 lim_log(mac_ctx, LOGE,
1965 FL("Received %s Req successful from " MAC_ADDRESS_STR),
1966 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
1967 MAC_ADDR_ARRAY(hdr->sa));
1968
1969 /*
1970 * AID for this association will be same as the peer Index used in DPH
1971 * table. Assign unused/least recently used peer Index from perStaDs.
1972 * NOTE: lim_assign_peer_idx() assigns AID values ranging between
1973 * 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT)
1974 */
1975
1976 peer_idx = lim_assign_peer_idx(mac_ctx, session);
1977
1978 if (!peer_idx) {
1979 /* Could not assign AID. Reject association */
1980 lim_log(mac_ctx, LOGE,
1981 FL("PeerIdx not avaialble. Reject associaton"));
1982 lim_reject_association(mac_ctx, hdr->sa, sub_type,
1983 true, auth_type, peer_idx, false,
1984 (tSirResultCodes)eSIR_MAC_UNSPEC_FAILURE_STATUS,
1985 session);
1986 goto error;
1987 }
1988
1989 /* Add an entry to hash table maintained by DPH module */
1990
1991 sta_ds = dph_add_hash_entry(mac_ctx, hdr->sa, peer_idx,
1992 &session->dph.dphHashTable);
1993
1994 if (sta_ds == NULL) {
1995 /* Could not add hash table entry at DPH */
1996 lim_log(mac_ctx, LOGE,
1997 FL("couldn't add hash entry at DPH for aid=%d, MacAddr:"
1998 MAC_ADDRESS_STR), peer_idx, MAC_ADDR_ARRAY(hdr->sa));
1999
2000 /* Release AID */
2001 lim_release_peer_idx(mac_ctx, peer_idx, session);
2002
2003 lim_reject_association(mac_ctx, hdr->sa, sub_type,
2004 true, auth_type, peer_idx, false,
2005 (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
2006 session);
2007 goto error;
2008 }
2009
2010sendIndToSme:
2011 if (false == lim_update_sta_ds(mac_ctx, hdr, session, assoc_req,
2012 sub_type, sta_ds, tmp_assoc_req, auth_type,
2013 &assoc_req_copied, peer_idx, qos_mode,
2014 pmf_connection))
2015 goto error;
2016
2017 /* BTAMP: Storing the parsed assoc request in the session array */
2018 if (session->parsedAssocReq)
2019 session->parsedAssocReq[sta_ds->assocId] = assoc_req;
2020 assoc_req_copied = true;
2021
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -07002022 /* If it is duplicate entry wait till the peer is deleted */
2023 if (dup_entry != true) {
2024 if (false == lim_update_sta_ctx(mac_ctx, session, assoc_req,
Krunal Soni99752a12016-04-12 17:44:45 -07002025 sub_type, sta_ds, update_ctx))
2026 goto error;
Sandeep Puligilla7e3e3c52016-09-02 17:54:21 -07002027 }
Krunal Soni99752a12016-04-12 17:44:45 -07002028
2029 /* AddSta is sucess here */
2030 if (LIM_IS_AP_ROLE(session) && IS_DOT11_MODE_HT(session->dot11mode) &&
2031 assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) {
2032 /*
2033 * Update in the HAL Sta Table for the Update of the Protection
2034 * Mode
2035 */
2036 lim_post_sm_state_update(mac_ctx, sta_ds->staIndex,
2037 sta_ds->htMIMOPSState, sta_ds->staAddr,
2038 session->smeSessionId);
2039 }
2040
2041 return;
2042
2043error:
2044
2045 lim_process_assoc_cleanup(mac_ctx, session, assoc_req, sta_ds,
2046 tmp_assoc_req, &assoc_req_copied);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047 return;
Naveen Rawatada5fac2016-01-28 16:24:32 -08002048}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002049
2050#ifdef FEATURE_WLAN_WAPI
2051/**
2052 * lim_fill_assoc_ind_wapi_info()- Updates WAPI data in assoc indication
2053 * @mac_ctx: Global Mac context
2054 * @assoc_req: pointer to association request
2055 * @assoc_ind: Pointer to association indication
2056 * @wpsie: WPS IE
2057 *
2058 * This function updates WAPI meta data in association indication message
2059 * sent to SME.
2060 *
2061 * Return: None
2062 */
2063static void lim_fill_assoc_ind_wapi_info(tpAniSirGlobal mac_ctx,
2064 tpSirAssocReq assoc_req, tpLimMlmAssocInd assoc_ind,
2065 uint8_t *wpsie)
2066{
2067 if (assoc_req->wapiPresent && (NULL == wpsie)) {
2068 lim_log(mac_ctx, LOG2,
2069 FL("Received WAPI IE length in Assoc Req is %d"),
2070 assoc_req->wapi.length);
2071 assoc_ind->wapiIE.wapiIEdata[0] = SIR_MAC_WAPI_EID;
2072 assoc_ind->wapiIE.wapiIEdata[1] = assoc_req->wapi.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302073 qdf_mem_copy(&assoc_ind->wapiIE.wapiIEdata[2],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002074 assoc_req->wapi.info, assoc_req->wapi.length);
2075 assoc_ind->wapiIE.length =
2076 2 + assoc_req->wapi.length;
2077 }
2078 return;
2079}
2080#endif
2081
2082/**
2083 * lim_fill_assoc_ind_vht_info() - Updates VHT information in assoc indication
2084 * @mac_ctx: Global Mac context
2085 * @assoc_req: pointer to association request
2086 * @session_entry: PE session entry
2087 * @assoc_ind: Pointer to association indication
2088 *
2089 * This function updates VHT information in association indication message
2090 * sent to SME.
2091 *
2092 * Return: None
2093 */
2094static void lim_fill_assoc_ind_vht_info(tpAniSirGlobal mac_ctx,
Naveen Rawat6186ff92015-10-12 14:33:53 -07002095 tpPESession session_entry,
2096 tpSirAssocReq assoc_req,
2097 tpLimMlmAssocInd assoc_ind)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002098{
2099 uint8_t chan;
2100
2101 if (session_entry->limRFBand == SIR_BAND_2_4_GHZ) {
Naveen Rawat6186ff92015-10-12 14:33:53 -07002102 if (session_entry->vhtCapability && assoc_req->VHTCaps.present)
Krishna Kumaar Natarajan294da812016-04-28 14:39:30 -07002103 assoc_ind->chan_info.info = MODE_11AC_VHT20_2G;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002104 else if (session_entry->htCapability
Naveen Rawat6186ff92015-10-12 14:33:53 -07002105 && assoc_req->HTCaps.present)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106 assoc_ind->chan_info.info = MODE_11NG_HT20;
2107 else
2108 assoc_ind->chan_info.info = MODE_11G;
Naveen Rawat6186ff92015-10-12 14:33:53 -07002109 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002110 }
Naveen Rawat6186ff92015-10-12 14:33:53 -07002111
2112 if (session_entry->vhtCapability && assoc_req->VHTCaps.present) {
2113 if ((session_entry->ch_width > CH_WIDTH_40MHZ)
2114 && assoc_req->HTCaps.supportedChannelWidthSet) {
2115 chan = session_entry->ch_center_freq_seg0;
2116 assoc_ind->chan_info.band_center_freq1 =
2117 cds_chan_to_freq(chan);
2118 assoc_ind->chan_info.info = MODE_11AC_VHT80;
2119 return;
2120 }
2121
2122 if ((session_entry->ch_width == CH_WIDTH_40MHZ)
2123 && assoc_req->HTCaps.supportedChannelWidthSet) {
2124 assoc_ind->chan_info.info = MODE_11AC_VHT40;
2125 if (session_entry->htSecondaryChannelOffset ==
2126 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
2127 assoc_ind->chan_info.band_center_freq1 += 10;
2128 else
2129 assoc_ind->chan_info.band_center_freq1 -= 10;
2130 return;
2131 }
2132
2133 assoc_ind->chan_info.info = MODE_11AC_VHT20;
2134 return;
2135 }
2136
2137 if (session_entry->htCapability && assoc_req->HTCaps.present) {
2138 if ((session_entry->ch_width == CH_WIDTH_40MHZ)
2139 && assoc_req->HTCaps.supportedChannelWidthSet) {
2140 assoc_ind->chan_info.info = MODE_11NA_HT40;
2141 if (session_entry->htSecondaryChannelOffset ==
2142 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
2143 assoc_ind->chan_info.band_center_freq1 += 10;
2144 else
2145 assoc_ind->chan_info.band_center_freq1 -= 10;
2146 return;
2147 }
2148
2149 assoc_ind->chan_info.info = MODE_11NA_HT20;
2150 return;
2151 }
2152
2153 assoc_ind->chan_info.info = MODE_11A;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002154 return;
2155}
2156
2157/**
2158 * lim_send_mlm_assoc_ind() - Sends assoc indication to SME
2159 * @mac_ctx: Global Mac context
2160 * @sta_ds: Station DPH hash entry
2161 * @session_entry: PE session entry
2162 *
2163 * This function sends either LIM_MLM_ASSOC_IND
2164 * or LIM_MLM_REASSOC_IND to SME.
2165 *
2166 * Return: None
2167 */
2168void lim_send_mlm_assoc_ind(tpAniSirGlobal mac_ctx,
2169 tpDphHashNode sta_ds, tpPESession session_entry)
2170{
2171 tpLimMlmAssocInd assoc_ind = NULL;
2172 tpSirAssocReq assoc_req;
2173 uint16_t temp, rsn_len;
2174 uint32_t phy_mode;
2175 uint8_t sub_type;
2176 uint8_t *wpsie = NULL;
2177 uint32_t tmp;
2178
2179 /* Get a copy of the already parsed Assoc Request */
2180 assoc_req =
2181 (tpSirAssocReq) session_entry->parsedAssocReq[sta_ds->assocId];
2182
2183 /* Get the phy_mode */
2184 lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
2185
2186 /* Determine if its Assoc or ReAssoc Request */
2187 if (assoc_req->reassocRequest == 1)
2188 sub_type = LIM_REASSOC;
2189 else
2190 sub_type = LIM_ASSOC;
2191
2192 lim_log(mac_ctx, LOG1,
2193 FL("Sessionid %d ssid %s sub_type %d Associd %d staAddr "
2194 MAC_ADDRESS_STR), session_entry->peSessionId,
2195 assoc_req->ssId.ssId, sub_type, sta_ds->assocId,
2196 MAC_ADDR_ARRAY(sta_ds->staAddr));
2197
2198 if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) {
2199 temp = sizeof(tLimMlmAssocInd);
2200
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302201 assoc_ind = qdf_mem_malloc(temp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002202 if (NULL == assoc_ind) {
2203 lim_release_peer_idx(mac_ctx, sta_ds->assocId,
2204 session_entry);
2205 lim_log(mac_ctx, LOGP,
2206 FL("AllocateMemory failed for assoc_ind"));
2207 return;
2208 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302209 qdf_mem_copy((uint8_t *) assoc_ind->peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002210 (uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
2211 assoc_ind->aid = sta_ds->assocId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302212 qdf_mem_copy((uint8_t *) &assoc_ind->ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002213 (uint8_t *) &(assoc_req->ssId),
2214 assoc_req->ssId.length + 1);
2215 assoc_ind->sessionId = session_entry->peSessionId;
2216 assoc_ind->authType = sta_ds->mlmStaContext.authType;
2217 assoc_ind->capabilityInfo = assoc_req->capabilityInfo;
2218
2219 /* Fill in RSN IE information */
2220 assoc_ind->rsnIE.length = 0;
2221 /* if WPS IE is present, ignore RSN IE */
2222 if (assoc_req->addIEPresent && assoc_req->addIE.length) {
2223 wpsie = limGetWscIEPtr(mac_ctx,
2224 assoc_req->addIE.addIEdata,
2225 assoc_req->addIE.length);
2226 }
2227 if (assoc_req->rsnPresent && (NULL == wpsie)) {
2228 lim_log(mac_ctx, LOG2, FL("Assoc Req RSN IE len = %d"),
2229 assoc_req->rsn.length);
2230 assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length;
2231 assoc_ind->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
2232 assoc_ind->rsnIE.rsnIEdata[1] =
2233 assoc_req->rsn.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302234 qdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002235 assoc_req->rsn.info,
2236 assoc_req->rsn.length);
2237 }
2238 /* Fill in 802.11h related info */
2239 if (assoc_req->powerCapabilityPresent
2240 && assoc_req->supportedChannelsPresent) {
2241 assoc_ind->spectrumMgtIndicator = eSIR_TRUE;
2242 assoc_ind->powerCap.minTxPower =
2243 assoc_req->powerCapability.minTxPower;
2244 assoc_ind->powerCap.maxTxPower =
2245 assoc_req->powerCapability.maxTxPower;
2246 lim_convert_supported_channels(mac_ctx, assoc_ind,
2247 assoc_req);
2248 } else {
2249 assoc_ind->spectrumMgtIndicator = eSIR_FALSE;
2250 }
2251
2252 /* This check is to avoid extra Sec IEs present incase of WPS */
2253 if (assoc_req->wpaPresent && (NULL == wpsie)) {
2254 rsn_len = assoc_ind->rsnIE.length;
2255 if ((rsn_len + assoc_req->wpa.length)
2256 >= SIR_MAC_MAX_IE_LENGTH) {
2257 lim_log(mac_ctx, LOGE,
2258 FL("rsnIEdata index out of bounds %d"),
2259 rsn_len);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302260 qdf_mem_free(assoc_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002261 return;
2262 }
2263 assoc_ind->rsnIE.rsnIEdata[rsn_len] =
2264 SIR_MAC_WPA_EID;
2265 assoc_ind->rsnIE.rsnIEdata[rsn_len + 1]
2266 = assoc_req->wpa.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302267 qdf_mem_copy(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 &assoc_ind->rsnIE.rsnIEdata[rsn_len + 2],
2269 assoc_req->wpa.info, assoc_req->wpa.length);
2270 assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length;
2271 }
2272#ifdef FEATURE_WLAN_WAPI
2273 lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind,
2274 wpsie);
2275#endif
2276
2277 assoc_ind->addIE.length = 0;
2278 if (assoc_req->addIEPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302279 qdf_mem_copy(&assoc_ind->addIE.addIEdata,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002280 assoc_req->addIE.addIEdata,
2281 assoc_req->addIE.length);
2282 assoc_ind->addIE.length = assoc_req->addIE.length;
2283 }
2284 /*
2285 * Add HT Capabilities into addIE for OBSS
2286 * processing in hostapd
2287 */
2288 if (assoc_req->HTCaps.present) {
2289 rsn_len = assoc_ind->addIE.length;
2290 if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN
2291 + 2 < SIR_MAC_MAX_IE_LENGTH) {
2292 assoc_ind->addIE.addIEdata[rsn_len] =
2293 SIR_MAC_HT_CAPABILITIES_EID;
2294 assoc_ind->addIE.addIEdata[rsn_len + 1] =
2295 DOT11F_IE_HTCAPS_MIN_LEN;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302296 qdf_mem_copy(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002297 &assoc_ind->addIE.addIEdata[rsn_len+2],
2298 ((uint8_t *)&assoc_req->HTCaps) + 1,
2299 DOT11F_IE_HTCAPS_MIN_LEN);
2300 assoc_ind->addIE.length +=
2301 2 + DOT11F_IE_HTCAPS_MIN_LEN;
2302 } else {
2303 lim_log(mac_ctx, LOGP,
2304 FL("Fail:HT capabilities IE to addIE"));
2305 }
2306 }
2307
2308 if (assoc_req->wmeInfoPresent) {
2309 if (wlan_cfg_get_int (mac_ctx,
2310 (uint16_t) WNI_CFG_WME_ENABLED, &tmp)
2311 != eSIR_SUCCESS)
2312 lim_log(mac_ctx, LOGP,
2313 FL("wlan_cfg_get_int failed for id %d"),
2314 WNI_CFG_WME_ENABLED);
2315
2316 /* check whether AP is enabled with WMM */
2317 if (tmp)
2318 assoc_ind->WmmStaInfoPresent = 1;
2319 else
2320 assoc_ind->WmmStaInfoPresent = 0;
2321 /*
2322 * Note: we are not rejecting association here
2323 * because IOT will fail
2324 */
2325 }
2326 /* Required for indicating the frames to upper layer */
2327 assoc_ind->assocReqLength = assoc_req->assocReqFrameLength;
2328 assoc_ind->assocReqPtr = assoc_req->assocReqFrame;
2329
2330 assoc_ind->beaconPtr = session_entry->beacon;
2331 assoc_ind->beaconLength = session_entry->bcnLen;
2332
2333 assoc_ind->chan_info.chan_id =
2334 session_entry->currentOperChannel;
2335 assoc_ind->chan_info.mhz =
2336 cds_chan_to_freq(session_entry->currentOperChannel);
2337 assoc_ind->chan_info.band_center_freq1 =
2338 cds_chan_to_freq(session_entry->currentOperChannel);
2339 assoc_ind->chan_info.band_center_freq2 = 0;
2340 assoc_ind->chan_info.reg_info_1 =
2341 (session_entry->maxTxPower << 16);
2342 assoc_ind->chan_info.reg_info_2 =
2343 (session_entry->maxTxPower << 8);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05302344 assoc_ind->chan_info.nss = sta_ds->nss;
2345 assoc_ind->chan_info.rate_flags =
2346 lim_get_max_rate_flags(mac_ctx, sta_ds);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002347 /* updates VHT information in assoc indication */
2348 lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
2349 assoc_ind);
2350 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
2351 (uint32_t *) assoc_ind);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302352 qdf_mem_free(assoc_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002353 }
2354 return;
2355}