Skip to content

Commit ddccc5e

Browse files
Yufeng Mokuba-moo
authored andcommitted
net: hns3: add support for triggering reset by ethtool
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 <[email protected]> Signed-off-by: Guangbin Huang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6e98893 commit ddccc5e

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3_enet.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,11 @@ struct hns3_hw_error_info {
596596
const char *msg;
597597
};
598598

599+
struct hns3_reset_type_map {
600+
enum ethtool_reset_flags rst_flags;
601+
enum hnae3_reset_type rst_type;
602+
};
603+
599604
static inline int ring_space(struct hns3_enet_ring *ring)
600605
{
601606
/* This smp_load_acquire() pairs with smp_store_release() in

drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,60 @@ static int hns3_get_rxnfc(struct net_device *netdev,
953953
}
954954
}
955955

956+
static const struct hns3_reset_type_map hns3_reset_type[] = {
957+
{ETH_RESET_MGMT, HNAE3_IMP_RESET},
958+
{ETH_RESET_ALL, HNAE3_GLOBAL_RESET},
959+
{ETH_RESET_DEDICATED, HNAE3_FUNC_RESET},
960+
};
961+
962+
static const struct hns3_reset_type_map hns3vf_reset_type[] = {
963+
{ETH_RESET_DEDICATED, HNAE3_VF_FUNC_RESET},
964+
};
965+
966+
static int hns3_set_reset(struct net_device *netdev, u32 *flags)
967+
{
968+
enum hnae3_reset_type rst_type = HNAE3_NONE_RESET;
969+
struct hnae3_handle *h = hns3_get_handle(netdev);
970+
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
971+
const struct hnae3_ae_ops *ops = h->ae_algo->ops;
972+
const struct hns3_reset_type_map *rst_type_map;
973+
u32 i, size;
974+
975+
if (ops->ae_dev_resetting && ops->ae_dev_resetting(h))
976+
return -EBUSY;
977+
978+
if (!ops->set_default_reset_request || !ops->reset_event)
979+
return -EOPNOTSUPP;
980+
981+
if (h->flags & HNAE3_SUPPORT_VF) {
982+
rst_type_map = hns3vf_reset_type;
983+
size = ARRAY_SIZE(hns3vf_reset_type);
984+
} else {
985+
rst_type_map = hns3_reset_type;
986+
size = ARRAY_SIZE(hns3_reset_type);
987+
}
988+
989+
for (i = 0; i < size; i++) {
990+
if (rst_type_map[i].rst_flags == *flags) {
991+
rst_type = rst_type_map[i].rst_type;
992+
break;
993+
}
994+
}
995+
996+
if (rst_type == HNAE3_NONE_RESET ||
997+
(rst_type == HNAE3_IMP_RESET &&
998+
ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2))
999+
return -EOPNOTSUPP;
1000+
1001+
netdev_info(netdev, "Setting reset type %d\n", rst_type);
1002+
1003+
ops->set_default_reset_request(ae_dev, rst_type);
1004+
1005+
ops->reset_event(h->pdev, h);
1006+
1007+
return 0;
1008+
}
1009+
9561010
static void hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
9571011
u32 tx_desc_num, u32 rx_desc_num)
9581012
{
@@ -1699,6 +1753,7 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
16991753
.set_priv_flags = hns3_set_priv_flags,
17001754
.get_tunable = hns3_get_tunable,
17011755
.set_tunable = hns3_set_tunable,
1756+
.reset = hns3_set_reset,
17021757
};
17031758

17041759
static const struct ethtool_ops hns3_ethtool_ops = {
@@ -1740,6 +1795,7 @@ static const struct ethtool_ops hns3_ethtool_ops = {
17401795
.get_ts_info = hns3_get_ts_info,
17411796
.get_tunable = hns3_get_tunable,
17421797
.set_tunable = hns3_set_tunable,
1798+
.reset = hns3_set_reset,
17431799
};
17441800

17451801
void hns3_ethtool_set_ops(struct net_device *netdev)

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3789,6 +3789,12 @@ static void hclge_do_reset(struct hclge_dev *hdev)
37893789
}
37903790

37913791
switch (hdev->reset_type) {
3792+
case HNAE3_IMP_RESET:
3793+
dev_info(&pdev->dev, "IMP reset requested\n");
3794+
val = hclge_read_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG);
3795+
hnae3_set_bit(val, HCLGE_TRIGGER_IMP_RESET_B, 1);
3796+
hclge_write_dev(&hdev->hw, HCLGE_PF_OTHER_INT_REG, val);
3797+
break;
37923798
case HNAE3_GLOBAL_RESET:
37933799
dev_info(&pdev->dev, "global reset requested\n");
37943800
val = hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG);

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ enum HLCGE_PORT_TYPE {
194194
#define HCLGE_VECTOR0_IMP_CMDQ_ERR_B 4U
195195
#define HCLGE_VECTOR0_IMP_RD_POISON_B 5U
196196
#define HCLGE_VECTOR0_ALL_MSIX_ERR_B 6U
197+
#define HCLGE_TRIGGER_IMP_RESET_B 7U
197198

198199
#define HCLGE_MAC_DEFAULT_FRAME \
199200
(ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN + ETH_DATA_LEN)

0 commit comments

Comments
 (0)