Commit 90a825a4 authored by David S. Miller's avatar David S. Miller

Merge branch 'dpaa2-switch-tc-hw-offload'

Ioana Ciornei says:

====================
dpaa2-switch: add tc hardware offload on ingress traffic

This patch set adds tc hardware offload on ingress traffic in
dpaa2-switch. The cls flower and matchall classifiers are supported
using the same ACL infrastructure supported by the dpaa2-switch.

The first patch creates a new structure to hold all the necessary
information related to an ACL table. This structure is used in the next
patches to create a link between each switch port and the table used.
Multiple ports can share the same ACL table when they also share the
ingress tc block. Also, some small changes in the priority of the
default STP trap is done in the second patch.

The support for cls flower is added in the 3rd patch, while the 4th
one builds on top of the infrastructure put in place and adds cls
matchall support.

The following flow keys are supported:
 - Ethernet: dst_mac/src_mac
 - IPv4: dst_ip/src_ip/ip_proto/tos
 - VLAN: vlan_id/vlan_prio/vlan_tpid/vlan_dei
 - L4: dst_port/src_port

Each filter can support only one action from the following list:
 - drop
 - mirred egress redirect
 - trap

With the last patch, we reuse the dpaa2_switch_acl_entry_add() function
added previously instead of open-coding the install of a new ACL entry
into the table.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5871d0c6 16617954
......@@ -11,7 +11,7 @@ fsl-dpaa2-eth-objs := dpaa2-eth.o dpaa2-ethtool.o dpni.o dpaa2-mac.o dpmac.o dpa
fsl-dpaa2-eth-${CONFIG_FSL_DPAA2_ETH_DCB} += dpaa2-eth-dcb.o
fsl-dpaa2-eth-${CONFIG_DEBUG_FS} += dpaa2-eth-debugfs.o
fsl-dpaa2-ptp-objs := dpaa2-ptp.o dprtc.o
fsl-dpaa2-switch-objs := dpaa2-switch.o dpaa2-switch-ethtool.o dpsw.o
fsl-dpaa2-switch-objs := dpaa2-switch.o dpaa2-switch-ethtool.o dpsw.o dpaa2-switch-flower.o
# Needed by the tracing framework
CFLAGS_dpaa2-eth.o := -I$(src)
This diff is collapsed.
......@@ -18,6 +18,7 @@
#include <net/switchdev.h>
#include <linux/if_bridge.h>
#include <linux/fsl/mc.h>
#include <net/pkt_cls.h>
#include <soc/fsl/dpaa2-io.h>
#include "dpsw.h"
......@@ -80,6 +81,8 @@
(DPAA2_SWITCH_TX_DATA_OFFSET + DPAA2_SWITCH_TX_BUF_ALIGN)
#define DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES 16
#define DPAA2_ETHSW_PORT_DEFAULT_TRAPS 1
#define DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE 256
extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops;
......@@ -101,6 +104,34 @@ struct dpaa2_switch_fdb {
bool in_use;
};
struct dpaa2_switch_acl_entry {
struct list_head list;
u16 prio;
unsigned long cookie;
struct dpsw_acl_entry_cfg cfg;
struct dpsw_acl_key key;
};
struct dpaa2_switch_acl_tbl {
struct list_head entries;
struct ethsw_core *ethsw;
u64 ports;
u16 id;
u8 num_rules;
bool in_use;
};
static inline bool
dpaa2_switch_acl_tbl_is_full(struct dpaa2_switch_acl_tbl *acl_tbl)
{
if ((acl_tbl->num_rules + DPAA2_ETHSW_PORT_DEFAULT_TRAPS) >=
DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES)
return true;
return false;
}
/* Per port private data */
struct ethsw_port_priv {
struct net_device *netdev;
......@@ -118,8 +149,7 @@ struct ethsw_port_priv {
bool ucast_flood;
bool learn_ena;
u16 acl_tbl;
u8 acl_num_rules;
struct dpaa2_switch_acl_tbl *acl_tbl;
};
/* Switch data */
......@@ -145,8 +175,21 @@ struct ethsw_core {
int napi_users;
struct dpaa2_switch_fdb *fdbs;
struct dpaa2_switch_acl_tbl *acls;
};
static inline int dpaa2_switch_get_index(struct ethsw_core *ethsw,
struct net_device *netdev)
{
int i;
for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
if (ethsw->ports[i]->netdev == netdev)
return ethsw->ports[i]->idx;
return -EINVAL;
}
static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw)
{
if (ethsw->sw_attr.options & DPSW_OPT_CTRL_IF_DIS) {
......@@ -183,4 +226,21 @@ int dpaa2_switch_port_vlans_del(struct net_device *netdev,
typedef int dpaa2_switch_fdb_cb_t(struct ethsw_port_priv *port_priv,
struct fdb_dump_entry *fdb_entry,
void *data);
/* TC offload */
int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
struct flow_cls_offload *cls);
int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
struct flow_cls_offload *cls);
int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl,
struct tc_cls_matchall_offload *cls);
int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl,
struct tc_cls_matchall_offload *cls);
int dpaa2_switch_acl_entry_add(struct dpaa2_switch_acl_tbl *acl_tbl,
struct dpaa2_switch_acl_entry *entry);
#endif /* __ETHSW_H */
......@@ -77,6 +77,7 @@
#define DPSW_CMDID_ACL_ADD DPSW_CMD_ID(0x090)
#define DPSW_CMDID_ACL_REMOVE DPSW_CMD_ID(0x091)
#define DPSW_CMDID_ACL_ADD_ENTRY DPSW_CMD_ID(0x092)
#define DPSW_CMDID_ACL_REMOVE_ENTRY DPSW_CMD_ID(0x093)
#define DPSW_CMDID_ACL_ADD_IF DPSW_CMD_ID(0x094)
#define DPSW_CMDID_ACL_REMOVE_IF DPSW_CMD_ID(0x095)
......
......@@ -1544,3 +1544,38 @@ int dpsw_acl_add_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_acl_remove_entry() - Removes an entry from ACL.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @acl_id: ACL ID
* @cfg: Entry configuration
*
* warning: This function has to be called after dpsw_acl_set_entry_cfg()
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
u16 acl_id, const struct dpsw_acl_entry_cfg *cfg)
{
struct dpsw_cmd_acl_entry *cmd_params;
struct fsl_mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_ENTRY,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params;
cmd_params->acl_id = cpu_to_le16(acl_id);
cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id);
cmd_params->precedence = cpu_to_le32(cfg->precedence);
cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
dpsw_set_field(cmd_params->result_action,
RESULT_ACTION,
cfg->result.action);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
......@@ -749,4 +749,7 @@ void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key,
int dpsw_acl_add_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
u16 acl_id, const struct dpsw_acl_entry_cfg *cfg);
int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
u16 acl_id, const struct dpsw_acl_entry_cfg *cfg);
#endif /* __FSL_DPSW_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment