|
@@ -225,8 +225,6 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
|
|
static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
|
|
static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
|
|
struct hns3_nic_priv *priv)
|
|
struct hns3_nic_priv *priv)
|
|
{
|
|
{
|
|
- struct hnae3_handle *h = priv->ae_handle;
|
|
|
|
-
|
|
|
|
/* initialize the configuration for interrupt coalescing.
|
|
/* initialize the configuration for interrupt coalescing.
|
|
* 1. GL (Interrupt Gap Limiter)
|
|
* 1. GL (Interrupt Gap Limiter)
|
|
* 2. RL (Interrupt Rate Limiter)
|
|
* 2. RL (Interrupt Rate Limiter)
|
|
@@ -239,9 +237,6 @@ static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
|
|
tqp_vector->tx_group.coal.int_gl = HNS3_INT_GL_50K;
|
|
tqp_vector->tx_group.coal.int_gl = HNS3_INT_GL_50K;
|
|
tqp_vector->rx_group.coal.int_gl = HNS3_INT_GL_50K;
|
|
tqp_vector->rx_group.coal.int_gl = HNS3_INT_GL_50K;
|
|
|
|
|
|
- /* Default: disable RL */
|
|
|
|
- h->kinfo.int_rl_setting = 0;
|
|
|
|
-
|
|
|
|
tqp_vector->int_adapt_down = HNS3_INT_ADAPT_DOWN_START;
|
|
tqp_vector->int_adapt_down = HNS3_INT_ADAPT_DOWN_START;
|
|
tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW;
|
|
tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW;
|
|
tqp_vector->tx_group.coal.flow_level = HNS3_FLOW_LOW;
|
|
tqp_vector->tx_group.coal.flow_level = HNS3_FLOW_LOW;
|
|
@@ -307,12 +302,12 @@ static int hns3_nic_set_real_num_queue(struct net_device *netdev)
|
|
|
|
|
|
static u16 hns3_get_max_available_channels(struct hnae3_handle *h)
|
|
static u16 hns3_get_max_available_channels(struct hnae3_handle *h)
|
|
{
|
|
{
|
|
- u16 free_tqps, max_rss_size, max_tqps;
|
|
|
|
|
|
+ u16 alloc_tqps, max_rss_size, rss_size;
|
|
|
|
|
|
- h->ae_algo->ops->get_tqps_and_rss_info(h, &free_tqps, &max_rss_size);
|
|
|
|
- max_tqps = h->kinfo.num_tc * max_rss_size;
|
|
|
|
|
|
+ h->ae_algo->ops->get_tqps_and_rss_info(h, &alloc_tqps, &max_rss_size);
|
|
|
|
+ rss_size = alloc_tqps / h->kinfo.num_tc;
|
|
|
|
|
|
- return min_t(u16, max_tqps, (free_tqps + h->kinfo.num_tqps));
|
|
|
|
|
|
+ return min_t(u16, rss_size, max_rss_size);
|
|
}
|
|
}
|
|
|
|
|
|
static int hns3_nic_net_up(struct net_device *netdev)
|
|
static int hns3_nic_net_up(struct net_device *netdev)
|
|
@@ -1491,13 +1486,11 @@ static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
|
|
}
|
|
}
|
|
|
|
|
|
ret = h->ae_algo->ops->set_mtu(h, new_mtu);
|
|
ret = h->ae_algo->ops->set_mtu(h, new_mtu);
|
|
- if (ret) {
|
|
|
|
|
|
+ if (ret)
|
|
netdev_err(netdev, "failed to change MTU in hardware %d\n",
|
|
netdev_err(netdev, "failed to change MTU in hardware %d\n",
|
|
ret);
|
|
ret);
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- netdev->mtu = new_mtu;
|
|
|
|
|
|
+ else
|
|
|
|
+ netdev->mtu = new_mtu;
|
|
|
|
|
|
/* if the netdev was running earlier, bring it up again */
|
|
/* if the netdev was running earlier, bring it up again */
|
|
if (if_running && hns3_nic_net_open(netdev))
|
|
if (if_running && hns3_nic_net_open(netdev))
|
|
@@ -1740,7 +1733,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
- NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
|
|
|
|
+ NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC;
|
|
|
|
|
|
netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
|
|
netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
|
|
|
|
|
|
@@ -1752,21 +1745,21 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
- NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
|
|
|
|
+ NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC;
|
|
|
|
|
|
netdev->vlan_features |=
|
|
netdev->vlan_features |=
|
|
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
|
|
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
|
|
NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO |
|
|
NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO |
|
|
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
- NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
|
|
|
|
+ NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC;
|
|
|
|
|
|
netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
|
netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
|
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
|
|
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
- NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
|
|
|
|
+ NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC;
|
|
|
|
|
|
if (pdev->revision != 0x20)
|
|
if (pdev->revision != 0x20)
|
|
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
|
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
|
@@ -3166,12 +3159,14 @@ static void hns3_nic_set_priv_ops(struct net_device *netdev)
|
|
static int hns3_client_init(struct hnae3_handle *handle)
|
|
static int hns3_client_init(struct hnae3_handle *handle)
|
|
{
|
|
{
|
|
struct pci_dev *pdev = handle->pdev;
|
|
struct pci_dev *pdev = handle->pdev;
|
|
|
|
+ u16 alloc_tqps, max_rss_size;
|
|
struct hns3_nic_priv *priv;
|
|
struct hns3_nic_priv *priv;
|
|
struct net_device *netdev;
|
|
struct net_device *netdev;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- netdev = alloc_etherdev_mq(sizeof(struct hns3_nic_priv),
|
|
|
|
- hns3_get_max_available_channels(handle));
|
|
|
|
|
|
+ handle->ae_algo->ops->get_tqps_and_rss_info(handle, &alloc_tqps,
|
|
|
|
+ &max_rss_size);
|
|
|
|
+ netdev = alloc_etherdev_mq(sizeof(struct hns3_nic_priv), alloc_tqps);
|
|
if (!netdev)
|
|
if (!netdev)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
@@ -3490,6 +3485,31 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void hns3_store_coal(struct hns3_nic_priv *priv)
|
|
|
|
+{
|
|
|
|
+ /* ethtool only support setting and querying one coal
|
|
|
|
+ * configuation for now, so save the vector 0' coal
|
|
|
|
+ * configuation here in order to restore it.
|
|
|
|
+ */
|
|
|
|
+ memcpy(&priv->tx_coal, &priv->tqp_vector[0].tx_group.coal,
|
|
|
|
+ sizeof(struct hns3_enet_coalesce));
|
|
|
|
+ memcpy(&priv->rx_coal, &priv->tqp_vector[0].rx_group.coal,
|
|
|
|
+ sizeof(struct hns3_enet_coalesce));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void hns3_restore_coal(struct hns3_nic_priv *priv)
|
|
|
|
+{
|
|
|
|
+ u16 vector_num = priv->vector_num;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < vector_num; i++) {
|
|
|
|
+ memcpy(&priv->tqp_vector[i].tx_group.coal, &priv->tx_coal,
|
|
|
|
+ sizeof(struct hns3_enet_coalesce));
|
|
|
|
+ memcpy(&priv->tqp_vector[i].rx_group.coal, &priv->rx_coal,
|
|
|
|
+ sizeof(struct hns3_enet_coalesce));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
|
|
static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
|
|
{
|
|
{
|
|
struct hnae3_knic_private_info *kinfo = &handle->kinfo;
|
|
struct hnae3_knic_private_info *kinfo = &handle->kinfo;
|
|
@@ -3536,6 +3556,8 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
|
|
/* Carrier off reporting is important to ethtool even BEFORE open */
|
|
/* Carrier off reporting is important to ethtool even BEFORE open */
|
|
netif_carrier_off(netdev);
|
|
netif_carrier_off(netdev);
|
|
|
|
|
|
|
|
+ hns3_restore_coal(priv);
|
|
|
|
+
|
|
ret = hns3_nic_init_vector_data(priv);
|
|
ret = hns3_nic_init_vector_data(priv);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
@@ -3563,6 +3585,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ hns3_store_coal(priv);
|
|
|
|
+
|
|
ret = hns3_uninit_all_ring(priv);
|
|
ret = hns3_uninit_all_ring(priv);
|
|
if (ret)
|
|
if (ret)
|
|
netdev_err(netdev, "uninit ring error\n");
|
|
netdev_err(netdev, "uninit ring error\n");
|
|
@@ -3597,24 +3621,7 @@ static int hns3_reset_notify(struct hnae3_handle *handle,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static void hns3_restore_coal(struct hns3_nic_priv *priv,
|
|
|
|
- struct hns3_enet_coalesce *tx,
|
|
|
|
- struct hns3_enet_coalesce *rx)
|
|
|
|
-{
|
|
|
|
- u16 vector_num = priv->vector_num;
|
|
|
|
- int i;
|
|
|
|
-
|
|
|
|
- for (i = 0; i < vector_num; i++) {
|
|
|
|
- memcpy(&priv->tqp_vector[i].tx_group.coal, tx,
|
|
|
|
- sizeof(struct hns3_enet_coalesce));
|
|
|
|
- memcpy(&priv->tqp_vector[i].rx_group.coal, rx,
|
|
|
|
- sizeof(struct hns3_enet_coalesce));
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num,
|
|
|
|
- struct hns3_enet_coalesce *tx,
|
|
|
|
- struct hns3_enet_coalesce *rx)
|
|
|
|
|
|
+static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num)
|
|
{
|
|
{
|
|
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
|
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
|
@@ -3632,7 +3639,7 @@ static int hns3_modify_tqp_num(struct net_device *netdev, u16 new_tqp_num,
|
|
if (ret)
|
|
if (ret)
|
|
goto err_alloc_vector;
|
|
goto err_alloc_vector;
|
|
|
|
|
|
- hns3_restore_coal(priv, tx, rx);
|
|
|
|
|
|
+ hns3_restore_coal(priv);
|
|
|
|
|
|
ret = hns3_nic_init_vector_data(priv);
|
|
ret = hns3_nic_init_vector_data(priv);
|
|
if (ret)
|
|
if (ret)
|
|
@@ -3664,7 +3671,6 @@ int hns3_set_channels(struct net_device *netdev,
|
|
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
|
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
|
struct hnae3_knic_private_info *kinfo = &h->kinfo;
|
|
struct hnae3_knic_private_info *kinfo = &h->kinfo;
|
|
- struct hns3_enet_coalesce tx_coal, rx_coal;
|
|
|
|
bool if_running = netif_running(netdev);
|
|
bool if_running = netif_running(netdev);
|
|
u32 new_tqp_num = ch->combined_count;
|
|
u32 new_tqp_num = ch->combined_count;
|
|
u16 org_tqp_num;
|
|
u16 org_tqp_num;
|
|
@@ -3696,15 +3702,7 @@ int hns3_set_channels(struct net_device *netdev,
|
|
goto open_netdev;
|
|
goto open_netdev;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Changing the tqp num may also change the vector num,
|
|
|
|
- * ethtool only support setting and querying one coal
|
|
|
|
- * configuation for now, so save the vector 0' coal
|
|
|
|
- * configuation here in order to restore it.
|
|
|
|
- */
|
|
|
|
- memcpy(&tx_coal, &priv->tqp_vector[0].tx_group.coal,
|
|
|
|
- sizeof(struct hns3_enet_coalesce));
|
|
|
|
- memcpy(&rx_coal, &priv->tqp_vector[0].rx_group.coal,
|
|
|
|
- sizeof(struct hns3_enet_coalesce));
|
|
|
|
|
|
+ hns3_store_coal(priv);
|
|
|
|
|
|
hns3_nic_dealloc_vector_data(priv);
|
|
hns3_nic_dealloc_vector_data(priv);
|
|
|
|
|
|
@@ -3712,10 +3710,9 @@ int hns3_set_channels(struct net_device *netdev,
|
|
hns3_put_ring_config(priv);
|
|
hns3_put_ring_config(priv);
|
|
|
|
|
|
org_tqp_num = h->kinfo.num_tqps;
|
|
org_tqp_num = h->kinfo.num_tqps;
|
|
- ret = hns3_modify_tqp_num(netdev, new_tqp_num, &tx_coal, &rx_coal);
|
|
|
|
|
|
+ ret = hns3_modify_tqp_num(netdev, new_tqp_num);
|
|
if (ret) {
|
|
if (ret) {
|
|
- ret = hns3_modify_tqp_num(netdev, org_tqp_num,
|
|
|
|
- &tx_coal, &rx_coal);
|
|
|
|
|
|
+ ret = hns3_modify_tqp_num(netdev, org_tqp_num);
|
|
if (ret) {
|
|
if (ret) {
|
|
/* If revert to old tqp failed, fatal error occurred */
|
|
/* If revert to old tqp failed, fatal error occurred */
|
|
dev_err(&netdev->dev,
|
|
dev_err(&netdev->dev,
|