1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2020 - 2025 Mucse Corporation. */
3
4 #include <linux/pci.h>
5 #include <net/rtnetlink.h>
6 #include <linux/etherdevice.h>
7
8 #include "rnpgbe.h"
9 #include "rnpgbe_hw.h"
10 #include "rnpgbe_mbx_fw.h"
11
12 static const char rnpgbe_driver_name[] = "rnpgbe";
13
14 /* rnpgbe_pci_tbl - PCI Device ID Table
15 *
16 * { PCI_VDEVICE(Vendor ID, Device ID),
17 * private_data (used for different hw chip) }
18 */
19 static struct pci_device_id rnpgbe_pci_tbl[] = {
20 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N210), board_n210 },
21 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N210L), board_n210 },
22 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N500_DUAL_PORT), board_n500 },
23 { PCI_VDEVICE(MUCSE, RNPGBE_DEVICE_ID_N500_QUAD_PORT), board_n500 },
24 /* required last entry */
25 {0, },
26 };
27
28 /**
29 * rnpgbe_open - Called when a network interface is made active
30 * @netdev: network interface device structure
31 *
32 * The open entry point is called when a network interface is made
33 * active by the system (IFF_UP).
34 *
35 * Return: 0
36 **/
rnpgbe_open(struct net_device * netdev)37 static int rnpgbe_open(struct net_device *netdev)
38 {
39 return 0;
40 }
41
42 /**
43 * rnpgbe_close - Disables a network interface
44 * @netdev: network interface device structure
45 *
46 * The close entry point is called when an interface is de-activated
47 * by the OS.
48 *
49 * Return: 0, this is not allowed to fail
50 **/
rnpgbe_close(struct net_device * netdev)51 static int rnpgbe_close(struct net_device *netdev)
52 {
53 return 0;
54 }
55
56 /**
57 * rnpgbe_xmit_frame - Send a skb to driver
58 * @skb: skb structure to be sent
59 * @netdev: network interface device structure
60 *
61 * Return: NETDEV_TX_OK
62 **/
rnpgbe_xmit_frame(struct sk_buff * skb,struct net_device * netdev)63 static netdev_tx_t rnpgbe_xmit_frame(struct sk_buff *skb,
64 struct net_device *netdev)
65 {
66 struct mucse *mucse = netdev_priv(netdev);
67
68 dev_kfree_skb_any(skb);
69 mucse->stats.tx_dropped++;
70
71 return NETDEV_TX_OK;
72 }
73
74 static const struct net_device_ops rnpgbe_netdev_ops = {
75 .ndo_open = rnpgbe_open,
76 .ndo_stop = rnpgbe_close,
77 .ndo_start_xmit = rnpgbe_xmit_frame,
78 };
79
80 /**
81 * rnpgbe_add_adapter - Add netdev for this pci_dev
82 * @pdev: PCI device information structure
83 * @board_type: board type
84 *
85 * rnpgbe_add_adapter initializes a netdev for this pci_dev
86 * structure. Initializes Bar map, private structure, and a
87 * hardware reset occur.
88 *
89 * Return: 0 on success, negative errno on failure
90 **/
rnpgbe_add_adapter(struct pci_dev * pdev,int board_type)91 static int rnpgbe_add_adapter(struct pci_dev *pdev,
92 int board_type)
93 {
94 struct net_device *netdev;
95 u8 perm_addr[ETH_ALEN];
96 void __iomem *hw_addr;
97 struct mucse *mucse;
98 struct mucse_hw *hw;
99 int err, err_notify;
100
101 netdev = alloc_etherdev_mq(sizeof(struct mucse), RNPGBE_MAX_QUEUES);
102 if (!netdev)
103 return -ENOMEM;
104
105 SET_NETDEV_DEV(netdev, &pdev->dev);
106 mucse = netdev_priv(netdev);
107 mucse->netdev = netdev;
108 mucse->pdev = pdev;
109 pci_set_drvdata(pdev, mucse);
110
111 hw = &mucse->hw;
112 hw_addr = devm_ioremap(&pdev->dev,
113 pci_resource_start(pdev, 2),
114 pci_resource_len(pdev, 2));
115 if (!hw_addr) {
116 err = -EIO;
117 goto err_free_net;
118 }
119
120 hw->hw_addr = hw_addr;
121 hw->pdev = pdev;
122
123 err = rnpgbe_init_hw(hw, board_type);
124 if (err) {
125 dev_err(&pdev->dev, "Init hw err %d\n", err);
126 goto err_free_net;
127 }
128 /* Step 1: Send power-up notification to firmware (no response expected)
129 * This informs firmware to initialize hardware power state, but
130 * firmware only acknowledges receipt without returning data. Must be
131 * done before synchronization as firmware may be in low-power idle
132 * state initially.
133 */
134 err_notify = rnpgbe_send_notify(hw, true, mucse_fw_powerup);
135 if (err_notify) {
136 dev_warn(&pdev->dev, "Send powerup to hw failed %d\n",
137 err_notify);
138 dev_warn(&pdev->dev, "Maybe low performance\n");
139 }
140 /* Step 2: Synchronize mailbox communication with firmware (requires
141 * response) After power-up, confirm firmware is ready to process
142 * requests with responses. This ensures subsequent request/response
143 * interactions work reliably.
144 */
145 err = mucse_mbx_sync_fw(hw);
146 if (err) {
147 dev_err(&pdev->dev, "Sync fw failed! %d\n", err);
148 goto err_powerdown;
149 }
150
151 netdev->netdev_ops = &rnpgbe_netdev_ops;
152 err = rnpgbe_reset_hw(hw);
153 if (err) {
154 dev_err(&pdev->dev, "Hw reset failed %d\n", err);
155 goto err_powerdown;
156 }
157
158 err = rnpgbe_get_permanent_mac(hw, perm_addr);
159 if (!err) {
160 eth_hw_addr_set(netdev, perm_addr);
161 } else if (err == -EINVAL) {
162 dev_warn(&pdev->dev, "Using random MAC\n");
163 eth_hw_addr_random(netdev);
164 } else if (err) {
165 dev_err(&pdev->dev, "get perm_addr failed %d\n", err);
166 goto err_powerdown;
167 }
168
169 err = register_netdev(netdev);
170 if (err)
171 goto err_powerdown;
172
173 return 0;
174 err_powerdown:
175 /* notify powerdown only powerup ok */
176 if (!err_notify) {
177 err_notify = rnpgbe_send_notify(hw, false, mucse_fw_powerup);
178 if (err_notify)
179 dev_warn(&pdev->dev, "Send powerdown to hw failed %d\n",
180 err_notify);
181 }
182 err_free_net:
183 free_netdev(netdev);
184 return err;
185 }
186
187 /**
188 * rnpgbe_probe - Device initialization routine
189 * @pdev: PCI device information struct
190 * @id: entry in rnpgbe_pci_tbl
191 *
192 * rnpgbe_probe initializes a PF adapter identified by a pci_dev
193 * structure.
194 *
195 * Return: 0 on success, negative errno on failure
196 **/
rnpgbe_probe(struct pci_dev * pdev,const struct pci_device_id * id)197 static int rnpgbe_probe(struct pci_dev *pdev, const struct pci_device_id *id)
198 {
199 int board_type = id->driver_data;
200 int err;
201
202 err = pci_enable_device_mem(pdev);
203 if (err)
204 return err;
205
206 err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(56));
207 if (err) {
208 dev_err(&pdev->dev,
209 "No usable DMA configuration, aborting %d\n", err);
210 goto err_disable_dev;
211 }
212
213 err = pci_request_mem_regions(pdev, rnpgbe_driver_name);
214 if (err) {
215 dev_err(&pdev->dev,
216 "pci_request_selected_regions failed %d\n", err);
217 goto err_disable_dev;
218 }
219
220 pci_set_master(pdev);
221 err = pci_save_state(pdev);
222 if (err) {
223 dev_err(&pdev->dev, "pci_save_state failed %d\n", err);
224 goto err_free_regions;
225 }
226
227 err = rnpgbe_add_adapter(pdev, board_type);
228 if (err)
229 goto err_free_regions;
230
231 return 0;
232 err_free_regions:
233 pci_release_mem_regions(pdev);
234 err_disable_dev:
235 pci_disable_device(pdev);
236 return err;
237 }
238
239 /**
240 * rnpgbe_rm_adapter - Remove netdev for this mucse structure
241 * @pdev: PCI device information struct
242 *
243 * rnpgbe_rm_adapter remove a netdev for this mucse structure
244 **/
rnpgbe_rm_adapter(struct pci_dev * pdev)245 static void rnpgbe_rm_adapter(struct pci_dev *pdev)
246 {
247 struct mucse *mucse = pci_get_drvdata(pdev);
248 struct mucse_hw *hw = &mucse->hw;
249 struct net_device *netdev;
250 int err;
251
252 if (!mucse)
253 return;
254 netdev = mucse->netdev;
255 unregister_netdev(netdev);
256 err = rnpgbe_send_notify(hw, false, mucse_fw_powerup);
257 if (err)
258 dev_warn(&pdev->dev, "Send powerdown to hw failed %d\n", err);
259 free_netdev(netdev);
260 }
261
262 /**
263 * rnpgbe_remove - Device removal routine
264 * @pdev: PCI device information struct
265 *
266 * rnpgbe_remove is called by the PCI subsystem to alert the driver
267 * that it should release a PCI device. This could be caused by a
268 * Hot-Plug event, or because the driver is going to be removed from
269 * memory.
270 **/
rnpgbe_remove(struct pci_dev * pdev)271 static void rnpgbe_remove(struct pci_dev *pdev)
272 {
273 rnpgbe_rm_adapter(pdev);
274 pci_release_mem_regions(pdev);
275 pci_disable_device(pdev);
276 }
277
278 /**
279 * rnpgbe_dev_shutdown - Device shutdown routine
280 * @pdev: PCI device information struct
281 **/
rnpgbe_dev_shutdown(struct pci_dev * pdev)282 static void rnpgbe_dev_shutdown(struct pci_dev *pdev)
283 {
284 struct mucse *mucse = pci_get_drvdata(pdev);
285 struct net_device *netdev = mucse->netdev;
286
287 rtnl_lock();
288 netif_device_detach(netdev);
289 if (netif_running(netdev))
290 rnpgbe_close(netdev);
291 rtnl_unlock();
292 pci_disable_device(pdev);
293 }
294
295 /**
296 * rnpgbe_shutdown - Device shutdown routine
297 * @pdev: PCI device information struct
298 *
299 * rnpgbe_shutdown is called by the PCI subsystem to alert the driver
300 * that os shutdown. Device should setup wakeup state here.
301 **/
rnpgbe_shutdown(struct pci_dev * pdev)302 static void rnpgbe_shutdown(struct pci_dev *pdev)
303 {
304 rnpgbe_dev_shutdown(pdev);
305 }
306
307 static struct pci_driver rnpgbe_driver = {
308 .name = rnpgbe_driver_name,
309 .id_table = rnpgbe_pci_tbl,
310 .probe = rnpgbe_probe,
311 .remove = rnpgbe_remove,
312 .shutdown = rnpgbe_shutdown,
313 };
314
315 module_pci_driver(rnpgbe_driver);
316
317 MODULE_DEVICE_TABLE(pci, rnpgbe_pci_tbl);
318 MODULE_AUTHOR("Yibo Dong, <dong100@mucse.com>");
319 MODULE_DESCRIPTION("Mucse(R) 1 Gigabit PCI Express Network Driver");
320 MODULE_LICENSE("GPL");
321