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