Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
0002 /* Copyright (C) 2017-2019 Netronome Systems, Inc. */
0003 
0004 #include <linux/bitfield.h>
0005 #include <linux/errno.h>
0006 #include <linux/etherdevice.h>
0007 #include <linux/if_link.h>
0008 #include <linux/if_ether.h>
0009 
0010 #include "nfpcore/nfp_cpp.h"
0011 #include "nfp_app.h"
0012 #include "nfp_main.h"
0013 #include "nfp_net_ctrl.h"
0014 #include "nfp_net.h"
0015 #include "nfp_net_sriov.h"
0016 
0017 static int
0018 nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg, bool warn)
0019 {
0020     u16 cap_vf;
0021 
0022     if (!app || !app->pf->vfcfg_tbl2)
0023         return -EOPNOTSUPP;
0024 
0025     cap_vf = readw(app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_CAP);
0026     if ((cap_vf & cap) != cap) {
0027         if (warn)
0028             nfp_warn(app->pf->cpp, "ndo_set_vf_%s not supported\n", msg);
0029         return -EOPNOTSUPP;
0030     }
0031 
0032     if (vf < 0 || vf >= app->pf->num_vfs) {
0033         if (warn)
0034             nfp_warn(app->pf->cpp, "invalid VF id %d\n", vf);
0035         return -EINVAL;
0036     }
0037 
0038     return 0;
0039 }
0040 
0041 static int
0042 nfp_net_sriov_update(struct nfp_app *app, int vf, u16 update, const char *msg)
0043 {
0044     struct nfp_net *nn;
0045     int ret;
0046 
0047     /* Write update info to mailbox in VF config symbol */
0048     writeb(vf, app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_VF_NUM);
0049     writew(update, app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_UPD);
0050 
0051     nn = list_first_entry(&app->pf->vnics, struct nfp_net, vnic_list);
0052     /* Signal VF reconfiguration */
0053     ret = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_VF);
0054     if (ret)
0055         return ret;
0056 
0057     ret = readw(app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_RET);
0058     if (ret)
0059         nfp_warn(app->pf->cpp,
0060              "FW refused VF %s update with errno: %d\n", msg, ret);
0061     return -ret;
0062 }
0063 
0064 int nfp_app_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
0065 {
0066     struct nfp_app *app = nfp_app_from_netdev(netdev);
0067     unsigned int vf_offset;
0068     int err;
0069 
0070     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_MAC, "mac", true);
0071     if (err)
0072         return err;
0073 
0074     if (is_multicast_ether_addr(mac)) {
0075         nfp_warn(app->pf->cpp,
0076              "invalid Ethernet address %pM for VF id %d\n",
0077              mac, vf);
0078         return -EINVAL;
0079     }
0080 
0081     /* Write MAC to VF entry in VF config symbol */
0082     vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ;
0083     writel(get_unaligned_be32(mac), app->pf->vfcfg_tbl2 + vf_offset);
0084     writew(get_unaligned_be16(mac + 4),
0085            app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_MAC_LO);
0086 
0087     err = nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_MAC, "MAC");
0088     if (!err)
0089         nfp_info(app->pf->cpp,
0090              "MAC %pM set on VF %d, reload the VF driver to make this change effective.\n",
0091              mac, vf);
0092 
0093     return err;
0094 }
0095 
0096 int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
0097             __be16 vlan_proto)
0098 {
0099     struct nfp_app *app = nfp_app_from_netdev(netdev);
0100     u16 update = NFP_NET_VF_CFG_MB_UPD_VLAN;
0101     bool is_proto_sup = true;
0102     unsigned int vf_offset;
0103     u32 vlan_tag;
0104     int err;
0105 
0106     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN, "vlan", true);
0107     if (err)
0108         return err;
0109 
0110     if (!eth_type_vlan(vlan_proto))
0111         return -EOPNOTSUPP;
0112 
0113     if (vlan > 4095 || qos > 7) {
0114         nfp_warn(app->pf->cpp,
0115              "invalid vlan id or qos for VF id %d\n", vf);
0116         return -EINVAL;
0117     }
0118 
0119     /* Check if fw supports or not */
0120     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto", true);
0121     if (err)
0122         is_proto_sup = false;
0123 
0124     if (vlan_proto != htons(ETH_P_8021Q)) {
0125         if (!is_proto_sup)
0126             return -EOPNOTSUPP;
0127         update |= NFP_NET_VF_CFG_MB_UPD_VLAN_PROTO;
0128     }
0129 
0130     /* Write VLAN tag to VF entry in VF config symbol */
0131     vlan_tag = FIELD_PREP(NFP_NET_VF_CFG_VLAN_VID, vlan) |
0132         FIELD_PREP(NFP_NET_VF_CFG_VLAN_QOS, qos);
0133 
0134     /* vlan_tag of 0 means that the configuration should be cleared and in
0135      * such circumstances setting the TPID has no meaning when
0136      * configuring firmware.
0137      */
0138     if (vlan_tag && is_proto_sup)
0139         vlan_tag |= FIELD_PREP(NFP_NET_VF_CFG_VLAN_PROT, ntohs(vlan_proto));
0140 
0141     vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ;
0142     writel(vlan_tag, app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN);
0143 
0144     return nfp_net_sriov_update(app, vf, update, "vlan");
0145 }
0146 
0147 int nfp_app_set_vf_rate(struct net_device *netdev, int vf,
0148             int min_tx_rate, int max_tx_rate)
0149 {
0150     struct nfp_app *app = nfp_app_from_netdev(netdev);
0151     u32 vf_offset, ratevalue;
0152     int err;
0153 
0154     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate", true);
0155     if (err)
0156         return err;
0157 
0158     if (max_tx_rate >= NFP_NET_VF_RATE_MAX ||
0159         min_tx_rate >= NFP_NET_VF_RATE_MAX) {
0160         nfp_warn(app->cpp, "tx-rate exceeds %d.\n",
0161              NFP_NET_VF_RATE_MAX);
0162         return -EINVAL;
0163     }
0164 
0165     vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ;
0166     ratevalue = FIELD_PREP(NFP_NET_VF_CFG_MAX_RATE,
0167                    max_tx_rate ? max_tx_rate :
0168                    NFP_NET_VF_RATE_MAX) |
0169             FIELD_PREP(NFP_NET_VF_CFG_MIN_RATE, min_tx_rate);
0170 
0171     writel(ratevalue,
0172            app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_RATE);
0173 
0174     return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_RATE,
0175                     "rate");
0176 }
0177 
0178 int nfp_app_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable)
0179 {
0180     struct nfp_app *app = nfp_app_from_netdev(netdev);
0181     unsigned int vf_offset;
0182     u8 vf_ctrl;
0183     int err;
0184 
0185     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_SPOOF,
0186                   "spoofchk", true);
0187     if (err)
0188         return err;
0189 
0190     /* Write spoof check control bit to VF entry in VF config symbol */
0191     vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ +
0192         NFP_NET_VF_CFG_CTRL;
0193     vf_ctrl = readb(app->pf->vfcfg_tbl2 + vf_offset);
0194     vf_ctrl &= ~NFP_NET_VF_CFG_CTRL_SPOOF;
0195     vf_ctrl |= FIELD_PREP(NFP_NET_VF_CFG_CTRL_SPOOF, enable);
0196     writeb(vf_ctrl, app->pf->vfcfg_tbl2 + vf_offset);
0197 
0198     return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_SPOOF,
0199                     "spoofchk");
0200 }
0201 
0202 int nfp_app_set_vf_trust(struct net_device *netdev, int vf, bool enable)
0203 {
0204     struct nfp_app *app = nfp_app_from_netdev(netdev);
0205     unsigned int vf_offset;
0206     u8 vf_ctrl;
0207     int err;
0208 
0209     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_TRUST,
0210                   "trust", true);
0211     if (err)
0212         return err;
0213 
0214     /* Write trust control bit to VF entry in VF config symbol */
0215     vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ +
0216         NFP_NET_VF_CFG_CTRL;
0217     vf_ctrl = readb(app->pf->vfcfg_tbl2 + vf_offset);
0218     vf_ctrl &= ~NFP_NET_VF_CFG_CTRL_TRUST;
0219     vf_ctrl |= FIELD_PREP(NFP_NET_VF_CFG_CTRL_TRUST, enable);
0220     writeb(vf_ctrl, app->pf->vfcfg_tbl2 + vf_offset);
0221 
0222     return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_TRUST,
0223                     "trust");
0224 }
0225 
0226 int nfp_app_set_vf_link_state(struct net_device *netdev, int vf,
0227                   int link_state)
0228 {
0229     struct nfp_app *app = nfp_app_from_netdev(netdev);
0230     unsigned int vf_offset;
0231     u8 vf_ctrl;
0232     int err;
0233 
0234     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_LINK_STATE,
0235                   "link_state", true);
0236     if (err)
0237         return err;
0238 
0239     switch (link_state) {
0240     case IFLA_VF_LINK_STATE_AUTO:
0241     case IFLA_VF_LINK_STATE_ENABLE:
0242     case IFLA_VF_LINK_STATE_DISABLE:
0243         break;
0244     default:
0245         return -EINVAL;
0246     }
0247 
0248     /* Write link state to VF entry in VF config symbol */
0249     vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ +
0250         NFP_NET_VF_CFG_CTRL;
0251     vf_ctrl = readb(app->pf->vfcfg_tbl2 + vf_offset);
0252     vf_ctrl &= ~NFP_NET_VF_CFG_CTRL_LINK_STATE;
0253     vf_ctrl |= FIELD_PREP(NFP_NET_VF_CFG_CTRL_LINK_STATE, link_state);
0254     writeb(vf_ctrl, app->pf->vfcfg_tbl2 + vf_offset);
0255 
0256     return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_LINK_STATE,
0257                     "link state");
0258 }
0259 
0260 int nfp_app_get_vf_config(struct net_device *netdev, int vf,
0261               struct ifla_vf_info *ivi)
0262 {
0263     struct nfp_app *app = nfp_app_from_netdev(netdev);
0264     u32 vf_offset, mac_hi, rate;
0265     u32 vlan_tag;
0266     u16 mac_lo;
0267     u8 flags;
0268     int err;
0269 
0270     err = nfp_net_sriov_check(app, vf, 0, "", true);
0271     if (err)
0272         return err;
0273 
0274     vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ;
0275 
0276     mac_hi = readl(app->pf->vfcfg_tbl2 + vf_offset);
0277     mac_lo = readw(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_MAC_LO);
0278 
0279     flags = readb(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_CTRL);
0280     vlan_tag = readl(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN);
0281 
0282     memset(ivi, 0, sizeof(*ivi));
0283     ivi->vf = vf;
0284 
0285     put_unaligned_be32(mac_hi, &ivi->mac[0]);
0286     put_unaligned_be16(mac_lo, &ivi->mac[4]);
0287 
0288     ivi->vlan = FIELD_GET(NFP_NET_VF_CFG_VLAN_VID, vlan_tag);
0289     ivi->qos = FIELD_GET(NFP_NET_VF_CFG_VLAN_QOS, vlan_tag);
0290     if (!nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto", false))
0291         ivi->vlan_proto = htons(FIELD_GET(NFP_NET_VF_CFG_VLAN_PROT, vlan_tag));
0292     ivi->spoofchk = FIELD_GET(NFP_NET_VF_CFG_CTRL_SPOOF, flags);
0293     ivi->trusted = FIELD_GET(NFP_NET_VF_CFG_CTRL_TRUST, flags);
0294     ivi->linkstate = FIELD_GET(NFP_NET_VF_CFG_CTRL_LINK_STATE, flags);
0295 
0296     err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate", false);
0297     if (!err) {
0298         rate = readl(app->pf->vfcfg_tbl2 + vf_offset +
0299                  NFP_NET_VF_CFG_RATE);
0300 
0301         ivi->max_tx_rate = FIELD_GET(NFP_NET_VF_CFG_MAX_RATE, rate);
0302         ivi->min_tx_rate = FIELD_GET(NFP_NET_VF_CFG_MIN_RATE, rate);
0303 
0304         if (ivi->max_tx_rate == NFP_NET_VF_RATE_MAX)
0305             ivi->max_tx_rate = 0;
0306         if (ivi->min_tx_rate == NFP_NET_VF_RATE_MAX)
0307             ivi->min_tx_rate = 0;
0308     }
0309 
0310     return 0;
0311 }