From b64052fc9bcb4fa3ca8701e74c1aac0e2847b724 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pablo=20Casc=C3=B3n?= Date: Thu, 15 Jun 2017 16:22:15 -0700 Subject: [PATCH] nfp: add VLAN filtering support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add general use per-vNIC mailbox area and use it for VLAN filtering support. Initially proto is hardcoded to 802.1q. Signed-off-by: Pablo Cascón Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- .../ethernet/netronome/nfp/nfp_net_common.c | 74 ++++++++++++++++++- .../net/ethernet/netronome/nfp/nfp_net_ctrl.h | 27 +++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 378512dec80d..2bdddd1ae666 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -280,6 +280,30 @@ int nfp_net_reconfig(struct nfp_net *nn, u32 update) return ret; } +/** + * nfp_net_reconfig_mbox() - Reconfigure the firmware via the mailbox + * @nn: NFP Net device to reconfigure + * @mbox_cmd: The value for the mailbox command + * + * Helper function for mailbox updates + * + * Return: Negative errno on error, 0 on success + */ +static int nfp_net_reconfig_mbox(struct nfp_net *nn, u32 mbox_cmd) +{ + int ret; + + nn_writeq(nn, NFP_NET_CFG_MBOX_CMD, mbox_cmd); + + ret = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_MBOX); + if (ret) { + nn_err(nn, "Mailbox update error\n"); + return ret; + } + + return -nn_readl(nn, NFP_NET_CFG_MBOX_RET); +} + /* Interrupt configuration and handling */ @@ -2960,6 +2984,40 @@ static int nfp_net_change_mtu(struct net_device *netdev, int new_mtu) return nfp_net_ring_reconfig(nn, dp, NULL); } +static int +nfp_net_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid) +{ + struct nfp_net *nn = netdev_priv(netdev); + + /* Priority tagged packets with vlan id 0 are processed by the + * NFP as untagged packets + */ + if (!vid) + return 0; + + nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_VID, vid); + nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_PROTO, ETH_P_8021Q); + + return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD); +} + +static int +nfp_net_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid) +{ + struct nfp_net *nn = netdev_priv(netdev); + + /* Priority tagged packets with vlan id 0 are processed by the + * NFP as untagged packets + */ + if (!vid) + return 0; + + nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_VID, vid); + nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_PROTO, ETH_P_8021Q); + + return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL); +} + static void nfp_net_stat64(struct net_device *netdev, struct rtnl_link_stats64 *stats) { @@ -3053,6 +3111,13 @@ static int nfp_net_set_features(struct net_device *netdev, new_ctrl &= ~NFP_NET_CFG_CTRL_TXVLAN; } + if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) { + if (features & NETIF_F_HW_VLAN_CTAG_FILTER) + new_ctrl |= NFP_NET_CFG_CTRL_CTAG_FILTER; + else + new_ctrl &= ~NFP_NET_CFG_CTRL_CTAG_FILTER; + } + if (changed & NETIF_F_SG) { if (features & NETIF_F_SG) new_ctrl |= NFP_NET_CFG_CTRL_GATHER; @@ -3289,6 +3354,8 @@ const struct net_device_ops nfp_net_netdev_ops = { .ndo_stop = nfp_net_netdev_close, .ndo_start_xmit = nfp_net_tx, .ndo_get_stats64 = nfp_net_stat64, + .ndo_vlan_rx_add_vid = nfp_net_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = nfp_net_vlan_rx_kill_vid, .ndo_setup_tc = nfp_net_setup_tc, .ndo_tx_timeout = nfp_net_tx_timeout, .ndo_set_rx_mode = nfp_net_set_rx_mode, @@ -3316,7 +3383,7 @@ void nfp_net_info(struct nfp_net *nn) nn->fw_ver.resv, nn->fw_ver.class, nn->fw_ver.major, nn->fw_ver.minor, nn->max_mtu); - nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", nn->cap, nn->cap & NFP_NET_CFG_CTRL_PROMISC ? "PROMISC " : "", nn->cap & NFP_NET_CFG_CTRL_L2BC ? "L2BCFILT " : "", @@ -3331,6 +3398,7 @@ void nfp_net_info(struct nfp_net *nn) nn->cap & NFP_NET_CFG_CTRL_LSO2 ? "TSO2 " : "", nn->cap & NFP_NET_CFG_CTRL_RSS ? "RSS1 " : "", nn->cap & NFP_NET_CFG_CTRL_RSS2 ? "RSS2 " : "", + nn->cap & NFP_NET_CFG_CTRL_CTAG_FILTER ? "CTAG_FILTER " : "", nn->cap & NFP_NET_CFG_CTRL_L2SWITCH ? "L2SWITCH " : "", nn->cap & NFP_NET_CFG_CTRL_MSIXAUTO ? "AUTOMASK " : "", nn->cap & NFP_NET_CFG_CTRL_IRQMOD ? "IRQMOD " : "", @@ -3547,6 +3615,10 @@ static void nfp_net_netdev_init(struct nfp_net *nn) nn->dp.ctrl |= NFP_NET_CFG_CTRL_TXVLAN; } } + if (nn->cap & NFP_NET_CFG_CTRL_CTAG_FILTER) { + netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; + nn->dp.ctrl |= NFP_NET_CFG_CTRL_CTAG_FILTER; + } netdev->features = netdev->hw_features; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h index 48a8bf97645e..e5e94e0746ec 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h @@ -124,6 +124,7 @@ #define NFP_NET_CFG_CTRL_SCATTER (0x1 << 8) /* Scatter DMA */ #define NFP_NET_CFG_CTRL_GATHER (0x1 << 9) /* Gather DMA */ #define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO (version 1) */ +#define NFP_NET_CFG_CTRL_CTAG_FILTER (0x1 << 11) /* VLAN CTAG filtering */ #define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */ #define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS (version 1) */ #define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */ @@ -162,6 +163,7 @@ #define NFP_NET_CFG_UPDATE_VXLAN (0x1 << 9) /* VXLAN port change */ #define NFP_NET_CFG_UPDATE_BPF (0x1 << 10) /* BPF program load */ #define NFP_NET_CFG_UPDATE_MACADDR (0x1 << 11) /* MAC address change */ +#define NFP_NET_CFG_UPDATE_MBOX (0x1 << 12) /* Mailbox update */ #define NFP_NET_CFG_UPDATE_ERR (0x1 << 31) /* A error occurred */ #define NFP_NET_CFG_TXRS_ENABLE 0x0008 #define NFP_NET_CFG_RXRS_ENABLE 0x0010 @@ -400,4 +402,29 @@ #define NFP_NET_CFG_RXR_STATS(_x) (NFP_NET_CFG_RXR_STATS_BASE + \ ((_x) * 0x10)) +/** + * General use mailbox area (0x1800 - 0x19ff) + * 4B used for update command and 4B return code + * followed by a max of 504B of variable length value + */ +#define NFP_NET_CFG_MBOX_CMD 0x1800 +#define NFP_NET_CFG_MBOX_RET 0x1804 +#define NFP_NET_CFG_MBOX_VAL 0x1808 +#define NFP_NET_CFG_MBOX_VAL_MAX_SZ 0x1F8 + +#define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD 1 +#define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL 2 + +/** + * VLAN filtering using general use mailbox + * @NFP_NET_CFG_VLAN_FILTER: Base address of VLAN filter mailbox + * @NFP_NET_CFG_VLAN_FILTER_VID: VLAN ID to filter + * @NFP_NET_CFG_VLAN_FILTER_PROTO: VLAN proto to filter + * @NFP_NET_CFG_VXLAN_SZ: Size of the VLAN filter mailbox in bytes + */ +#define NFP_NET_CFG_VLAN_FILTER NFP_NET_CFG_MBOX_VAL +#define NFP_NET_CFG_VLAN_FILTER_VID NFP_NET_CFG_VLAN_FILTER +#define NFP_NET_CFG_VLAN_FILTER_PROTO (NFP_NET_CFG_VLAN_FILTER + 2) +#define NFP_NET_CFG_VLAN_FILTER_SZ 0x0004 + #endif /* _NFP_NET_CTRL_H_ */ -- 2.20.1