Add TX queue rate limiting functionality for Amber-Lite NICs. Due to hardware design differences, the TX queue rate limiting configuration for Amber-Lite NICs requires updates compared to Sapphire NICs.
Signed-off-by: Zaiyu Wang <[email protected]> --- drivers/net/txgbe/base/txgbe_osdep.h | 2 + drivers/net/txgbe/base/txgbe_regs.h | 12 +++++ drivers/net/txgbe/txgbe_ethdev.c | 69 +++++++++++++++++++++++----- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/drivers/net/txgbe/base/txgbe_osdep.h b/drivers/net/txgbe/base/txgbe_osdep.h index a1477653e2..f4282b3241 100644 --- a/drivers/net/txgbe/base/txgbe_osdep.h +++ b/drivers/net/txgbe/base/txgbe_osdep.h @@ -164,6 +164,8 @@ static inline u64 REVERT_BIT_MASK64(u64 mask) #define IOMEM +#define BIT(nr) (1UL << (nr)) + #define prefetch(x) rte_prefetch0(x) #define ARRAY_SIZE(x) ((int32_t)RTE_DIM(x)) diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h index 2e0ac9c742..f2e4994863 100644 --- a/drivers/net/txgbe/base/txgbe_regs.h +++ b/drivers/net/txgbe/base/txgbe_regs.h @@ -1656,6 +1656,18 @@ enum txgbe_5tuple_protocol { #define TXGBE_ARBTXRATE_MIN(v) LS(v, 0, 0x3FFF) #define TXGBE_ARBTXRATE_MAX(v) LS(v, 16, 0x3FFF) +#define TXGBE_TDM_RL_QUEUE_IDX 0x018210 +#define TXGBE_TDM_RL_QUEUE_CFG 0x018214 +#define TXGBE_TDM_FACTOR_INT_MASK MS(16, 0xFFFF) +#define TXGBE_TDM_FACTOR_FRA_MASK MS(0, 0xFFFC) +#define TXGBE_TDM_FACTOR_INT_SHIFT 16 +#define TXGBE_TDM_FACTOR_FRA_SHIFT 2 + +#define TXGBE_TDM_RL_VM_IDX 0x018218 +#define TXGBE_TDM_RL_VM_CFG 0x01821C +#define TXGBE_TDM_RL_CFG 0x018400 +#define TXGBE_TDM_RL_EN MS(0, 0x1) + /* qos */ #define TXGBE_ARBTXCTL 0x018200 #define TXGBE_ARBTXCTL_RRM MS(1, 0x1) diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index e6694f7fc2..c7c3668066 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -4245,33 +4245,80 @@ txgbe_configure_msix(struct rte_eth_dev *dev) | TXGBE_ITR_WRDSA); } +static u16 txgbe_frac_to_bi(u16 frac, u16 denom, int max_bits) +{ + u16 value = 0; + + while (frac > 0 && max_bits > 0) { + max_bits -= 1; + frac *= 2; + if (frac >= denom) { + value |= BIT(max_bits); + frac -= denom; + } + } + + return value; +} + int txgbe_set_queue_rate_limit(struct rte_eth_dev *dev, uint16_t queue_idx, uint32_t tx_rate) { struct txgbe_hw *hw = TXGBE_DEV_HW(dev); uint32_t bcnrc_val; + int factor_int, factor_fra; + uint32_t link_speed; if (queue_idx >= hw->mac.max_tx_queues) return -EINVAL; - if (tx_rate != 0) { - bcnrc_val = TXGBE_ARBTXRATE_MAX(tx_rate); - bcnrc_val |= TXGBE_ARBTXRATE_MIN(tx_rate / 2); - } else { - bcnrc_val = 0; - } - /* * Set global transmit compensation time to the MMW_SIZE in ARBTXMMW * register. MMW_SIZE=0x014 if 9728-byte jumbo is supported. */ wr32(hw, TXGBE_ARBTXMMW, 0x14); - /* Set ARBTXRATE of queue X */ - wr32(hw, TXGBE_ARBPOOLIDX, queue_idx); - wr32(hw, TXGBE_ARBTXRATE, bcnrc_val); - txgbe_flush(hw); + if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) { + if (tx_rate) { + u16 frac; + + link_speed = dev->data->dev_link.link_speed; + tx_rate = tx_rate * 105 / 100; + /* Calculate the rate factor values to set */ + factor_int = link_speed / tx_rate; + frac = (link_speed % tx_rate) * 10000 / tx_rate; + factor_fra = txgbe_frac_to_bi(frac, 10000, 14); + if (tx_rate > link_speed) { + factor_int = 1; + factor_fra = 0; + } + + wr32(hw, TXGBE_TDM_RL_QUEUE_IDX, queue_idx); + wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG, + TXGBE_TDM_FACTOR_INT_MASK, factor_int << TXGBE_TDM_FACTOR_INT_SHIFT); + wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG, + TXGBE_TDM_FACTOR_FRA_MASK, factor_fra << TXGBE_TDM_FACTOR_FRA_SHIFT); + wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG, + TXGBE_TDM_RL_EN, TXGBE_TDM_RL_EN); + } else { + wr32(hw, TXGBE_TDM_RL_QUEUE_IDX, queue_idx); + wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG, + TXGBE_TDM_RL_EN, 0); + } + } else { + if (tx_rate != 0) { + bcnrc_val = TXGBE_ARBTXRATE_MAX(tx_rate); + bcnrc_val |= TXGBE_ARBTXRATE_MIN(tx_rate / 2); + } else { + bcnrc_val = 0; + } + + /* Set ARBTXRATE of queue X */ + wr32(hw, TXGBE_ARBPOOLIDX, queue_idx); + wr32(hw, TXGBE_ARBTXRATE, bcnrc_val); + txgbe_flush(hw); + } return 0; } -- 2.21.0.windows.1

