Commit 6d4c3981 authored by Salil Mehta's avatar Salil Mehta Committed by David S. Miller

net: hns3: Changes to make enet watchdog timeout func common for PF/VF

HNS3 drivers enet layer, used for the ring management and stack
interaction, is common to both VF and PF. PF already supports reset
functionality to handle the network stack watchdog timeout trigger
but the existing code is not generic enough to be used to support VF
reset as well.
This patch does following:
1. Makes the existing watchdog timeout handler in enet layer generic
   i.e. suitable for both VF and PF and
2. Introduces the new reset event handler for the VF code.
3. Changes existing reset event handler of PF code to initialize the
   reset level
Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a2e10a2
...@@ -118,6 +118,7 @@ enum hnae3_reset_notify_type { ...@@ -118,6 +118,7 @@ enum hnae3_reset_notify_type {
}; };
enum hnae3_reset_type { enum hnae3_reset_type {
HNAE3_VF_RESET,
HNAE3_FUNC_RESET, HNAE3_FUNC_RESET,
HNAE3_CORE_RESET, HNAE3_CORE_RESET,
HNAE3_GLOBAL_RESET, HNAE3_GLOBAL_RESET,
...@@ -400,8 +401,7 @@ struct hnae3_ae_ops { ...@@ -400,8 +401,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 +495,9 @@ struct hnae3_handle { ...@@ -495,6 +495,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;
......
...@@ -320,7 +320,7 @@ static int hns3_nic_net_open(struct net_device *netdev) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -532,8 +532,6 @@ struct hns3_nic_priv { ...@@ -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;
......
...@@ -2845,27 +2845,31 @@ static void hclge_reset(struct hclge_dev *hdev) ...@@ -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)
......
...@@ -832,6 +832,19 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) ...@@ -832,6 +832,19 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
2, true, NULL, 0); 2, true, NULL, 0);
} }
static void hclgevf_reset_event(struct hnae3_handle *handle)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
handle->reset_level = HNAE3_VF_RESET;
/* request VF reset here. Code added later */
handle->last_reset_time = jiffies;
}
static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) static u32 hclgevf_get_fw_version(struct hnae3_handle *handle)
{ {
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
...@@ -1526,6 +1539,7 @@ static const struct hnae3_ae_ops hclgevf_ops = { ...@@ -1526,6 +1539,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
.get_tc_size = hclgevf_get_tc_size, .get_tc_size = hclgevf_get_tc_size,
.get_fw_version = hclgevf_get_fw_version, .get_fw_version = hclgevf_get_fw_version,
.set_vlan_filter = hclgevf_set_vlan_filter, .set_vlan_filter = hclgevf_set_vlan_filter,
.reset_event = hclgevf_reset_event,
.get_channels = hclgevf_get_channels, .get_channels = hclgevf_get_channels,
.get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info, .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info,
.get_status = hclgevf_get_status, .get_status = hclgevf_get_status,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment