xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/hal_g6/hal_rx.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _HAL_RX_C_
16 #include "hal_headers.h"
17 
rtw_hal_cfg_rxhci(void * hal,u8 en)18 void rtw_hal_cfg_rxhci(void *hal, u8 en)
19 {
20 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
21 
22 	PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "%s : enable %d.\n", __func__, en);
23 
24 	if (RTW_HAL_STATUS_SUCCESS != rtw_hal_mac_cfg_rxhci(hal_info, en))
25 		PHL_ERR("%s failure \n", __func__);
26 }
27 
28 enum rtw_hal_status
rtw_hal_set_rxfltr_by_mode(void * hal,u8 band,enum rtw_rx_fltr_mode mode)29 rtw_hal_set_rxfltr_by_mode(void *hal, u8 band, enum rtw_rx_fltr_mode mode)
30 {
31 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
32 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
33 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
34 	enum rtw_rx_fltr_mode set_mode = -1;
35 
36 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s : band(%d), mode(%d)\n",
37 		__func__, band, mode);
38 	/* Note: @hal_info_t.rx_fltr_mode is used to recored any mode other than
39 	 * sniffer mode, it effectively records the mode before entering monitor
40 	 * mode and the subsequent modes set after entering monitor mode.
41 	 */
42 
43 	if ((mode == RX_FLTR_MODE_SNIFFER && hal_info->monitor_mode) ||
44 	    (mode == RX_FLTR_MODE_RESTORE && !hal_info->monitor_mode))
45 		return RTW_HAL_STATUS_FAILURE;
46 
47 	if (hal_info->monitor_mode && mode != RX_FLTR_MODE_RESTORE) {
48 		hal_info->rx_fltr_mode = mode;
49 		return RTW_HAL_STATUS_SUCCESS;
50 	}
51 
52 	set_mode = (mode == RX_FLTR_MODE_RESTORE) ?
53 		hal_info->rx_fltr_mode : mode;
54 
55 	hstatus = rtw_hal_mac_set_rxfltr_by_mode(hal_com, band, set_mode);
56 	if (hstatus != RTW_HAL_STATUS_SUCCESS)
57 		return hstatus;
58 
59 	hal_info->monitor_mode = (mode == RX_FLTR_MODE_SNIFFER);
60 
61 	/* Record @hal_info_t.rx_fltr_mode only when the mode is not monitor and
62 	 * restore, otherwise, it is kept intact.
63 	 * TODO: The rx fltr mode should be recorded  separately for each band.
64 	 */
65 	if (mode != RX_FLTR_MODE_SNIFFER &&
66 	    mode != RX_FLTR_MODE_RESTORE)
67 		hal_info->rx_fltr_mode = mode;
68 
69 	return RTW_HAL_STATUS_SUCCESS;
70 }
71 
rtw_hal_get_rxfltr_mode(void * hal,u8 band)72 enum rtw_rx_fltr_mode rtw_hal_get_rxfltr_mode(void *hal, u8 band)
73 {
74 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
75 
76 	return (hal_info->monitor_mode) ? RX_FLTR_MODE_SNIFFER :
77 		hal_info->rx_fltr_mode;
78 }
79 
rtw_hal_scan_set_rxfltr_by_mode(void * hinfo,enum phl_phy_idx phy_idx,bool off_channel,u8 * mode)80 enum rtw_hal_status rtw_hal_scan_set_rxfltr_by_mode(void *hinfo,
81 	enum phl_phy_idx phy_idx, bool off_channel, u8 *mode)
82 {
83 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
84 
85 	if (off_channel) {
86 		/* backup rx filter mode */
87 		*mode = rtw_hal_get_rxfltr_mode(hinfo, phy_idx);
88 		hal_status = rtw_hal_set_rxfltr_by_mode(hinfo,
89 			phy_idx, RX_FLTR_MODE_SCAN);
90 	} else {
91 		/* restore rx filter mode */
92 		hal_status = rtw_hal_set_rxfltr_by_mode(hinfo,
93 			phy_idx, *mode);
94 	}
95 	return hal_status;
96 }
97 
98 enum rtw_hal_status
rtw_hal_enter_mon_mode(void * hinfo,enum phl_phy_idx phy_idx)99 rtw_hal_enter_mon_mode(void *hinfo, enum phl_phy_idx phy_idx)
100 {
101 	return rtw_hal_set_rxfltr_by_mode(hinfo, phy_idx, RX_FLTR_MODE_SNIFFER);
102 }
103 
104 enum rtw_hal_status
rtw_hal_leave_mon_mode(void * hinfo,enum phl_phy_idx phy_idx)105 rtw_hal_leave_mon_mode(void *hinfo, enum phl_phy_idx phy_idx)
106 {
107 	return rtw_hal_set_rxfltr_by_mode(hinfo, phy_idx, RX_FLTR_MODE_RESTORE);
108 }
109 
rtw_hal_acpt_crc_err_pkt(void * hal,u8 band,u8 enable)110 enum rtw_hal_status rtw_hal_acpt_crc_err_pkt(void *hal, u8 band, u8 enable)
111 {
112 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
113 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
114 
115 
116 	return rtw_hal_mac_set_rxfltr_acpt_crc_err(hal_com, band, enable);
117 }
118 
rtw_hal_set_rxfltr_mpdu_size(void * hal,u8 band,u16 size)119 enum rtw_hal_status rtw_hal_set_rxfltr_mpdu_size(void *hal, u8 band, u16 size)
120 {
121 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
122 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
123 
124 
125 	return rtw_hal_mac_set_rxfltr_mpdu_size(hal_com, band, size);
126 }
rtw_hal_set_rxfltr_by_type(void * hal,u8 band,u8 type,u8 target)127 enum rtw_hal_status rtw_hal_set_rxfltr_by_type(void *hal, u8 band, u8 type, u8 target)
128 {
129 
130 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
131 	enum rtw_hal_status hstats = RTW_HAL_STATUS_FAILURE;
132 
133 	hstats = rtw_hal_mac_set_rxfltr_by_type(hal_info->hal_com, band, type, target);
134 
135 	if (RTW_HAL_STATUS_SUCCESS != hstats)
136 		PHL_ERR("%s : type %u status %u target %u.band %u \n", __func__, type, hstats, target, band);
137 
138 
139 	return hstats;
140 }
141 
142 enum rtw_hal_status
rtw_hal_poll_hw_rx_done(void * hal)143 rtw_hal_poll_hw_rx_done(void *hal)
144 {
145 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
146 	enum rtw_hal_status sts = RTW_HAL_STATUS_SUCCESS;
147 
148 	sts = rtw_hal_mac_poll_hw_rx_done(hal_info);
149 
150 	return sts;
151 }
152 
153 enum rtw_hal_status
rtw_hal_hw_rx_resume(void * hal)154 rtw_hal_hw_rx_resume(void *hal)
155 {
156 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
157 	enum rtw_hal_status sts = RTW_HAL_STATUS_SUCCESS;
158 
159 	sts = rtw_hal_mac_hw_rx_resume(hal_info);
160 
161 	return sts;
162 }
163 
164 #ifdef CONFIG_PCI_HCI
165 /**
166  * rtw_hal_rx_res_query - query current HW rx resource with specifc dma channel
167  * @hal: see struct hal_info_t
168  * @dma_ch: the target dma channel
169  * @host_idx: current host index of this channel
170  * @hw_idx: current hw index of this channel
171  *
172  * this function returns the number of available tx resource
173  * NOTE, input host_idx and hw_idx ptr shall NOT be NULL
174  */
rtw_hal_rx_res_query(void * hal,u8 dma_ch,u16 * host_idx,u16 * hw_idx)175 u16 rtw_hal_rx_res_query(void *hal, u8 dma_ch, u16 *host_idx, u16 *hw_idx)
176 {
177 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
178 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
179 	u16 res_num = 0;
180 
181 	res_num = trx_ops->query_rx_res(hal_info->hal_com, dma_ch, host_idx,
182 					hw_idx);
183 
184 	return res_num;
185 }
186 
187 
188 /**
189  * rtw_hal_query_rxch_num - query total hw rx dma channels number
190  *
191  * returns the number of  hw rx dma channel
192  */
rtw_hal_query_rxch_num(void * hal)193 u8 rtw_hal_query_rxch_num(void *hal)
194 {
195 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
196 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
197 	u8 ch_num = 0;
198 
199 	ch_num = trx_ops->query_rxch_num();
200 
201 	return ch_num;
202 }
rtw_hal_check_rxrdy(struct rtw_phl_com_t * phl_com,void * hal,u8 * rxbuf,u8 dma_ch)203 u8 rtw_hal_check_rxrdy(struct rtw_phl_com_t *phl_com, void* hal, u8 *rxbuf, u8 dma_ch)
204 {
205 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
206 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
207 	u8 res = 0;
208 
209 	res = trx_ops->check_rxrdy(phl_com, rxbuf, dma_ch);
210 
211 	return res;
212 }
213 
rtw_hal_handle_rxbd_info(void * hal,u8 * rxbuf,u16 * buf_size)214 u8 rtw_hal_handle_rxbd_info(void* hal, u8 *rxbuf, u16 *buf_size)
215 {
216 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
217 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
218 	u8 res = 0;
219 
220 	res = trx_ops->handle_rxbd_info(hal_info, rxbuf, buf_size);
221 
222 	return res;
223 }
224 
225 enum rtw_hal_status
rtw_hal_update_rxbd(void * hal,struct rx_base_desc * rxbd,struct rtw_rx_buf * rxbuf)226 rtw_hal_update_rxbd(void *hal, struct rx_base_desc *rxbd,
227 					struct rtw_rx_buf *rxbuf)
228 {
229 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
230 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
231 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
232 
233 	hstatus = trx_ops->update_rxbd(hal_info, rxbd, rxbuf);
234 
235 	return hstatus;
236 }
237 
238 
rtw_hal_notify_rxdone(void * hal,struct rx_base_desc * rxbd,u8 ch,u16 rxcnt)239 enum rtw_hal_status rtw_hal_notify_rxdone(void* hal,
240 				struct rx_base_desc *rxbd, u8 ch, u16 rxcnt)
241 {
242 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
243 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
244 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
245 
246 	hstatus = trx_ops->notify_rxdone(hal_info, rxbd, ch, rxcnt);
247 
248 	return hstatus;
249 }
250 
rtw_hal_handle_wp_rpt(void * hal,u8 * rp,u16 len,u8 * sw_retry,u8 * dma_ch,u16 * wp_seq,u8 * macid,u8 * ac_queue,u8 * txsts)251 u16 rtw_hal_handle_wp_rpt(void *hal, u8 *rp, u16 len, u8 *sw_retry, u8 *dma_ch,
252 			  u16 *wp_seq, u8 *macid, u8 *ac_queue, u8 *txsts)
253 {
254 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
255 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
256 	u16 rsize = 0;
257 
258 	rsize = trx_ops->handle_wp_rpt(hal_info, rp, len, sw_retry, dma_ch,
259 				       wp_seq, macid, ac_queue, txsts);
260 	return rsize;
261 }
262 
263 #endif /*CONFIG_PCI_HCI*/
264 
265 
266 #ifdef CONFIG_USB_HCI
267 enum rtw_hal_status
rtw_hal_query_info(void * hal,u8 info_id,void * value)268 rtw_hal_query_info(void* hal, u8 info_id, void *value)
269 {
270 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
271 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
272 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
273 
274 	hstatus = trx_ops->query_hal_info(hal_info, info_id, value);
275 
276 	return hstatus;
277 }
278 
279 enum rtw_hal_status
rtw_hal_usb_rx_agg_cfg(void * hal,u8 mode,u8 agg_mode,u8 drv_define,u8 timeout,u8 size,u8 pkt_num)280 	rtw_hal_usb_rx_agg_cfg(void *hal, u8 mode, u8 agg_mode,
281 	u8 drv_define, u8 timeout, u8 size, u8 pkt_num)
282 {
283 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
284 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
285 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
286 
287 	hstatus = trx_ops->usb_rx_agg_cfg(hal, mode, agg_mode,
288 		drv_define, timeout, size, pkt_num);
289 
290 	return hstatus;
291 }
292 
rtw_hal_handle_wp_rpt_usb(void * hal,u8 * rp,u16 len,u8 * macid,u8 * ac_queue,u8 * txsts)293 u16 rtw_hal_handle_wp_rpt_usb(void *hal, u8 *rp, u16 len, u8 *macid, u8 *ac_queue,
294 		u8 *txsts)
295 {
296 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
297 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
298 	u16 rsize = 0;
299 
300 	rsize = trx_ops->handle_wp_rpt(hal_info, rp, len, macid, ac_queue, txsts);
301 	return rsize;
302 }
303 
304 #endif
305 
306 enum rtw_hal_status
rtw_hal_handle_rx_buffer(struct rtw_phl_com_t * phl_com,void * hal,u8 * buf,u32 buf_size,struct rtw_phl_rx_pkt * rxpkt)307 rtw_hal_handle_rx_buffer(struct rtw_phl_com_t *phl_com, void* hal,
308 				u8 *buf, u32 buf_size,
309 				struct rtw_phl_rx_pkt *rxpkt)
310 {
311 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
312 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
313 	struct hal_trx_ops *trx_ops = hal_info->trx_ops;
314 
315 	hstatus = trx_ops->handle_rx_buffer(phl_com, hal_info,
316 					      buf, buf_size, rxpkt);
317 
318 	return hstatus;
319 }
320 
321 #ifdef CONFIG_SDIO_HCI
rtw_hal_sdio_rx_agg_cfg(void * hal,bool enable,u8 drv_define,u8 timeout,u8 size,u8 pkt_num)322 void rtw_hal_sdio_rx_agg_cfg(void *hal, bool enable, u8 drv_define,
323 			     u8 timeout, u8 size, u8 pkt_num)
324 {
325 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
326 
327 
328 	rtw_hal_mac_sdio_rx_agg_cfg(hal_info->hal_com, enable, drv_define,
329 				    timeout, size, pkt_num);
330 }
331 
rtw_hal_sdio_rx(void * hal,struct rtw_rx_buf * rxbuf)332 int rtw_hal_sdio_rx(void *hal, struct rtw_rx_buf *rxbuf)
333 {
334 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
335 
336 
337 	return rtw_hal_mac_sdio_rx(hal_info->hal_com, rxbuf);
338 }
339 
rtw_hal_sdio_parse_rx(void * hal,struct rtw_rx_buf * rxbuf)340 int rtw_hal_sdio_parse_rx(void *hal, struct rtw_rx_buf *rxbuf)
341 {
342 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
343 
344 
345 	return rtw_hal_mac_sdio_parse_rx(hal_info->hal_com, rxbuf);
346 }
347 #endif /* CONFIG_SDIO_HCI */
348 
349 void
hal_rx_ppdu_sts_normal_data(struct rtw_phl_com_t * phl_com,void * hdr,struct rtw_r_meta_data * meta)350 hal_rx_ppdu_sts_normal_data(struct rtw_phl_com_t *phl_com,
351 			    void *hdr,
352 			    struct rtw_r_meta_data *meta)
353 {
354 	struct rtw_phl_ppdu_sts_info *ppdu_info = NULL;
355 	enum phl_band_idx band = HW_BAND_0;
356 
357 	do {
358 		if ((NULL == phl_com) || (NULL == meta))
359 			break;
360 		ppdu_info = &phl_com->ppdu_sts_info;
361 		band = (meta->bb_sel > 0) ? HW_BAND_1 : HW_BAND_0;
362 		if ((ppdu_info->cur_rx_ppdu_cnt[band] == meta->ppdu_cnt) &&
363 		    (false == ppdu_info->latest_rx_is_psts[band])) {
364 			/**
365 			 * add condition to avoid check fail for ppdu cnt run around 0 -> 1 -> ... -> 0
366 			 * example :
367 			 * 	[frame_A(ppdu_cnt = 0)] -> [ppdu_sts(ppdu_cnt = 0)]
368 			 *  	->[ppdu_sts(ppdu_cnt = 1)] -> [ppdu_sts(ppdu_cnt = 2)] ...
369 			 * 	... ->[ppdu_sts(ppdu_cnt = 7)] -> [frame_B(ppdu_cnt = 0)] ...
370 			 * 	Therefore, frame_B has same ppdu_cnt with frame_A.
371 			 *	But they are different PPDU.
372 			**/
373 			break;
374 		}
375 		meta->ppdu_cnt_chg = true;
376 		/* start of the PPDU */
377 		ppdu_info->latest_rx_is_psts[band] = false;
378 		ppdu_info->sts_ent[band][meta->ppdu_cnt].addr_cam_vld = meta->addr_cam_vld;
379 		ppdu_info->sts_ent[band][meta->ppdu_cnt].frame_type = PHL_GET_80211_HDR_TYPE(hdr);
380 		ppdu_info->sts_ent[band][meta->ppdu_cnt].crc32 = meta->crc32;
381 		ppdu_info->sts_ent[band][meta->ppdu_cnt].rx_rate = meta->rx_rate;
382 		ppdu_info->sts_ent[band][meta->ppdu_cnt].ppdu_type = meta->ppdu_type;
383 
384 		if(RTW_IS_BEACON_OR_PROBE_RESP_PKT(ppdu_info->sts_ent[band][meta->ppdu_cnt].frame_type)) {
385 			PHL_GET_80211_HDR_ADDRESS3(phl_com->drv_priv, hdr,
386 				ppdu_info->sts_ent[band][meta->ppdu_cnt].src_mac_addr);
387 		}
388 		else if (meta->a1_match &&
389 			  RTW_IS_ASOC_REQ_PKT(ppdu_info->sts_ent[band][meta->ppdu_cnt].frame_type)) {
390 
391 			PHL_GET_80211_HDR_ADDRESS2(phl_com->drv_priv, hdr,
392 				ppdu_info->sts_ent[band][meta->ppdu_cnt].src_mac_addr);
393 
394 			#ifdef DBG_AP_CLIENT_ASSOC_RSSI
395 			{
396 				u8 *src = NULL;
397 
398 				src = ppdu_info->sts_ent[band][meta->ppdu_cnt].src_mac_addr;
399 
400 				PHL_INFO("%s [Rx-ASOC_REQ] - MAC-Addr:%02x-%02x-%02x-%02x-%02x-%02x, a1_match:%d ppdu_cnt:%d\n",
401 					__func__,
402 					src[0], src[1], src[2], src[3], src[4], src[5],
403 					meta->a1_match,
404 					meta->ppdu_cnt);
405 			}
406 			#endif
407 		}
408 		else {
409 			_os_mem_cpy(phl_com->drv_priv,
410 				ppdu_info->sts_ent[band][meta->ppdu_cnt].src_mac_addr,
411 				meta->ta, MAC_ADDRESS_LENGTH);
412 		}
413 		ppdu_info->sts_ent[band][meta->ppdu_cnt].valid = false;
414 		ppdu_info->cur_rx_ppdu_cnt[band] = meta->ppdu_cnt;
415 		PHL_TRACE(COMP_PHL_PSTS, _PHL_INFO_,
416 				"Start of the PPDU : band %d ; ppdu_cnt %d ; frame_type %d ; addr_cam_vld %d ; size %d ; rate 0x%x ; crc32 %d\n",
417 				band,
418 				ppdu_info->cur_rx_ppdu_cnt[band],
419 				ppdu_info->sts_ent[band][meta->ppdu_cnt].frame_type,
420 				ppdu_info->sts_ent[band][meta->ppdu_cnt].addr_cam_vld,
421 				meta->pktlen,
422 				meta->rx_rate,
423 				meta->crc32);
424 	} while (false);
425 
426 }
427 
428 void
hal_rx_ppdu_sts(struct rtw_phl_com_t * phl_com,struct rtw_phl_rx_pkt * phl_rx,struct hal_ppdu_sts * ppdu_sts)429 hal_rx_ppdu_sts(struct rtw_phl_com_t *phl_com,
430 		struct rtw_phl_rx_pkt *phl_rx,
431 		struct hal_ppdu_sts *ppdu_sts)
432 {
433 	struct rtw_phl_ppdu_sts_info *ppdu_info = NULL;
434 	struct rtw_phl_rssi_stat *rssi_stat = NULL;
435 	struct rtw_r_meta_data *meta = &(phl_rx->r.mdata);
436 	struct rtw_phl_ppdu_phy_info *phy_info = &(phl_rx->r.phy_info);
437 	u8 i = 0;
438 	enum phl_band_idx band = HW_BAND_0;
439 	struct rtw_phl_ppdu_sts_ent *sts_ent = NULL;
440 
441 	if ((NULL == phl_com) || (NULL == meta) || (NULL == ppdu_sts))
442 		return;
443 
444 	ppdu_info = &phl_com->ppdu_sts_info;
445 	rssi_stat = &phl_com->rssi_stat;
446 	band = (meta->bb_sel > 0) ? HW_BAND_1 : HW_BAND_0;
447 	ppdu_info->latest_rx_is_psts[band] = true;
448 
449 	if (0 == phy_info->is_valid)
450 		return;
451 
452 	if (ppdu_info->cur_rx_ppdu_cnt[band] != meta->ppdu_cnt) {
453 		PHL_TRACE(COMP_PHL_PSTS, _PHL_INFO_,
454 			  "[WARNING] ppdu cnt mis-match (band %d ; cur : %d , rxmeta : %d)\n",
455 			  band,
456 			  ppdu_info->cur_rx_ppdu_cnt[band],
457 			  meta->ppdu_cnt);
458 	}
459 	sts_ent = &(ppdu_info->sts_ent[band][meta->ppdu_cnt]);
460 
461 	if (meta->crc32 || sts_ent->crc32) {
462 		UPDATE_MA_RSSI(rssi_stat, RTW_RSSI_UNKNOWN,
463 			 phy_info->rssi);
464 		return;
465 	}
466 	if (sts_ent->rx_rate != meta->rx_rate) {
467 		PHL_TRACE(COMP_PHL_PSTS, _PHL_INFO_,
468 			  "[WARNING] PPDU STS rx rate mis-match\n");
469 		UPDATE_MA_RSSI(rssi_stat, RTW_RSSI_UNKNOWN,
470 			       phy_info->rssi);
471 		return;
472 	}
473 	if (sts_ent->ppdu_type != meta->ppdu_type) {
474 		PHL_TRACE(COMP_PHL_PSTS, _PHL_INFO_,
475 			  "[WARNING] PPDU STS ppdu_type mis-match\n");
476 		UPDATE_MA_RSSI(rssi_stat, RTW_RSSI_UNKNOWN,
477 			       phy_info->rssi);
478 		return;
479 	}
480 	if (sts_ent->valid == true) {
481 		PHL_TRACE(COMP_PHL_PSTS, _PHL_INFO_,
482 			  "[WARNING] PPDU STS is already updated, skip this ppdu status\n");
483 		return;
484 	}
485 
486 	/* update ppdu_info entry */
487 	sts_ent->freerun_cnt = meta->freerun_cnt;
488 	_os_mem_cpy(phl_com->drv_priv,
489 		    &(sts_ent->phy_info),
490 		    phy_info, sizeof(struct rtw_phl_ppdu_phy_info));
491 
492 	sts_ent->usr_num = ppdu_sts->usr_num;
493 	for (i = 0; i < ppdu_sts->usr_num; i++) {
494 		if (ppdu_sts->usr[i].vld) {
495 			sts_ent->sta[i].macid =
496 				ppdu_sts->usr[i].macid;
497 			sts_ent->sta[i].vld = 1;
498 		} else {
499 			sts_ent->sta[i].vld = 0;
500 		}
501 	}
502 	sts_ent->phl_done = false;
503 	sts_ent->valid = true;
504 
505 	/* update rssi stat */
506 	_os_spinlock(phl_com->drv_priv, &rssi_stat->lock, _bh, NULL);
507 	switch (sts_ent->frame_type &
508 		(BIT(1) | BIT(0))) {
509 		case RTW_FRAME_TYPE_MGNT :
510 			if (sts_ent->addr_cam_vld) {
511 				UPDATE_MA_RSSI(rssi_stat,
512 					 (1 == meta->a1_match) ?
513 					  RTW_RSSI_MGNT_ACAM_A1M :
514 					  RTW_RSSI_MGNT_ACAM,
515 					 phy_info->rssi);
516 			} else {
517 				UPDATE_MA_RSSI(rssi_stat, RTW_RSSI_MGNT_OTHER,
518 					 phy_info->rssi);
519 			}
520 		break;
521 		case RTW_FRAME_TYPE_CTRL :
522 			if (sts_ent->addr_cam_vld) {
523 				UPDATE_MA_RSSI(rssi_stat,
524 					 (1 == meta->a1_match) ?
525 					  RTW_RSSI_CTRL_ACAM_A1M :
526 					  RTW_RSSI_CTRL_ACAM,
527 					 phy_info->rssi);
528 			} else {
529 				UPDATE_MA_RSSI(rssi_stat, RTW_RSSI_CTRL_OTHER,
530 					 phy_info->rssi);
531 			}
532 		break;
533 		case RTW_FRAME_TYPE_DATA :
534 			if (sts_ent->addr_cam_vld) {
535 				UPDATE_MA_RSSI(rssi_stat,
536 					 (1 == meta->a1_match) ?
537 					  RTW_RSSI_DATA_ACAM_A1M :
538 					  RTW_RSSI_DATA_ACAM,
539 					 phy_info->rssi);
540 			} else {
541 				UPDATE_MA_RSSI(rssi_stat, RTW_RSSI_DATA_OTHER,
542 					 phy_info->rssi);
543 			}
544 		break;
545 		default:
546 			UPDATE_MA_RSSI(rssi_stat, RTW_RSSI_UNKNOWN,
547 				       phy_info->rssi);
548 		break;
549 	}
550 	_os_spinunlock(phl_com->drv_priv, &rssi_stat->lock, _bh, NULL);
551 }
552