1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2019-2021, Intel Corporation. */ 3 4 #include "ice.h" 5 #include "ice_eswitch.h" 6 #include "ice_devlink.h" 7 #include "ice_virtchnl_pf.h" 8 9 /** 10 * ice_repr_get_sw_port_id - get port ID associated with representor 11 * @repr: pointer to port representor 12 */ 13 static int ice_repr_get_sw_port_id(struct ice_repr *repr) 14 { 15 return repr->vf->pf->hw.port_info->lport; 16 } 17 18 /** 19 * ice_repr_get_phys_port_name - get phys port name 20 * @netdev: pointer to port representor netdev 21 * @buf: write here port name 22 * @len: max length of buf 23 */ 24 static int 25 ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len) 26 { 27 struct ice_netdev_priv *np = netdev_priv(netdev); 28 struct ice_repr *repr = np->repr; 29 int res; 30 31 /* Devlink port is registered and devlink core is taking care of name formatting. */ 32 if (repr->vf->devlink_port.devlink) 33 return -EOPNOTSUPP; 34 35 res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr), 36 repr->vf->vf_id); 37 if (res <= 0) 38 return -EOPNOTSUPP; 39 return 0; 40 } 41 42 /** 43 * ice_netdev_to_repr - Get port representor for given netdevice 44 * @netdev: pointer to port representor netdev 45 */ 46 struct ice_repr *ice_netdev_to_repr(struct net_device *netdev) 47 { 48 struct ice_netdev_priv *np = netdev_priv(netdev); 49 50 return np->repr; 51 } 52 53 /** 54 * ice_repr_open - Enable port representor's network interface 55 * @netdev: network interface device structure 56 * 57 * The open entry point is called when a port representor's network 58 * interface is made active by the system (IFF_UP). Corresponding 59 * VF is notified about link status change. 60 * 61 * Returns 0 on success 62 */ 63 static int ice_repr_open(struct net_device *netdev) 64 { 65 struct ice_repr *repr = ice_netdev_to_repr(netdev); 66 struct ice_vf *vf; 67 68 vf = repr->vf; 69 vf->link_forced = true; 70 vf->link_up = true; 71 ice_vc_notify_vf_link_state(vf); 72 73 netif_carrier_on(netdev); 74 netif_tx_start_all_queues(netdev); 75 76 return 0; 77 } 78 79 /** 80 * ice_repr_stop - Disable port representor's network interface 81 * @netdev: network interface device structure 82 * 83 * The stop entry point is called when a port representor's network 84 * interface is de-activated by the system. Corresponding 85 * VF is notified about link status change. 86 * 87 * Returns 0 on success 88 */ 89 static int ice_repr_stop(struct net_device *netdev) 90 { 91 struct ice_repr *repr = ice_netdev_to_repr(netdev); 92 struct ice_vf *vf; 93 94 vf = repr->vf; 95 vf->link_forced = true; 96 vf->link_up = false; 97 ice_vc_notify_vf_link_state(vf); 98 99 netif_carrier_off(netdev); 100 netif_tx_stop_all_queues(netdev); 101 102 return 0; 103 } 104 105 static struct devlink_port * 106 ice_repr_get_devlink_port(struct net_device *netdev) 107 { 108 struct ice_repr *repr = ice_netdev_to_repr(netdev); 109 110 return &repr->vf->devlink_port; 111 } 112 113 static const struct net_device_ops ice_repr_netdev_ops = { 114 .ndo_get_phys_port_name = ice_repr_get_phys_port_name, 115 .ndo_open = ice_repr_open, 116 .ndo_stop = ice_repr_stop, 117 .ndo_get_devlink_port = ice_repr_get_devlink_port, 118 }; 119 120 /** 121 * ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev 122 * @netdev: pointer to netdev 123 */ 124 bool ice_is_port_repr_netdev(struct net_device *netdev) 125 { 126 return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops); 127 } 128 129 /** 130 * ice_repr_reg_netdev - register port representor netdev 131 * @netdev: pointer to port representor netdev 132 */ 133 static int 134 ice_repr_reg_netdev(struct net_device *netdev) 135 { 136 eth_hw_addr_random(netdev); 137 netdev->netdev_ops = &ice_repr_netdev_ops; 138 139 netif_carrier_off(netdev); 140 netif_tx_stop_all_queues(netdev); 141 142 return register_netdev(netdev); 143 } 144 145 /** 146 * ice_repr_add - add representor for VF 147 * @vf: pointer to VF structure 148 */ 149 static int ice_repr_add(struct ice_vf *vf) 150 { 151 struct ice_q_vector *q_vector; 152 struct ice_netdev_priv *np; 153 struct ice_repr *repr; 154 int err; 155 156 repr = kzalloc(sizeof(*repr), GFP_KERNEL); 157 if (!repr) 158 return -ENOMEM; 159 160 repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv)); 161 if (!repr->netdev) { 162 err = -ENOMEM; 163 goto err_alloc; 164 } 165 166 repr->src_vsi = ice_get_vf_vsi(vf); 167 repr->vf = vf; 168 vf->repr = repr; 169 np = netdev_priv(repr->netdev); 170 np->repr = repr; 171 172 q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL); 173 if (!q_vector) { 174 err = -ENOMEM; 175 goto err_alloc_q_vector; 176 } 177 repr->q_vector = q_vector; 178 179 err = ice_devlink_create_vf_port(vf); 180 if (err) 181 goto err_devlink; 182 183 err = ice_repr_reg_netdev(repr->netdev); 184 if (err) 185 goto err_netdev; 186 187 devlink_port_type_eth_set(&vf->devlink_port, repr->netdev); 188 189 return 0; 190 191 err_netdev: 192 ice_devlink_destroy_vf_port(vf); 193 err_devlink: 194 kfree(repr->q_vector); 195 vf->repr->q_vector = NULL; 196 err_alloc_q_vector: 197 free_netdev(repr->netdev); 198 repr->netdev = NULL; 199 err_alloc: 200 kfree(repr); 201 vf->repr = NULL; 202 return err; 203 } 204 205 /** 206 * ice_repr_rem - remove representor from VF 207 * @vf: pointer to VF structure 208 */ 209 static void ice_repr_rem(struct ice_vf *vf) 210 { 211 ice_devlink_destroy_vf_port(vf); 212 kfree(vf->repr->q_vector); 213 vf->repr->q_vector = NULL; 214 unregister_netdev(vf->repr->netdev); 215 free_netdev(vf->repr->netdev); 216 vf->repr->netdev = NULL; 217 kfree(vf->repr); 218 vf->repr = NULL; 219 } 220 221 /** 222 * ice_repr_add_for_all_vfs - add port representor for all VFs 223 * @pf: pointer to PF structure 224 */ 225 int ice_repr_add_for_all_vfs(struct ice_pf *pf) 226 { 227 int err; 228 int i; 229 230 ice_for_each_vf(pf, i) { 231 struct ice_vf *vf = &pf->vf[i]; 232 233 err = ice_repr_add(vf); 234 if (err) 235 goto err; 236 237 ice_vc_change_ops_to_repr(&vf->vc_ops); 238 } 239 240 return 0; 241 242 err: 243 for (i = i - 1; i >= 0; i--) { 244 struct ice_vf *vf = &pf->vf[i]; 245 246 ice_repr_rem(vf); 247 ice_vc_set_dflt_vf_ops(&vf->vc_ops); 248 } 249 250 return err; 251 } 252 253 /** 254 * ice_repr_rem_from_all_vfs - remove port representor for all VFs 255 * @pf: pointer to PF structure 256 */ 257 void ice_repr_rem_from_all_vfs(struct ice_pf *pf) 258 { 259 int i; 260 261 ice_for_each_vf(pf, i) { 262 struct ice_vf *vf = &pf->vf[i]; 263 264 ice_repr_rem(vf); 265 ice_vc_set_dflt_vf_ops(&vf->vc_ops); 266 } 267 } 268