nfp: provide infrastructure for offloading flower based TC filters
Adds a flower based TC offload handler for representor devices, this is in addition to the bpf based offload handler. The changes in this patch will be used in a follow-up patch to add tc flower offload to the NFP. The flower app enables tc offloads on representors by default. Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com> Signed-off-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
8f15df600d
Коммит
8a2768732a
|
@ -32,7 +32,8 @@ nfp-objs := \
|
|||
ifeq ($(CONFIG_NFP_APP_FLOWER),y)
|
||||
nfp-objs += \
|
||||
flower/cmsg.o \
|
||||
flower/main.o
|
||||
flower/main.o \
|
||||
flower/offload.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BPF_SYSCALL),y)
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
#include <net/devlink.h>
|
||||
#include <net/dst_metadata.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "../nfpcore/nfp_cpp.h"
|
||||
#include "../nfpcore/nfp_nffw.h"
|
||||
#include "../nfpcore/nfp_nsp.h"
|
||||
#include "../nfp_app.h"
|
||||
#include "../nfp_main.h"
|
||||
|
@ -46,6 +48,8 @@
|
|||
#include "../nfp_port.h"
|
||||
#include "./cmsg.h"
|
||||
|
||||
#define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL
|
||||
|
||||
/**
|
||||
* struct nfp_flower_priv - Flower APP per-vNIC priv data
|
||||
* @nn: Pointer to vNIC
|
||||
|
@ -313,6 +317,8 @@ err_invalid_port:
|
|||
static int nfp_flower_init(struct nfp_app *app)
|
||||
{
|
||||
const struct nfp_pf *pf = app->pf;
|
||||
u64 version;
|
||||
int err;
|
||||
|
||||
if (!pf->eth_tbl) {
|
||||
nfp_warn(app->cpp, "FlowerNIC requires eth table\n");
|
||||
|
@ -329,6 +335,18 @@ static int nfp_flower_init(struct nfp_app *app)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
version = nfp_rtsym_read_le(app->pf->rtbl, "hw_flower_version", &err);
|
||||
if (err) {
|
||||
nfp_warn(app->cpp, "FlowerNIC requires hw_flower_version memory symbol\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* We need to ensure hardware has enough flower capabilities. */
|
||||
if (version != NFP_FLOWER_ALLOWED_VER) {
|
||||
nfp_warn(app->cpp, "FlowerNIC: unsupported firmware version\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
app->priv = kzalloc(sizeof(struct nfp_flower_priv), GFP_KERNEL);
|
||||
if (!app->priv)
|
||||
return -ENOMEM;
|
||||
|
@ -367,4 +385,6 @@ const struct nfp_app_type app_flower = {
|
|||
|
||||
.eswitch_mode_get = eswitch_mode_get,
|
||||
.repr_get = nfp_flower_repr_get,
|
||||
|
||||
.setup_tc = nfp_flower_setup_tc,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Netronome Systems, Inc.
|
||||
*
|
||||
* This software is dual licensed under the GNU General License Version 2,
|
||||
* June 1991 as shown in the file COPYING in the top-level directory of this
|
||||
* source tree or the BSD 2-Clause License provided below. You have the
|
||||
* option to license this software under the complete terms of either license.
|
||||
*
|
||||
* The BSD 2-Clause License:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __NFP_FLOWER_H__
|
||||
#define __NFP_FLOWER_H__ 1
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct tc_to_netdev;
|
||||
struct net_device;
|
||||
struct nfp_app;
|
||||
|
||||
int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev,
|
||||
u32 handle, __be16 proto, struct tc_to_netdev *tc);
|
||||
#endif
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Netronome Systems, Inc.
|
||||
*
|
||||
* This software is dual licensed under the GNU General License Version 2,
|
||||
* June 1991 as shown in the file COPYING in the top-level directory of this
|
||||
* source tree or the BSD 2-Clause License provided below. You have the
|
||||
* option to license this software under the complete terms of either license.
|
||||
*
|
||||
* The BSD 2-Clause License:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/devlink.h>
|
||||
#include <net/pkt_cls.h>
|
||||
|
||||
#include "cmsg.h"
|
||||
#include "main.h"
|
||||
#include "../nfpcore/nfp_cpp.h"
|
||||
#include "../nfpcore/nfp_nsp.h"
|
||||
#include "../nfp_app.h"
|
||||
#include "../nfp_main.h"
|
||||
#include "../nfp_net.h"
|
||||
#include "../nfp_port.h"
|
||||
|
||||
/**
|
||||
* nfp_flower_add_offload() - Adds a new flow to hardware.
|
||||
* @app: Pointer to the APP handle
|
||||
* @netdev: netdev structure.
|
||||
* @flow: TC flower classifier offload structure.
|
||||
*
|
||||
* Adds a new flow to the repeated hash structure and action payload.
|
||||
*
|
||||
* Return: negative value on error, 0 if configured successfully.
|
||||
*/
|
||||
static int
|
||||
nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
|
||||
struct tc_cls_flower_offload *flow)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfp_flower_del_offload() - Removes a flow from hardware.
|
||||
* @app: Pointer to the APP handle
|
||||
* @netdev: netdev structure.
|
||||
* @flow: TC flower classifier offload structure
|
||||
*
|
||||
* Removes a flow from the repeated hash structure and clears the
|
||||
* action payload.
|
||||
*
|
||||
* Return: negative value on error, 0 if removed successfully.
|
||||
*/
|
||||
static int
|
||||
nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
|
||||
struct tc_cls_flower_offload *flow)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfp_flower_get_stats() - Populates flow stats obtained from hardware.
|
||||
* @app: Pointer to the APP handle
|
||||
* @flow: TC flower classifier offload structure
|
||||
*
|
||||
* Populates a flow statistics structure which which corresponds to a
|
||||
* specific flow.
|
||||
*
|
||||
* Return: negative value on error, 0 if stats populated successfully.
|
||||
*/
|
||||
static int
|
||||
nfp_flower_get_stats(struct nfp_app *app, struct tc_cls_flower_offload *flow)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev,
|
||||
struct tc_cls_flower_offload *flower)
|
||||
{
|
||||
switch (flower->command) {
|
||||
case TC_CLSFLOWER_REPLACE:
|
||||
return nfp_flower_add_offload(app, netdev, flower);
|
||||
case TC_CLSFLOWER_DESTROY:
|
||||
return nfp_flower_del_offload(app, netdev, flower);
|
||||
case TC_CLSFLOWER_STATS:
|
||||
return nfp_flower_get_stats(app, flower);
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev,
|
||||
u32 handle, __be16 proto, struct tc_to_netdev *tc)
|
||||
{
|
||||
if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!eth_proto_is_802_3(proto))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (tc->type != TC_SETUP_CLSFLOWER)
|
||||
return -EINVAL;
|
||||
|
||||
return nfp_flower_repr_offload(app, netdev, tc->cls_flower);
|
||||
}
|
|
@ -3097,18 +3097,6 @@ static void nfp_net_stat64(struct net_device *netdev,
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_net_setup_tc(struct net_device *netdev, u32 handle, u32 chain_index,
|
||||
__be16 proto, struct tc_to_netdev *tc)
|
||||
{
|
||||
struct nfp_net *nn = netdev_priv(netdev);
|
||||
|
||||
if (chain_index)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return nfp_app_setup_tc(nn->app, netdev, handle, proto, tc);
|
||||
}
|
||||
|
||||
static int nfp_net_set_features(struct net_device *netdev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
|
@ -3424,7 +3412,7 @@ const struct net_device_ops nfp_net_netdev_ops = {
|
|||
.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_setup_tc = nfp_port_setup_tc,
|
||||
.ndo_tx_timeout = nfp_net_tx_timeout,
|
||||
.ndo_set_rx_mode = nfp_net_set_rx_mode,
|
||||
.ndo_change_mtu = nfp_net_change_mtu,
|
||||
|
|
|
@ -258,6 +258,7 @@ const struct net_device_ops nfp_repr_netdev_ops = {
|
|||
.ndo_has_offload_stats = nfp_repr_has_offload_stats,
|
||||
.ndo_get_offload_stats = nfp_repr_get_offload_stats,
|
||||
.ndo_get_phys_port_name = nfp_port_get_phys_port_name,
|
||||
.ndo_setup_tc = nfp_port_setup_tc,
|
||||
};
|
||||
|
||||
static void nfp_repr_clean(struct nfp_repr *repr)
|
||||
|
@ -302,6 +303,11 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
|
|||
netdev->netdev_ops = &nfp_repr_netdev_ops;
|
||||
SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops);
|
||||
|
||||
if (nfp_app_has_tc(app)) {
|
||||
netdev->features |= NETIF_F_HW_TC;
|
||||
netdev->hw_features |= NETIF_F_HW_TC;
|
||||
}
|
||||
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
goto err_clean;
|
||||
|
|
|
@ -88,6 +88,21 @@ const struct switchdev_ops nfp_port_switchdev_ops = {
|
|||
.switchdev_port_attr_get = nfp_port_attr_get,
|
||||
};
|
||||
|
||||
int nfp_port_setup_tc(struct net_device *netdev, u32 handle, u32 chain_index,
|
||||
__be16 proto, struct tc_to_netdev *tc)
|
||||
{
|
||||
struct nfp_port *port;
|
||||
|
||||
if (chain_index)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
port = nfp_port_from_netdev(netdev);
|
||||
if (!port)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return nfp_app_setup_tc(port->app, netdev, handle, proto, tc);
|
||||
}
|
||||
|
||||
struct nfp_port *
|
||||
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <net/devlink.h>
|
||||
|
||||
struct tc_to_netdev;
|
||||
struct net_device;
|
||||
struct nfp_app;
|
||||
struct nfp_pf;
|
||||
|
@ -108,6 +109,9 @@ struct nfp_port {
|
|||
|
||||
extern const struct switchdev_ops nfp_port_switchdev_ops;
|
||||
|
||||
int nfp_port_setup_tc(struct net_device *netdev, u32 handle, u32 chain_index,
|
||||
__be16 proto, struct tc_to_netdev *tc);
|
||||
|
||||
struct nfp_port *nfp_port_from_netdev(struct net_device *netdev);
|
||||
struct nfp_port *
|
||||
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id);
|
||||
|
|
Загрузка…
Ссылка в новой задаче