1*8d765af5SAbhijit Gangurde // SPDX-License-Identifier: GPL-2.0 2*8d765af5SAbhijit Gangurde /* Copyright (C) 2018-2025, Advanced Micro Devices, Inc. */ 3*8d765af5SAbhijit Gangurde 4*8d765af5SAbhijit Gangurde #include <linux/module.h> 5*8d765af5SAbhijit Gangurde #include <linux/printk.h> 6*8d765af5SAbhijit Gangurde #include <net/addrconf.h> 7*8d765af5SAbhijit Gangurde 8*8d765af5SAbhijit Gangurde #include "ionic_ibdev.h" 9*8d765af5SAbhijit Gangurde 10*8d765af5SAbhijit Gangurde #define DRIVER_DESCRIPTION "AMD Pensando RoCE HCA driver" 11*8d765af5SAbhijit Gangurde #define DEVICE_DESCRIPTION "AMD Pensando RoCE HCA" 12*8d765af5SAbhijit Gangurde 13*8d765af5SAbhijit Gangurde MODULE_AUTHOR("Allen Hubbe <allen.hubbe@amd.com>"); 14*8d765af5SAbhijit Gangurde MODULE_DESCRIPTION(DRIVER_DESCRIPTION); 15*8d765af5SAbhijit Gangurde MODULE_LICENSE("GPL"); 16*8d765af5SAbhijit Gangurde MODULE_IMPORT_NS("NET_IONIC"); 17*8d765af5SAbhijit Gangurde 18*8d765af5SAbhijit Gangurde static void ionic_destroy_ibdev(struct ionic_ibdev *dev) 19*8d765af5SAbhijit Gangurde { 20*8d765af5SAbhijit Gangurde ib_unregister_device(&dev->ibdev); 21*8d765af5SAbhijit Gangurde ib_dealloc_device(&dev->ibdev); 22*8d765af5SAbhijit Gangurde } 23*8d765af5SAbhijit Gangurde 24*8d765af5SAbhijit Gangurde static struct ionic_ibdev *ionic_create_ibdev(struct ionic_aux_dev *ionic_adev) 25*8d765af5SAbhijit Gangurde { 26*8d765af5SAbhijit Gangurde struct ib_device *ibdev; 27*8d765af5SAbhijit Gangurde struct ionic_ibdev *dev; 28*8d765af5SAbhijit Gangurde struct net_device *ndev; 29*8d765af5SAbhijit Gangurde int rc; 30*8d765af5SAbhijit Gangurde 31*8d765af5SAbhijit Gangurde dev = ib_alloc_device(ionic_ibdev, ibdev); 32*8d765af5SAbhijit Gangurde if (!dev) 33*8d765af5SAbhijit Gangurde return ERR_PTR(-EINVAL); 34*8d765af5SAbhijit Gangurde 35*8d765af5SAbhijit Gangurde ionic_fill_lif_cfg(ionic_adev->lif, &dev->lif_cfg); 36*8d765af5SAbhijit Gangurde 37*8d765af5SAbhijit Gangurde ibdev = &dev->ibdev; 38*8d765af5SAbhijit Gangurde ibdev->dev.parent = dev->lif_cfg.hwdev; 39*8d765af5SAbhijit Gangurde 40*8d765af5SAbhijit Gangurde strscpy(ibdev->name, "ionic_%d", IB_DEVICE_NAME_MAX); 41*8d765af5SAbhijit Gangurde strscpy(ibdev->node_desc, DEVICE_DESCRIPTION, IB_DEVICE_NODE_DESC_MAX); 42*8d765af5SAbhijit Gangurde 43*8d765af5SAbhijit Gangurde ibdev->node_type = RDMA_NODE_IB_CA; 44*8d765af5SAbhijit Gangurde ibdev->phys_port_cnt = 1; 45*8d765af5SAbhijit Gangurde 46*8d765af5SAbhijit Gangurde /* the first two eq are reserved for async events */ 47*8d765af5SAbhijit Gangurde ibdev->num_comp_vectors = dev->lif_cfg.eq_count - 2; 48*8d765af5SAbhijit Gangurde 49*8d765af5SAbhijit Gangurde ndev = ionic_lif_netdev(ionic_adev->lif); 50*8d765af5SAbhijit Gangurde addrconf_ifid_eui48((u8 *)&ibdev->node_guid, ndev); 51*8d765af5SAbhijit Gangurde rc = ib_device_set_netdev(ibdev, ndev, 1); 52*8d765af5SAbhijit Gangurde /* ionic_lif_netdev() returns ndev with refcount held */ 53*8d765af5SAbhijit Gangurde dev_put(ndev); 54*8d765af5SAbhijit Gangurde if (rc) 55*8d765af5SAbhijit Gangurde goto err_admin; 56*8d765af5SAbhijit Gangurde 57*8d765af5SAbhijit Gangurde rc = ib_register_device(ibdev, "ionic_%d", ibdev->dev.parent); 58*8d765af5SAbhijit Gangurde if (rc) 59*8d765af5SAbhijit Gangurde goto err_register; 60*8d765af5SAbhijit Gangurde 61*8d765af5SAbhijit Gangurde return dev; 62*8d765af5SAbhijit Gangurde 63*8d765af5SAbhijit Gangurde err_register: 64*8d765af5SAbhijit Gangurde err_admin: 65*8d765af5SAbhijit Gangurde ib_dealloc_device(&dev->ibdev); 66*8d765af5SAbhijit Gangurde 67*8d765af5SAbhijit Gangurde return ERR_PTR(rc); 68*8d765af5SAbhijit Gangurde } 69*8d765af5SAbhijit Gangurde 70*8d765af5SAbhijit Gangurde static int ionic_aux_probe(struct auxiliary_device *adev, 71*8d765af5SAbhijit Gangurde const struct auxiliary_device_id *id) 72*8d765af5SAbhijit Gangurde { 73*8d765af5SAbhijit Gangurde struct ionic_aux_dev *ionic_adev; 74*8d765af5SAbhijit Gangurde struct ionic_ibdev *dev; 75*8d765af5SAbhijit Gangurde 76*8d765af5SAbhijit Gangurde ionic_adev = container_of(adev, struct ionic_aux_dev, adev); 77*8d765af5SAbhijit Gangurde dev = ionic_create_ibdev(ionic_adev); 78*8d765af5SAbhijit Gangurde if (IS_ERR(dev)) 79*8d765af5SAbhijit Gangurde return dev_err_probe(&adev->dev, PTR_ERR(dev), 80*8d765af5SAbhijit Gangurde "Failed to register ibdev\n"); 81*8d765af5SAbhijit Gangurde 82*8d765af5SAbhijit Gangurde auxiliary_set_drvdata(adev, dev); 83*8d765af5SAbhijit Gangurde ibdev_dbg(&dev->ibdev, "registered\n"); 84*8d765af5SAbhijit Gangurde 85*8d765af5SAbhijit Gangurde return 0; 86*8d765af5SAbhijit Gangurde } 87*8d765af5SAbhijit Gangurde 88*8d765af5SAbhijit Gangurde static void ionic_aux_remove(struct auxiliary_device *adev) 89*8d765af5SAbhijit Gangurde { 90*8d765af5SAbhijit Gangurde struct ionic_ibdev *dev = auxiliary_get_drvdata(adev); 91*8d765af5SAbhijit Gangurde 92*8d765af5SAbhijit Gangurde dev_dbg(&adev->dev, "unregister ibdev\n"); 93*8d765af5SAbhijit Gangurde ionic_destroy_ibdev(dev); 94*8d765af5SAbhijit Gangurde dev_dbg(&adev->dev, "unregistered\n"); 95*8d765af5SAbhijit Gangurde } 96*8d765af5SAbhijit Gangurde 97*8d765af5SAbhijit Gangurde static const struct auxiliary_device_id ionic_aux_id_table[] = { 98*8d765af5SAbhijit Gangurde { .name = "ionic.rdma", }, 99*8d765af5SAbhijit Gangurde {}, 100*8d765af5SAbhijit Gangurde }; 101*8d765af5SAbhijit Gangurde 102*8d765af5SAbhijit Gangurde MODULE_DEVICE_TABLE(auxiliary, ionic_aux_id_table); 103*8d765af5SAbhijit Gangurde 104*8d765af5SAbhijit Gangurde static struct auxiliary_driver ionic_aux_r_driver = { 105*8d765af5SAbhijit Gangurde .name = "rdma", 106*8d765af5SAbhijit Gangurde .probe = ionic_aux_probe, 107*8d765af5SAbhijit Gangurde .remove = ionic_aux_remove, 108*8d765af5SAbhijit Gangurde .id_table = ionic_aux_id_table, 109*8d765af5SAbhijit Gangurde }; 110*8d765af5SAbhijit Gangurde 111*8d765af5SAbhijit Gangurde static int __init ionic_mod_init(void) 112*8d765af5SAbhijit Gangurde { 113*8d765af5SAbhijit Gangurde int rc; 114*8d765af5SAbhijit Gangurde 115*8d765af5SAbhijit Gangurde rc = auxiliary_driver_register(&ionic_aux_r_driver); 116*8d765af5SAbhijit Gangurde if (rc) 117*8d765af5SAbhijit Gangurde goto err_aux; 118*8d765af5SAbhijit Gangurde 119*8d765af5SAbhijit Gangurde return 0; 120*8d765af5SAbhijit Gangurde 121*8d765af5SAbhijit Gangurde err_aux: 122*8d765af5SAbhijit Gangurde return rc; 123*8d765af5SAbhijit Gangurde } 124*8d765af5SAbhijit Gangurde 125*8d765af5SAbhijit Gangurde static void __exit ionic_mod_exit(void) 126*8d765af5SAbhijit Gangurde { 127*8d765af5SAbhijit Gangurde auxiliary_driver_unregister(&ionic_aux_r_driver); 128*8d765af5SAbhijit Gangurde } 129*8d765af5SAbhijit Gangurde 130*8d765af5SAbhijit Gangurde module_init(ionic_mod_init); 131*8d765af5SAbhijit Gangurde module_exit(ionic_mod_exit); 132