xref: /linux/drivers/net/ethernet/intel/ice/ice_sf_eth.c (revision 177ef7f1e2a051e8962048ffd41973d29be3302c)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2024, Intel Corporation. */
3 #include "ice.h"
4 #include "ice_lib.h"
5 #include "ice_fltr.h"
6 #include "ice_sf_eth.h"
7 #include "devlink/devlink_port.h"
8 #include "devlink/devlink.h"
9 
10 /**
11  * ice_sf_dev_probe - subfunction driver probe function
12  * @adev: pointer to the auxiliary device
13  * @id: pointer to the auxiliary_device id
14  *
15  * Configure VSI and netdev resources for the subfunction device.
16  *
17  * Return: zero on success or an error code on failure.
18  */
19 static int ice_sf_dev_probe(struct auxiliary_device *adev,
20 			    const struct auxiliary_device_id *id)
21 {
22 	struct ice_sf_dev *sf_dev = ice_adev_to_sf_dev(adev);
23 	struct ice_dynamic_port *dyn_port = sf_dev->dyn_port;
24 	struct ice_vsi *vsi = dyn_port->vsi;
25 	struct ice_pf *pf = dyn_port->pf;
26 	struct device *dev = &adev->dev;
27 	struct ice_sf_priv *priv;
28 	struct devlink *devlink;
29 	int err;
30 
31 	vsi->type = ICE_VSI_SF;
32 	vsi->port_info = pf->hw.port_info;
33 	vsi->flags = ICE_VSI_FLAG_INIT;
34 
35 	priv = ice_allocate_sf(&adev->dev, pf);
36 	if (!priv) {
37 		dev_err(dev, "Subfunction devlink alloc failed");
38 		return -ENOMEM;
39 	}
40 
41 	priv->dev = sf_dev;
42 	sf_dev->priv = priv;
43 	devlink = priv_to_devlink(priv);
44 
45 	devl_lock(devlink);
46 
47 	err = ice_vsi_cfg(vsi);
48 	if (err) {
49 		dev_err(dev, "Subfunction vsi config failed");
50 		goto err_free_devlink;
51 	}
52 	vsi->sf = dyn_port;
53 
54 	err = ice_devlink_create_sf_dev_port(sf_dev);
55 	if (err) {
56 		dev_err(dev, "Cannot add ice virtual devlink port for subfunction");
57 		goto err_vsi_decfg;
58 	}
59 
60 	err = devl_port_fn_devlink_set(&dyn_port->devlink_port, devlink);
61 	if (err) {
62 		dev_err(dev, "Can't link devlink instance to SF devlink port");
63 		goto err_devlink_destroy;
64 	}
65 
66 	ice_napi_add(vsi);
67 
68 	devl_register(devlink);
69 	devl_unlock(devlink);
70 
71 	return 0;
72 
73 err_devlink_destroy:
74 	ice_devlink_destroy_sf_dev_port(sf_dev);
75 err_vsi_decfg:
76 	ice_vsi_decfg(vsi);
77 err_free_devlink:
78 	devl_unlock(devlink);
79 	devlink_free(devlink);
80 	return err;
81 }
82 
83 /**
84  * ice_sf_dev_remove - subfunction driver remove function
85  * @adev: pointer to the auxiliary device
86  *
87  * Deinitalize VSI and netdev resources for the subfunction device.
88  */
89 static void ice_sf_dev_remove(struct auxiliary_device *adev)
90 {
91 	struct ice_sf_dev *sf_dev = ice_adev_to_sf_dev(adev);
92 	struct ice_dynamic_port *dyn_port = sf_dev->dyn_port;
93 	struct ice_vsi *vsi = dyn_port->vsi;
94 	struct devlink *devlink;
95 
96 	devlink = priv_to_devlink(sf_dev->priv);
97 	devl_lock(devlink);
98 
99 	ice_vsi_close(vsi);
100 
101 	ice_devlink_destroy_sf_dev_port(sf_dev);
102 	devl_unregister(devlink);
103 	devl_unlock(devlink);
104 	devlink_free(devlink);
105 	ice_vsi_decfg(vsi);
106 }
107 
108 static const struct auxiliary_device_id ice_sf_dev_id_table[] = {
109 	{ .name = "ice.sf", },
110 	{ },
111 };
112 
113 MODULE_DEVICE_TABLE(auxiliary, ice_sf_dev_id_table);
114 
115 static struct auxiliary_driver ice_sf_driver = {
116 	.name = "sf",
117 	.probe = ice_sf_dev_probe,
118 	.remove = ice_sf_dev_remove,
119 	.id_table = ice_sf_dev_id_table
120 };
121 
122 /**
123  * ice_sf_driver_register - Register new auxiliary subfunction driver
124  *
125  * Return: zero on success or an error code on failure.
126  */
127 int ice_sf_driver_register(void)
128 {
129 	return auxiliary_driver_register(&ice_sf_driver);
130 }
131 
132 /**
133  * ice_sf_driver_unregister - Unregister new auxiliary subfunction driver
134  *
135  */
136 void ice_sf_driver_unregister(void)
137 {
138 	auxiliary_driver_unregister(&ice_sf_driver);
139 }
140