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