1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/* Copyright(c) 2018-2019  Realtek Corporation
3 */
4
5#include "main.h"
6#include "rx.h"
7#include "ps.h"
8#include "debug.h"
9
10void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
11		  struct sk_buff *skb)
12{
13	struct ieee80211_hdr *hdr;
14	struct rtw_vif *rtwvif;
15
16	hdr = (struct ieee80211_hdr *)skb->data;
17
18	if (!ieee80211_is_data(hdr->frame_control))
19		return;
20
21	if (!is_broadcast_ether_addr(hdr->addr1) &&
22	    !is_multicast_ether_addr(hdr->addr1)) {
23		rtwdev->stats.rx_unicast += skb->len;
24		rtwdev->stats.rx_cnt++;
25		if (vif) {
26			rtwvif = (struct rtw_vif *)vif->drv_priv;
27			rtwvif->stats.rx_unicast += skb->len;
28			rtwvif->stats.rx_cnt++;
29		}
30	}
31}
32EXPORT_SYMBOL(rtw_rx_stats);
33
34struct rtw_rx_addr_match_data {
35	struct rtw_dev *rtwdev;
36	struct ieee80211_hdr *hdr;
37	struct rtw_rx_pkt_stat *pkt_stat;
38	u8 *bssid;
39};
40
41static void rtw_rx_phy_stat(struct rtw_dev *rtwdev,
42			    struct rtw_rx_pkt_stat *pkt_stat,
43			    struct ieee80211_hdr *hdr)
44{
45	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
46	struct rtw_pkt_count *cur_pkt_cnt = &dm_info->cur_pkt_count;
47	u8 rate_ss, rate_ss_evm, evm_id;
48	u8 i, idx;
49
50	dm_info->curr_rx_rate = pkt_stat->rate;
51
52	if (ieee80211_is_beacon(hdr->frame_control))
53		cur_pkt_cnt->num_bcn_pkt++;
54
55	switch (pkt_stat->rate) {
56	case DESC_RATE1M...DESC_RATE11M:
57		goto pkt_num;
58	case DESC_RATE6M...DESC_RATE54M:
59		rate_ss = 0;
60		rate_ss_evm = 1;
61		evm_id = RTW_EVM_OFDM;
62		break;
63	case DESC_RATEMCS0...DESC_RATEMCS7:
64	case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT1SS_MCS9:
65		rate_ss = 1;
66		rate_ss_evm = 1;
67		evm_id = RTW_EVM_1SS;
68		break;
69	case DESC_RATEMCS8...DESC_RATEMCS15:
70	case DESC_RATEVHT2SS_MCS0...DESC_RATEVHT2SS_MCS9:
71		rate_ss = 2;
72		rate_ss_evm = 2;
73		evm_id = RTW_EVM_2SS_A;
74		break;
75	default:
76		rtw_warn(rtwdev, "unknown pkt rate = %d\n", pkt_stat->rate);
77		return;
78	}
79
80	for (i = 0; i < rate_ss_evm; i++) {
81		idx = evm_id + i;
82		ewma_evm_add(&dm_info->ewma_evm[idx],
83			     dm_info->rx_evm_dbm[i]);
84	}
85
86	for (i = 0; i < rtwdev->hal.rf_path_num; i++) {
87		idx = RTW_SNR_OFDM_A + 4 * rate_ss + i;
88		ewma_snr_add(&dm_info->ewma_snr[idx],
89			     dm_info->rx_snr[i]);
90	}
91pkt_num:
92	cur_pkt_cnt->num_qry_pkt[pkt_stat->rate]++;
93}
94
95static void rtw_rx_addr_match_iter(void *data, u8 *mac,
96				   struct ieee80211_vif *vif)
97{
98	struct rtw_rx_addr_match_data *iter_data = data;
99	struct ieee80211_sta *sta;
100	struct ieee80211_hdr *hdr = iter_data->hdr;
101	struct rtw_dev *rtwdev = iter_data->rtwdev;
102	struct rtw_sta_info *si;
103	struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat;
104	u8 *bssid = iter_data->bssid;
105
106	if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
107		return;
108
109	if (!(ether_addr_equal(vif->addr, hdr->addr1) ||
110	      ieee80211_is_beacon(hdr->frame_control)))
111		return;
112
113	rtw_rx_phy_stat(rtwdev, pkt_stat, hdr);
114	sta = ieee80211_find_sta_by_ifaddr(rtwdev->hw, hdr->addr2,
115					   vif->addr);
116	if (!sta)
117		return;
118
119	si = (struct rtw_sta_info *)sta->drv_priv;
120	ewma_rssi_add(&si->avg_rssi, pkt_stat->rssi);
121}
122
123static void rtw_rx_addr_match(struct rtw_dev *rtwdev,
124			      struct rtw_rx_pkt_stat *pkt_stat,
125			      struct ieee80211_hdr *hdr)
126{
127	struct rtw_rx_addr_match_data data = {};
128
129	if (pkt_stat->crc_err || pkt_stat->icv_err || !pkt_stat->phy_status ||
130	    ieee80211_is_ctl(hdr->frame_control))
131		return;
132
133	data.rtwdev = rtwdev;
134	data.hdr = hdr;
135	data.pkt_stat = pkt_stat;
136	data.bssid = get_hdr_bssid(hdr);
137
138	rtw_iterate_vifs_atomic(rtwdev, rtw_rx_addr_match_iter, &data);
139}
140
141void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
142			   struct rtw_rx_pkt_stat *pkt_stat,
143			   struct ieee80211_hdr *hdr,
144			   struct ieee80211_rx_status *rx_status,
145			   u8 *phy_status)
146{
147	struct ieee80211_hw *hw = rtwdev->hw;
148	u8 path;
149
150	memset(rx_status, 0, sizeof(*rx_status));
151	rx_status->freq = hw->conf.chandef.chan->center_freq;
152	rx_status->band = hw->conf.chandef.chan->band;
153	if (pkt_stat->crc_err)
154		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
155	if (pkt_stat->decrypted)
156		rx_status->flag |= RX_FLAG_DECRYPTED;
157
158	if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0)
159		rx_status->encoding = RX_ENC_VHT;
160	else if (pkt_stat->rate >= DESC_RATEMCS0)
161		rx_status->encoding = RX_ENC_HT;
162
163	if (rx_status->band == NL80211_BAND_5GHZ &&
164	    pkt_stat->rate >= DESC_RATE6M &&
165	    pkt_stat->rate <= DESC_RATE54M) {
166		rx_status->rate_idx = pkt_stat->rate - DESC_RATE6M;
167	} else if (rx_status->band == NL80211_BAND_2GHZ &&
168		   pkt_stat->rate >= DESC_RATE1M &&
169		   pkt_stat->rate <= DESC_RATE54M) {
170		rx_status->rate_idx = pkt_stat->rate - DESC_RATE1M;
171	} else if (pkt_stat->rate >= DESC_RATEMCS0) {
172		rtw_desc_to_mcsrate(pkt_stat->rate, &rx_status->rate_idx,
173				    &rx_status->nss);
174	}
175
176	rx_status->flag |= RX_FLAG_MACTIME_START;
177	rx_status->mactime = pkt_stat->tsf_low;
178
179	if (pkt_stat->bw == RTW_CHANNEL_WIDTH_80)
180		rx_status->bw = RATE_INFO_BW_80;
181	else if (pkt_stat->bw == RTW_CHANNEL_WIDTH_40)
182		rx_status->bw = RATE_INFO_BW_40;
183	else
184		rx_status->bw = RATE_INFO_BW_20;
185
186	rx_status->signal = pkt_stat->signal_power;
187	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
188		rx_status->chains |= BIT(path);
189		rx_status->chain_signal[path] = pkt_stat->rx_power[path];
190	}
191
192	rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
193}
194EXPORT_SYMBOL(rtw_rx_fill_rx_status);
195