[PATCH net-next 3/5] net: enetc: update max chained Tx BD number for i.MX95 ENETC

Wei Fang posted 5 patches 2 weeks, 3 days ago
There is a newer version of this series
[PATCH net-next 3/5] net: enetc: update max chained Tx BD number for i.MX95 ENETC
Posted by Wei Fang 2 weeks, 3 days ago
The max chained Tx BDs of latest ENETC (i.MX95 ENETC, rev 4.1) has been
increased to 63, but since the range of MAX_SKB_FRAGS is 17~45, so for
i.MX95 ENETC and later revision, it is better to set ENETC4_MAX_SKB_FRAGS
to MAX_SKB_FRAGS.
Because the maximum number of chained BDs supported by LS1028A and i.MX95
ENETC is different, so add max_frags to struct enetc_drvdata to indicate
the maximum chained BDs supported by device.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc.c        | 13 +++++++++----
 drivers/net/ethernet/freescale/enetc/enetc.h        | 13 +++++++++++--
 .../net/ethernet/freescale/enetc/enetc_pf_common.c  |  1 +
 drivers/net/ethernet/freescale/enetc/enetc_vf.c     |  1 +
 4 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index f98d14841838..b294ca4c2885 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -530,6 +530,7 @@ static void enetc_tso_complete_csum(struct enetc_bdr *tx_ring, struct tso_t *tso
 
 static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
+	struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
 	int hdr_len, total_len, data_len;
 	struct enetc_tx_swbd *tx_swbd;
 	union enetc_tx_bd *txbd;
@@ -595,7 +596,7 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
 			bd_data_num++;
 			tso_build_data(skb, &tso, size);
 
-			if (unlikely(bd_data_num >= ENETC_MAX_SKB_FRAGS && data_len))
+			if (unlikely(bd_data_num >= priv->max_frags && data_len))
 				goto err_chained_bd;
 		}
 
@@ -656,7 +657,7 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
 		count = enetc_map_tx_tso_buffs(tx_ring, skb);
 		enetc_unlock_mdio();
 	} else {
-		if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS))
+		if (unlikely(skb_shinfo(skb)->nr_frags > priv->max_frags))
 			if (unlikely(skb_linearize(skb)))
 				goto drop_packet_err;
 
@@ -674,7 +675,7 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
 	if (unlikely(!count))
 		goto drop_packet_err;
 
-	if (enetc_bd_unused(tx_ring) < ENETC_TXBDS_MAX_NEEDED)
+	if (enetc_bd_unused(tx_ring) < ENETC_TXBDS_MAX_NEEDED(priv->max_frags))
 		netif_stop_subqueue(ndev, tx_ring->index);
 
 	return NETDEV_TX_OK;
@@ -942,7 +943,8 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
 	if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) &&
 		     __netif_subqueue_stopped(ndev, tx_ring->index) &&
 		     !test_bit(ENETC_TX_DOWN, &priv->flags) &&
-		     (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) {
+		     (enetc_bd_unused(tx_ring) >=
+		      ENETC_TXBDS_MAX_NEEDED(priv->max_frags)))) {
 		netif_wake_subqueue(ndev, tx_ring->index);
 	}
 
@@ -3317,6 +3319,7 @@ EXPORT_SYMBOL_GPL(enetc_pci_remove);
 static const struct enetc_drvdata enetc_pf_data = {
 	.sysclk_freq = ENETC_CLK_400M,
 	.pmac_offset = ENETC_PMAC_OFFSET,
+	.max_frags = ENETC_MAX_SKB_FRAGS,
 	.eth_ops = &enetc_pf_ethtool_ops,
 };
 
