hinic: add set_channels ethtool_ops support
authorLuo bin <luobin9@huawei.com>
Tue, 2 Jun 2020 00:40:32 +0000 (08:40 +0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 2 Jun 2020 22:10:24 +0000 (15:10 -0700)
add support to change TX/RX queue number with "ethtool -L combined".

V5 -> V6: remove check for carrier in hinic_xmit_frame
V4 -> V5: change time zone in patch header
V3 -> V4: update date in patch header
V2 -> V3: remove check for zero channels->combined_count
V1 -> V2: update commit message("ethtool -L" to "ethtool -L combined")
V0 -> V1: remove check for channels->tx_count/rx_count/other_count

Signed-off-by: Luo bin <luobin9@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/huawei/hinic/hinic_ethtool.c
drivers/net/ethernet/huawei/hinic/hinic_main.c

index ace18d2580490bc29b32c3cbe60a394a6ace8642..efb02e03e7dad4dbbb2b92435ec6355f620a840f 100644 (file)
@@ -619,14 +619,37 @@ static void hinic_get_channels(struct net_device *netdev,
        struct hinic_dev *nic_dev = netdev_priv(netdev);
        struct hinic_hwdev *hwdev = nic_dev->hwdev;
 
-       channels->max_rx = hwdev->nic_cap.max_qps;
-       channels->max_tx = hwdev->nic_cap.max_qps;
-       channels->max_other = 0;
-       channels->max_combined = 0;
-       channels->rx_count = hinic_hwdev_num_qps(hwdev);
-       channels->tx_count = hinic_hwdev_num_qps(hwdev);
-       channels->other_count = 0;
-       channels->combined_count = 0;
+       channels->max_combined = nic_dev->max_qps;
+       channels->combined_count = hinic_hwdev_num_qps(hwdev);
+}
+
+static int hinic_set_channels(struct net_device *netdev,
+                             struct ethtool_channels *channels)
+{
+       struct hinic_dev *nic_dev = netdev_priv(netdev);
+       unsigned int count = channels->combined_count;
+       int err;
+
+       netif_info(nic_dev, drv, netdev, "Set max combined queue number from %d to %d\n",
+                  hinic_hwdev_num_qps(nic_dev->hwdev), count);
+
+       if (netif_running(netdev)) {
+               netif_info(nic_dev, drv, netdev, "Restarting netdev\n");
+               hinic_close(netdev);
+
+               nic_dev->hwdev->nic_cap.num_qps = count;
+
+               err = hinic_open(netdev);
+               if (err) {
+                       netif_err(nic_dev, drv, netdev,
+                                 "Failed to open netdev\n");
+                       return -EFAULT;
+               }
+       } else {
+               nic_dev->hwdev->nic_cap.num_qps = count;
+       }
+
+       return 0;
 }
 
 static int hinic_get_rss_hash_opts(struct hinic_dev *nic_dev,
@@ -1219,6 +1242,7 @@ static const struct ethtool_ops hinic_ethtool_ops = {
        .get_ringparam = hinic_get_ringparam,
        .set_ringparam = hinic_set_ringparam,
        .get_channels = hinic_get_channels,
+       .set_channels = hinic_set_channels,
        .get_rxnfc = hinic_get_rxnfc,
        .set_rxnfc = hinic_set_rxnfc,
        .get_rxfh_key_size = hinic_get_rxfh_key_size,
index c8ab129a7ae80ab19d985448cefdee1d4e1a1e63..e9e6f4c9309a1b8f41fff1672cea94685f501533 100644 (file)
@@ -326,7 +326,6 @@ static void hinic_enable_rss(struct hinic_dev *nic_dev)
        int i, node, err = 0;
        u16 num_cpus = 0;
 
-       nic_dev->max_qps = hinic_hwdev_max_num_qps(hwdev);
        if (nic_dev->max_qps <= 1) {
                nic_dev->flags &= ~HINIC_RSS_ENABLE;
                nic_dev->rss_limit = nic_dev->max_qps;
@@ -1031,6 +1030,7 @@ static int nic_dev_init(struct pci_dev *pdev)
        nic_dev->rq_depth = HINIC_RQ_DEPTH;
        nic_dev->sriov_info.hwdev = hwdev;
        nic_dev->sriov_info.pdev = pdev;
+       nic_dev->max_qps = num_qps;
 
        sema_init(&nic_dev->mgmt_lock, 1);