xref: /linux/drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c (revision c284d3e423382be3591d5b1e402e330e6c3f726c)
1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2024 Hisilicon Limited.
3 
4 #include <linux/etherdevice.h>
5 #include <linux/netdevice.h>
6 #include <linux/phy.h>
7 #include <linux/rtnetlink.h>
8 #include "hbg_common.h"
9 #include "hbg_err.h"
10 #include "hbg_hw.h"
11 
12 static void hbg_restore_mac_table(struct hbg_priv *priv)
13 {
14 	struct hbg_mac_filter *filter = &priv->filter;
15 	u64 addr;
16 	u32 i;
17 
18 	for (i = 0; i < filter->table_max_len; i++)
19 		if (!is_zero_ether_addr(filter->mac_table[i].addr)) {
20 			addr = ether_addr_to_u64(filter->mac_table[i].addr);
21 			hbg_hw_set_uc_addr(priv, addr, i);
22 		}
23 
24 	hbg_hw_set_mac_filter_enable(priv, priv->filter.enabled);
25 }
26 
27 static void hbg_restore_user_def_settings(struct hbg_priv *priv)
28 {
29 	struct ethtool_pauseparam *pause_param = &priv->user_def.pause_param;
30 
31 	hbg_restore_mac_table(priv);
32 	hbg_hw_set_mtu(priv, priv->netdev->mtu);
33 	hbg_hw_set_pause_enable(priv, pause_param->tx_pause,
34 				pause_param->rx_pause);
35 }
36 
37 int hbg_rebuild(struct hbg_priv *priv)
38 {
39 	int ret;
40 
41 	ret = hbg_hw_init(priv);
42 	if (ret)
43 		return ret;
44 
45 	hbg_restore_user_def_settings(priv);
46 	return 0;
47 }
48 
49 static int hbg_reset_prepare(struct hbg_priv *priv, enum hbg_reset_type type)
50 {
51 	int ret;
52 
53 	ASSERT_RTNL();
54 
55 	if (netif_running(priv->netdev)) {
56 		dev_warn(&priv->pdev->dev,
57 			 "failed to reset because port is up\n");
58 		return -EBUSY;
59 	}
60 
61 	priv->reset_type = type;
62 	set_bit(HBG_NIC_STATE_RESETTING, &priv->state);
63 	clear_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
64 	ret = hbg_hw_event_notify(priv, HBG_HW_EVENT_RESET);
65 	if (ret) {
66 		set_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
67 		clear_bit(HBG_NIC_STATE_RESETTING, &priv->state);
68 	}
69 
70 	return ret;
71 }
72 
73 static int hbg_reset_done(struct hbg_priv *priv, enum hbg_reset_type type)
74 {
75 	int ret;
76 
77 	if (!test_bit(HBG_NIC_STATE_RESETTING, &priv->state) ||
78 	    type != priv->reset_type)
79 		return 0;
80 
81 	ASSERT_RTNL();
82 
83 	clear_bit(HBG_NIC_STATE_RESETTING, &priv->state);
84 	ret = hbg_rebuild(priv);
85 	if (ret) {
86 		set_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
87 		dev_err(&priv->pdev->dev, "failed to rebuild after reset\n");
88 		return ret;
89 	}
90 
91 	dev_info(&priv->pdev->dev, "reset done\n");
92 	return ret;
93 }
94 
95 /* must be protected by rtnl lock */
96 int hbg_reset(struct hbg_priv *priv)
97 {
98 	int ret;
99 
100 	ASSERT_RTNL();
101 	ret = hbg_reset_prepare(priv, HBG_RESET_TYPE_FUNCTION);
102 	if (ret)
103 		return ret;
104 
105 	return hbg_reset_done(priv, HBG_RESET_TYPE_FUNCTION);
106 }
107 
108 void hbg_err_reset(struct hbg_priv *priv)
109 {
110 	bool running;
111 
112 	rtnl_lock();
113 	running = netif_running(priv->netdev);
114 	if (running)
115 		dev_close(priv->netdev);
116 
117 	hbg_reset(priv);
118 
119 	/* in hbg_pci_err_detected(), we will detach first,
120 	 * so we need to attach before open
121 	 */
122 	if (!netif_device_present(priv->netdev))
123 		netif_device_attach(priv->netdev);
124 
125 	if (running)
126 		dev_open(priv->netdev, NULL);
127 	rtnl_unlock();
128 }
129 
130 static pci_ers_result_t hbg_pci_err_detected(struct pci_dev *pdev,
131 					     pci_channel_state_t state)
132 {
133 	struct net_device *netdev = pci_get_drvdata(pdev);
134 
135 	netif_device_detach(netdev);
136 
137 	if (state == pci_channel_io_perm_failure)
138 		return PCI_ERS_RESULT_DISCONNECT;
139 
140 	pci_disable_device(pdev);
141 	return PCI_ERS_RESULT_NEED_RESET;
142 }
143 
144 static pci_ers_result_t hbg_pci_err_slot_reset(struct pci_dev *pdev)
145 {
146 	struct net_device *netdev = pci_get_drvdata(pdev);
147 	struct hbg_priv *priv = netdev_priv(netdev);
148 
149 	if (pci_enable_device(pdev)) {
150 		dev_err(&pdev->dev,
151 			"failed to re-enable PCI device after reset\n");
152 		return PCI_ERS_RESULT_DISCONNECT;
153 	}
154 
155 	pci_set_master(pdev);
156 	pci_restore_state(pdev);
157 	pci_save_state(pdev);
158 
159 	hbg_err_reset(priv);
160 	netif_device_attach(netdev);
161 	return PCI_ERS_RESULT_RECOVERED;
162 }
163 
164 static void hbg_pci_err_reset_prepare(struct pci_dev *pdev)
165 {
166 	struct net_device *netdev = pci_get_drvdata(pdev);
167 	struct hbg_priv *priv = netdev_priv(netdev);
168 
169 	rtnl_lock();
170 	hbg_reset_prepare(priv, HBG_RESET_TYPE_FLR);
171 }
172 
173 static void hbg_pci_err_reset_done(struct pci_dev *pdev)
174 {
175 	struct net_device *netdev = pci_get_drvdata(pdev);
176 	struct hbg_priv *priv = netdev_priv(netdev);
177 
178 	hbg_reset_done(priv, HBG_RESET_TYPE_FLR);
179 	rtnl_unlock();
180 }
181 
182 static const struct pci_error_handlers hbg_pci_err_handler = {
183 	.error_detected = hbg_pci_err_detected,
184 	.slot_reset = hbg_pci_err_slot_reset,
185 	.reset_prepare = hbg_pci_err_reset_prepare,
186 	.reset_done = hbg_pci_err_reset_done,
187 };
188 
189 void hbg_set_pci_err_handler(struct pci_driver *pdrv)
190 {
191 	pdrv->err_handler = &hbg_pci_err_handler;
192 }
193