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>
This commit is contained in:
Hao Chen 2021-11-18 20:12:41 +08:00 committed by David S. Miller
parent 448f413a8b
commit e445f08af2
3 changed files with 60 additions and 2 deletions

View file

@ -5532,7 +5532,7 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
return 0;
}
static int hns3_reset_notify(struct hnae3_handle *handle,
int hns3_reset_notify(struct hnae3_handle *handle,
enum hnae3_reset_notify_type type)
{
int ret = 0;

View 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);

View 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;