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