nfp: support 802.1ad VLAN assingment to VF
authorBaowen Zheng <baowen.zheng@corigine.com>
Tue, 19 Apr 2022 12:44:43 +0000 (14:44 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 22 Apr 2022 10:00:42 +0000 (11:00 +0100)
The NFP driver already supports assignment of 802.1Q VLANs to VFs

e.g.
 # ip link set $DEV vf $VF_NUM vlan $VLAN_ID [proto 802.1Q]

This patch enhances the NFP driver to also allow assingment of
802.1ad VLANs to VFs.

e.g.
 # ip link set $DEV vf $VF_NUM vlan $VLAN_ID proto 802.1ad

Signed-off-by: Bin Chen <bin.chen@corigine.com>
Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com>
Signed-off-by: Yinjun Zhang <yunjin.zhang@corigine.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfp_net_sriov.c
drivers/net/ethernet/netronome/nfp/nfp_net_sriov.h

index 3fdaaf8ed2ba494dc272ae2b452a70bfa39422e7..4627715a5e323b62a085f99b666c94f58072dda3 100644 (file)
@@ -95,15 +95,17 @@ int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
                        __be16 vlan_proto)
 {
        struct nfp_app *app = nfp_app_from_netdev(netdev);
+       u16 update = NFP_NET_VF_CFG_MB_UPD_VLAN;
+       bool is_proto_sup = true;
        unsigned int vf_offset;
-       u16 vlan_tci;
+       u32 vlan_tag;
        int err;
 
        err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN, "vlan");
        if (err)
                return err;
 
-       if (vlan_proto != htons(ETH_P_8021Q))
+       if (!eth_type_vlan(vlan_proto))
                return -EOPNOTSUPP;
 
        if (vlan > 4095 || qos > 7) {
@@ -112,14 +114,32 @@ int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
                return -EINVAL;
        }
 
+       /* Check if fw supports or not */
+       err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto");
+       if (err)
+               is_proto_sup = false;
+
+       if (vlan_proto != htons(ETH_P_8021Q)) {
+               if (!is_proto_sup)
+                       return -EOPNOTSUPP;
+               update |= NFP_NET_VF_CFG_MB_UPD_VLAN_PROTO;
+       }
+
        /* Write VLAN tag to VF entry in VF config symbol */
-       vlan_tci = FIELD_PREP(NFP_NET_VF_CFG_VLAN_VID, vlan) |
+       vlan_tag = FIELD_PREP(NFP_NET_VF_CFG_VLAN_VID, vlan) |
                FIELD_PREP(NFP_NET_VF_CFG_VLAN_QOS, qos);
+
+       /* vlan_tag of 0 means that the configuration should be cleared and in
+        * such circumstances setting the TPID has no meaning when
+        * configuring firmware.
+        */
+       if (vlan_tag && is_proto_sup)
+               vlan_tag |= FIELD_PREP(NFP_NET_VF_CFG_VLAN_PROT, ntohs(vlan_proto));
+
        vf_offset = NFP_NET_VF_CFG_MB_SZ + vf * NFP_NET_VF_CFG_SZ;
-       writew(vlan_tci, app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN);
+       writel(vlan_tag, app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN);
 
-       return nfp_net_sriov_update(app, vf, NFP_NET_VF_CFG_MB_UPD_VLAN,
-                                   "vlan");
+       return nfp_net_sriov_update(app, vf, update, "vlan");
 }
 
 int nfp_app_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable)
@@ -209,7 +229,7 @@ int nfp_app_get_vf_config(struct net_device *netdev, int vf,
 {
        struct nfp_app *app = nfp_app_from_netdev(netdev);
        unsigned int vf_offset;
-       u16 vlan_tci;
+       u32 vlan_tag;
        u32 mac_hi;
        u16 mac_lo;
        u8 flags;
@@ -225,7 +245,7 @@ int nfp_app_get_vf_config(struct net_device *netdev, int vf,
        mac_lo = readw(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_MAC_LO);
 
        flags = readb(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_CTRL);
-       vlan_tci = readw(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN);
+       vlan_tag = readl(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_VLAN);
 
        memset(ivi, 0, sizeof(*ivi));
        ivi->vf = vf;
@@ -233,9 +253,10 @@ int nfp_app_get_vf_config(struct net_device *netdev, int vf,
        put_unaligned_be32(mac_hi, &ivi->mac[0]);
        put_unaligned_be16(mac_lo, &ivi->mac[4]);
 
-       ivi->vlan = FIELD_GET(NFP_NET_VF_CFG_VLAN_VID, vlan_tci);
-       ivi->qos = FIELD_GET(NFP_NET_VF_CFG_VLAN_QOS, vlan_tci);
-
+       ivi->vlan = FIELD_GET(NFP_NET_VF_CFG_VLAN_VID, vlan_tag);
+       ivi->qos = FIELD_GET(NFP_NET_VF_CFG_VLAN_QOS, vlan_tag);
+       if (!nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto"))
+               ivi->vlan_proto = htons(FIELD_GET(NFP_NET_VF_CFG_VLAN_PROT, vlan_tag));
        ivi->spoofchk = FIELD_GET(NFP_NET_VF_CFG_CTRL_SPOOF, flags);
        ivi->trusted = FIELD_GET(NFP_NET_VF_CFG_CTRL_TRUST, flags);
        ivi->linkstate = FIELD_GET(NFP_NET_VF_CFG_CTRL_LINK_STATE, flags);
index 786be58a907e6b985b35b202df78a078f5970aea..7b72cc0834765a7c296be50522ae2515c342596f 100644 (file)
@@ -19,6 +19,7 @@
 #define   NFP_NET_VF_CFG_MB_CAP_SPOOF                    (0x1 << 2)
 #define   NFP_NET_VF_CFG_MB_CAP_LINK_STATE               (0x1 << 3)
 #define   NFP_NET_VF_CFG_MB_CAP_TRUST                    (0x1 << 4)
+#define   NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO               (0x1 << 5)
 #define NFP_NET_VF_CFG_MB_RET                          0x2
 #define NFP_NET_VF_CFG_MB_UPD                          0x4
 #define   NFP_NET_VF_CFG_MB_UPD_MAC                      (0x1 << 0)
@@ -26,6 +27,7 @@
 #define   NFP_NET_VF_CFG_MB_UPD_SPOOF                    (0x1 << 2)
 #define   NFP_NET_VF_CFG_MB_UPD_LINK_STATE               (0x1 << 3)
 #define   NFP_NET_VF_CFG_MB_UPD_TRUST                    (0x1 << 4)
+#define   NFP_NET_VF_CFG_MB_UPD_VLAN_PROTO               (0x1 << 5)
 #define NFP_NET_VF_CFG_MB_VF_NUM                       0x7
 
 /* VF config entry
@@ -43,6 +45,7 @@
 #define     NFP_NET_VF_CFG_LS_MODE_ENABLE                  1
 #define     NFP_NET_VF_CFG_LS_MODE_DISABLE                 2
 #define NFP_NET_VF_CFG_VLAN                            0x8
+#define   NFP_NET_VF_CFG_VLAN_PROT                       0xffff0000
 #define   NFP_NET_VF_CFG_VLAN_QOS                        0xe000
 #define   NFP_NET_VF_CFG_VLAN_VID                        0x0fff