]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
net: hns3: add support to set/get tx copybreak buf size via ethtool for hns3 driver
authorHao Chen <chenhao288@hisilicon.com>
Thu, 18 Nov 2021 12:12:41 +0000 (20:12 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Nov 2021 12:31:47 +0000 (12:31 +0000)
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>
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c

index d5100179f8d589dc4ea517f5bafca0612a5fcc38..84a89441d864f36fc39dad19a23325853dc20ceb 100644 (file)
@@ -5532,8 +5532,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
        return 0;
 }
 
-static int hns3_reset_notify(struct hnae3_handle *handle,
-                            enum hnae3_reset_notify_type type)
+int hns3_reset_notify(struct hnae3_handle *handle,
+                     enum hnae3_reset_notify_type type)
 {
        int ret = 0;
 
index 1715c98d906d5d2040855c4583710d3c20203c8d..361a6390e1593a7c2f082ea6ecef20cc00bd68cd 100644 (file)
@@ -705,6 +705,8 @@ void hns3_set_vector_coalesce_tx_ql(struct hns3_enet_tqp_vector *tqp_vector,
                                    u32 ql_value);
 
 void hns3_request_update_promisc_mode(struct hnae3_handle *handle);
+int hns3_reset_notify(struct hnae3_handle *handle,
+                     enum hnae3_reset_notify_type type);
 
 #ifdef CONFIG_HNS3_DCB
 void hns3_dcbnl_setup(struct hnae3_handle *handle);
index c8442b86df9417cdcfad68512c882acc119b952d..9a816dbec61320611bb7905793decafcab2c39f1 100644 (file)
@@ -1695,6 +1695,7 @@ static int hns3_get_tunable(struct net_device *netdev,
                            void *data)
 {
        struct hns3_nic_priv *priv = netdev_priv(netdev);
+       struct hnae3_handle *h = priv->ae_handle;
        int ret = 0;
 
        switch (tuna->id) {
@@ -1705,6 +1706,9 @@ static int hns3_get_tunable(struct net_device *netdev,
        case ETHTOOL_RX_COPYBREAK:
                *(u32 *)data = priv->rx_copybreak;
                break;
+       case ETHTOOL_TX_COPYBREAK_BUF_SIZE:
+               *(u32 *)data = h->kinfo.tx_spare_buf_size;
+               break;
        default:
                ret = -EOPNOTSUPP;
                break;
@@ -1713,11 +1717,43 @@ static int hns3_get_tunable(struct net_device *netdev,
        return ret;
 }
 
+static int hns3_set_tx_spare_buf_size(struct net_device *netdev,
+                                     u32 data)
+{
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
+       struct hnae3_handle *h = priv->ae_handle;
+       int ret;
+
+       if (hns3_nic_resetting(netdev))
+               return -EBUSY;
+
+       h->kinfo.tx_spare_buf_size = data;
+
+       ret = hns3_reset_notify(h, HNAE3_DOWN_CLIENT);
+       if (ret)
+               return ret;
+
+       ret = hns3_reset_notify(h, HNAE3_UNINIT_CLIENT);
+       if (ret)
+               return ret;
+
+       ret = hns3_reset_notify(h, HNAE3_INIT_CLIENT);
+       if (ret)
+               return ret;
+
+       ret = hns3_reset_notify(h, HNAE3_UP_CLIENT);
+       if (ret)
+               hns3_reset_notify(h, HNAE3_UNINIT_CLIENT);
+
+       return ret;
+}
+
 static int hns3_set_tunable(struct net_device *netdev,
                            const struct ethtool_tunable *tuna,
                            const void *data)
 {
        struct hns3_nic_priv *priv = netdev_priv(netdev);
+       u32 old_tx_spare_buf_size, new_tx_spare_buf_size;
        struct hnae3_handle *h = priv->ae_handle;
        int i, ret = 0;
 
@@ -1735,6 +1771,26 @@ static int hns3_set_tunable(struct net_device *netdev,
                for (i = h->kinfo.num_tqps; i < h->kinfo.num_tqps * 2; i++)
                        priv->ring[i].rx_copybreak = priv->rx_copybreak;
 
+               break;
+       case ETHTOOL_TX_COPYBREAK_BUF_SIZE:
+               old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size;
+               new_tx_spare_buf_size = *(u32 *)data;
+               ret = hns3_set_tx_spare_buf_size(netdev, new_tx_spare_buf_size);
+               if (ret) {
+                       int ret1;
+
+                       netdev_warn(netdev,
+                                   "change tx spare buf size fail, revert to old value\n");
+                       ret1 = hns3_set_tx_spare_buf_size(netdev,
+                                                         old_tx_spare_buf_size);
+                       if (ret1) {
+                               netdev_err(netdev,
+                                          "revert to old tx spare buf size fail\n");
+                               return ret1;
+                       }
+
+                       return ret;
+               }
                break;
        default:
                ret = -EOPNOTSUPP;