blob: 114e563379696e44b1fdba3e42b6c592aff0be96 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302 * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*
29 *
30 * This file lim_process_beacon_frame.cc contains the code
31 * for processing Received Beacon Frame.
32 * Author: Chandra Modumudi
33 * Date: 03/01/02
34 * History:-
35 * Date Modified by Modification Information
36 * --------------------------------------------------------------------
37 *
38 */
39
40#include "wni_cfg.h"
41#include "ani_global.h"
42#include "cfg_api.h"
43#include "sch_api.h"
44#include "utils_api.h"
45#include "lim_types.h"
46#include "lim_utils.h"
47#include "lim_assoc_utils.h"
48#include "lim_prop_exts_utils.h"
49#include "lim_ser_des_utils.h"
50
51/**
52 * lim_process_beacon_frame() - to process beacon frames
53 * @mac_ctx: Pointer to Global MAC structure
54 * @rx_pkt_info: A pointer to RX packet info structure
55 * @session: A pointer to session
56 *
57 * This function is called by limProcessMessageQueue() upon Beacon
58 * frame reception.
59 * Note:
60 * 1. Beacons received in 'normal' state in IBSS are handled by
61 * Beacon Processing module.
62 *
63 * Return: none
64 */
65
66void
67lim_process_beacon_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
68 tpPESession session)
69{
70 tpSirMacMgmtHdr mac_hdr;
71 tSchBeaconStruct *bcn_ptr;
72
73 mac_ctx->lim.gLimNumBeaconsRcvd++;
74
75 /*
76 * here is it required to increment session specific heartBeat
77 * beacon counter
78 */
79 mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
80 lim_log(mac_ctx, LOG2,
81 FL("Received Beacon frame with length=%d from "),
82 WMA_GET_RX_MPDU_LEN(rx_pkt_info));
83 lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOG2);
84
85 /* Expect Beacon in any state as Scan is independent of LIM state */
Anurag Chouhan600c3a02016-03-01 10:33:54 +053086 bcn_ptr = qdf_mem_malloc(sizeof(*bcn_ptr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087 if (NULL == bcn_ptr) {
88 lim_log(mac_ctx, LOGE,
89 FL("Unable to allocate memory"));
90 return;
91 }
92 /* Parse received Beacon */
93 if (sir_convert_beacon_frame2_struct(mac_ctx,
94 rx_pkt_info, bcn_ptr) !=
95 eSIR_SUCCESS) {
96 /*
97 * Received wrongly formatted/invalid Beacon.
98 * Ignore it and move on.
99 */
100 lim_log(mac_ctx, LOGW,
101 FL("Received invalid Beacon in state %X"),
102 session->limMlmState);
103 lim_print_mlm_state(mac_ctx, LOGW,
104 session->limMlmState);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530105 qdf_mem_free(bcn_ptr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106 return;
107 }
108 /*
109 * during scanning, when any session is active, and
110 * beacon/Pr belongs to one of the session, fill up the
111 * following, TBD - HB couter
112 */
113 if ((!session->lastBeaconDtimPeriod) &&
114 (sir_compare_mac_addr(session->bssId,
115 bcn_ptr->bssid))) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530116 qdf_mem_copy((uint8_t *)&session->lastBeaconTimeStamp,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800117 (uint8_t *) bcn_ptr->timeStamp,
118 sizeof(uint64_t));
119 session->lastBeaconDtimCount =
120 bcn_ptr->tim.dtimCount;
121 session->lastBeaconDtimPeriod =
122 bcn_ptr->tim.dtimPeriod;
123 session->currentBssBeaconCnt++;
124 }
125 MTRACE(mac_trace(mac_ctx,
126 TRACE_CODE_RX_MGMT_TSF, 0, bcn_ptr->timeStamp[0]);)
127 MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF, 0,
128 bcn_ptr->timeStamp[1]);)
129 lim_check_and_add_bss_description(mac_ctx, bcn_ptr,
130 rx_pkt_info, false, true);
131
132 if ((mac_ctx->lim.gLimMlmState ==
133 eLIM_MLM_WT_PROBE_RESP_STATE) ||
134 (mac_ctx->lim.gLimMlmState ==
135 eLIM_MLM_PASSIVE_SCAN_STATE)) {
136 lim_check_and_add_bss_description(mac_ctx, bcn_ptr,
137 rx_pkt_info,
138 ((mac_ctx->lim.gLimHalScanState ==
139 eLIM_HAL_SCANNING_STATE) ? true : false),
140 false);
141 /*
142 * Calling dfsChannelList which will convert DFS channel
143 * to active channel for x secs if this channel is DFS
144 */
145 lim_set_dfs_channel_list(mac_ctx,
146 bcn_ptr->channelNumber,
147 &mac_ctx->lim.dfschannelList);
148 } else if (session->limMlmState ==
149 eLIM_MLM_WT_JOIN_BEACON_STATE) {
150 if (session->beacon != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530151 qdf_mem_free(session->beacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800152 session->beacon = NULL;
Sreelakshmi Konamki3b8ba612015-12-02 18:13:22 +0530153 session->bcnLen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800154 }
155 session->bcnLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530156 session->beacon = qdf_mem_malloc(session->bcnLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800157 if (NULL == session->beacon) {
158 lim_log(mac_ctx, LOGE,
159 FL("fail to alloc mem to store bcn"));
160 } else {
161 /*
162 * Store the Beacon/ProbeRsp. This is sent to
163 * csr/hdd in join cnf response.
164 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530165 qdf_mem_copy(session->beacon,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800166 WMA_GET_RX_MPDU_DATA(rx_pkt_info),
167 session->bcnLen);
168 }
169 lim_check_and_announce_join_success(mac_ctx, bcn_ptr,
170 mac_hdr, session);
171 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530172 qdf_mem_free(bcn_ptr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800173 return;
174}
175
176/**---------------------------------------------------------------
177 \fn lim_process_beacon_frame_no_session
178 \brief This function is called by limProcessMessageQueue()
179 \ upon Beacon reception.
180 \
181 \param pMac
182 \param *pRxPacketInfo - A pointer to Rx packet info structure
183 \return None
184 ------------------------------------------------------------------*/
185void
186lim_process_beacon_frame_no_session(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo)
187{
188 tpSirMacMgmtHdr pHdr;
189 tSchBeaconStruct *pBeacon;
190
191 pMac->lim.gLimNumBeaconsRcvd++;
192 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
193
194 lim_log(pMac, LOG2, FL("Received Beacon frame with length=%d from "),
195 WMA_GET_RX_MPDU_LEN(pRxPacketInfo));
196 lim_print_mac_addr(pMac, pHdr->sa, LOG2);
197
198
199 /**
200 * No session has been established. Expect Beacon only when
201 * 1. STA is in Scan mode waiting for Beacon/Probe response or
202 * 2. STA/AP is in Learn mode
203 */
204 if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
205 (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ||
206 (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530207 pBeacon = qdf_mem_malloc(sizeof(tSchBeaconStruct));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800208 if (NULL == pBeacon) {
209 lim_log(pMac, LOGE,
210 FL
211 ("Unable to allocate memory in lim_process_beacon_frame_no_session"));
212 return;
213 }
214
215 if (sir_convert_beacon_frame2_struct
216 (pMac, (uint8_t *) pRxPacketInfo,
217 pBeacon) != eSIR_SUCCESS) {
218 /* Received wrongly formatted/invalid Beacon. Ignore and move on. */
219 lim_log(pMac, LOGW,
220 FL
221 ("Received invalid Beacon in global MLM state %X"),
222 pMac->lim.gLimMlmState);
223 lim_print_mlm_state(pMac, LOGW, pMac->lim.gLimMlmState);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530224 qdf_mem_free(pBeacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800225 return;
226 }
227
228 if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
229 (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)) {
230 lim_check_and_add_bss_description(pMac, pBeacon,
231 pRxPacketInfo, true,
232 false);
233 /* Calling dfsChannelList which will convert DFS channel
234 * to Active channel for x secs if this channel is DFS channel */
235 lim_set_dfs_channel_list(pMac, pBeacon->channelNumber,
236 &pMac->lim.dfschannelList);
237 } else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) {
238 } /* end of eLIM_MLM_LEARN_STATE) */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530239 qdf_mem_free(pBeacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800240 } /* end of (eLIM_MLM_WT_PROBE_RESP_STATE) || (eLIM_MLM_PASSIVE_SCAN_STATE) */
241 else {
Sreelakshmi Konamki39acb132015-12-16 13:06:22 +0530242 lim_log(pMac, LOG1, FL("Rcvd Beacon in unexpected MLM state %s (%d)"),
243 lim_mlm_state_str(pMac->lim.gLimMlmState),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800244 pMac->lim.gLimMlmState);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800245#ifdef WLAN_DEBUG
246 pMac->lim.gLimUnexpBcnCnt++;
247#endif
248 }
249
250 return;
251} /*** end lim_process_beacon_frame_no_session() ***/