From: Lorenzo Bianconi <lorenzo@kernel.org>
To: Shayne Chen <shayne.chen@mediatek.com>
Cc: Felix Fietkau <nbd@nbd.name>,
linux-wireless <linux-wireless@vger.kernel.org>,
Ryder Lee <ryder.lee@mediatek.com>,
Evelyn Tsai <evelyn.tsai@mediatek.com>,
Bo Jiao <Bo.Jiao@mediatek.com>,
linux-mediatek <linux-mediatek@lists.infradead.org>,
Peter Chiu <chui-hao.chiu@mediatek.com>
Subject: Re: [PATCH 08/12] wifi: mt76: mt7996: set ifs time by mcu command
Date: Fri, 2 Jun 2023 20:12:02 +0200 [thread overview]
Message-ID: <ZHow8sIRb/vuBBWD@lore-desk> (raw)
In-Reply-To: <20230602152108.26860-8-shayne.chen@mediatek.com>
[-- Attachment #1: Type: text/plain, Size: 9738 bytes --]
> From: Peter Chiu <chui-hao.chiu@mediatek.com>
>
> There's a race between driver and fw on some tx/rx control registers
> when setting ifs, which will cause accidental hw queue pause problems.
> Avoid this by setting ifs time with bss_info mcu command.
>
> Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
> Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
> Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
> ---
> .../net/wireless/mediatek/mt76/mt7996/mac.c | 27 +----------
> .../net/wireless/mediatek/mt76/mt7996/main.c | 5 +-
> .../net/wireless/mediatek/mt76/mt7996/mcu.c | 47 +++++++++++++++++++
> .../net/wireless/mediatek/mt76/mt7996/mcu.h | 17 +++++++
> .../wireless/mediatek/mt76/mt7996/mt7996.h | 3 +-
> 5 files changed, 70 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> index 130eb7b4fd91..78d9127e63ab 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> @@ -1604,20 +1604,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy)
> mt7996_mcu_get_chan_mib_info(phy, true);
> }
>
> -void mt7996_mac_set_timing(struct mt7996_phy *phy)
> +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy)
> {
> s16 coverage_class = phy->coverage_class;
> struct mt7996_dev *dev = phy->dev;
> struct mt7996_phy *phy2 = mt7996_phy2(dev);
> struct mt7996_phy *phy3 = mt7996_phy3(dev);
> - u32 val, reg_offset;
> + u32 reg_offset;
> u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) |
> FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
> u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
> FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
> u8 band_idx = phy->mt76->band_idx;
> int offset;
> - bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
>
> if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
> return;
> @@ -1630,34 +1629,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy)
> coverage_class = max_t(s16, coverage_class,
> phy3->coverage_class);
>
> - mt76_set(dev, MT_ARB_SCR(band_idx),
> - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
> - udelay(1);
> -
> offset = 3 * coverage_class;
> reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
> FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
>
> mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset);
> mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset);
> - mt76_wr(dev, MT_TMAC_ICR0(band_idx),
> - FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
> - FIELD_PREP(MT_IFS_RIFS, 2) |
> - FIELD_PREP(MT_IFS_SIFS, 10) |
> - FIELD_PREP(MT_IFS_SLOT, phy->slottime));
> -
> - if (!a_band)
> - mt76_wr(dev, MT_TMAC_ICR1(band_idx),
> - FIELD_PREP(MT_IFS_EIFS_CCK, 314));
> -
> - if (phy->slottime < 20 || a_band)
> - val = MT7996_CFEND_RATE_DEFAULT;
> - else
> - val = MT7996_CFEND_RATE_11B;
> -
> - mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val);
> - mt76_clear(dev, MT_ARB_SCR(band_idx),
> - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
> }
>
> void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band)
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
> index 8a1edc5c1288..6001b534b657 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
> @@ -287,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy)
> if (ret)
> goto out;
>
> - mt7996_mac_set_timing(phy);
> ret = mt7996_dfs_init_radar_detector(phy);
> mt7996_mac_cca_stats_reset(phy);
>
> @@ -565,7 +564,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
>
> if (slottime != phy->slottime) {
> phy->slottime = slottime;
> - mt7996_mac_set_timing(phy);
> + mt7996_mcu_set_timing(phy, vif);
> }
> }
>
> @@ -905,7 +904,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
>
> mutex_lock(&dev->mt76.mutex);
> phy->coverage_class = max_t(s16, coverage_class, 0);
> - mt7996_mac_set_timing(phy);
> + mt7996_mac_set_coverage_class(phy);
> mutex_unlock(&dev->mt76.mutex);
> }
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
> index db51b3023654..52c6c502e9b3 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
> @@ -701,6 +701,35 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif,
> sizeof(req), true);
> }
>
> +static void
> +mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
> +{
> + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
> + struct mt7996_phy *phy = mvif->phy;
> + struct bss_ifs_time_tlv *ifs_time;
> + struct tlv *tlv;
> + bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
nit: I think it is better to do it in the other way around since the band can
be even 6GHz. Something like:
bool is_2ghz_band = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ
or even just use phy->mt76->chandef.chan->band directly.
Regards,
Lorenzo
> + u16 eifs_time = a_band ? 84 : 78;
> +
> + tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));
> +
> + ifs_time = (struct bss_ifs_time_tlv *)tlv;
> + ifs_time->slot_valid = true;
> + ifs_time->sifs_valid = true;
> + ifs_time->rifs_valid = true;
> + ifs_time->eifs_valid = true;
> +
> + ifs_time->slot_time = cpu_to_le16(phy->slottime);
> + ifs_time->sifs_time = cpu_to_le16(10);
> + ifs_time->rifs_time = cpu_to_le16(2);
> + ifs_time->eifs_time = cpu_to_le16(eifs_time);
> +
> + if (!a_band) {
> + ifs_time->eifs_cck_valid = true;
> + ifs_time->eifs_cck_time = cpu_to_le16(314);
> + }
> +}
> +
> static int
> mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
> struct ieee80211_vif *vif,
> @@ -826,6 +855,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
> mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
> mt7996_mcu_bss_ra_tlv(skb, vif, phy);
> mt7996_mcu_bss_txcmd_tlv(skb, true);
> + mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
>
> if (vif->bss_conf.he_support)
> mt7996_mcu_bss_he_tlv(skb, vif, phy);
> @@ -838,6 +868,23 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
> MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
> }
>
> +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
> +{
> + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
> + struct mt7996_dev *dev = phy->dev;
> + struct sk_buff *skb;
> +
> + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
> + MT7996_BSS_UPDATE_MAX_SIZE);
> + if (IS_ERR(skb))
> + return PTR_ERR(skb);
> +
> + mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
> +
> + return mt76_mcu_skb_send_msg(&dev->mt76, skb,
> + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
> +}
> +
> static int
> mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
> struct ieee80211_ampdu_params *params,
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
> index d7075a4d0667..078f82858621 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
> @@ -317,6 +317,22 @@ struct bss_sec_tlv {
> u8 __rsv2[1];
> } __packed;
>
> +struct bss_ifs_time_tlv {
> + __le16 tag;
> + __le16 len;
> + u8 slot_valid;
> + u8 sifs_valid;
> + u8 rifs_valid;
> + u8 eifs_valid;
> + __le16 slot_time;
> + __le16 sifs_time;
> + __le16 rifs_time;
> + __le16 eifs_time;
> + u8 eifs_cck_valid;
> + u8 rsv;
> + __le16 eifs_cck_time;
> +} __packed;
> +
> struct bss_power_save {
> __le16 tag;
> __le16 len;
> @@ -552,6 +568,7 @@ enum {
> sizeof(struct bss_txcmd_tlv) + \
> sizeof(struct bss_power_save) + \
> sizeof(struct bss_sec_tlv) + \
> + sizeof(struct bss_ifs_time_tlv) + \
> sizeof(struct bss_mld_tlv))
>
> #define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
> index 7dfdc7384056..42892f06faa7 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
> @@ -463,6 +463,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,
> const struct mt7996_dfs_pattern *pattern);
> int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
> int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
> +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
> int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
> int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
> u8 rx_sel, u8 val);
> @@ -526,7 +527,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
> struct sk_buff *skb, struct mt76_wcid *wcid,
> struct ieee80211_key_conf *key, int pid,
> enum mt76_txq_id qid, u32 changed);
> -void mt7996_mac_set_timing(struct mt7996_phy *phy);
> +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy);
> int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
> struct ieee80211_sta *sta);
> void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
> --
> 2.39.2
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
next prev parent reply other threads:[~2023-06-02 18:12 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-02 15:20 [PATCH 01/12] wifi: mt76: mt7996: move radio ctrl commands to proper functions Shayne Chen
2023-06-02 15:20 ` [PATCH 02/12] wifi: mt76: connac: add a setting bit for dsp firmware Shayne Chen
2023-06-02 17:55 ` Lorenzo Bianconi
2023-06-02 15:20 ` [PATCH 03/12] wifi: mt76: mt7996: add dsp firmware download Shayne Chen
2023-06-02 17:56 ` Lorenzo Bianconi
2023-06-07 14:16 ` Kalle Valo
2023-06-02 15:21 ` [PATCH 04/12] wifi: mt76: mt7996: fix bss wlan_idx when sending bss_info command Shayne Chen
2023-06-02 15:21 ` [PATCH 05/12] wifi: mt76: mt7996: init he and eht cap for AP_VLAN Shayne Chen
2023-06-02 15:21 ` [PATCH 06/12] wifi: mt76: mt7996: enable VHT extended NSS BW feature Shayne Chen
2023-06-02 15:21 ` [PATCH 07/12] wifi: mt76: connac: add a new bss_info tag for setting ifs time Shayne Chen
2023-06-02 17:57 ` Lorenzo Bianconi
2023-06-02 15:21 ` [PATCH 08/12] wifi: mt76: mt7996: set ifs time by mcu command Shayne Chen
2023-06-02 18:12 ` Lorenzo Bianconi [this message]
2023-06-02 15:21 ` [PATCH 09/12] wifi: mt76: mt7996: use correct phy for background radar event Shayne Chen
2023-06-02 15:21 ` [PATCH 10/12] wifi: mt76: mt7996: fix WA event ring size Shayne Chen
2023-06-02 15:21 ` [PATCH 11/12] wifi: mt76: mt7996: add muru support Shayne Chen
2023-06-02 15:21 ` [PATCH 12/12] wifi: mt76: mt7996: increase tx token size Shayne Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZHow8sIRb/vuBBWD@lore-desk \
--to=lorenzo@kernel.org \
--cc=Bo.Jiao@mediatek.com \
--cc=chui-hao.chiu@mediatek.com \
--cc=evelyn.tsai@mediatek.com \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
--cc=nbd@nbd.name \
--cc=ryder.lee@mediatek.com \
--cc=shayne.chen@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).