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