Merge branch 'hns3-fixes'
authorDavid S. Miller <davem@davemloft.net>
Wed, 27 Oct 2021 13:47:34 +0000 (14:47 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 27 Oct 2021 13:47:34 +0000 (14:47 +0100)
Guangbin Huang says:

====================
net: hns3: add some fixes for -net

This series adds some fixes for the HNS3 ethernet driver.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h

index d701451..da3a593 100644 (file)
@@ -568,6 +568,7 @@ struct hnae3_ae_ops {
                               u32 *auto_neg, u32 *rx_en, u32 *tx_en);
        int (*set_pauseparam)(struct hnae3_handle *handle,
                              u32 auto_neg, u32 rx_en, u32 tx_en);
+       int (*restore_pauseparam)(struct hnae3_handle *handle);
 
        int (*set_autoneg)(struct hnae3_handle *handle, bool enable);
        int (*get_autoneg)(struct hnae3_handle *handle);
index 2b66c59..e54f962 100644 (file)
@@ -137,7 +137,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
                .name = "uc",
                .cmd = HNAE3_DBG_CMD_MAC_UC,
                .dentry = HNS3_DBG_DENTRY_MAC,
-               .buf_len = HNS3_DBG_READ_LEN,
+               .buf_len = HNS3_DBG_READ_LEN_128KB,
                .init = hns3_dbg_common_file_init,
        },
        {
@@ -256,7 +256,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
                .name = "tqp",
                .cmd = HNAE3_DBG_CMD_REG_TQP,
                .dentry = HNS3_DBG_DENTRY_REG,
-               .buf_len = HNS3_DBG_READ_LEN,
+               .buf_len = HNS3_DBG_READ_LEN_128KB,
                .init = hns3_dbg_common_file_init,
        },
        {
@@ -298,7 +298,7 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
                .name = "fd_tcam",
                .cmd = HNAE3_DBG_CMD_FD_TCAM,
                .dentry = HNS3_DBG_DENTRY_FD,
-               .buf_len = HNS3_DBG_READ_LEN,
+               .buf_len = HNS3_DBG_READ_LEN_1MB,
                .init = hns3_dbg_common_file_init,
        },
        {
@@ -462,7 +462,7 @@ static const struct hns3_dbg_item rx_queue_info_items[] = {
        { "TAIL", 2 },
        { "HEAD", 2 },
        { "FBDNUM", 2 },
-       { "PKTNUM", 2 },
+       { "PKTNUM", 5 },
        { "COPYBREAK", 2 },
        { "RING_EN", 2 },
        { "RX_RING_EN", 2 },
@@ -565,7 +565,7 @@ static const struct hns3_dbg_item tx_queue_info_items[] = {
        { "HEAD", 2 },
        { "FBDNUM", 2 },
        { "OFFSET", 2 },
-       { "PKTNUM", 2 },
+       { "PKTNUM", 5 },
        { "RING_EN", 2 },
        { "TX_RING_EN", 2 },
        { "BASE_ADDR", 10 },
@@ -790,13 +790,13 @@ static int hns3_dbg_rx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
 }
 
 static const struct hns3_dbg_item tx_bd_info_items[] = {
-       { "BD_IDX", 5 },
-       { "ADDRESS", 2 },
+       { "BD_IDX", 2 },
+       { "ADDRESS", 13 },
        { "VLAN_TAG", 2 },
        { "SIZE", 2 },
        { "T_CS_VLAN_TSO", 2 },
        { "OT_VLAN_TAG", 3 },
-       { "TV", 2 },
+       { "TV", 5 },
        { "OLT_VLAN_LEN", 2 },
        { "PAYLEN_OL4CS", 2 },
        { "BD_FE_SC_VLD", 2 },
index 5ebd96f..7d92dd2 100644 (file)
@@ -824,6 +824,26 @@ static int hns3_check_ksettings_param(const struct net_device *netdev,
        return 0;
 }
 
+static int hns3_set_phy_link_ksettings(struct net_device *netdev,
+                                      const struct ethtool_link_ksettings *cmd)
+{
+       struct hnae3_handle *handle = hns3_get_handle(netdev);
+       const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
+       int ret;
+
+       if (cmd->base.speed == SPEED_1000 &&
+           cmd->base.autoneg == AUTONEG_DISABLE)
+               return -EINVAL;
+
+       if (cmd->base.autoneg == AUTONEG_DISABLE && ops->restore_pauseparam) {
+               ret = ops->restore_pauseparam(handle);
+               if (ret)
+                       return ret;
+       }
+
+       return phy_ethtool_ksettings_set(netdev->phydev, cmd);
+}
+
 static int hns3_set_link_ksettings(struct net_device *netdev,
                                   const struct ethtool_link_ksettings *cmd)
 {
@@ -842,16 +862,11 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
                  cmd->base.autoneg, cmd->base.speed, cmd->base.duplex);
 
        /* Only support ksettings_set for netdev with phy attached for now */
-       if (netdev->phydev) {
-               if (cmd->base.speed == SPEED_1000 &&
-                   cmd->base.autoneg == AUTONEG_DISABLE)
-                       return -EINVAL;
-
-               return phy_ethtool_ksettings_set(netdev->phydev, cmd);
-       } else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
-                  ops->set_phy_link_ksettings) {
+       if (netdev->phydev)
+               return hns3_set_phy_link_ksettings(netdev, cmd);
+       else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
+                ops->set_phy_link_ksettings)
                return ops->set_phy_link_ksettings(handle, cmd);
-       }
 
        if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
                return -EOPNOTSUPP;
index 32f62cd..9cda8b3 100644 (file)
@@ -391,7 +391,7 @@ static int hclge_dbg_dump_mac(struct hclge_dev *hdev, char *buf, int len)
 static int hclge_dbg_dump_dcb_qset(struct hclge_dev *hdev, char *buf, int len,
                                   int *pos)
 {
-       struct hclge_dbg_bitmap_cmd *bitmap;
+       struct hclge_dbg_bitmap_cmd req;
        struct hclge_desc desc;
        u16 qset_id, qset_num;
        int ret;
@@ -408,12 +408,12 @@ static int hclge_dbg_dump_dcb_qset(struct hclge_dev *hdev, char *buf, int len,
                if (ret)
                        return ret;
 
-               bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
+               req.bitmap = (u8)le32_to_cpu(desc.data[1]);
 
                *pos += scnprintf(buf + *pos, len - *pos,
                                  "%04u           %#x            %#x             %#x               %#x\n",
-                                 qset_id, bitmap->bit0, bitmap->bit1,
-                                 bitmap->bit2, bitmap->bit3);
+                                 qset_id, req.bit0, req.bit1, req.bit2,
+                                 req.bit3);
        }
 
        return 0;
@@ -422,7 +422,7 @@ static int hclge_dbg_dump_dcb_qset(struct hclge_dev *hdev, char *buf, int len,
 static int hclge_dbg_dump_dcb_pri(struct hclge_dev *hdev, char *buf, int len,
                                  int *pos)
 {
-       struct hclge_dbg_bitmap_cmd *bitmap;
+       struct hclge_dbg_bitmap_cmd req;
        struct hclge_desc desc;
        u8 pri_id, pri_num;
        int ret;
@@ -439,12 +439,11 @@ static int hclge_dbg_dump_dcb_pri(struct hclge_dev *hdev, char *buf, int len,
                if (ret)
                        return ret;
 
-               bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
+               req.bitmap = (u8)le32_to_cpu(desc.data[1]);
 
                *pos += scnprintf(buf + *pos, len - *pos,
                                  "%03u       %#x           %#x                %#x\n",
-                                 pri_id, bitmap->bit0, bitmap->bit1,
-                                 bitmap->bit2);
+                                 pri_id, req.bit0, req.bit1, req.bit2);
        }
 
        return 0;
@@ -453,7 +452,7 @@ static int hclge_dbg_dump_dcb_pri(struct hclge_dev *hdev, char *buf, int len,
 static int hclge_dbg_dump_dcb_pg(struct hclge_dev *hdev, char *buf, int len,
                                 int *pos)
 {
-       struct hclge_dbg_bitmap_cmd *bitmap;
+       struct hclge_dbg_bitmap_cmd req;
        struct hclge_desc desc;
        u8 pg_id;
        int ret;
@@ -466,12 +465,11 @@ static int hclge_dbg_dump_dcb_pg(struct hclge_dev *hdev, char *buf, int len,
                if (ret)
                        return ret;
 
-               bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
+               req.bitmap = (u8)le32_to_cpu(desc.data[1]);
 
                *pos += scnprintf(buf + *pos, len - *pos,
                                  "%03u      %#x           %#x               %#x\n",
-                                 pg_id, bitmap->bit0, bitmap->bit1,
-                                 bitmap->bit2);
+                                 pg_id, req.bit0, req.bit1, req.bit2);
        }
 
        return 0;
@@ -511,7 +509,7 @@ static int hclge_dbg_dump_dcb_queue(struct hclge_dev *hdev, char *buf, int len,
 static int hclge_dbg_dump_dcb_port(struct hclge_dev *hdev, char *buf, int len,
                                   int *pos)
 {
-       struct hclge_dbg_bitmap_cmd *bitmap;
+       struct hclge_dbg_bitmap_cmd req;
        struct hclge_desc desc;
        u8 port_id = 0;
        int ret;
@@ -521,12 +519,12 @@ static int hclge_dbg_dump_dcb_port(struct hclge_dev *hdev, char *buf, int len,
        if (ret)
                return ret;
 
-       bitmap = (struct hclge_dbg_bitmap_cmd *)&desc.data[1];
+       req.bitmap = (u8)le32_to_cpu(desc.data[1]);
 
        *pos += scnprintf(buf + *pos, len - *pos, "port_mask: %#x\n",
-                        bitmap->bit0);
+                        req.bit0);
        *pos += scnprintf(buf + *pos, len - *pos, "port_shaping_pass: %#x\n",
-                        bitmap->bit1);
+                        req.bit1);
 
        return 0;
 }
index dcd40cc..269e579 100644 (file)
@@ -2847,33 +2847,29 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
 {
        if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
            !test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state))
-               mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
-                                   hclge_wq, &hdev->service_task, 0);
+               mod_delayed_work(hclge_wq, &hdev->service_task, 0);
 }
 
 static void hclge_reset_task_schedule(struct hclge_dev *hdev)
 {
        if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
+           test_bit(HCLGE_STATE_SERVICE_INITED, &hdev->state) &&
            !test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
-               mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
-                                   hclge_wq, &hdev->service_task, 0);
+               mod_delayed_work(hclge_wq, &hdev->service_task, 0);
 }
 
 static void hclge_errhand_task_schedule(struct hclge_dev *hdev)
 {
        if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
            !test_and_set_bit(HCLGE_STATE_ERR_SERVICE_SCHED, &hdev->state))
