summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89/chan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/chan.c')
-rw-r--r--drivers/net/wireless/realtek/rtw89/chan.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index a5d1bf573ea6..0bf27a344d2b 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -4,6 +4,104 @@
#include "chan.h"
+static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
+ u8 center_chan)
+{
+ switch (band) {
+ default:
+ case RTW89_BAND_2G:
+ switch (center_chan) {
+ default:
+ case 1 ... 14:
+ return RTW89_CH_2G;
+ }
+ case RTW89_BAND_5G:
+ switch (center_chan) {
+ default:
+ case 36 ... 64:
+ return RTW89_CH_5G_BAND_1;
+ case 100 ... 144:
+ return RTW89_CH_5G_BAND_3;
+ case 149 ... 177:
+ return RTW89_CH_5G_BAND_4;
+ }
+ case RTW89_BAND_6G:
+ switch (center_chan) {
+ default:
+ case 1 ... 29:
+ return RTW89_CH_6G_BAND_IDX0;
+ case 33 ... 61:
+ return RTW89_CH_6G_BAND_IDX1;
+ case 65 ... 93:
+ return RTW89_CH_6G_BAND_IDX2;
+ case 97 ... 125:
+ return RTW89_CH_6G_BAND_IDX3;
+ case 129 ... 157:
+ return RTW89_CH_6G_BAND_IDX4;
+ case 161 ... 189:
+ return RTW89_CH_6G_BAND_IDX5;
+ case 193 ... 221:
+ return RTW89_CH_6G_BAND_IDX6;
+ case 225 ... 253:
+ return RTW89_CH_6G_BAND_IDX7;
+ }
+ }
+}
+
+static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw,
+ u32 center_freq,
+ u32 primary_freq)
+{
+ u8 primary_chan_idx;
+ u32 offset;
+
+ switch (bw) {
+ default:
+ case RTW89_CHANNEL_WIDTH_20:
+ primary_chan_idx = RTW89_SC_DONT_CARE;
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ if (primary_freq > center_freq)
+ primary_chan_idx = RTW89_SC_20_UPPER;
+ else
+ primary_chan_idx = RTW89_SC_20_LOWER;
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ case RTW89_CHANNEL_WIDTH_160:
+ if (primary_freq > center_freq) {
+ offset = (primary_freq - center_freq - 10) / 20;
+ primary_chan_idx = RTW89_SC_20_UPPER + offset * 2;
+ } else {
+ offset = (center_freq - primary_freq - 10) / 20;
+ primary_chan_idx = RTW89_SC_20_LOWER + offset * 2;
+ }
+ break;
+ }
+
+ return primary_chan_idx;
+}
+
+void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
+ enum rtw89_band band, enum rtw89_bandwidth bandwidth)
+{
+ enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
+ u32 center_freq, primary_freq;
+
+ memset(chan, 0, sizeof(*chan));
+ chan->channel = center_chan;
+ chan->primary_channel = primary_chan;
+ chan->band_type = band;
+ chan->band_width = bandwidth;
+
+ center_freq = ieee80211_channel_to_frequency(center_chan, nl_band);
+ primary_freq = ieee80211_channel_to_frequency(primary_chan, nl_band);
+
+ chan->freq = center_freq;
+ chan->subband_type = rtw89_get_subband_type(band, center_chan);
+ chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq,
+ primary_freq);
+}
+
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
enum rtw89_sub_entity_idx idx,
const struct rtw89_chan *new)