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

Commit 6686c459 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-VF-reset'

Salil Mehta says:

====================
Add support of VF Reset to HNS3 VF driver

This patch-set adds the support of VF reset to the existing VF driver.
VF Reset can be triggered due to TX watchdog firing  as a result of TX
data-path not working. VF reset could also be a result of some internal
configuration changes if that requires reset, or as a result of the
PF/Core/Global/IMP(Integrated Management Processor) reset happened in
the PF.

Summary of Patches:
* Watchdog timer trigger chnages are present in Patch 1.
* Reset Service Task and related Event handling is present in Patches {2,3}
* Changes to send reset request to PF, reset stack and re-initialization
  of the hclge device is present in Patches {4,5,6}
* Changes related to ARQ (Asynchronous Receive Queue) and its event handling
  are present in Patches {7,8}
* Changes required in PF to handle the VF Reset request and actually perform
  hardware VF reset is there in Patch 9.

NOTE: This patch depends upon "[PATCH net-next 00/11] fix some bugs for HNS3 driver"
	Link: https://lkml.org/lkml/2018/3/21/72


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1a2e10a2 2bfbd35d
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -11,6 +11,7 @@


enum HCLGE_MBX_OPCODE {
enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_RESET = 0x01,		/* (VF -> PF) assert reset */
	HCLGE_MBX_RESET = 0x01,		/* (VF -> PF) assert reset */
	HCLGE_MBX_ASSERTING_RESET,	/* (PF -> VF) PF is asserting reset*/
	HCLGE_MBX_SET_UNICAST,		/* (VF -> PF) set UC addr */
	HCLGE_MBX_SET_UNICAST,		/* (VF -> PF) set UC addr */
	HCLGE_MBX_SET_MULTICAST,	/* (VF -> PF) set MC addr */
	HCLGE_MBX_SET_MULTICAST,	/* (VF -> PF) set MC addr */
	HCLGE_MBX_SET_VLAN,		/* (VF -> PF) set VLAN */
	HCLGE_MBX_SET_VLAN,		/* (VF -> PF) set VLAN */
@@ -85,6 +86,21 @@ struct hclge_mbx_pf_to_vf_cmd {
	u16 msg[8];
	u16 msg[8];
};
};


/* used by VF to store the received Async responses from PF */
struct hclgevf_mbx_arq_ring {
#define HCLGE_MBX_MAX_ARQ_MSG_SIZE	8
#define HCLGE_MBX_MAX_ARQ_MSG_NUM	1024
	struct hclgevf_dev *hdev;
	u32 head;
	u32 tail;
	u32 count;
	u16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE];
};

#define hclge_mbx_ring_ptr_move_crq(crq) \
#define hclge_mbx_ring_ptr_move_crq(crq) \
	(crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num)
	(crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num)
#define hclge_mbx_tail_ptr_move_arq(arq) \
	(arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE)
#define hclge_mbx_head_ptr_move_arq(arq) \
		(arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE)
#endif
#endif
+6 −2
Original line number Original line Diff line number Diff line
@@ -118,6 +118,8 @@ enum hnae3_reset_notify_type {
};
};


