Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtase: Add ndo_setup_tc support for CBS offload in traffic control setup

Add support for ndo_setup_tc to enable CBS offload functionality as
part of traffic control configuration for network devices, where CBS
is applied from the CPU to the switch. More specifically, CBS is
applied at the GMAC in the topmost architecture diagram.

Signed-off-by: Justin Lai <justinlai0215@realtek.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250416115757.28156-1-justinlai0215@realtek.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Justin Lai and committed by
Paolo Abeni
37f2f2fe b77ad30c

+75
+15
drivers/net/ethernet/realtek/rtase/rtase.h
··· 170 170 #define RTASE_TC_MODE_MASK GENMASK(11, 10) 171 171 172 172 RTASE_TOKSEL = 0x2046, 173 + RTASE_TXQCRDT_0 = 0x2500, 173 174 RTASE_RFIFONFULL = 0x4406, 174 175 RTASE_INT_MITI_TX = 0x0A00, 175 176 RTASE_INT_MITI_RX = 0x0A80, ··· 260 259 #define RTASE_VLAN_TAG_MASK GENMASK(15, 0) 261 260 #define RTASE_RX_PKT_SIZE_MASK GENMASK(13, 0) 262 261 262 + /* txqos hardware definitions */ 263 + #define RTASE_1T_CLOCK 64 264 + #define RTASE_1T_POWER 10000000 265 + #define RTASE_IDLESLOPE_INT_SHIFT 25 266 + #define RTASE_IDLESLOPE_INT_MASK GENMASK(31, 25) 267 + 263 268 #define RTASE_IVEC_NAME_SIZE (IFNAMSIZ + 10) 264 269 265 270 struct rtase_int_vector { ··· 301 294 u64 alloc_fail; 302 295 }; 303 296 297 + struct rtase_txqos { 298 + int hicredit; 299 + int locredit; 300 + int idleslope; 301 + int sendslope; 302 + }; 303 + 304 304 struct rtase_stats { 305 305 u64 tx_dropped; 306 306 u64 rx_dropped; ··· 327 313 328 314 struct page_pool *page_pool; 329 315 struct rtase_ring tx_ring[RTASE_NUM_TX_QUEUE]; 316 + struct rtase_txqos tx_qos[RTASE_NUM_TX_QUEUE]; 330 317 struct rtase_ring rx_ring[RTASE_NUM_RX_QUEUE]; 331 318 struct rtase_counters *tally_vaddr; 332 319 dma_addr_t tally_paddr;
+60
drivers/net/ethernet/realtek/rtase/rtase_main.c
··· 1661 1661 stats->rx_length_errors = tp->stats.rx_length_errors; 1662 1662 } 1663 1663 1664 + static void rtase_set_hw_cbs(const struct rtase_private *tp, u32 queue) 1665 + { 1666 + u32 idle = tp->tx_qos[queue].idleslope * RTASE_1T_CLOCK; 1667 + u32 val, i; 1668 + 1669 + val = u32_encode_bits(idle / RTASE_1T_POWER, RTASE_IDLESLOPE_INT_MASK); 1670 + idle %= RTASE_1T_POWER; 1671 + 1672 + for (i = 1; i <= RTASE_IDLESLOPE_INT_SHIFT; i++) { 1673 + idle *= 2; 1674 + if ((idle / RTASE_1T_POWER) == 1) 1675 + val |= BIT(RTASE_IDLESLOPE_INT_SHIFT - i); 1676 + 1677 + idle %= RTASE_1T_POWER; 1678 + } 1679 + 1680 + rtase_w32(tp, RTASE_TXQCRDT_0 + queue * 4, val); 1681 + } 1682 + 1683 + static int rtase_setup_tc_cbs(struct rtase_private *tp, 1684 + const struct tc_cbs_qopt_offload *qopt) 1685 + { 1686 + int queue = qopt->queue; 1687 + 1688 + if (queue < 0 || queue >= tp->func_tx_queue_num) 1689 + return -EINVAL; 1690 + 1691 + if (!qopt->enable) { 1692 + tp->tx_qos[queue].hicredit = 0; 1693 + tp->tx_qos[queue].locredit = 0; 1694 + tp->tx_qos[queue].idleslope = 0; 1695 + tp->tx_qos[queue].sendslope = 0; 1696 + 1697 + rtase_w32(tp, RTASE_TXQCRDT_0 + queue * 4, 0); 1698 + } else { 1699 + tp->tx_qos[queue].hicredit = qopt->hicredit; 1700 + tp->tx_qos[queue].locredit = qopt->locredit; 1701 + tp->tx_qos[queue].idleslope = qopt->idleslope; 1702 + tp->tx_qos[queue].sendslope = qopt->sendslope; 1703 + 1704 + rtase_set_hw_cbs(tp, queue); 1705 + } 1706 + 1707 + return 0; 1708 + } 1709 + 1710 + static int rtase_setup_tc(struct net_device *dev, enum tc_setup_type type, 1711 + void *type_data) 1712 + { 1713 + struct rtase_private *tp = netdev_priv(dev); 1714 + 1715 + switch (type) { 1716 + case TC_SETUP_QDISC_CBS: 1717 + return rtase_setup_tc_cbs(tp, type_data); 1718 + default: 1719 + return -EOPNOTSUPP; 1720 + } 1721 + } 1722 + 1664 1723 static netdev_features_t rtase_fix_features(struct net_device *dev, 1665 1724 netdev_features_t features) 1666 1725 { ··· 1755 1696 .ndo_change_mtu = rtase_change_mtu, 1756 1697 .ndo_tx_timeout = rtase_tx_timeout, 1757 1698 .ndo_get_stats64 = rtase_get_stats64, 1699 + .ndo_setup_tc = rtase_setup_tc, 1758 1700 .ndo_fix_features = rtase_fix_features, 1759 1701 .ndo_set_features = rtase_set_features, 1760 1702 };