On Tue, Oct 17, 2017 at 2:18 PM, Shannon Nelson
wrote:
> This patch adds support for macvlan hardware offload (l2-fwd-offload)
> feature using the XL710's macvlan-to-queue filtering machanism. These
> are most useful for supporting separate mac addresses for Container
> virtualization using Docker and similar configurations.
>
> The basic design is to partition off some of the PF's general LAN queues
> outside of the standard RSS pool and use them as the offload queues.
> This especially makes sense on machines with more than 64 CPUs: since
> the RSS pool is limited to a maximum of 64, the queues assigned to the
> remaining CPUs essentially go unused. When on a machine with fewer than
> 64 CPUs, we shrink the RSS pool and use the upper queues for the offload.
>
> If the user has added Flow Director filters, enabling of macvlan offload
> is disallowed.
>
> To use this feature, use ethtool to enable l2-fwd-offload
> ethtool -K ethX l2-fwd-offload on
> When the next macvlan devices are created on ethX, the macvlan driver
> will automatically attempt to setup the hardweare offload.
>
> Signed-off-by: Shannon Nelson
> ---
> drivers/net/ethernet/intel/i40e/i40e.h | 10 +
> drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 15 ++
> drivers/net/ethernet/intel/i40e/i40e_main.c| 239
> +++-
> drivers/net/ethernet/intel/i40e/i40e_txrx.h|1 +
> 4 files changed, 264 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e.h
> b/drivers/net/ethernet/intel/i40e/i40e.h
> index a187f53..4868ae2 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e.h
> +++ b/drivers/net/ethernet/intel/i40e/i40e.h
> @@ -365,6 +365,10 @@ struct i40e_pf {
> u8 atr_sample_rate;
> bool wol_en;
>
> + u16 macvlan_hint;
> + u16 macvlan_used;
> + u16 macvlan_num;
> +
> struct hlist_head fdir_filter_list;
> u16 fdir_pf_active_filters;
> unsigned long fd_flush_timestamp;
> @@ -712,6 +716,12 @@ struct i40e_netdev_priv {
> struct i40e_vsi *vsi;
> };
>
> +struct i40e_fwd {
> + struct net_device *vdev;
> + u16 tx_base_queue;
> + /* future expansion here might include number of queues */
> +};
> +
> /* struct that defines an interrupt vector */
> struct i40e_q_vector {
> struct i40e_vsi *vsi;
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> index afd3ca8..e1628c1 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> @@ -3817,6 +3817,13 @@ static int i40e_set_rxnfc(struct net_device *netdev,
> struct ethtool_rxnfc *cmd)
> struct i40e_pf *pf = vsi->back;
> int ret = -EOPNOTSUPP;
>
> + if (pf->macvlan_num) {
> + dev_warn(>pdev->dev,
> +"Remove %d remaining macvlan offloads to change
> filter options\n",
> +pf->macvlan_used);
> + return -EBUSY;
> + }
> +
> switch (cmd->cmd) {
> case ETHTOOL_SRXFH:
> ret = i40e_set_rss_hash_opt(pf, cmd);
> @@ -3909,6 +3916,14 @@ static int i40e_set_channels(struct net_device *dev,
> if (count > i40e_max_channels(vsi))
> return -EINVAL;
>
> + /* verify that macvlan offloads are not in use */
> + if (pf->macvlan_num) {
> + dev_warn(>pdev->dev,
> +"Remove %d remaining macvlan offloads to change
> channel count\n",
> +pf->macvlan_used);
> + return -EBUSY;
> + }
> +
> /* verify that the number of channels does not invalidate any current
> * flow director rules
> */
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index e4b8a4b..7b26c6f 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -9221,6 +9221,66 @@ static void i40e_clear_rss_lut(struct i40e_vsi *vsi)
> }
>
> /**
> + * i40e_fix_features - fix the proposed netdev feature flags
> + * @netdev: ptr to the netdev being adjusted
> + * @features: the feature set that the stack is suggesting
> + * Note: expects to be called while under rtnl_lock()
> + **/
> +static netdev_features_t i40e_fix_features(struct net_device *netdev,
> + netdev_features_t features)
> +{
> + struct i40e_netdev_priv *np = netdev_priv(netdev);
> + struct i40e_pf *pf = np->vsi->back;
> + struct i40e_vsi *vsi = np->vsi;
> +
> + /* make sure there are queues to be used for macvlan offload */
> + if (features & NETIF_F_HW_L2FW_DOFFLOAD &&
> + !(netdev->features & NETIF_F_HW_L2FW_DOFFLOAD)) {
> + const u8 drop = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
> +