enum hnae3_reset_type {
enum hnae3_reset_type {
	HNAE3_VF_RESET,
	HNAE3_VF_FULL_RESET,
	HNAE3_FUNC_RESET,
	HNAE3_FUNC_RESET,
	HNAE3_CORE_RESET,
	HNAE3_CORE_RESET,
	HNAE3_GLOBAL_RESET,
	HNAE3_GLOBAL_RESET,
@@ -400,8 +402,7 @@ struct hnae3_ae_ops {
	int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid,
	int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid,
				  u16 vlan, u8 qos, __be16 proto);
				  u16 vlan, u8 qos, __be16 proto);
	int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable);
	int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable);
	void (*reset_event)(struct hnae3_handle *handle,
	void (*reset_event)(struct hnae3_handle *handle);
			    enum hnae3_reset_type reset);
	void (*get_channels)(struct hnae3_handle *handle,
	void (*get_channels)(struct hnae3_handle *handle,
			     struct ethtool_channels *ch);
			     struct ethtool_channels *ch);
	void (*get_tqps_and_rss_info)(struct hnae3_handle *h,
	void (*get_tqps_and_rss_info)(struct hnae3_handle *h,
@@ -495,6 +496,9 @@ struct hnae3_handle {
	struct hnae3_ae_algo *ae_algo;  /* the class who provides this handle */
	struct hnae3_ae_algo *ae_algo;  /* the class who provides this handle */
	u64 flags; /* Indicate the capabilities for this handle*/
	u64 flags; /* Indicate the capabilities for this handle*/


	unsigned long last_reset_time;
	enum hnae3_reset_type reset_level;

	union {
	union {
		struct net_device *netdev; /* first member */
		struct net_device *netdev; /* first member */
		struct hnae3_knic_private_info kinfo;
		struct hnae3_knic_private_info kinfo;
+7 −23
Original line number Original line Diff line number Diff line
@@ -320,7 +320,7 @@ static int hns3_nic_net_open(struct net_device *netdev)
		return ret;
		return ret;
	}
	}


	priv->last_reset_time = jiffies;
	priv->ae_handle->last_reset_time = jiffies;
	return 0;
	return 0;
}
}


@@ -1543,7 +1543,6 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev)
static void hns3_nic_net_timeout(struct net_device *ndev)
static void hns3_nic_net_timeout(struct net_device *ndev)
{
{
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	struct hns3_nic_priv *priv = netdev_priv(ndev);
	unsigned long last_reset_time = priv->last_reset_time;
	struct hnae3_handle *h = priv->ae_handle;
	struct hnae3_handle *h = priv->ae_handle;


	if (!hns3_get_tx_timeo_queue_info(ndev))
	if (!hns3_get_tx_timeo_queue_info(ndev))
@@ -1551,24 +1550,12 @@ static void hns3_nic_net_timeout(struct net_device *ndev)


	priv->tx_timeout_count++;
	priv->tx_timeout_count++;


	/* This timeout is far away enough from last timeout,
	if (time_before(jiffies, (h->last_reset_time + ndev->watchdog_timeo)))
	 * if timeout again,set the reset type to PF reset
	 */
	if (time_after(jiffies, (last_reset_time + 20 * HZ)))
		priv->reset_level = HNAE3_FUNC_RESET;

	/* Don't do any new action before the next timeout */
	else if (time_before(jiffies, (last_reset_time + ndev->watchdog_timeo)))
		return;
		return;


	priv->last_reset_time = jiffies;
	/* request the reset */

	if (h->ae_algo->ops->reset_event)
	if (h->ae_algo->ops->reset_event)
		h->ae_algo->ops->reset_event(h, priv->reset_level);
		h->ae_algo->ops->reset_event(h);

	priv->reset_level++;
	if (priv->reset_level > HNAE3_GLOBAL_RESET)
		priv->reset_level = HNAE3_GLOBAL_RESET;
}
}


static const struct net_device_ops hns3_nic_netdev_ops = {
static const struct net_device_ops hns3_nic_netdev_ops = {
@@ -3122,8 +3109,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
	priv->dev = &pdev->dev;
	priv->dev = &pdev->dev;
	priv->netdev = netdev;
	priv->netdev = netdev;
	priv->ae_handle = handle;
	priv->ae_handle = handle;
	priv->last_reset_time = jiffies;
	priv->ae_handle->reset_level = HNAE3_NONE_RESET;
	priv->reset_level = HNAE3_FUNC_RESET;
	priv->ae_handle->last_reset_time = jiffies;
	priv->tx_timeout_count = 0;
	priv->tx_timeout_count = 0;


	handle->kinfo.netdev = netdev;
	handle->kinfo.netdev = netdev;
@@ -3355,7 +3342,6 @@ static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
{
{
	struct hnae3_knic_private_info *kinfo = &handle->kinfo;
	struct hnae3_knic_private_info *kinfo = &handle->kinfo;
	struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev);
	int ret = 0;
	int ret = 0;


	if (netif_running(kinfo->netdev)) {
	if (netif_running(kinfo->netdev)) {
@@ -3365,8 +3351,7 @@ static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
				   "hns net up fail, ret=%d!\n", ret);
				   "hns net up fail, ret=%d!\n", ret);
			return ret;
			return ret;
		}
		}

		handle->last_reset_time = jiffies;
		priv->last_reset_time = jiffies;
	}
	}


	return ret;
	return ret;
