xref: /linux/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
3 
4 #include <linux/delay.h>
5 #include <linux/iopoll.h>
6 
7 #include "hinic3_hw_cfg.h"
8 #include "hinic3_hw_comm.h"
9 #include "hinic3_hwdev.h"
10 #include "hinic3_hwif.h"
11 #include "hinic3_lld.h"
12 #include "hinic3_mgmt.h"
13 #include "hinic3_pci_id_tbl.h"
14 
15 #define HINIC3_VF_PCI_CFG_REG_BAR  0
16 #define HINIC3_PF_PCI_CFG_REG_BAR  1
17 #define HINIC3_PCI_INTR_REG_BAR    2
18 /* Only PF has mgmt bar */
19 #define HINIC3_PCI_MGMT_REG_BAR    3
20 #define HINIC3_PCI_DB_BAR          4
21 
22 #define HINIC3_IS_VF_DEV(pdev)     ((pdev)->device == PCI_DEV_ID_HINIC3_VF)
23 
24 #define HINIC3_EVENT_POLL_SLEEP_US   1000
25 #define HINIC3_EVENT_POLL_TIMEOUT_US 10000000
26 
27 static struct hinic3_adev_device {
28 	const char *name;
29 } hinic3_adev_devices[HINIC3_SERVICE_T_MAX] = {
30 	[HINIC3_SERVICE_T_NIC] = {
31 		.name = "nic",
32 	},
33 };
34 
hinic3_adev_svc_supported(struct hinic3_hwdev * hwdev,enum hinic3_service_type svc_type)35 static bool hinic3_adev_svc_supported(struct hinic3_hwdev *hwdev,
36 				      enum hinic3_service_type svc_type)
37 {
38 	switch (svc_type) {
39 	case HINIC3_SERVICE_T_NIC:
40 		return hinic3_support_nic(hwdev);
41 	default:
42 		break;
43 	}
44 
45 	return false;
46 }
47 
hinic3_comm_adev_release(struct device * dev)48 static void hinic3_comm_adev_release(struct device *dev)
49 {
50 	struct hinic3_adev *hadev = container_of(dev, struct hinic3_adev,
51 						 adev.dev);
52 
53 	kfree(hadev);
54 }
55 
hinic3_add_one_adev(struct hinic3_hwdev * hwdev,enum hinic3_service_type svc_type)56 static struct hinic3_adev *hinic3_add_one_adev(struct hinic3_hwdev *hwdev,
57 					       enum hinic3_service_type svc_type)
58 {
59 	struct hinic3_adev *hadev;
60 	const char *svc_name;
61 	int ret;
62 
63 	hadev = kzalloc_obj(*hadev);
64 	if (!hadev)
65 		return NULL;
66 
67 	svc_name = hinic3_adev_devices[svc_type].name;
68 	hadev->adev.name = svc_name;
69 	hadev->adev.id = hwdev->dev_id;
70 	hadev->adev.dev.parent = hwdev->dev;
71 	hadev->adev.dev.release = hinic3_comm_adev_release;
72 	hadev->svc_type = svc_type;
73 	hadev->hwdev = hwdev;
74 
75 	ret = auxiliary_device_init(&hadev->adev);
76 	if (ret) {
77 		dev_err(hwdev->dev, "failed init adev %s %u\n",
78 			svc_name, hwdev->dev_id);
79 		kfree(hadev);
80 		return NULL;
81 	}
82 
83 	ret = auxiliary_device_add(&hadev->adev);
84 	if (ret) {
85 		dev_err(hwdev->dev, "failed to add adev %s %u\n",
86 			svc_name, hwdev->dev_id);
87 		auxiliary_device_uninit(&hadev->adev);
88 		return NULL;
89 	}
90 
91 	return hadev;
92 }
93 
hinic3_del_one_adev(struct hinic3_hwdev * hwdev,enum hinic3_service_type svc_type)94 static void hinic3_del_one_adev(struct hinic3_hwdev *hwdev,
95 				enum hinic3_service_type svc_type)
96 {
97 	struct hinic3_pcidev *pci_adapter = hwdev->adapter;
98 	struct hinic3_adev *hadev;
99 	int timeout;
100 	bool state;
101 
102 	timeout = read_poll_timeout(test_and_set_bit, state, !state,
103 				    HINIC3_EVENT_POLL_SLEEP_US,
104 				    HINIC3_EVENT_POLL_TIMEOUT_US,
105 				    false, svc_type, &pci_adapter->state);
106 
107 	hadev = pci_adapter->hadev[svc_type];
108 	auxiliary_device_delete(&hadev->adev);
109 	auxiliary_device_uninit(&hadev->adev);
110 	pci_adapter->hadev[svc_type] = NULL;
111 	if (!timeout)
112 		clear_bit(svc_type, &pci_adapter->state);
113 }
114 
hinic3_attach_aux_devices(struct hinic3_hwdev * hwdev)115 static int hinic3_attach_aux_devices(struct hinic3_hwdev *hwdev)
116 {
117 	struct hinic3_pcidev *pci_adapter = hwdev->adapter;
118 	enum hinic3_service_type svc_type;
119 
120 	mutex_lock(&pci_adapter->pdev_mutex);
121 
122 	for (svc_type = 0; svc_type < HINIC3_SERVICE_T_MAX; svc_type++) {
123 		if (!hinic3_adev_svc_supported(hwdev, svc_type))
124 			continue;
125 
126 		pci_adapter->hadev[svc_type] = hinic3_add_one_adev(hwdev,
127 								   svc_type);
128 		if (!pci_adapter->hadev[svc_type])
129 			goto err_del_adevs;
130 	}
131 	mutex_unlock(&pci_adapter->pdev_mutex);
132 
133 	return 0;
134 
135 err_del_adevs:
136 	while (svc_type > 0) {
137 		svc_type--;
138 		if (pci_adapter->hadev[svc_type]) {
139 			hinic3_del_one_adev(hwdev, svc_type);
140 			pci_adapter->hadev[svc_type] = NULL;
141 		}
142 	}
143 	mutex_unlock(&pci_adapter->pdev_mutex);
144 
145 	return -ENOMEM;
146 }
147 
hinic3_detach_aux_devices(struct hinic3_hwdev * hwdev)148 static void hinic3_detach_aux_devices(struct hinic3_hwdev *hwdev)
149 {
150 	struct hinic3_pcidev *pci_adapter = hwdev->adapter;
151 	int i;
152 
153 	mutex_lock(&pci_adapter->pdev_mutex);
154 	for (i = 0; i < ARRAY_SIZE(hinic3_adev_devices); i++) {
155 		if (pci_adapter->hadev[i])
156 			hinic3_del_one_adev(hwdev, i);
157 	}
158 	mutex_unlock(&pci_adapter->pdev_mutex);
159 }
160 
hinic3_adev_get_hwdev(struct auxiliary_device * adev)161 struct hinic3_hwdev *hinic3_adev_get_hwdev(struct auxiliary_device *adev)
162 {
163 	struct hinic3_adev *hadev;
164 
165 	hadev = container_of(adev, struct hinic3_adev, adev);
166 
167 	return hadev->hwdev;
168 }
169 
hinic3_adev_event_register(struct auxiliary_device * adev,void (* event_handler)(struct auxiliary_device * adev,struct hinic3_event_info * event))170 void hinic3_adev_event_register(struct auxiliary_device *adev,
171 				void (*event_handler)(struct auxiliary_device *adev,
172 						      struct hinic3_event_info *event))
173 {
174 	struct hinic3_adev *hadev;
175 
176 	hadev = container_of(adev, struct hinic3_adev, adev);
177 	hadev->event = event_handler;
178 }
179 
hinic3_adev_event_unregister(struct auxiliary_device * adev)180 void hinic3_adev_event_unregister(struct auxiliary_device *adev)
181 {
182 	struct hinic3_adev *hadev;
183 
184 	hadev = container_of(adev, struct hinic3_adev, adev);
185 	hadev->event = NULL;
186 }
187 
hinic3_mapping_bar(struct pci_dev * pdev,struct hinic3_pcidev * pci_adapter)188 static int hinic3_mapping_bar(struct pci_dev *pdev,
189 			      struct hinic3_pcidev *pci_adapter)
190 {
191 	int cfg_bar;
192 
193 	cfg_bar = HINIC3_IS_VF_DEV(pdev) ?
194 			HINIC3_VF_PCI_CFG_REG_BAR : HINIC3_PF_PCI_CFG_REG_BAR;
195 
196 	pci_adapter->cfg_reg_base = pci_ioremap_bar(pdev, cfg_bar);
197 	if (!pci_adapter->cfg_reg_base) {
198 		dev_err(&pdev->dev, "Failed to map configuration regs\n");
199 		return -ENOMEM;
200 	}
201 
202 	pci_adapter->intr_reg_base = pci_ioremap_bar(pdev,
203 						     HINIC3_PCI_INTR_REG_BAR);
204 	if (!pci_adapter->intr_reg_base) {
205 		dev_err(&pdev->dev, "Failed to map interrupt regs\n");
206 		goto err_unmap_cfg_reg_base;
207 	}
208 
209 	if (!HINIC3_IS_VF_DEV(pdev)) {
210 		pci_adapter->mgmt_reg_base =
211 			pci_ioremap_bar(pdev, HINIC3_PCI_MGMT_REG_BAR);
212 		if (!pci_adapter->mgmt_reg_base) {
213 			dev_err(&pdev->dev, "Failed to map mgmt regs\n");
214 			goto err_unmap_intr_reg_base;
215 		}
216 	}
217 
218 	pci_adapter->db_base_phy = pci_resource_start(pdev, HINIC3_PCI_DB_BAR);
219 	pci_adapter->db_dwqe_len = pci_resource_len(pdev, HINIC3_PCI_DB_BAR);
220 	pci_adapter->db_base = pci_ioremap_bar(pdev, HINIC3_PCI_DB_BAR);
221 	if (!pci_adapter->db_base) {
222 		dev_err(&pdev->dev, "Failed to map doorbell regs\n");
223 		goto err_unmap_mgmt_reg_base;
224 	}
225 
226 	return 0;
227 
228 err_unmap_mgmt_reg_base:
229 	if (!HINIC3_IS_VF_DEV(pdev))
230 		iounmap(pci_adapter->mgmt_reg_base);
231 err_unmap_intr_reg_base:
232 	iounmap(pci_adapter->intr_reg_base);
233 err_unmap_cfg_reg_base:
234 	iounmap(pci_adapter->cfg_reg_base);
235 
236 	return -ENOMEM;
237 }
238 
hinic3_unmapping_bar(struct hinic3_pcidev * pci_adapter)239 static void hinic3_unmapping_bar(struct hinic3_pcidev *pci_adapter)
240 {
241 	iounmap(pci_adapter->db_base);
242 	if (!HINIC3_IS_VF_DEV(pci_adapter->pdev))
243 		iounmap(pci_adapter->mgmt_reg_base);
244 	iounmap(pci_adapter->intr_reg_base);
245 	iounmap(pci_adapter->cfg_reg_base);
246 }
247 
hinic3_pci_init(struct pci_dev * pdev)248 static int hinic3_pci_init(struct pci_dev *pdev)
249 {
250 	struct hinic3_pcidev *pci_adapter;
251 	int err;
252 
253 	pci_adapter = kzalloc_obj(*pci_adapter);
254 	if (!pci_adapter)
255 		return -ENOMEM;
256 
257 	pci_adapter->pdev = pdev;
258 	mutex_init(&pci_adapter->pdev_mutex);
259 
260 	pci_set_drvdata(pdev, pci_adapter);
261 
262 	err = pci_enable_device(pdev);
263 	if (err) {
264 		dev_err(&pdev->dev, "Failed to enable PCI device\n");
265 		goto err_free_pci_adapter;
266 	}
267 
268 	err = pci_request_regions(pdev, HINIC3_NIC_DRV_NAME);
269 	if (err) {
270 		dev_err(&pdev->dev, "Failed to request regions\n");
271 		goto err_disable_device;
272 	}
273 
274 	pci_set_master(pdev);
275 
276 	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
277 	if (err) {
278 		dev_err(&pdev->dev, "Failed to set DMA mask\n");
279 		goto err_release_regions;
280 	}
281 
282 	return 0;
283 
284 err_release_regions:
285 	pci_clear_master(pdev);
286 	pci_release_regions(pdev);
287 err_disable_device:
288 	pci_disable_device(pdev);
289 err_free_pci_adapter:
290 	pci_set_drvdata(pdev, NULL);
291 	mutex_destroy(&pci_adapter->pdev_mutex);
292 	kfree(pci_adapter);
293 
294 	return err;
295 }
296 
hinic3_pci_uninit(struct pci_dev * pdev)297 static void hinic3_pci_uninit(struct pci_dev *pdev)
298 {
299 	struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
300 
301 	pci_clear_master(pdev);
302 	pci_release_regions(pdev);
303 	pci_disable_device(pdev);
304 	pci_set_drvdata(pdev, NULL);
305 	mutex_destroy(&pci_adapter->pdev_mutex);
306 	kfree(pci_adapter);
307 }
308 
hinic3_func_init(struct pci_dev * pdev,struct hinic3_pcidev * pci_adapter)309 static int hinic3_func_init(struct pci_dev *pdev,
310 			    struct hinic3_pcidev *pci_adapter)
311 {
312 	int err;
313 
314 	err = hinic3_init_hwdev(pdev);
315 	if (err) {
316 		dev_err(&pdev->dev, "Failed to initialize hardware device\n");
317 		return err;
318 	}
319 
320 	if (HINIC3_IS_PF(pci_adapter->hwdev))
321 		hinic3_sync_time_to_fw(pci_adapter->hwdev);
322 
323 	err = hinic3_attach_aux_devices(pci_adapter->hwdev);
324 	if (err)
325 		goto err_free_hwdev;
326 
327 	return 0;
328 
329 err_free_hwdev:
330 	hinic3_free_hwdev(pci_adapter->hwdev);
331 
332 	return err;
333 }
334 
hinic3_func_uninit(struct pci_dev * pdev)335 static void hinic3_func_uninit(struct pci_dev *pdev)
336 {
337 	struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
338 
339 	/* disable mgmt reporting before flushing mgmt work-queue. */
340 	hinic3_set_pf_status(pci_adapter->hwdev->hwif, HINIC3_PF_STATUS_INIT);
341 	hinic3_flush_mgmt_workq(pci_adapter->hwdev);
342 	hinic3_detach_aux_devices(pci_adapter->hwdev);
343 	hinic3_free_hwdev(pci_adapter->hwdev);
344 }
345 
hinic3_probe_func(struct hinic3_pcidev * pci_adapter)346 static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
347 {
348 	struct pci_dev *pdev = pci_adapter->pdev;
349 	struct comm_cmd_bdf_info bdf_info = {};
350 	int err;
351 
352 	err = hinic3_mapping_bar(pdev, pci_adapter);
353 	if (err) {
354 		dev_err(&pdev->dev, "Failed to map bar\n");
355 		goto err_out;
356 	}
357 
358 	err = hinic3_func_init(pdev, pci_adapter);
359 	if (err)
360 		goto err_unmap_bar;
361 
362 	if (HINIC3_IS_PF(pci_adapter->hwdev)) {
363 		bdf_info.function_idx =
364 			hinic3_global_func_id(pci_adapter->hwdev);
365 		bdf_info.bus = pdev->bus->number;
366 		bdf_info.device = PCI_SLOT(pdev->devfn);
367 		bdf_info.function =  PCI_FUNC(pdev->devfn);
368 
369 		err = hinic3_set_bdf_ctxt(pci_adapter->hwdev, &bdf_info);
370 		if (err) {
371 			dev_err(&pdev->dev, "Failed to set BDF info to fw\n");
372 			goto err_uninit_func;
373 		}
374 	}
375 
376 	return 0;
377 
378 err_uninit_func:
379 	hinic3_func_uninit(pdev);
380 err_unmap_bar:
381 	hinic3_unmapping_bar(pci_adapter);
382 err_out:
383 	dev_err(&pdev->dev, "PCIe device probe function failed\n");
384 
385 	return err;
386 }
387 
hinic3_remove_func(struct hinic3_pcidev * pci_adapter)388 static void hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
389 {
390 	struct pci_dev *pdev = pci_adapter->pdev;
391 
392 	hinic3_func_uninit(pdev);
393 	hinic3_unmapping_bar(pci_adapter);
394 }
395 
hinic3_probe(struct pci_dev * pdev,const struct pci_device_id * id)396 static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
397 {
398 	struct hinic3_pcidev *pci_adapter;
399 	int err;
400 
401 	err = hinic3_pci_init(pdev);
402 	if (err)
403 		goto err_out;
404 
405 	pci_adapter = pci_get_drvdata(pdev);
406 	err = hinic3_probe_func(pci_adapter);
407 	if (err)
408 		goto err_uninit_pci;
409 
410 	return 0;
411 
412 err_uninit_pci:
413 	hinic3_pci_uninit(pdev);
414 err_out:
415 	dev_err(&pdev->dev, "PCIe device probe failed\n");
416 
417 	return err;
418 }
419 
hinic3_remove(struct pci_dev * pdev)420 static void hinic3_remove(struct pci_dev *pdev)
421 {
422 	struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
423 
424 	hinic3_remove_func(pci_adapter);
425 	hinic3_pci_uninit(pdev);
426 }
427 
428 static const struct pci_device_id hinic3_pci_table[] = {
429 	{PCI_VDEVICE(HUAWEI, PCI_DEV_ID_HINIC3_VF), 0},
430 	{0, 0}
431 
432 };
433 
434 MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
435 
hinic3_shutdown(struct pci_dev * pdev)436 static void hinic3_shutdown(struct pci_dev *pdev)
437 {
438 	struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
439 
440 	pci_disable_device(pdev);
441 
442 	if (pci_adapter)
443 		hinic3_set_api_stop(pci_adapter->hwdev);
444 }
445 
446 static struct pci_driver hinic3_driver = {
447 	.name            = HINIC3_NIC_DRV_NAME,
448 	.id_table        = hinic3_pci_table,
449 	.probe           = hinic3_probe,
450 	.remove          = hinic3_remove,
451 	.shutdown        = hinic3_shutdown,
452 	.sriov_configure = pci_sriov_configure_simple
453 };
454 
hinic3_lld_init(void)455 int hinic3_lld_init(void)
456 {
457 	return pci_register_driver(&hinic3_driver);
458 }
459 
hinic3_lld_exit(void)460 void hinic3_lld_exit(void)
461 {
462 	pci_unregister_driver(&hinic3_driver);
463 }
464