wifi: rtw88: add the update channel flow to support setting by parameters
authorChih-Kang Chang <gary.chang@realtek.com>
Tue, 9 Aug 2022 08:41:03 +0000 (16:41 +0800)
committerKalle Valo <kvalo@kernel.org>
Wed, 10 Aug 2022 05:48:46 +0000 (08:48 +0300)
In order to set channel info to hal during HW scan, we add the update
channel flow to support setting by parameters to meet the HW scan
requriement.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220809084107.38137-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw88/main.c
drivers/net/wireless/realtek/rtw88/main.h

index 381f258835a7e22c77bdb2a13d44a57230076e8e..790dcfed1125dd2609b0387db0e8b8d5b8d5a911 100644 (file)
@@ -675,67 +675,127 @@ void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period)
        rtw_write8(rtwdev, REG_DTIM_COUNTER_ROOT, dtim_period - 1);
 }
 
+void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel,
+                       u8 primary_channel, enum rtw_supported_band band,
+                       enum rtw_bandwidth bandwidth)
+{
+       enum nl80211_band nl_band = rtw_hw_to_nl80211_band(band);
+       struct rtw_hal *hal = &rtwdev->hal;
+       u8 *cch_by_bw = hal->cch_by_bw;
+       u32 center_freq, primary_freq;
+       enum rtw_sar_bands sar_band;
+       u8 primary_channel_idx;
+
+       center_freq = ieee80211_channel_to_frequency(center_channel, nl_band);
+       primary_freq = ieee80211_channel_to_frequency(primary_channel, nl_band);
+
+       /* assign the center channel used while 20M bw is selected */
+       cch_by_bw[RTW_CHANNEL_WIDTH_20] = primary_channel;
+
+       /* assign the center channel used while current bw is selected */
+       cch_by_bw[bandwidth] = center_channel;
+
+       switch (bandwidth) {
+       case RTW_CHANNEL_WIDTH_20:
+               primary_channel_idx = RTW_SC_DONT_CARE;
+               break;
+       case RTW_CHANNEL_WIDTH_40:
+               if (primary_freq > center_freq)
+                       primary_channel_idx = RTW_SC_20_UPPER;
+               else
+                       primary_channel_idx = RTW_SC_20_LOWER;
+               break;
+       case RTW_CHANNEL_WIDTH_80:
+               if (primary_freq > center_freq) {
+                       if (primary_freq - center_freq == 10)
+                               primary_channel_idx = RTW_SC_20_UPPER;
+                       else
+                               primary_channel_idx = RTW_SC_20_UPMOST;
+
+                       /* assign the center channel used
+                        * while 40M bw is selected
+                        */
+                       cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel + 4;
+               } else {
+                       if (center_freq - primary_freq == 10)
+                               primary_channel_idx = RTW_SC_20_LOWER;
+                       else
+                               primary_channel_idx = RTW_SC_20_LOWEST;
+
+                       /* assign the center channel used
+                        * while 40M bw is selected
+                        */
+                       cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_channel - 4;
+               }
+               break;
+       default:
+               break;
+       }
+
+       switch (center_channel) {
+       case 1 ... 14:
+               sar_band = RTW_SAR_BAND_0;
+               break;
+       case 36 ... 64:
+               sar_band = RTW_SAR_BAND_1;
+               break;
+       case 100 ... 144:
+               sar_band = RTW_SAR_BAND_3;
+               break;
+       case 149 ... 177:
+               sar_band = RTW_SAR_BAND_4;
+               break;
+       default:
+               WARN(1, "unknown ch(%u) to SAR band\n", center_channel);
+               sar_band = RTW_SAR_BAND_0;
+               break;
+       }
+
+       hal->current_primary_channel_index = primary_channel_idx;
+       hal->current_band_width = bandwidth;
+       hal->primary_channel = primary_channel;
+       hal->current_channel = center_channel;
+       hal->current_band_type = band;
+       hal->sar_band = sar_band;
+}
+
 void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
                            struct rtw_channel_params *chan_params)
 {
        struct ieee80211_channel *channel = chandef->chan;
        enum nl80211_chan_width width = chandef->width;
-       u8 *cch_by_bw = chan_params->cch_by_bw;
        u32 primary_freq, center_freq;
        u8 center_chan;
        u8 bandwidth = RTW_CHANNEL_WIDTH_20;
-       u8 primary_chan_idx = 0;
-       u8 i;
 
        center_chan = channel->hw_value;
        primary_freq = channel->center_freq;
        center_freq = chandef->center_freq1;
 
-       /* assign the center channel used while 20M bw is selected */
-       cch_by_bw[RTW_CHANNEL_WIDTH_20] = channel->hw_value;
-
        switch (width) {
        case NL80211_CHAN_WIDTH_20_NOHT:
        case NL80211_CHAN_WIDTH_20:
                bandwidth = RTW_CHANNEL_WIDTH_20;
-               primary_chan_idx = RTW_SC_DONT_CARE;
                break;
        case NL80211_CHAN_WIDTH_40:
                bandwidth = RTW_CHANNEL_WIDTH_40;
-               if (primary_freq > center_freq) {
-                       primary_chan_idx = RTW_SC_20_UPPER;
+               if (primary_freq > center_freq)
                        center_chan -= 2;
-               } else {
-                       primary_chan_idx = RTW_SC_20_LOWER;
+               else
                        center_chan += 2;
-               }
                break;
        case NL80211_CHAN_WIDTH_80:
                bandwidth = RTW_CHANNEL_WIDTH_80;
                if (primary_freq > center_freq) {
-                       if (primary_freq - center_freq == 10) {
-                               primary_chan_idx = RTW_SC_20_UPPER;
+                       if (primary_freq - center_freq == 10)
                                center_chan -= 2;
-                       } else {
-                               primary_chan_idx = RTW_SC_20_UPMOST;
+                       else
                                center_chan -= 6;
-                       }
-                       /* assign the center channel used
-                        * while 40M bw is selected
-                        */
-                       cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_chan + 4;
                } else {
-                       if (center_freq - primary_freq == 10) {
-                               primary_chan_idx = RTW_SC_20_LOWER;
+                       if (center_freq - primary_freq == 10)
                                center_chan += 2;
-                       } else {
-                               primary_chan_idx = RTW_SC_20_LOWEST;
+                       else
                                center_chan += 6;
-                       }
-                       /* assign the center channel used
-                        * while 40M bw is selected
-                        */
-                       cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_chan - 4;
                }
                break;
        default:
@@ -745,13 +805,7 @@ void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
 
        chan_params->center_chan = center_chan;
        chan_params->bandwidth = bandwidth;
-       chan_params->primary_chan_idx = primary_chan_idx;
-
-       /* assign the center channel used while current bw is selected */
-       cch_by_bw[bandwidth] = center_chan;
-
-       for (i = bandwidth + 1; i <= RTW_MAX_CHANNEL_WIDTH; i++)
-               cch_by_bw[i] = 0;
+       chan_params->primary_chan = channel->hw_value;
 }
 
 void rtw_set_channel(struct rtw_dev *rtwdev)
@@ -760,45 +814,21 @@ void rtw_set_channel(struct rtw_dev *rtwdev)
        struct ieee80211_hw *hw = rtwdev->hw;
        struct rtw_hal *hal = &rtwdev->hal;
        struct rtw_channel_params ch_param;
-       u8 center_chan, bandwidth, primary_chan_idx;
-       u8 i;
+       u8 center_chan, primary_chan, bandwidth, band;
 
        rtw_get_channel_params(&hw->conf.chandef, &ch_param);
        if (WARN(ch_param.center_chan == 0, "Invalid channel\n"))
                return;
 
        center_chan = ch_param.center_chan;
+       primary_chan = ch_param.primary_chan;
        bandwidth = ch_param.bandwidth;
-       primary_chan_idx = ch_param.primary_chan_idx;
-
-       hal->current_band_width = bandwidth;
-       hal->current_channel = center_chan;
-       hal->current_primary_channel_index = primary_chan_idx;
-       hal->current_band_type = center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
-
-       switch (center_chan) {
-       case 1 ... 14:
-               hal->sar_band = RTW_SAR_BAND_0;
-               break;
-       case 36 ... 64:
-               hal->sar_band = RTW_SAR_BAND_1;
-               break;
-       case 100 ... 144:
-               hal->sar_band = RTW_SAR_BAND_3;
-               break;
-       case 149 ... 177:
-               hal->sar_band = RTW_SAR_BAND_4;
-               break;
-       default:
-               WARN(1, "unknown ch(%u) to SAR band\n", center_chan);
-               hal->sar_band = RTW_SAR_BAND_0;
-               break;
-       }
+       band = ch_param.center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
 
-       for (i = RTW_CHANNEL_WIDTH_20; i <= RTW_MAX_CHANNEL_WIDTH; i++)
-               hal->cch_by_bw[i] = ch_param.cch_by_bw[i];
+       rtw_update_channel(rtwdev, center_chan, primary_chan, band, bandwidth);
 
-       chip->ops->set_channel(rtwdev, center_chan, bandwidth, primary_chan_idx);
+       chip->ops->set_channel(rtwdev, center_chan, bandwidth,
+                              hal->current_primary_channel_index);
 
        if (hal->current_band_type == RTW_BAND_5G) {
                rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_5G);
index b3a7969b2b81cff9d6b2f0ab2d0d9f8b73d8e0b4..e15d35f2c59577f21d8ef8208ee4a193a311335e 100644 (file)
@@ -510,12 +510,8 @@ struct rtw_timer_list {
 
 struct rtw_channel_params {
        u8 center_chan;
+       u8 primary_chan;
        u8 bandwidth;
-       u8 primary_chan_idx;
-       /* center channel by different available bandwidth,
-        * val of (bw > current bandwidth) is invalid
-        */
-       u8 cch_by_bw[RTW_MAX_CHANNEL_WIDTH + 1];
 };
 
 struct rtw_hw_reg {
@@ -1898,6 +1894,7 @@ struct rtw_hal {
        u8 current_primary_channel_index;
        u8 current_band_width;
        u8 current_band_type;
+       u8 primary_channel;
 
        /* center channel for different available bandwidth,
         * val of (bw > current_band_width) is invalid
@@ -2134,6 +2131,20 @@ static inline int rtw_chip_dump_fw_crash(struct rtw_dev *rtwdev)
        return 0;
 }
 
+static inline
+enum nl80211_band rtw_hw_to_nl80211_band(enum rtw_supported_band hw_band)
+{
+       switch (hw_band) {
+       default:
+       case RTW_BAND_2G:
+               return NL80211_BAND_2GHZ;
+       case RTW_BAND_5G:
+               return NL80211_BAND_5GHZ;
+       case RTW_BAND_60G:
+               return NL80211_BAND_60GHZ;
+       }
+}
+
 void rtw_set_rx_freq_band(struct rtw_rx_pkt_stat *pkt_stat, u8 channel);
 void rtw_set_dtim_period(struct rtw_dev *rtwdev, int dtim_period);
 void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
@@ -2175,4 +2186,7 @@ int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size,
                u32 fwcd_item);
 int rtw_dump_reg(struct rtw_dev *rtwdev, const u32 addr, const u32 size);
 void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool config_1ss);
+void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel,
+                       u8 primary_channel, enum rtw_supported_band band,
+                       enum rtw_bandwidth bandwidth);
 #endif