@@ -3378,7 +3363,6 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	int ret;
	int ret;


	priv->reset_level = 1;
	hns3_init_mac_addr(netdev);
	hns3_init_mac_addr(netdev);
	hns3_nic_set_rx_mode(netdev);
	hns3_nic_set_rx_mode(netdev);
	hns3_recover_hw_addr(netdev);
	hns3_recover_hw_addr(netdev);
+0 −2
Original line number Original line Diff line number Diff line
@@ -532,8 +532,6 @@ struct hns3_nic_priv {
	/* The most recently read link state */
	/* The most recently read link state */
	int link;
	int link;
	u64 tx_timeout_count;
	u64 tx_timeout_count;
	enum hnae3_reset_type reset_level;
	unsigned long last_reset_time;


	unsigned long state;
	unsigned long state;


+21 −17
Original line number Original line Diff line number Diff line
@@ -2749,7 +2749,7 @@ static int hclge_reset_wait(struct hclge_dev *hdev)
	return 0;
	return 0;
}
}


static int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id)
int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id)
{
{
	struct hclge_desc desc;
	struct hclge_desc desc;
	struct hclge_reset_cmd *req = (struct hclge_reset_cmd *)desc.data;
	struct hclge_reset_cmd *req = (struct hclge_reset_cmd *)desc.data;
@@ -2845,27 +2845,31 @@ static void hclge_reset(struct hclge_dev *hdev)
	hclge_notify_client(hdev, HNAE3_UP_CLIENT);
	hclge_notify_client(hdev, HNAE3_UP_CLIENT);
}
}


static void hclge_reset_event(struct hnae3_handle *handle,
static void hclge_reset_event(struct hnae3_handle *handle)
			      enum hnae3_reset_type reset)
{
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	struct hclge_dev *hdev = vport->back;


	dev_info(&hdev->pdev->dev,
	/* check if this is a new reset request and we are not here just because
		 "Receive reset event , reset_type is %d", reset);
	 * last reset attempt did not succeed and watchdog hit us again. We will
	 * know this if last reset request did not occur very recently (watchdog
	 * timer = 5*HZ, let us check after sufficiently large time, say 4*5*Hz)
	 * In case of new request we reset the "reset level" to PF reset.
	 */
	if (time_after(jiffies, (handle->last_reset_time + 4 * 5 * HZ)))
		handle->reset_level = HNAE3_FUNC_RESET;

	dev_info(&hdev->pdev->dev, "received reset event , reset type is %d",
		 handle->reset_level);


	switch (reset) {
	case HNAE3_FUNC_RESET:
	case HNAE3_CORE_RESET:
	case HNAE3_GLOBAL_RESET:
	/* request reset & schedule reset task */
	/* request reset & schedule reset task */
		set_bit(reset, &hdev->reset_request);
	set_bit(handle->reset_level, &hdev->reset_request);
	hclge_reset_task_schedule(hdev);
	hclge_reset_task_schedule(hdev);
		break;

	default:
	if (handle->reset_level < HNAE3_GLOBAL_RESET)
		dev_warn(&hdev->pdev->dev, "Unsupported reset event:%d", reset);
		handle->reset_level++;
		break;

	}
	handle->last_reset_time = jiffies;
}
}


static void hclge_reset_subtask(struct hclge_dev *hdev)
static void hclge_reset_subtask(struct hclge_dev *hdev)
Loading