linux-mediatek.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
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 --]

  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).