Commit e445f08a authored by Hao Chen's avatar Hao Chen Committed by David S. Miller

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: default avatarHao Chen <chenhao288@hisilicon.com>
Signed-off-by: default avatarGuangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 448f413a
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment