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