1 /*
2 * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * This file lim_scan_result_utils.cc contains the utility functions
22 * LIM uses for maintaining and accessing scan results on STA.
23 * Author: Chandra Modumudi
24 * Date: 02/13/02
25 * History:-
26 * Date Modified by Modification Information
27 * --------------------------------------------------------------------
28 */
29
30 #include "lim_types.h"
31 #include "lim_utils.h"
32 #include "lim_ser_des_utils.h"
33 #include "lim_api.h"
34 #include "lim_ft_defs.h"
35 #include "lim_session.h"
36 #include "rrm_api.h"
37 #include "cds_utils.h"
38
39 /**
40 * lim_collect_bss_description()
41 *
42 ***FUNCTION:
43 * This function is called during scan upon receiving
44 * Beacon/Probe Response frame to check if the received
45 * frame matches scan criteria, collect BSS description
46 * and add it to cached scan results.
47 *
48 ***LOGIC:
49 *
50 ***ASSUMPTIONS:
51 * NA
52 *
53 ***NOTE:
54 * NA
55 *
56 * @param mac - Pointer to Global MAC structure
57 * @param pBPR - Pointer to parsed Beacon/Probe Response structure
58 * @param pRxPacketInfo - Pointer to Received frame's BD
59 * @param fScanning - flag to indicate if it is during scan.
60 * ---------------------------------------------
61 *
62 * @return None
63 */
64 void
lim_collect_bss_description(struct mac_context * mac,struct bss_description * pBssDescr,tpSirProbeRespBeacon pBPR,uint8_t * pRxPacketInfo,uint8_t fScanning)65 lim_collect_bss_description(struct mac_context *mac,
66 struct bss_description *pBssDescr,
67 tpSirProbeRespBeacon pBPR,
68 uint8_t *pRxPacketInfo, uint8_t fScanning)
69 {
70 uint8_t *pBody;
71 uint32_t ieLen = 0;
72 tpSirMacMgmtHdr pHdr;
73 uint32_t chan_freq;
74 uint8_t rfBand = 0;
75
76 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
77
78 if (SIR_MAC_B_PR_SSID_OFFSET > WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)) {
79 QDF_ASSERT(WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >=
80 SIR_MAC_B_PR_SSID_OFFSET);
81 return;
82 }
83 ieLen =
84 WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET;
85 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
86 rfBand = WMA_GET_RX_RFBAND(pRxPacketInfo);
87
88 /**
89 * Length of BSS description is without length of
90 * length itself and length of pointer that holds ieFields.
91 *
92 * struct bss_description
93 * +--------+---------------------------------+---------------+
94 * | length | other fields | pointer to IEs|
95 * +--------+---------------------------------+---------------+
96 * ^
97 * ieFields
98 */
99 pBssDescr->length =
100 (uint16_t)(offsetof(struct bss_description, ieFields[0]) -
101 sizeof(pBssDescr->length) + ieLen);
102
103 /* Copy BSS Id */
104 qdf_mem_copy((uint8_t *) &pBssDescr->bssId,
105 (uint8_t *) pHdr->bssId, sizeof(tSirMacAddr));
106
107 /* Copy Timestamp, Beacon Interval and Capability Info */
108 pBssDescr->scansystimensec = qdf_get_bootbased_boottime_ns();
109
110 pBssDescr->timeStamp[0] = pBPR->timeStamp[0];
111 pBssDescr->timeStamp[1] = pBPR->timeStamp[1];
112 pBssDescr->beaconInterval = pBPR->beaconInterval;
113 pBssDescr->capabilityInfo =
114 lim_get_u16((uint8_t *) &pBPR->capabilityInfo);
115
116 if (!pBssDescr->beaconInterval) {
117 pe_warn("Beacon Interval is ZERO, making it to default 100 "
118 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(pHdr->bssId));
119 pBssDescr->beaconInterval = 100;
120 }
121 /*
122 * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut
123 * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz
124 * band, so not relying on the 'last Scanned Channel' stored in LIM.
125 * Instead use the value returned by RXP in BD. This the the same value which HAL programs into
126 * RXP before every channel switch.
127 * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from
128 * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen.
129 * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it
130 * is not present in the beacon, we go for the channel info present in RXP.
131 * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel.
132 * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices.
133 */
134 chan_freq = lim_get_channel_from_beacon(mac, pBPR);
135 pBssDescr->chan_freq = chan_freq;
136
137 /* set the network type in bss description */
138 pBssDescr->nwType =
139 lim_get_nw_type(mac, chan_freq, SIR_MAC_MGMT_FRAME, pBPR);
140
141 /* Copy RSSI & SINR from BD */
142 pBssDescr->rssi = (int8_t) WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo);
143 pBssDescr->rssi_raw = (int8_t) WMA_GET_RX_RSSI_RAW(pRxPacketInfo);
144
145 /* SINR no longer reported by HW */
146 pBssDescr->sinr = 0;
147 pe_debug(QDF_MAC_ADDR_FMT " rssi: normalized: %d, absolute: %d",
148 QDF_MAC_ADDR_REF(pHdr->bssId), pBssDescr->rssi,
149 pBssDescr->rssi_raw);
150
151 pBssDescr->received_time = (uint64_t)qdf_mc_timer_get_system_time();
152 pBssDescr->tsf_delta = WMA_GET_RX_TSF_DELTA(pRxPacketInfo);
153 pBssDescr->seq_ctrl = pHdr->seqControl;
154
155 pe_debug("Received %s from BSSID: " QDF_MAC_ADDR_FMT " tsf_delta = %u Seq Num: %x ssid:" QDF_SSID_FMT ", rssi: %d",
156 pBssDescr->fProbeRsp ? "Probe Rsp" : "Beacon",
157 QDF_MAC_ADDR_REF(pHdr->bssId),
158 pBssDescr->tsf_delta, ((pHdr->seqControl.seqNumHi <<
159 HIGH_SEQ_NUM_OFFSET) | pHdr->seqControl.seqNumLo),
160 QDF_SSID_REF(pBPR->ssId.length, pBPR->ssId.ssId),
161 pBssDescr->rssi_raw);
162
163 if (fScanning) {
164 rrm_get_start_tsf(mac, pBssDescr->startTSF);
165 pBssDescr->parentTSF = WMA_GET_RX_TIMESTAMP(pRxPacketInfo);
166 }
167
168 /* MobilityDomain */
169 pBssDescr->mdie[0] = 0;
170 pBssDescr->mdie[1] = 0;
171 pBssDescr->mdie[2] = 0;
172 pBssDescr->mdiePresent = false;
173 /* If mdie is present in the probe resp we */
174 /* fill it in the bss description */
175 if (pBPR->mdiePresent) {
176 pBssDescr->mdiePresent = true;
177 pBssDescr->mdie[0] = pBPR->mdie[0];
178 pBssDescr->mdie[1] = pBPR->mdie[1];
179 pBssDescr->mdie[2] = pBPR->mdie[2];
180 }
181
182 #ifdef FEATURE_WLAN_ESE
183 pBssDescr->QBSSLoad_present = false;
184 pBssDescr->QBSSLoad_avail = 0;
185 if (pBPR->QBSSLoad.present) {
186 pBssDescr->QBSSLoad_present = true;
187 pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail;
188 }
189 #endif
190 /* Copy IE fields */
191 qdf_mem_copy((uint8_t *) &pBssDescr->ieFields,
192 pBody + SIR_MAC_B_PR_SSID_OFFSET, ieLen);
193
194 /*set channel number in beacon in case it is not present */
195 pBPR->chan_freq = chan_freq;
196 mac->lim.beacon_probe_rsp_cnt_per_scan++;
197
198 return;
199 } /*** end lim_collect_bss_description() ***/
200