1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2025 Broadcom.
3
4 #include <linux/init.h>
5 #include <linux/crash_dump.h>
6 #include <linux/module.h>
7 #include <linux/pci.h>
8
9 #include "bnge.h"
10 #include "bnge_devlink.h"
11 #include "bnge_hwrm.h"
12 #include "bnge_hwrm_lib.h"
13
14 MODULE_LICENSE("GPL");
15 MODULE_DESCRIPTION(DRV_SUMMARY);
16
17 char bnge_driver_name[] = DRV_NAME;
18
19 static const struct {
20 char *name;
21 } board_info[] = {
22 [BCM57708] = { "Broadcom BCM57708 50Gb/100Gb/200Gb/400Gb/800Gb Ethernet" },
23 };
24
25 static const struct pci_device_id bnge_pci_tbl[] = {
26 { PCI_VDEVICE(BROADCOM, 0x1780), .driver_data = BCM57708 },
27 /* Required last entry */
28 {0, }
29 };
30 MODULE_DEVICE_TABLE(pci, bnge_pci_tbl);
31
bnge_print_device_info(struct pci_dev * pdev,enum board_idx idx)32 static void bnge_print_device_info(struct pci_dev *pdev, enum board_idx idx)
33 {
34 struct device *dev = &pdev->dev;
35
36 dev_info(dev, "%s found at mem %lx\n", board_info[idx].name,
37 (long)pci_resource_start(pdev, 0));
38
39 pcie_print_link_status(pdev);
40 }
41
bnge_aux_registered(struct bnge_dev * bd)42 bool bnge_aux_registered(struct bnge_dev *bd)
43 {
44 return false;
45 }
46
bnge_nvm_cfg_ver_get(struct bnge_dev * bd)47 static void bnge_nvm_cfg_ver_get(struct bnge_dev *bd)
48 {
49 struct hwrm_nvm_get_dev_info_output nvm_info;
50
51 if (!bnge_hwrm_nvm_dev_info(bd, &nvm_info))
52 snprintf(bd->nvm_cfg_ver, FW_VER_STR_LEN, "%d.%d.%d",
53 nvm_info.nvm_cfg_ver_maj, nvm_info.nvm_cfg_ver_min,
54 nvm_info.nvm_cfg_ver_upd);
55 }
56
bnge_func_qcaps(struct bnge_dev * bd)57 static int bnge_func_qcaps(struct bnge_dev *bd)
58 {
59 int rc;
60
61 rc = bnge_hwrm_func_qcaps(bd);
62 if (rc)
63 return rc;
64
65 rc = bnge_hwrm_queue_qportcfg(bd);
66 if (rc) {
67 dev_err(bd->dev, "query qportcfg failure rc: %d\n", rc);
68 return rc;
69 }
70
71 rc = bnge_hwrm_func_resc_qcaps(bd);
72 if (rc) {
73 dev_err(bd->dev, "query resc caps failure rc: %d\n", rc);
74 return rc;
75 }
76
77 rc = bnge_hwrm_func_qcfg(bd);
78 if (rc) {
79 dev_err(bd->dev, "query config failure rc: %d\n", rc);
80 return rc;
81 }
82
83 rc = bnge_hwrm_vnic_qcaps(bd);
84 if (rc) {
85 dev_err(bd->dev, "vnic caps failure rc: %d\n", rc);
86 return rc;
87 }
88
89 return 0;
90 }
91
bnge_fw_unregister_dev(struct bnge_dev * bd)92 static void bnge_fw_unregister_dev(struct bnge_dev *bd)
93 {
94 /* ctx mem free after unrgtr only */
95 bnge_hwrm_func_drv_unrgtr(bd);
96 bnge_free_ctx_mem(bd);
97 }
98
bnge_fw_register_dev(struct bnge_dev * bd)99 static int bnge_fw_register_dev(struct bnge_dev *bd)
100 {
101 int rc;
102
103 bd->fw_cap = 0;
104 rc = bnge_hwrm_ver_get(bd);
105 if (rc) {
106 dev_err(bd->dev, "Get Version command failed rc: %d\n", rc);
107 return rc;
108 }
109
110 bnge_nvm_cfg_ver_get(bd);
111
112 rc = bnge_hwrm_func_reset(bd);
113 if (rc) {
114 dev_err(bd->dev, "Failed to reset function rc: %d\n", rc);
115 return rc;
116 }
117
118 bnge_hwrm_fw_set_time(bd);
119
120 rc = bnge_hwrm_func_drv_rgtr(bd);
121 if (rc) {
122 dev_err(bd->dev, "Failed to rgtr with firmware rc: %d\n", rc);
123 return rc;
124 }
125
126 rc = bnge_alloc_ctx_mem(bd);
127 if (rc) {
128 dev_err(bd->dev, "Failed to allocate ctx mem rc: %d\n", rc);
129 goto err_func_unrgtr;
130 }
131
132 /* Get the resources and configuration from firmware */
133 rc = bnge_func_qcaps(bd);
134 if (rc) {
135 dev_err(bd->dev, "Failed initial configuration rc: %d\n", rc);
136 rc = -ENODEV;
137 goto err_func_unrgtr;
138 }
139
140 return 0;
141
142 err_func_unrgtr:
143 bnge_fw_unregister_dev(bd);
144 return rc;
145 }
146
bnge_pci_disable(struct pci_dev * pdev)147 static void bnge_pci_disable(struct pci_dev *pdev)
148 {
149 pci_release_regions(pdev);
150 if (pci_is_enabled(pdev))
151 pci_disable_device(pdev);
152 }
153
bnge_pci_enable(struct pci_dev * pdev)154 static int bnge_pci_enable(struct pci_dev *pdev)
155 {
156 int rc;
157
158 rc = pci_enable_device(pdev);
159 if (rc) {
160 dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
161 return rc;
162 }
163
164 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
165 dev_err(&pdev->dev,
166 "Cannot find PCI device base address, aborting\n");
167 rc = -ENODEV;
168 goto err_pci_disable;
169 }
170
171 rc = pci_request_regions(pdev, bnge_driver_name);
172 if (rc) {
173 dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
174 goto err_pci_disable;
175 }
176
177 dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
178
179 pci_set_master(pdev);
180
181 return 0;
182
183 err_pci_disable:
184 pci_disable_device(pdev);
185 return rc;
186 }
187
bnge_unmap_bars(struct pci_dev * pdev)188 static void bnge_unmap_bars(struct pci_dev *pdev)
189 {
190 struct bnge_dev *bd = pci_get_drvdata(pdev);
191
192 if (bd->bar1) {
193 pci_iounmap(pdev, bd->bar1);
194 bd->bar1 = NULL;
195 }
196
197 if (bd->bar0) {
198 pci_iounmap(pdev, bd->bar0);
199 bd->bar0 = NULL;
200 }
201 }
202
bnge_set_max_func_irqs(struct bnge_dev * bd,unsigned int max_irqs)203 static void bnge_set_max_func_irqs(struct bnge_dev *bd,
204 unsigned int max_irqs)
205 {
206 bd->hw_resc.max_irqs = max_irqs;
207 }
208
bnge_get_max_irq(struct pci_dev * pdev)209 static int bnge_get_max_irq(struct pci_dev *pdev)
210 {
211 u16 ctrl;
212
213 pci_read_config_word(pdev, pdev->msix_cap + PCI_MSIX_FLAGS, &ctrl);
214 return (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;
215 }
216
bnge_map_db_bar(struct bnge_dev * bd)217 static int bnge_map_db_bar(struct bnge_dev *bd)
218 {
219 if (!bd->db_size)
220 return -ENODEV;
221
222 bd->bar1 = pci_iomap(bd->pdev, 2, bd->db_size);
223 if (!bd->bar1)
224 return -ENOMEM;
225
226 return 0;
227 }
228
bnge_probe_one(struct pci_dev * pdev,const struct pci_device_id * ent)229 static int bnge_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
230 {
231 unsigned int max_irqs;
232 struct bnge_dev *bd;
233 int rc;
234
235 if (pci_is_bridge(pdev))
236 return -ENODEV;
237
238 if (!pdev->msix_cap) {
239 dev_err(&pdev->dev, "MSIX capability missing, aborting\n");
240 return -ENODEV;
241 }
242
243 if (is_kdump_kernel()) {
244 pci_clear_master(pdev);
245 pcie_flr(pdev);
246 }
247
248 rc = bnge_pci_enable(pdev);
249 if (rc)
250 return rc;
251
252 bnge_print_device_info(pdev, ent->driver_data);
253
254 bd = bnge_devlink_alloc(pdev);
255 if (!bd) {
256 dev_err(&pdev->dev, "Devlink allocation failed\n");
257 rc = -ENOMEM;
258 goto err_pci_disable;
259 }
260
261 bd->bar0 = pci_ioremap_bar(pdev, 0);
262 if (!bd->bar0) {
263 dev_err(&pdev->dev, "Failed mapping BAR-0, aborting\n");
264 rc = -ENOMEM;
265 goto err_devl_free;
266 }
267
268 rc = bnge_init_hwrm_resources(bd);
269 if (rc)
270 goto err_bar_unmap;
271
272 rc = bnge_fw_register_dev(bd);
273 if (rc) {
274 dev_err(&pdev->dev, "Failed to register with firmware rc = %d\n", rc);
275 goto err_hwrm_cleanup;
276 }
277
278 bnge_devlink_register(bd);
279
280 max_irqs = bnge_get_max_irq(pdev);
281 bnge_set_max_func_irqs(bd, max_irqs);
282
283 bnge_aux_init_dflt_config(bd);
284
285 rc = bnge_net_init_dflt_config(bd);
286 if (rc) {
287 dev_err(&pdev->dev, "Error setting up default cfg to netdev rc = %d\n",
288 rc);
289 goto err_fw_reg;
290 }
291
292 rc = bnge_map_db_bar(bd);
293 if (rc) {
294 dev_err(&pdev->dev, "Failed mapping doorbell BAR rc = %d, aborting\n",
295 rc);
296 goto err_config_uninit;
297 }
298
299 rc = bnge_alloc_irqs(bd);
300 if (rc) {
301 dev_err(&pdev->dev, "Error IRQ allocation rc = %d\n", rc);
302 goto err_config_uninit;
303 }
304
305 rc = bnge_netdev_alloc(bd, max_irqs);
306 if (rc)
307 goto err_free_irq;
308
309 pci_save_state(pdev);
310
311 return 0;
312
313 err_free_irq:
314 bnge_free_irqs(bd);
315
316 err_config_uninit:
317 bnge_net_uninit_dflt_config(bd);
318
319 err_fw_reg:
320 bnge_devlink_unregister(bd);
321 bnge_fw_unregister_dev(bd);
322
323 err_hwrm_cleanup:
324 bnge_cleanup_hwrm_resources(bd);
325
326 err_bar_unmap:
327 bnge_unmap_bars(pdev);
328
329 err_devl_free:
330 bnge_devlink_free(bd);
331
332 err_pci_disable:
333 bnge_pci_disable(pdev);
334 return rc;
335 }
336
bnge_remove_one(struct pci_dev * pdev)337 static void bnge_remove_one(struct pci_dev *pdev)
338 {
339 struct bnge_dev *bd = pci_get_drvdata(pdev);
340
341 bnge_netdev_free(bd);
342
343 bnge_free_irqs(bd);
344
345 bnge_net_uninit_dflt_config(bd);
346
347 bnge_devlink_unregister(bd);
348
349 bnge_fw_unregister_dev(bd);
350
351 bnge_cleanup_hwrm_resources(bd);
352
353 bnge_unmap_bars(pdev);
354
355 bnge_devlink_free(bd);
356
357 bnge_pci_disable(pdev);
358 }
359
bnge_shutdown(struct pci_dev * pdev)360 static void bnge_shutdown(struct pci_dev *pdev)
361 {
362 pci_disable_device(pdev);
363
364 if (system_state == SYSTEM_POWER_OFF) {
365 pci_wake_from_d3(pdev, 0);
366 pci_set_power_state(pdev, PCI_D3hot);
367 }
368 }
369
370 static struct pci_driver bnge_driver = {
371 .name = bnge_driver_name,
372 .id_table = bnge_pci_tbl,
373 .probe = bnge_probe_one,
374 .remove = bnge_remove_one,
375 .shutdown = bnge_shutdown,
376 };
377
bnge_init_module(void)378 static int __init bnge_init_module(void)
379 {
380 return pci_register_driver(&bnge_driver);
381 }
382 module_init(bnge_init_module);
383
bnge_exit_module(void)384 static void __exit bnge_exit_module(void)
385 {
386 pci_unregister_driver(&bnge_driver);
387 }
388 module_exit(bnge_exit_module);
389