Commit 424a4f52 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-fixes'



Guangbin Huang says:

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

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

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 440ffcdd 630a6738
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+8 −8
Original line number Diff line number Diff line
@@ -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 },
+24 −9
Original line number Diff line number Diff line
@@ -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;
+14 −16
Original line number Diff line number Diff line
@@ -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;
}
+36 −29
Original line number Diff line number Diff line
@@ -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;
Loading