-               mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
-                                   hclge_wq, &hdev->service_task, 0);
+               mod_delayed_work(hclge_wq, &hdev->service_task, 0);
 }
 
 void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time)
 {
        if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
            !test_bit(HCLGE_STATE_RST_FAIL, &hdev->state))
-               mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
-                                   hclge_wq, &hdev->service_task,
-                                   delay_time);
+               mod_delayed_work(hclge_wq, &hdev->service_task, delay_time);
 }
 
 static int hclge_get_mac_link_status(struct hclge_dev *hdev, int *link_status)
@@ -3491,33 +3487,14 @@ static void hclge_get_misc_vector(struct hclge_dev *hdev)
        hdev->num_msi_used += 1;
 }
 
-static void hclge_irq_affinity_notify(struct irq_affinity_notify *notify,
-                                     const cpumask_t *mask)
-{
-       struct hclge_dev *hdev = container_of(notify, struct hclge_dev,
-                                             affinity_notify);
-
-       cpumask_copy(&hdev->affinity_mask, mask);
-}
-
-static void hclge_irq_affinity_release(struct kref *ref)
-{
-}
-
 static void hclge_misc_affinity_setup(struct hclge_dev *hdev)
 {
        irq_set_affinity_hint(hdev->misc_vector.vector_irq,
                              &hdev->affinity_mask);
-
-       hdev->affinity_notify.notify = hclge_irq_affinity_notify;
-       hdev->affinity_notify.release = hclge_irq_affinity_release;
-       irq_set_affinity_notifier(hdev->misc_vector.vector_irq,
-                                 &hdev->affinity_notify);
 }
 
 static void hclge_misc_affinity_teardown(struct hclge_dev *hdev)
 {
-       irq_set_affinity_notifier(hdev->misc_vector.vector_irq, NULL);
        irq_set_affinity_hint(hdev->misc_vector.vector_irq, NULL);
 }
 