@@ -3325,11 +3328,13 @@ static const struct enetc_drvdata enetc4_pf_data = {
 	.pmac_offset = ENETC4_PMAC_OFFSET,
 	.rx_csum = 1,
 	.tx_csum = 1,
+	.max_frags = ENETC4_MAX_SKB_FRAGS,
 	.eth_ops = &enetc4_pf_ethtool_ops,
 };
 
 static const struct enetc_drvdata enetc_vf_data = {
 	.sysclk_freq = ENETC_CLK_400M,
+	.max_frags = ENETC_MAX_SKB_FRAGS,
 	.eth_ops = &enetc_vf_ethtool_ops,
 };
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index ee11ff97e9ed..a78af4f624e0 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -59,9 +59,16 @@ struct enetc_rx_swbd {
 
 /* ENETC overhead: optional extension BD + 1 BD gap */
 #define ENETC_TXBDS_NEEDED(val)	((val) + 2)
-/* max # of chained Tx BDs is 15, including head and extension BD */
+/* For LS1028A, max # of chained Tx BDs is 15, including head and
+ * extension BD.
+ */
 #define ENETC_MAX_SKB_FRAGS	13
-#define ENETC_TXBDS_MAX_NEEDED	ENETC_TXBDS_NEEDED(ENETC_MAX_SKB_FRAGS + 1)
+/* For ENETC v4 and later versions, max # of chained Tx BDs is 63,
+ * including head and extension BD, but the range of MAX_SKB_FRAGS
+ * is 17 ~ 45, so set ENETC4_MAX_SKB_FRAGS to MAX_SKB_FRAGS.
+ */
+#define ENETC4_MAX_SKB_FRAGS		MAX_SKB_FRAGS
+#define ENETC_TXBDS_MAX_NEEDED(x)	ENETC_TXBDS_NEEDED((x) + 1)
 
 struct enetc_ring_stats {
 	unsigned int packets;
@@ -236,6 +243,7 @@ struct enetc_drvdata {
 	u32 pmac_offset; /* Only valid for PSI which supports 802.1Qbu */
 	u8 rx_csum:1;
 	u8 tx_csum:1;
+	u8 max_frags;
 	u64 sysclk_freq;
 	const struct ethtool_ops *eth_ops;
 };
@@ -379,6 +387,7 @@ struct enetc_ndev_priv {
 	u16 msg_enable;
 
 	u8 preemptible_tcs;
+	u8 max_frags; /* The maximum number of BDs for fragments */
 
 	enum enetc_active_offloads active_offloads;
 
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 3a8a5b6d8c26..2c4c6af672e7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -101,6 +101,7 @@ void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 
 	priv->msg_enable = (NETIF_MSG_WOL << 1) - 1;
 	priv->sysclk_freq = si->drvdata->sysclk_freq;
+	priv->max_frags = si->drvdata->max_frags;
 	ndev->netdev_ops = ndev_ops;
 	enetc_set_ethtool_ops(ndev);
 	ndev->watchdog_timeo = 5 * HZ;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 31e630638090..052833acd220 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -129,6 +129,7 @@ static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
 
 	priv->msg_enable = (NETIF_MSG_IFUP << 1) - 1;
 	priv->sysclk_freq = si->drvdata->sysclk_freq;
+	priv->max_frags = si->drvdata->max_frags;
 	ndev->netdev_ops = ndev_ops;
 	enetc_set_ethtool_ops(ndev);
 	ndev->watchdog_timeo = 5 * HZ;
-- 
2.34.1
Re: [PATCH net-next 3/5] net: enetc: update max chained Tx BD number for i.MX95 ENETC
Posted by Frank Li 2 weeks, 2 days ago
On Thu, Nov 07, 2024 at 11:38:15AM +0800, Wei Fang wrote:
> The max chained Tx BDs of latest ENETC (i.MX95 ENETC, rev 4.1) has been
> increased to 63, but since the range of MAX_SKB_FRAGS is 17~45, so for
> i.MX95 ENETC and later revision, it is better to set ENETC4_MAX_SKB_FRAGS
> to MAX_SKB_FRAGS.

Add empty line here

> Because the maximum number of chained BDs supported by LS1028A and i.MX95
> ENETC is different, so add max_frags to struct enetc_drvdata to indicate
> the maximum chained BDs supported by device.

Add ... because ...

Reviewed-by: Frank Li <Frank.Li@nxp.com>
>
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> ---
>  drivers/net/ethernet/freescale/enetc/enetc.c        | 13 +++++++++----
>  drivers/net/ethernet/freescale/enetc/enetc.h        | 13 +++++++++++--
>  .../net/ethernet/freescale/enetc/enetc_pf_common.c  |  1 +
>  drivers/net/ethernet/freescale/enetc/enetc_vf.c     |  1 +
>  4 files changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
> index f98d14841838..b294ca4c2885 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc.c
> @@ -530,6 +530,7 @@ static void enetc_tso_complete_csum(struct enetc_bdr *tx_ring, struct tso_t *tso
>
>  static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
>  {
> +	struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
>  	int hdr_len, total_len, data_len;
>  	struct enetc_tx_swbd *tx_swbd;
>  	union enetc_tx_bd *txbd;
> @@ -595,7 +596,7 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
>  			bd_data_num++;
>  			tso_build_data(skb, &tso, size);
>
> -			if (unlikely(bd_data_num >= ENETC_MAX_SKB_FRAGS && data_len))
> +			if (unlikely(bd_data_num >= priv->max_frags && data_len))
>  				goto err_chained_bd;
>  		}
>
> @@ -656,7 +657,7 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
>  		count = enetc_map_tx_tso_buffs(tx_ring, skb);
>  		enetc_unlock_mdio();
>  	} else {
> -		if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS))
> +		if (unlikely(skb_shinfo(skb)->nr_frags > priv->max_frags))
>  			if (unlikely(skb_linearize(skb)))
>  				goto drop_packet_err;
>
> @@ -674,7 +675,7 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
>  	if (unlikely(!count))
>  		goto drop_packet_err;
>
> -	if (enetc_bd_unused(tx_ring) < ENETC_TXBDS_MAX_NEEDED)
> +	if (enetc_bd_unused(tx_ring) < ENETC_TXBDS_MAX_NEEDED(priv->max_frags))
>  		netif_stop_subqueue(ndev, tx_ring->index);
>
>  	return NETDEV_TX_OK;
> @@ -942,7 +943,8 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
>  	if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) &&
>  		     __netif_subqueue_stopped(ndev, tx_ring->index) &&
>  		     !test_bit(ENETC_TX_DOWN, &priv->flags) &&
> -		     (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) {
> +		     (enetc_bd_unused(tx_ring) >=
> +		      ENETC_TXBDS_MAX_NEEDED(priv->max_frags)))) {
>  		netif_wake_subqueue(ndev, tx_ring->index);
>  	}
>
> @@ -3317,6 +3319,7 @@ EXPORT_SYMBOL_GPL(enetc_pci_remove);
>  static const struct enetc_drvdata enetc_pf_data = {
>  	.sysclk_freq = ENETC_CLK_400M,
>  	.pmac_offset = ENETC_PMAC_OFFSET,
> +	.max_frags = ENETC_MAX_SKB_FRAGS,
>  	.eth_ops = &enetc_pf_ethtool_ops,
>  };
>
> @@ -3325,11 +3328,13 @@ static const struct enetc_drvdata enetc4_pf_data = {
>  	.pmac_offset = ENETC4_PMAC_OFFSET,
>  	.rx_csum = 1,
>  	.tx_csum = 1,
> +	.max_frags = ENETC4_MAX_SKB_FRAGS,
>  	.eth_ops = &enetc4_pf_ethtool_ops,
>  };
>
>  static const struct enetc_drvdata enetc_vf_data = {
>  	.sysclk_freq = ENETC_CLK_400M,
> +	.max_frags = ENETC_MAX_SKB_FRAGS,
>  	.eth_ops = &enetc_vf_ethtool_ops,
>  };
>
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
> index ee11ff97e9ed..a78af4f624e0 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc.h
> +++ b/drivers/net/ethernet/freescale/enetc/enetc.h
> @@ -59,9 +59,16 @@ struct enetc_rx_swbd {
>
>  /* ENETC overhead: optional extension BD + 1 BD gap */
>  #define ENETC_TXBDS_NEEDED(val)	((val) + 2)
> -/* max # of chained Tx BDs is 15, including head and extension BD */
> +/* For LS1028A, max # of chained Tx BDs is 15, including head and
> + * extension BD.
> + */
>  #define ENETC_MAX_SKB_FRAGS	13
> -#define ENETC_TXBDS_MAX_NEEDED	ENETC_TXBDS_NEEDED(ENETC_MAX_SKB_FRAGS + 1)
> +/* For ENETC v4 and later versions, max # of chained Tx BDs is 63,
> + * including head and extension BD, but the range of MAX_SKB_FRAGS
> + * is 17 ~ 45, so set ENETC4_MAX_SKB_FRAGS to MAX_SKB_FRAGS.
> + */
> +#define ENETC4_MAX_SKB_FRAGS		MAX_SKB_FRAGS
> +#define ENETC_TXBDS_MAX_NEEDED(x)	ENETC_TXBDS_NEEDED((x) + 1)
>
>  struct enetc_ring_stats {
>  	unsigned int packets;
> @@ -236,6 +243,7 @@ struct enetc_drvdata {
>  	u32 pmac_offset; /* Only valid for PSI which supports 802.1Qbu */
>  	u8 rx_csum:1;
>  	u8 tx_csum:1;
> +	u8 max_frags;
>  	u64 sysclk_freq;
>  	const struct ethtool_ops *eth_ops;
>  };
> @@ -379,6 +387,7 @@ struct enetc_ndev_priv {
>  	u16 msg_enable;
>
>  	u8 preemptible_tcs;
> +	u8 max_frags; /* The maximum number of BDs for fragments */
>
>  	enum enetc_active_offloads active_offloads;
>
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
> index 3a8a5b6d8c26..2c4c6af672e7 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
> @@ -101,6 +101,7 @@ void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
>
>  	priv->msg_enable = (NETIF_MSG_WOL << 1) - 1;
>  	priv->sysclk_freq = si->drvdata->sysclk_freq;
> +	priv->max_frags = si->drvdata->max_frags;
>  	ndev->netdev_ops = ndev_ops;
>  	enetc_set_ethtool_ops(ndev);
>  	ndev->watchdog_timeo = 5 * HZ;
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
> index 31e630638090..052833acd220 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
> @@ -129,6 +129,7 @@ static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
>
>  	priv->msg_enable = (NETIF_MSG_IFUP << 1) - 1;
>  	priv->sysclk_freq = si->drvdata->sysclk_freq;
> +	priv->max_frags = si->drvdata->max_frags;
>  	ndev->netdev_ops = ndev_ops;
>  	enetc_set_ethtool_ops(ndev);
>  	ndev->watchdog_timeo = 5 * HZ;
> --
> 2.34.1
>