Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6d818e3 authored by Yunsheng Lin's avatar Yunsheng Lin Committed by David S. Miller
Browse files

net: hns3: Add vport alive state checking support



Currently there is no way for pf to know if a vf device is
alive or not, so PF does not know which vf to notify when
reset happens, or which vf's mtu is invalid when vf and pf
share the same hardware mtu setting.

This patch adds vport alive state checking support, in order
to support the above scenario.

Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e6d7d79d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_BIND_FUNC_QUEUE,	/* (VF -> PF) bind function and queue */
	HCLGE_MBX_GET_LINK_STATUS,	/* (VF -> PF) get link status */
	HCLGE_MBX_QUEUE_RESET,		/* (VF -> PF) reset queue */
	HCLGE_MBX_KEEP_ALIVE,		/* (VF -> PF) send keep alive cmd */
	HCLGE_MBX_SET_ALIVE,		/* (VF -> PF) set alive state */
};

/* below are per-VF mac-vlan subcodes */
+6 −0
Original line number Diff line number Diff line
@@ -210,6 +210,10 @@ struct hnae3_ae_dev {
 *   Enable the hardware
 * stop()
 *   Disable the hardware
 * start_client()
 *   Inform the hclge that client has been started
 * stop_client()
 *   Inform the hclge that client has been stopped
 * get_status()
 *   Get the carrier state of the back channel of the handle, 1 for ok, 0 for
 *   non-ok
@@ -319,6 +323,8 @@ struct hnae3_ae_ops {
				       struct hnae3_ae_dev *ae_dev);
	int (*start)(struct hnae3_handle *handle);
	void (*stop)(struct hnae3_handle *handle);
	int (*client_start)(struct hnae3_handle *handle);
	void (*client_stop)(struct hnae3_handle *handle);
	int (*get_status)(struct hnae3_handle *handle);
	void (*get_ksettings_an_result)(struct hnae3_handle *handle,
					u8 *auto_neg, u32 *speed, u8 *duplex);
+24 −0
Original line number Diff line number Diff line
@@ -3540,6 +3540,22 @@ static void hns3_nic_set_priv_ops(struct net_device *netdev)
		priv->ops.maybe_stop_tx = hns3_nic_maybe_stop_tx;
}

static int hns3_client_start(struct hnae3_handle *handle)
{
	if (!handle->ae_algo->ops->client_start)
		return 0;

	return handle->ae_algo->ops->client_start(handle);
}

static void hns3_client_stop(struct hnae3_handle *handle)
{
	if (!handle->ae_algo->ops->client_stop)
		return;

	handle->ae_algo->ops->client_stop(handle);
}

static int hns3_client_init(struct hnae3_handle *handle)
{
	struct pci_dev *pdev = handle->pdev;
@@ -3607,6 +3623,12 @@ static int hns3_client_init(struct hnae3_handle *handle)
		goto out_reg_netdev_fail;
	}

	ret = hns3_client_start(handle);
	if (ret) {
		dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret);
			goto out_reg_netdev_fail;
	}

	hns3_dcbnl_setup(handle);

	/* MTU range: (ETH_MIN_MTU(kernel default) - 9702) */
@@ -3635,6 +3657,8 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	int ret;

	hns3_client_stop(handle);

	hns3_remove_hw_addr(netdev);

	if (netdev->reg_state != NETREG_UNINITIALIZED)
+55 −0
Original line number Diff line number Diff line
@@ -2911,6 +2911,19 @@ static void hclge_mailbox_service_task(struct work_struct *work)
	clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state);
}

static void hclge_update_vport_alive(struct hclge_dev *hdev)
{
	int i;

	/* start from vport 1 for PF is always alive */
	for (i = 1; i < hdev->num_alloc_vport; i++) {
		struct hclge_vport *vport = &hdev->vport[i];

		if (time_after(jiffies, vport->last_active_jiffies + 8 * HZ))
			clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
	}
}

static void hclge_service_task(struct work_struct *work)
{
	struct hclge_dev *hdev =
@@ -2923,6 +2936,7 @@ static void hclge_service_task(struct work_struct *work)

	hclge_update_speed_duplex(hdev);
	hclge_update_link_status(hdev);
	hclge_update_vport_alive(hdev);
	hclge_service_complete(hdev);
}

@@ -5208,6 +5222,32 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
	hclge_update_link_status(hdev);
}

int hclge_vport_start(struct hclge_vport *vport)
{
	set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
	vport->last_active_jiffies = jiffies;
	return 0;
}

void hclge_vport_stop(struct hclge_vport *vport)
{
	clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
}

static int hclge_client_start(struct hnae3_handle *handle)
{
	struct hclge_vport *vport = hclge_get_vport(handle);

	return hclge_vport_start(vport);
}

static void hclge_client_stop(struct hnae3_handle *handle)
{
	struct hclge_vport *vport = hclge_get_vport(handle);

	hclge_vport_stop(vport);
}

static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
					 u16 cmdq_resp, u8  resp_code,
					 enum hclge_mac_vlan_tbl_opcode op)
@@ -7189,6 +7229,17 @@ static void hclge_stats_clear(struct hclge_dev *hdev)
	memset(&hdev->hw_stats, 0, sizeof(hdev->hw_stats));
}

static void hclge_reset_vport_state(struct hclge_dev *hdev)
{
	struct hclge_vport *vport = hdev->vport;
	int i;

	for (i = 0; i < hdev->num_alloc_vport; i++) {
		hclge_vport_start(vport);
		vport++;
	}
}

static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
{
	struct hclge_dev *hdev = ae_dev->priv;
@@ -7274,6 +7325,8 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
	if (hclge_enable_tm_hw_error(hdev, true))
		dev_err(&pdev->dev, "failed to enable TM hw error interrupts\n");

	hclge_reset_vport_state(hdev);

	dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n",
		 HCLGE_DRIVER_NAME);

@@ -7682,6 +7735,8 @@ static const struct hnae3_ae_ops hclge_ops = {
	.set_loopback = hclge_set_loopback,
	.start = hclge_ae_start,
	.stop = hclge_ae_stop,
	.client_start = hclge_client_start,
	.client_stop = hclge_client_stop,
	.get_status = hclge_get_status,
	.get_ksettings_an_result = hclge_get_ksettings_an_result,
	.update_speed_duplex_h = hclge_update_speed_duplex_h,
+10 −0
Original line number Diff line number Diff line
@@ -728,6 +728,11 @@ struct hclge_rss_tuple_cfg {
	u8 ipv6_fragment_en;
};

enum HCLGE_VPORT_STATE {
	HCLGE_VPORT_STATE_ALIVE,
	HCLGE_VPORT_STATE_MAX
};

struct hclge_vport {
	u16 alloc_tqps;	/* Allocated Tx/Rx queues */

@@ -753,6 +758,9 @@ struct hclge_vport {
	struct hclge_dev *back;  /* Back reference to associated dev */
	struct hnae3_handle nic;
	struct hnae3_handle roce;

	unsigned long state;
	unsigned long last_active_jiffies;
};

void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
@@ -800,4 +808,6 @@ int hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id);
int hclge_cfg_flowctrl(struct hclge_dev *hdev);
int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id);
int hclge_vport_start(struct hclge_vport *vport);
void hclge_vport_stop(struct hclge_vport *vport);
#endif
Loading