@@ -11021,6 +10998,35 @@ static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg,
        return -EOPNOTSUPP;
 }
 
+static int hclge_restore_pauseparam(struct hnae3_handle *handle)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+       u32 auto_neg, rx_pause, tx_pause;
+       int ret;
+
+       hclge_get_pauseparam(handle, &auto_neg, &rx_pause, &tx_pause);
+       /* when autoneg is disabled, the pause setting of phy has no effect
+        * unless the link goes down.
+        */
+       ret = phy_suspend(hdev->hw.mac.phydev);
+       if (ret)
+               return ret;
+
+       phy_set_asym_pause(hdev->hw.mac.phydev, rx_pause, tx_pause);
+
+       ret = phy_resume(hdev->hw.mac.phydev);
+       if (ret)
+               return ret;
+
+       ret = hclge_mac_pause_setup_hw(hdev);
+       if (ret)
+               dev_err(&hdev->pdev->dev,
+                       "restore pauseparam error, ret = %d.\n", ret);
+
+       return ret;
+}
+
 static void hclge_get_ksettings_an_result(struct hnae3_handle *handle,
                                          u8 *auto_neg, u32 *speed, u8 *duplex)
 {
@@ -12984,6 +12990,7 @@ static const struct hnae3_ae_ops hclge_ops = {
        .halt_autoneg = hclge_halt_autoneg,
        .get_pauseparam = hclge_get_pauseparam,
        .set_pauseparam = hclge_set_pauseparam,
+       .restore_pauseparam = hclge_restore_pauseparam,
        .set_mtu = hclge_set_mtu,
        .reset_queue = hclge_reset_tqp,
        .get_stats = hclge_get_stats,
@@ -13052,7 +13059,7 @@ static int hclge_init(void)
 {
        pr_info("%s is initializing\n", HCLGE_NAME);
 
-       hclge_wq = alloc_workqueue("%s", 0, 0, HCLGE_NAME);
+       hclge_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, HCLGE_NAME);
        if (!hclge_wq) {
                pr_err("%s: failed to create workqueue\n", HCLGE_NAME);
                return -ENOMEM;
index de6afbc..69cd8f8 100644 (file)
@@ -944,7 +944,6 @@ struct hclge_dev {
 
        /* affinity mask and notify for misc interrupt */
        cpumask_t affinity_mask;
-       struct irq_affinity_notify affinity_notify;
        struct hclge_ptp *ptp;
        struct devlink *devlink;
 };
index 95074e9..124791e 100644 (file)
@@ -1435,7 +1435,7 @@ static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc)
        return 0;
 }
 
-static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
+int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
 {
        bool tx_en, rx_en;
 
index 2ee9b79..4b2c3a7 100644 (file)
@@ -244,6 +244,7 @@ int hclge_tm_get_pri_weight(struct hclge_dev *hdev, u8 pri_id, u8 *weight);
 int hclge_tm_get_pri_shaper(struct hclge_dev *hdev, u8 pri_id,
                            enum hclge_opcode_type cmd,
                            struct hclge_tm_shaper_para *para);
+int hclge_mac_pause_setup_hw(struct hclge_dev *hdev);
 int hclge_tm_get_q_to_qs_map(struct hclge_dev *hdev, u16 q_id, u16 *qset_id);
 int hclge_tm_get_q_to_tc(struct hclge_dev *hdev, u16 q_id, u8 *tc_id);
 int hclge_tm_get_pg_to_pri_map(struct hclge_dev *hdev, u8 pg_id,
index bef6b98..cf00ad7 100644 (file)
@@ -2232,6 +2232,7 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev)
 void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev)
 {
        if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) &&
+           test_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state) &&
            !test_and_set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED,
                              &hdev->state))
                mod_delayed_work(hclgevf_wq, &hdev->service_task, 0);
@@ -3449,6 +3450,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
 
        hclgevf_init_rxd_adv_layout(hdev);
 
+       set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
+
        hdev->last_reset_time = jiffies;
        dev_info(&hdev->pdev->dev, "finished initializing %s driver\n",
                 HCLGEVF_DRIVER_NAME);
@@ -3899,7 +3902,7 @@ static int hclgevf_init(void)
 {
        pr_info("%s is initializing\n", HCLGEVF_NAME);
 
-       hclgevf_wq = alloc_workqueue("%s", 0, 0, HCLGEVF_NAME);
+       hclgevf_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, HCLGEVF_NAME);
        if (!hclgevf_wq) {
                pr_err("%s: failed to create workqueue\n", HCLGEVF_NAME);
                return -ENOMEM;
index 883130a..28288d7 100644 (file)
@@ -146,6 +146,7 @@ enum hclgevf_states {
        HCLGEVF_STATE_REMOVING,
        HCLGEVF_STATE_NIC_REGISTERED,
        HCLGEVF_STATE_ROCE_REGISTERED,
+       HCLGEVF_STATE_SERVICE_INITED,
        /* task states */
        HCLGEVF_STATE_RST_SERVICE_SCHED,
        HCLGEVF_STATE_RST_HANDLING,