Skip to content

Commit

Permalink
net: hns3: add support for triggering reset by ethtool
Browse files Browse the repository at this point in the history
Currently, four reset types are supported for the HNS3 ethernet
driver: IMP reset, global reset, function reset, and FLR. Only
FLR can now be triggered by the user. To restore the device when
an exception occurs, add support for triggering reset by ethtool.

Run the "ethtool --reset DEVNAME mgmt | all | dedicated" to
trigger the IMP | global | function reset manually.

In addition, VF can only trigger function reset.

Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Link: https://lore.kernel.org/r/1628602128-15640-1-git-send-email-huangguangbin2@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Yufeng Mo authored and Jakub Kicinski committed Aug 11, 2021
1 parent 6e98893 commit ddccc5e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,11 @@ struct hns3_hw_error_info {
const char *msg;
};

struct hns3_reset_type_map {
enum ethtool_reset_flags rst_flags;
enum hnae3_reset_type rst_type;
};

static inline int ring_space(struct hns3_enet_ring *ring)
{
/* This smp_load_acquire() pairs with smp_store_release() in
Expand Down
56 changes: 56 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,60 @@ static int hns3_get_rxnfc(struct net_device *netdev,
}
}

static const struct hns3_reset_type_map hns3_reset_type[] = {
{ETH_RESET_MGMT, HNAE3_IMP_RESET},
{ETH_RESET_ALL, HNAE3_GLOBAL_RESET},
{ETH_RESET_DEDICATED, HNAE3_FUNC_RESET},
};

static const struct hns3_reset_type_map hns3vf_reset_type[] = {
{ETH_RESET_DEDICATED, HNAE3_VF_FUNC_RESET},
};

static int hns3_set_reset(struct net_device *netdev, u32 *flags)
{
enum hnae3_reset_type rst_type = HNAE3_NONE_RESET;
struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
const struct hnae3_ae_ops *ops = h->ae_algo->ops;
const struct hns3_reset_type_map *rst_type_map;
u32 i, size;

if (ops->ae_dev_resetting && ops->ae_dev_resetting(h))
return -EBUSY;

if (!ops->set_default_reset_request || !ops->reset_event)
return -EOPNOTSUPP;

if (h->flags & HNAE3_SUPPORT_VF) {
rst_type_map = hns3vf_reset_type;
size = ARRAY_SIZE(hns3vf_reset_type);
} else {
rst_type_map = hns3_reset_type;
size = ARRAY_SIZE(hns3_reset_type);
}

for (i = 0; i < size; i++) {
if (rst_type_map[i].rst_flags == *flags) {
rst_type = rst_type_map[i].rst_type;
break;
}
}

if (rst_type == HNAE3_NONE_RESET ||
(rst_type == HNAE3_IMP_RESET &&
ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2))
return -EOPNOTSUPP;

netdev_info(netdev, "Setting reset type %d\n", rst_type);

ops->set_default_reset_request(ae_dev, rst_type);

ops->reset_event(h->pdev, h);

return 0;
}

static void hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
u32 tx_desc_num, u32 rx_desc_num)
{
Expand Down Expand Up @@ -1699,6 +1753,7 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
.set_priv_flags = hns3_set_priv_flags,
.get_tunable = hns3_get_tunable,
.set_tunable = hns3_set_tunable,
.reset = hns3_set_reset,
};

static const struct ethtool_ops hns3_ethtool_ops = {
Expand Down Expand Up @@ -1740,6 +1795,7 @@ static const struct ethtool_ops hns3_ethtool_ops = {
.get_ts_info = hns3_get_ts_info,
.get_tunable = hns3_get_tunable,
.set_tunable = hns3_set_tunable,
.reset = hns3_set_reset,
};

void hns3_ethtool_set_ops(struct net_device *netdev)
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3789,6 +3789,12 @@ static void hclge_do_reset(struct hclge_dev *hdev)
}

switch (hdev->reset_type) {
case HNAE3_IMP_RESET:
dev_info(&pdev->dev, "IMP reset requested\n");
val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG);
hnae3_set_bit(val, HCLGE_TRIGGER_IMP_RESET_B, 1);
hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG, val);
break;
case HNAE3_GLOBAL_RESET:
dev_info(&pdev->dev, "global reset requested\n");
val = hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ enum HLCGE_PORT_TYPE {
#define HCLGE_VECTOR0_IMP_CMDQ_ERR_B 4U
#define HCLGE_VECTOR0_IMP_RD_POISON_B 5U
#define HCLGE_VECTOR0_ALL_MSIX_ERR_B 6U
#define HCLGE_TRIGGER_IMP_RESET_B 7U

#define HCLGE_MAC_DEFAULT_FRAME \
(ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN + ETH_DATA_LEN)
Expand Down

0 comments on commit ddccc5e

Please sign in to comment.