xref: /linux/drivers/infiniband/hw/ionic/ionic_ibdev.c (revision 8d765af51a099884bab37a51e211c7047f67f1f3)
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