1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 /* Copyright (C) 2017-2019 Netronome Systems, Inc. */ 3 4 #include <linux/bitfield.h> 5 #include <linux/errno.h> 6 #include <linux/etherdevice.h> 7 #include <linux/if_link.h> 8 #include <linux/if_ether.h> 9 10 #include "nfpcore/nfp_cpp.h" 11 #include "nfp_app.h" 12 #include "nfp_main.h" 13 #include "nfp_net_ctrl.h" 14 #include "nfp_net.h" 15 #include "nfp_net_sriov.h" 16 17 static int 18 nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg) 19 { 20 u16 cap_vf; 21 22 if (!app || !app->pf->vfcfg_tbl2) 23 return -EOPNOTSUPP; 24 25 cap_vf = readw(app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_CAP); 26 if ((cap_vf & cap) != cap) { 27 nfp_warn(app->pf->cpp, "ndo_set_vf_%s not supported\n", msg); 28 return -EOPNOTSUPP; 29 } 30 31 if (vf < 0 || vf >= app->pf->num_vfs) { 32 nfp_warn(app->pf->cpp, "invalid VF id %d\n", vf); 33 return -EINVAL; 34 } 35 36 return 0; 37 } 38 39 static int 40 nfp_net_sriov_update(struct nfp_app *app, int vf, u16 update, const char *msg) 41 { 42 struct nfp_net *nn; 43 int ret; 44 45 /* Write update info to mailbox in VF config symbol */ 46 writeb(vf, app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_VF_NUM); 47 writew(update, app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_UPD); 48 49 nn = list_first_entry(&app->pf->vnics, struct nfp_net, vnic_list); 50 /* Signal VF reconfiguration */ 51 ret = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_VF); 52 if (ret) 53 return ret; 54 55 ret = readw(app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_RET); 56 if (ret) 57 nfp_warn(app->pf->cpp, 58 "FW refused VF %s update with errno: %d\n", msg, ret); 59 return -ret; 60 } 61 62 int nfp_app_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) 63 { 64 struct nfp_app *app = nfp_app_from_netdev(netdev); 65 unsigned int vf_offset; 66 int err; 67 68 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_MAC, "mac"); 69 if (err) 70 return err; 71 72 if (is_multicast_ether_addr(mac)) { 73 nfp_warn(app->pf->cpp, 74 "invalid Ethernet address %pM for VF id %d\n", 75 mac, vf); 76 return -EINVAL; 77 } 78 79 /* Write MAC to VF entry in VF config symbol */ 80 vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ; 81 writel(get_unaligned_be32(mac), app->pf->vfcfg_tbl2 + vf_offset); 82 writew(get_unaligned_be16(mac + 4), 83 app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_MAC_LO); 84 85 err = nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_MAC, "MAC"); 86 if (!err) 87 nfp_info(app->pf->cpp, 88 "MAC %pM set on VF %d, reload the VF driver to make this change effective.\n", 89 mac, vf); 90 91 return err; 92 } 93 94 int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos, 95 __be16 vlan_proto) 96 { 97 struct nfp_app *app = nfp_app_from_netdev(netdev); 98 u16 update = NFP_NET_VF_CFG_MB_UPD_VLAN; 99 bool is_proto_sup = true; 100 unsigned int vf_offset; 101 u32 vlan_tag; 102 int err; 103 104 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN, "vlan"); 105 if (err) 106 return err; 107 108 if (!eth_type_vlan(vlan_proto)) 109 return -EOPNOTSUPP; 110 111 if (vlan > 4095 || qos > 7) { 112 nfp_warn(app->pf->cpp, 113 "invalid vlan id or qos for VF id %d\n", vf); 114 return -EINVAL; 115 } 116 117 /* Check if fw supports or not */ 118 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto"); 119 if (err) 120 is_proto_sup = false; 121 122 if (vlan_proto != htons(ETH_P_8021Q)) { 123 if (!is_proto_sup) 124 return -EOPNOTSUPP; 125 update |= NFP_NET_VF_CFG_MB_UPD_VLAN_PROTO; 126 } 127 128 /* Write VLAN tag to VF entry in VF config symbol */ 129 vlan_tag = FIELD_PREP(NFP_NET_VF_CFG_VLAN_VID, vlan) | 130 FIELD_PREP(NFP_NET_VF_CFG_VLAN_QOS, qos); 131 132 /* vlan_tag of 0 means that the configuration should be cleared and in 133 * such circumstances setting the TPID has no meaning when 134 * configuring firmware. 135 */ 136 if (vlan_tag && is_proto_sup) 137 vlan_tag |= FIELD_PREP(NFP_NET_VF_CFG_VLAN_PROT, ntohs(vlan_proto)); 138 139 vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ; 140 writel(vlan_tag, app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN); 141 142 return nfp_net_sriov_update(app, vf, update, "vlan"); 143 } 144 145 int nfp_app_set_vf_rate(struct net_device *netdev, int vf, 146 int min_tx_rate, int max_tx_rate) 147 { 148 struct nfp_app *app = nfp_app_from_netdev(netdev); 149 u32 vf_offset, ratevalue; 150 int err; 151 152 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate"); 153 if (err) 154 return err; 155 156 if (max_tx_rate >= NFP_NET_VF_RATE_MAX || 157 min_tx_rate >= NFP_NET_VF_RATE_MAX) { 158 nfp_warn(app->cpp, "tx-rate exceeds %d.\n", 159 NFP_NET_VF_RATE_MAX); 160 return -EINVAL; 161 } 162 163 vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ; 164 ratevalue = FIELD_PREP(NFP_NET_VF_CFG_MAX_RATE, 165 max_tx_rate ? max_tx_rate : 166 NFP_NET_VF_RATE_MAX) | 167 FIELD_PREP(NFP_NET_VF_CFG_MIN_RATE, min_tx_rate); 168 169 writel(ratevalue, 170 app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_RATE); 171 172 return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_RATE, 173 "rate"); 174 } 175 176 int nfp_app_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable) 177 { 178 struct nfp_app *app = nfp_app_from_netdev(netdev); 179 unsigned int vf_offset; 180 u8 vf_ctrl; 181 int err; 182 183 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_SPOOF, 184 "spoofchk"); 185 if (err) 186 return err; 187 188 /* Write spoof check control bit to VF entry in VF config symbol */ 189 vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ + 190 NFP_NET_VF_CFG_CTRL; 191 vf_ctrl = readb(app->pf->vfcfg_tbl2 + vf_offset); 192 vf_ctrl &= ~NFP_NET_VF_CFG_CTRL_SPOOF; 193 vf_ctrl |= FIELD_PREP(NFP_NET_VF_CFG_CTRL_SPOOF, enable); 194 writeb(vf_ctrl, app->pf->vfcfg_tbl2 + vf_offset); 195 196 return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_SPOOF, 197 "spoofchk"); 198 } 199 200 int nfp_app_set_vf_trust(struct net_device *netdev, int vf, bool enable) 201 { 202 struct nfp_app *app = nfp_app_from_netdev(netdev); 203 unsigned int vf_offset; 204 u8 vf_ctrl; 205 int err; 206 207 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_TRUST, 208 "trust"); 209 if (err) 210 return err; 211 212 /* Write trust control bit to VF entry in VF config symbol */ 213 vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ + 214 NFP_NET_VF_CFG_CTRL; 215 vf_ctrl = readb(app->pf->vfcfg_tbl2 + vf_offset); 216 vf_ctrl &= ~NFP_NET_VF_CFG_CTRL_TRUST; 217 vf_ctrl |= FIELD_PREP(NFP_NET_VF_CFG_CTRL_TRUST, enable); 218 writeb(vf_ctrl, app->pf->vfcfg_tbl2 + vf_offset); 219 220 return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_TRUST, 221 "trust"); 222 } 223 224 int nfp_app_set_vf_link_state(struct net_device *netdev, int vf, 225 int link_state) 226 { 227 struct nfp_app *app = nfp_app_from_netdev(netdev); 228 unsigned int vf_offset; 229 u8 vf_ctrl; 230 int err; 231 232 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_LINK_STATE, 233 "link_state"); 234 if (err) 235 return err; 236 237 switch (link_state) { 238 case IFLA_VF_LINK_STATE_AUTO: 239 case IFLA_VF_LINK_STATE_ENABLE: 240 case IFLA_VF_LINK_STATE_DISABLE: 241 break; 242 default: 243 return -EINVAL; 244 } 245 246 /* Write link state to VF entry in VF config symbol */ 247 vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ + 248 NFP_NET_VF_CFG_CTRL; 249 vf_ctrl = readb(app->pf->vfcfg_tbl2 + vf_offset); 250 vf_ctrl &= ~NFP_NET_VF_CFG_CTRL_LINK_STATE; 251 vf_ctrl |= FIELD_PREP(NFP_NET_VF_CFG_CTRL_LINK_STATE, link_state); 252 writeb(vf_ctrl, app->pf->vfcfg_tbl2 + vf_offset); 253 254 return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_LINK_STATE, 255 "link state"); 256 } 257 258 int nfp_app_get_vf_config(struct net_device *netdev, int vf, 259 struct ifla_vf_info *ivi) 260 { 261 struct nfp_app *app = nfp_app_from_netdev(netdev); 262 u32 vf_offset, mac_hi, rate; 263 u32 vlan_tag; 264 u16 mac_lo; 265 u8 flags; 266 int err; 267 268 err = nfp_net_sriov_check(app, vf, 0, ""); 269 if (err) 270 return err; 271 272 vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ; 273 274 mac_hi = readl(app->pf->vfcfg_tbl2 + vf_offset); 275 mac_lo = readw(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_MAC_LO); 276 277 flags = readb(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_CTRL); 278 vlan_tag = readl(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN); 279 280 memset(ivi, 0, sizeof(*ivi)); 281 ivi->vf = vf; 282 283 put_unaligned_be32(mac_hi, &ivi->mac[0]); 284 put_unaligned_be16(mac_lo, &ivi->mac[4]); 285 286 ivi->vlan = FIELD_GET(NFP_NET_VF_CFG_VLAN_VID, vlan_tag); 287 ivi->qos = FIELD_GET(NFP_NET_VF_CFG_VLAN_QOS, vlan_tag); 288 if (!nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto")) 289 ivi->vlan_proto = htons(FIELD_GET(NFP_NET_VF_CFG_VLAN_PROT, vlan_tag)); 290 ivi->spoofchk = FIELD_GET(NFP_NET_VF_CFG_CTRL_SPOOF, flags); 291 ivi->trusted = FIELD_GET(NFP_NET_VF_CFG_CTRL_TRUST, flags); 292 ivi->linkstate = FIELD_GET(NFP_NET_VF_CFG_CTRL_LINK_STATE, flags); 293 294 err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate"); 295 if (!err) { 296 rate = readl(app->pf->vfcfg_tbl2 + vf_offset + 297 NFP_NET_VF_CFG_RATE); 298 299 ivi->max_tx_rate = FIELD_GET(NFP_NET_VF_CFG_MAX_RATE, rate); 300 ivi->min_tx_rate = FIELD_GET(NFP_NET_VF_CFG_MIN_RATE, rate); 301 302 if (ivi->max_tx_rate == NFP_NET_VF_RATE_MAX) 303 ivi->max_tx_rate = 0; 304 if (ivi->min_tx_rate == NFP_NET_VF_RATE_MAX) 305 ivi->min_tx_rate = 0; 306 } 307 308 return 0; 309 } 310