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