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
hbg_restore_mac_table(struct hbg_priv * priv)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
hbg_restore_user_def_settings(struct hbg_priv * priv)27 static void hbg_restore_user_def_settings(struct hbg_priv *priv)
28 {
29 /* The index of host mac is always 0. */
30 u64 rx_pause_addr = ether_addr_to_u64(priv->filter.mac_table[0].addr);
31 struct ethtool_pauseparam *pause_param = &priv->user_def.pause_param;
32
33 hbg_restore_mac_table(priv);
34 hbg_hw_set_mtu(priv, priv->netdev->mtu);
35 hbg_hw_set_pause_enable(priv, pause_param->tx_pause,
36 pause_param->rx_pause);
37 hbg_hw_set_rx_pause_mac_addr(priv, rx_pause_addr);
38 }
39
hbg_rebuild(struct hbg_priv * priv)40 int hbg_rebuild(struct hbg_priv *priv)
41 {
42 int ret;
43
44 ret = hbg_hw_init(priv);
45 if (ret)
46 return ret;
47
48 hbg_restore_user_def_settings(priv);
49 return 0;
50 }
51
hbg_reset_prepare(struct hbg_priv * priv,enum hbg_reset_type type)52 static int hbg_reset_prepare(struct hbg_priv *priv, enum hbg_reset_type type)
53 {
54 int ret;
55
56 ASSERT_RTNL();
57
58 if (netif_running(priv->netdev)) {
59 dev_warn(&priv->pdev->dev,
60 "failed to reset because port is up\n");
61 return -EBUSY;
62 }
63
64 netif_device_detach(priv->netdev);
65
66 priv->reset_type = type;
67 set_bit(HBG_NIC_STATE_RESETTING, &priv->state);
68 clear_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
69 ret = hbg_hw_event_notify(priv, HBG_HW_EVENT_RESET);
70 if (ret) {
71 set_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
72 clear_bit(HBG_NIC_STATE_RESETTING, &priv->state);
73 }
74
75 return ret;
76 }
77
hbg_reset_done(struct hbg_priv * priv,enum hbg_reset_type type)78 static int hbg_reset_done(struct hbg_priv *priv, enum hbg_reset_type type)
79 {
80 int ret;
81
82 if (!test_bit(HBG_NIC_STATE_RESETTING, &priv->state) ||
83 type != priv->reset_type)
84 return 0;
85
86 ASSERT_RTNL();
87
88 clear_bit(HBG_NIC_STATE_RESETTING, &priv->state);
89 ret = hbg_rebuild(priv);
90 if (ret) {
91 set_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
92 dev_err(&priv->pdev->dev, "failed to rebuild after reset\n");
93 return ret;
94 }
95
96 netif_device_attach(priv->netdev);
97
98 dev_info(&priv->pdev->dev, "reset done\n");
99 return ret;
100 }
101
102 /* must be protected by rtnl lock */
hbg_reset(struct hbg_priv * priv)103 int hbg_reset(struct hbg_priv *priv)
104 {
105 int ret;
106
107 ASSERT_RTNL();
108 ret = hbg_reset_prepare(priv, HBG_RESET_TYPE_FUNCTION);
109 if (ret)
110 return ret;
111
112 return hbg_reset_done(priv, HBG_RESET_TYPE_FUNCTION);
113 }
114
hbg_err_reset(struct hbg_priv * priv)115 void hbg_err_reset(struct hbg_priv *priv)
116 {
117 bool running;
118
119 rtnl_lock();
120 running = netif_running(priv->netdev);
121 if (running)
122 dev_close(priv->netdev);
123
124 if (hbg_reset(priv))
125 goto err_unlock;
126
127 if (running)
128 dev_open(priv->netdev, NULL);
129
130 err_unlock:
131 rtnl_unlock();
132 }
133
hbg_pci_err_detected(struct pci_dev * pdev,pci_channel_state_t state)134 static pci_ers_result_t hbg_pci_err_detected(struct pci_dev *pdev,
135 pci_channel_state_t state)
136 {
137 struct net_device *netdev = pci_get_drvdata(pdev);
138
139 netif_device_detach(netdev);
140
141 if (state == pci_channel_io_perm_failure)
142 return PCI_ERS_RESULT_DISCONNECT;
143
144 pci_disable_device(pdev);
145 return PCI_ERS_RESULT_NEED_RESET;
146 }
147
hbg_pci_err_slot_reset(struct pci_dev * pdev)148 static pci_ers_result_t hbg_pci_err_slot_reset(struct pci_dev *pdev)
149 {
150 struct net_device *netdev = pci_get_drvdata(pdev);
151 struct hbg_priv *priv = netdev_priv(netdev);
152
153 if (pci_enable_device(pdev)) {
154 dev_err(&pdev->dev,
155 "failed to re-enable PCI device after reset\n");
156 return PCI_ERS_RESULT_DISCONNECT;
157 }
158
159 pci_set_master(pdev);
160 pci_restore_state(pdev);
161 pci_save_state(pdev);
162
163 hbg_err_reset(priv);
164 return PCI_ERS_RESULT_RECOVERED;
165 }
166
hbg_pci_err_reset_prepare(struct pci_dev * pdev)167 static void hbg_pci_err_reset_prepare(struct pci_dev *pdev)
168 {
169 struct net_device *netdev = pci_get_drvdata(pdev);
170 struct hbg_priv *priv = netdev_priv(netdev);
171
172 rtnl_lock();
173 hbg_reset_prepare(priv, HBG_RESET_TYPE_FLR);
174 }
175
hbg_pci_err_reset_done(struct pci_dev * pdev)176 static void hbg_pci_err_reset_done(struct pci_dev *pdev)
177 {
178 struct net_device *netdev = pci_get_drvdata(pdev);
179 struct hbg_priv *priv = netdev_priv(netdev);
180
181 hbg_reset_done(priv, HBG_RESET_TYPE_FLR);
182 rtnl_unlock();
183 }
184
185 static const struct pci_error_handlers hbg_pci_err_handler = {
186 .error_detected = hbg_pci_err_detected,
187 .slot_reset = hbg_pci_err_slot_reset,
188 .reset_prepare = hbg_pci_err_reset_prepare,
189 .reset_done = hbg_pci_err_reset_done,
190 };
191
hbg_set_pci_err_handler(struct pci_driver * pdrv)192 void hbg_set_pci_err_handler(struct pci_driver *pdrv)
193 {
194 pdrv->err_handler = &hbg_pci_err_handler;
195 }
196