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

net: hns3: add support to set/get tx copybreak buf size via ethtool for hns3 driver

Tx copybreak buf size is used for tx copybreak feature, the feature is
used for small size packet or frag. It adds a queue based tx shared
bounce buffer to memcpy the small packet when the len of xmitted skb is
below tx_copybreak(value to distinguish small size and normal size),
and reduce the overhead of dma map and unmap when IOMMU is on.

Support setting it via ethtool --set-tunable parameter and getting
it via ethtool --get-tunable parameter.

Signed-off-by: Hao Chen <chenhao288@hisilicon.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Hao Chen and committed by
David S. Miller
e445f08a 448f413a

+60 -2
+2 -2
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
··· 5532 5532 return 0; 5533 5533 } 5534 5534 5535 - static int hns3_reset_notify(struct hnae3_handle *handle, 5536 - enum hnae3_reset_notify_type type) 5535 + int hns3_reset_notify(struct hnae3_handle *handle, 5536 + enum hnae3_reset_notify_type type) 5537 5537 { 5538 5538 int ret = 0; 5539 5539
+2
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
··· 705 705 u32 ql_value); 706 706 707 707 void hns3_request_update_promisc_mode(struct hnae3_handle *handle); 708 + int hns3_reset_notify(struct hnae3_handle *handle, 709 + enum hnae3_reset_notify_type type); 708 710 709 711 #ifdef CONFIG_HNS3_DCB 710 712 void hns3_dcbnl_setup(struct hnae3_handle *handle);
+56
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
··· 1695 1695 void *data) 1696 1696 { 1697 1697 struct hns3_nic_priv *priv = netdev_priv(netdev); 1698 + struct hnae3_handle *h = priv->ae_handle; 1698 1699 int ret = 0; 1699 1700 1700 1701 switch (tuna->id) { ··· 1706 1705 case ETHTOOL_RX_COPYBREAK: 1707 1706 *(u32 *)data = priv->rx_copybreak; 1708 1707 break; 1708 + case ETHTOOL_TX_COPYBREAK_BUF_SIZE: 1709 + *(u32 *)data = h->kinfo.tx_spare_buf_size; 1710 + break; 1709 1711 default: 1710 1712 ret = -EOPNOTSUPP; 1711 1713 break; 1712 1714 } 1715 + 1716 + return ret; 1717 + } 1718 + 1719 + static int hns3_set_tx_spare_buf_size(struct net_device *netdev, 1720 + u32 data) 1721 + { 1722 + struct hns3_nic_priv *priv = netdev_priv(netdev); 1723 + struct hnae3_handle *h = priv->ae_handle; 1724 + int ret; 1725 + 1726 + if (hns3_nic_resetting(netdev)) 1727 + return -EBUSY; 1728 + 1729 + h->kinfo.tx_spare_buf_size = data; 1730 + 1731 + ret = hns3_reset_notify(h, HNAE3_DOWN_CLIENT); 1732 + if (ret) 1733 + return ret; 1734 + 1735 + ret = hns3_reset_notify(h, HNAE3_UNINIT_CLIENT); 1736 + if (ret) 1737 + return ret; 1738 + 1739 + ret = hns3_reset_notify(h, HNAE3_INIT_CLIENT); 1740 + if (ret) 1741 + return ret; 1742 + 1743 + ret = hns3_reset_notify(h, HNAE3_UP_CLIENT); 1744 + if (ret) 1745 + hns3_reset_notify(h, HNAE3_UNINIT_CLIENT); 1713 1746 1714 1747 return ret; 1715 1748 } ··· 1753 1718 const void *data) 1754 1719 { 1755 1720 struct hns3_nic_priv *priv = netdev_priv(netdev); 1721 + u32 old_tx_spare_buf_size, new_tx_spare_buf_size; 1756 1722 struct hnae3_handle *h = priv->ae_handle; 1757 1723 int i, ret = 0; 1758 1724 ··· 1771 1735 for (i = h->kinfo.num_tqps; i < h->kinfo.num_tqps * 2; i++) 1772 1736 priv->ring[i].rx_copybreak = priv->rx_copybreak; 1773 1737 1738 + break; 1739 + case ETHTOOL_TX_COPYBREAK_BUF_SIZE: 1740 + old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size; 1741 + new_tx_spare_buf_size = *(u32 *)data; 1742 + ret = hns3_set_tx_spare_buf_size(netdev, new_tx_spare_buf_size); 1743 + if (ret) { 1744 + int ret1; 1745 + 1746 + netdev_warn(netdev, 1747 + "change tx spare buf size fail, revert to old value\n"); 1748 + ret1 = hns3_set_tx_spare_buf_size(netdev, 1749 + old_tx_spare_buf_size); 1750 + if (ret1) { 1751 + netdev_err(netdev, 1752 + "revert to old tx spare buf size fail\n"); 1753 + return ret1; 1754 + } 1755 + 1756 + return ret; 1757 + } 1774 1758 break; 1775 1759 default: 1776 1760 ret = -EOPNOTSUPP;