xref: /linux/drivers/net/ethernet/broadcom/bnge/bnge_core.c (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
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